جاری‌سازی پیام‌ها بااستفاده از Google Chat API

این راهنما توضیح می‌دهد که چگونه بااستفاده از منبع StreamMessage در Chat API، پیام‌ها را به‌صورت افزایشی در Google Chat جاری‌سازی کنید. جاری‌سازی به برنامه Google Chat شما امکان می‌دهد تا پیش‌از نهایی کردن پیام، نشانگرهای پیشرفت زنده، مراحل استدلال یا اجرای ابزار واسط، و پاسخ‌های نوشتاری افزایشی را نمایش دهد.

جاری‌سازی برای برنامه‌های Chat طراحی شده است که از هوش مصنوعی زایا یا گردش‌های کاری پس‌زمینه طولانی‌مدت استفاده می‌کنند، جایی که تولید پاسخ کامل چندین ثانیه یا دقیقه طول می‌کشد.

نحوه عملکرد جاری‌سازی پیام

پیام جاری‌سازی قبل‌از تبدیل شدن به منبع استاندارد Message در فضا، ازطریق وضعیت جاری‌سازی فعال پیشرفت می‌کند:

  1. شروع جاری‌سازی (spaces.streamMessages.create): برنامه Chat شما یک StreamMessage در فضای رشته‌ای ایجاد می‌کند و به پیام تعامل کاربر که به آن پاسخ می‌دهد ارجاع می‌دهد. ‫API نشانگر پیشرفت هم‌زمان را در رشته نمایش می‌دهد و نام منبع StreamMessage و nextChunkToken اولیه را برمی‌گرداند.
  2. به‌روزرسانی جاری‌سازی (appendStreamMessageContent یا patch): همان‌طور که برنامه Chat شما خروجی تولید می‌کند، به‌روزرسانی‌های متوالی را بااستفاده از جدیدترین nextChunkToken ارسال می‌کند:
    • برای به‌هم پیوستن تکه‌های نوشتار جدید، افزودن مراحل میانی، افزودن نقل‌قول‌های درون‌خطی، یا به‌روزرسانی progressText، spaces.streamMessages.appendStreamMessageContent را فراخوانی کنید.
    • برای جایگزین کردن بخش‌های محتوای جاری‌شده یا به‌روزرسانی progressText در محل، spaces.streamMessages.patch را فراخوانی کنید.
  3. جاری‌سازی را نهایی یا حذف کنید (commit یا delete):
    • برای نهایی کردن جاری‌سازی و تبدیل آن به منبع دائمی Message، با spaces.streamMessages.commit تماس بگیرید. همچنین می‌توانید عناصر فقط-ثبت‌شدنی مثل کارت‌ها، ابزاره‌های جانبی، و منابع پانویس را هنگام ثبت کردن پیوست کنید.
    • برای صرف‌نظر کردن از جاری‌سازی فعال بدون ذخیره کردن پیام در فضا، spaces.streamMessages.delete را فراخوانی کنید.

وقتی جاری‌سازی فعال است، فقط فرستنده پیام مرجع (referencedMessage) که درحال جاری‌سازی است می‌تواند روی توقف کلیک کند تا تولید را لغو کند. ‫Chat رویداد فرمان سیستم لغو را به برنامه Chat شما ارسال می‌کند تا بتوانید کار پسین را متوقف کنید و خروجی جزئی را ثبت کنید یا جریان را حذف کنید.

پیش‌نیازها

برای جاری‌سازی پیام‌ها با Chat API، پیش‌نیازهای زیر را تکمیل کنید:

  • حساب Google Workspace Business یا Enterprise با دسترسی به Google Chat.
  • محیط خود را راه‌اندازی کنید:
  • «برنامه Chat» خود را به فضای Chat رشته‌ای (یا پیام مستقیم یک‌به‌یک که ازقبل حداقل یک پیام دارد) اضافه کنید و نام منبع پیام قابل‌دسترسی را برای پاسخ دادن به آن (spaces/SPACE_ID/messages/MESSAGE_ID) دریافت کنید.
  • برای نمونه‌های Python، «کتابخانه کارخواه Google API» را برای Python و google-auth نصب کنید و کارخواه سرویس Chat API را مقداردهی اولیه کنید:

    pip install google-api-python-client google-auth
    from google.oauth2 import service_account
    from googleapiclient.discovery import build
    
    SCOPES = ["https://www.googleapis.com/auth/chat.bot"]
    creds = service_account.Credentials.from_service_account_file(
        "credentials.json", scopes=SCOPES
    )
    chat = build("chat", "v1", credentials=creds)
    

شروع کردن جاری‌سازی

برای شروع جاری‌سازی پاسخ، spaces.streamMessages.create را فراخوانی کنید و StreamMessage را در بدنه درخواست ارسال کنید:

  • ‫referencedMessage (الزامی): نام منبع پیامی که پاسخ را راه‌اندازی کرده است، قالب‌بندی‌شده به‌صورت spaces/{space}/messages/{message}. پیام ارجاع‌شده باید متعلق به همان فضا باشد و برای برنامه Chat شما قابل‌دسترسی باشد. Chat پاسخ جاری‌سازی‌شده را در همان رشته referencedMessage پست می‌کند.
  • ‫progressText (الزامی): برچسب وضعیت نوشتار ساده غیرخالی (حداکثر ۲۵۰ نویسه) که در کنار نشانگر پیشرفت نشان داده می‌شود، مثل "Thinking...".
  • markupSyntax (اختیاری): نحو قالب‌بندی نوشتار برای پیام، مثل MARKUP_SYNTAX_MARKDOWN یا MARKUP_SYNTAX_CHAT (اگر MARKUP_SYNTAX_UNSPECIFIED باشد، به‌طور پیش‌فرض از نحو پیکربندی‌شده برنامه Chat استفاده می‌شود). اگر قصد دارید نقل‌قول‌های درون‌خطی اضافه کنید، MARKUP_SYNTAX_MARKDOWN را تنظیم کنید.
  • ‫streamContentChunks (اختیاری): text، step، یا citation اولیه برای نمایش فوری.

هر دو name (spaces/{space}/streamMessages/{stream_message}) و nextChunkToken را از پاسخ برای تماس‌های بعدی ذخیره کنید.

HTTP

POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
  "referencedMessage": "spaces/SPACE_ID/messages/MESSAGE_ID",
  "progressText": "Thinking...",
  "markupSyntax": "MARKUP_SYNTAX_MARKDOWN"
}

Python

stream = (
    chat.spaces()
    .streamMessages()
    .create(
        parent="spaces/SPACE_ID",
        body={
            "referencedMessage": "spaces/SPACE_ID/messages/MESSAGE_ID",
            "progressText": "Thinking...",
            "markupSyntax": "MARKUP_SYNTAX_MARKDOWN",
        },
    )
    .execute()
)

stream_name = stream["name"]
chunk_token = stream["nextChunkToken"]

این روش منبع StreamMessage را برمی‌گرداند:

{
  "name": "spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID",
  "progressText": "Thinking...",
  "markupSyntax": "MARKUP_SYNTAX_MARKDOWN",
  "nextChunkToken": "INITIAL_CHUNK_TOKEN"
}

افزودن تکه‌های محتوا

وقتی برنامه Chat شما مراحل میانی یا توکن‌های نوشتاری تولید می‌کند، spaces.streamMessages.appendStreamMessageContent را فراخوانی کنید:

  • جدیدترین nextChunkToken را در chunkToken ارسال کن. هر فراخوانی موفق nextChunkToken جدیدی را برمی‌گرداند که باید در درخواست به‌روزرسانی یا ثبت بعدی‌تان ارسال کنید.
  • text تکه مستقیماً به نوشتار جاری‌شده قبلی متصل می‌شود. درصورت نیاز، بین بخش‌ها فاصله یا خط جدید اضافه کنید.
  • step تکه به فهرست مراحل میانی نشان‌داده‌شده در پیام اضافه می‌شود.
  • ‫progressText اختیاری است. اگر progressText را حذف کنید یا آن را روی "" تنظیم کنید، Chat همچنان progressText تنظیم‌شده قبلی را نمایش می‌دهد.

HTTP

POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID:appendStreamMessageContent HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
  "chunkToken": "INITIAL_CHUNK_TOKEN",
  "progressText": "Searching documentation...",
  "streamContentChunks": [
    {
      "step": {
        "title": "Search knowledge base",
        "description": "Found 3 matching articles."
      }
    },
    {
      "text": "See <chat-citation data-id=\"c1\">guide</chat-citation>:\n"
    },
    {
      "citation": {
        "id": "c1",
        "citedSources": [
          {
            "title": "System Architecture Guide",
            "uri": "https://example.com/docs/arch"
          }
        ]
      }
    }
  ]
}

Python

stream = (
    chat.spaces()
    .streamMessages()
    .appendStreamMessageContent(
        name=stream_name,
        body={
            "chunkToken": chunk_token,
            "progressText": "Searching documentation...",
            "streamContentChunks": [
                {
                    "step": {
                        "title": "Search knowledge base",
                        "description": "Found 3 matching articles.",
                    }
                },
                {
                    "text": (
                        'See <chat-citation data-id="c1">'
                        "guide</chat-citation>:\n"
                    )
                },
                {
                    "citation": {
                        "id": "c1",
                        "citedSources": [
                            {
                                "title": "System Architecture Guide",
                                "uri": "https://example.com/docs/arch",
                            }
                        ],
                    }
                },
            ],
        },
    )
    .execute()
)

chunk_token = stream["nextChunkToken"]

جایگزین کردن محتوای جاری‌سازی‌شده یا نوشتار پیشرفت

اگر لازم است محتوای قبلاً جاری‌سازی‌شده را بازنویسی کنید (مثلاً پس‌از اجرای فیلتر ایمنی یا پس‌پردازش) یا فقط progressText را بدون افزودن تکه‌ها به‌روز کنید، spaces.streamMessages.patch را فراخوانی کنید:

  • updateMask را روی فهرست فیلدهای جداشده با کاما برای به‌روزرسانی تنظیم کنید: progressText، streamContentChunks، یا progressText,streamContentChunks.
  • جدیدترین nextChunkToken را در بدنه درخواست StreamMessage قرار دهید و nextChunkToken جدید برگردانده‌شده در پاسخ را ثبت کنید.
  • وقتی streamContentChunks در updateMask باشد، بخش‌های ارائه‌شده جایگزین محتوای جاری‌سازی‌شده قبلی می‌شود و به آن اضافه نمی‌شود.
  • وقتی progressText در updateMask است، progressText نباید خالی باشد نوشتار ساده تا ۲۵۰ نویسه.

HTTP

PATCH https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID?updateMask=progressText,streamContentChunks HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
  "nextChunkToken": "LATEST_CHUNK_TOKEN",
  "progressText": "Formatting response...",
  "streamContentChunks": [
    {
      "text": "Updated response text."
    }
  ]
}

Python

stream = (
    chat.spaces()
    .streamMessages()
    .patch(
        name=stream_name,
        updateMask="progressText,streamContentChunks",
        body={
            "nextChunkToken": chunk_token,
            "progressText": "Formatting response...",
            "streamContentChunks": [
                {"text": "Updated response text."}
            ],
        },
    )
    .execute()
)

chunk_token = stream["nextChunkToken"]

نهایی کردن جاری‌سازی

وقتی تولید تمام شد، spaces.streamMessages.commit را با جدیدترین chunkToken فراخوانی کنید تا جاری‌سازی را در منبع دائمی Message نهایی کنید:

  • می‌توانید به‌صورت اختیاری streamContentChunks نهایی را در درخواست نهایی‌سازی بگنجانید، ازجمله انواع تکه‌های فقط نهایی‌سازی (card،‏ accessoryWidget، و citedSource).
  • اگر قبلاً محتوای غیرخالی را در تماس‌های قبلی جاری‌سازی کرده‌اید، می‌توانید streamContentChunks را هنگام نهایی‌سازی حذف کنید. پیام نهایی ثبت‌شده نمی‌تواند خالی باشد.

HTTP

POST https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID:commit HTTP/1.1
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
  "chunkToken": "LATEST_CHUNK_TOKEN",
  "streamContentChunks": [
    {
      "text": "All checks passed."
    },
    {
      "citedSource": {
        "title": "Deployment Runbook",
        "uri": "https://example.com/docs/runbook"
      }
    },
    {
      "card": {
        "cardId": "details-card",
        "card": {
          "header": {
            "title": "Build Status"
          },
          "sections": [
            {
              "widgets": [
                {
                  "textParagraph": {
                    "text": "All 42 checks succeeded."
                  }
                }
              ]
            }
          ]
        }
      }
    }
  ]
}

Python

status_card = {
    "cardId": "details-card",
    "card": {
        "header": {"title": "Build Status"},
        "sections": [
            {
                "widgets": [
                    {"textParagraph": {"text": "All 42 checks succeeded."}}
                ]
            }
        ],
    },
}

commit_response = (
    chat.spaces()
    .streamMessages()
    .commit(
        name=stream_name,
        body={
            "chunkToken": chunk_token,
            "streamContentChunks": [
                {"text": "All checks passed."},
                {
                    "citedSource": {
                        "title": "Deployment Runbook",
                        "uri": "https://example.com/docs/runbook",
                    }
                },
                {"card": status_card},
            ],
        },
    )
    .execute()
)

final_message = commit_response["message"]
print(f"Committed message: {final_message['name']}")

صرف‌نظر کردن از جاری‌سازی فعال

اگر خطای غیرقابل‌بازیابی رخ دهد یا کاربر تولید را لغو کند و شما نخواهید پاسخ ناقصی در رشته باقی بماند، spaces.streamMessages.delete را فراخوانی کنید:

HTTP

DELETE https://chat.googleapis.com/v1/spaces/SPACE_ID/streamMessages/STREAM_MESSAGE_ID HTTP/1.1
Authorization: Bearer ACCESS_TOKEN

Python

chat.spaces().streamMessages().delete(name=stream_name).execute()

وقتی جاری‌سازی در Message ثبت شد، اگر لازم است پیام نهایی‌شده را حذف کنید، به‌جای آن با spaces.messages.delete تماس بگیرید.

انواع تکه‌های محتوای پشتیبانی‌شده

هر ورودی در streamContentChunks یک فیلد را در اتحادیه StreamContentChunk مشخص می‌کند. برخی‌از انواع تکه‌ها را می‌توان درطول جاری‌سازی ارسال کرد، درحالی‌که برخی دیگر فقط در spaces.streamMessages.commit پذیرفته می‌شوند:

فیلد قطعه روش‌های پشتیبانی‌شده فیلد نهایی Message یادداشت‌ها
text ‫create، appendStreamMessageContent، patch، commit text نوشتار افزایشی. در appendStreamMessageContent به‌هم پیوسته شد؛ در patch جایگزین شد. نوشتار نهایی ثبت‌شده نمی‌تواند از ۳۲٬۰۰۰ بایت بیشتر باشد.
step ‫create، appendStreamMessageContent، patch، commit elements.steps.steps[] مرحله پردازش میانی با نوشتار ساده title (الزامی) و description اختیاری.
citation ‫create، appendStreamMessageContent، patch، commit elements.citations[] درون‌خطی Citation با id الفباعددی (کمتر از ۶۳ نویسه، زیرخط مجاز است) و citedSources. به برچسب‌های markupSyntax: "MARKUP_SYNTAX_MARKDOWN" و <chat-citation data-id="ID">...</chat-citation> مطابق در text نیاز دارد. ارسال citation با id موجود، استناد قبلی را رونویسی می‌کند.
card فقط commit cardsV2[] کارت تعاملی یا اطلاعاتی CardWithId.
accessoryWidget فقط commit accessoryWidgets[] AccessoryWidget دکمه‌های نمایش‌داده‌شده در زیر پیام، مثل دکمه‌های بازخورد.
citedSource فقط commit elements.citedSources[] CitedSource پیوند پانویس زیر پیام بدون برچسب‌های استناد درون‌خطی نمایش داده می‌شود.

رسیدگی به لغو جاری‌سازی به‌درخواست کاربر

وقتی جاری‌سازی فعال است، فقط فرستنده پیام ارجاع‌شده (referencedMessage) که درحال جاری‌سازی است می‌تواند روی توقف در پیام جاری‌سازی کلیک کند. وقتی کاربر جاری‌سازی را متوقف می‌کند، Chat یک رویداد تعامل فرمان سیستم حاوی cancelStream.streamMessage (نام منبع spaces/{space}/streamMessages/{stream_message} جاری‌سازی متوقف‌شده) به نقطه پایانی برنامه Chat شما ارسال می‌کند.

ساختار بارداده JSON ورودی به این بستگی دارد که برنامه Chat را به‌عنوان برافزای Google Workspace بسازید یا بااستفاده از رویدادهای تعامل Chat API:

برافزاهای Google Workspace

{
  "commonEventObject": {
    "hostApp": "CHAT"
  },
  "chat": {
    "user": {
      "name": "users/USER_ID"
    },
    "space": {
      "name": "spaces/SPACE_ID"
    },
    "systemCommandPayload": {
      "systemCommandMetadata": {
        "cancelStream": {
          "streamMessage": "spaces/SPACE_ID/streamMessages/STREAM_ID"
        }
      }
    }
  }
}

Google Chat API

{
  "type": "SYSTEM_COMMAND",
  "space": {
    "name": "spaces/SPACE_ID"
  },
  "user": {
    "name": "users/USER_ID"
  },
  "systemCommandMetadata": {
    "cancelStream": {
      "streamMessage": "spaces/SPACE_ID/streamMessages/STREAM_ID"
    }
  }
}

وقتی برنامه Chat شما رویداد cancelStream را دریافت می‌کند:

  1. به کارگر پس‌زمینه خود علامت دهید تا تولید نشانه‌های بیشتر یا اجرای ابزارهای پایین‌دستی را برای streamMessage متوقف کند.
  2. جاری‌سازی فعال را بااستفاده از یکی از رویکردهای زیر حل‌وفصل کنید:
    • Keep partial output: Call spaces.streamMessages.commit with the latest chunkToken (optionally appending a note such as "\n\n_Generation stopped._").
    • صرف‌نظر کردن از پاسخ: spaces.streamMessages.delete را بگویید تا چیزی در رشته ذخیره نشود.
  3. یک پاسخ HTTP 200 OK JSON خالی ({}) از کنترل‌کننده رویداد تعامل خود برگردانید.

محدودیت‌ها

جاری‌سازی پیام محدودیت‌های زیر را دارد:

  • دردسترس بودن پلاتفرم: جاری‌سازی پیام فقط در Chat در وب قابل‌مشاهده است. پشتیبانی از Android و iOS به‌زودی ارائه می‌شود.
  • پایان زمان جاری‌سازی: StreamMessage فعال ۱۰ دقیقه پس‌از ایجاد منقضی می‌شود. برنامه Chat شما باید ظرف ۱۰ دقیقه از شروع جاری‌سازی، spaces.streamMessages.commit یا spaces.streamMessages.delete را فراخوانی کند.