इस गाइड में, Chat API में StreamMessage संसाधन का इस्तेमाल करके, Google Chat में मैसेज को धीरे-धीरे स्ट्रीम करने का तरीका बताया गया है. स्ट्रीमिंग की सुविधा से, Google Chat ऐप्लिकेशन को लाइव प्रोग्रेस इंडिकेटर, इंटरमीडिएट रीज़निंग या टूल-एक्ज़ीक्यूशन के चरण, और मैसेज को फ़ाइनल करने से पहले, टेक्स्ट के जवाबों को इंक्रीमेंटल तौर पर दिखाने की सुविधा मिलती है.
स्ट्रीमिंग की सुविधा, जनरेटिव एआई की मदद से काम करने वाले Chat ऐप्लिकेशन या लंबे समय तक चलने वाले बैकएंड वर्कफ़्लो के लिए डिज़ाइन की गई है. इनमें पूरा जवाब जनरेट करने में कुछ सेकंड या मिनट लगते हैं.
मैसेज स्ट्रीमिंग की सुविधा कैसे काम करती है
किसी स्पेस में स्टैंडर्ड
Message
संसाधन बनने से पहले, स्ट्रीमिंग मैसेज को ऐक्टिव स्ट्रीमिंग स्टेटस से गुज़रना पड़ता है:
- स्ट्रीम शुरू करना (
spaces.streamMessages.create): आपका चैट ऐप्लिकेशन, थ्रेड वाले स्पेस मेंStreamMessageबनाता है. इसमें उपयोगकर्ता के उस इंटरैक्शन मैसेज का रेफ़रंस दिया जाता है जिसका जवाब दिया जा रहा है. एपीआई, थ्रेड में लाइव प्रोग्रेस इंडिकेटर दिखाता है. साथ ही,StreamMessageसंसाधन का नाम और शुरुआतीnextChunkTokenदिखाता है. - स्ट्रीम (
appendStreamMessageContentयाpatch) को अपडेट करना: Chat ऐप्लिकेशन, आउटपुट जनरेट करने के बाद, नएnextChunkTokenका इस्तेमाल करके क्रम से अपडेट भेजता है:- टेक्स्ट के नए हिस्सों को जोड़ने, बीच के चरणों को जोड़ने, इनलाइन उद्धरण जोड़ने या
progressTextको अपडेट करने के लिए,spaces.streamMessages.appendStreamMessageContentको कॉल करें. - स्ट्रीम किए गए कॉन्टेंट के हिस्सों को बदलने या
progressTextको अपडेट करने के लिए,spaces.streamMessages.patchको कॉल करें.
- टेक्स्ट के नए हिस्सों को जोड़ने, बीच के चरणों को जोड़ने, इनलाइन उद्धरण जोड़ने या
- स्ट्रीम को सेव करें या खारिज करें (
commitयाdelete):- स्ट्रीम को पूरा करने और उसे स्थायी
Messageसंसाधन में बदलने के लिए,spaces.streamMessages.commitको कॉल करें. कमिट करते समय, सिर्फ़ कमिट किए जा सकने वाले एलिमेंट भी अटैच किए जा सकते हैं. जैसे, कार्ड, ऐक्सेसरी विजेट, और फ़ुटर सोर्स. - स्पेस में मैसेज सेव किए बिना, किसी ऐक्टिव स्ट्रीम को खारिज करने के लिए,
spaces.streamMessages.deleteको कॉल करें.
- स्ट्रीम को पूरा करने और उसे स्थायी
स्ट्रीम चालू होने पर, सिर्फ़ उस रेफ़रंस मैसेज (referencedMessage) को भेजने वाला व्यक्ति रोकें पर क्लिक करके, जवाब जनरेट होने की प्रोसेस को रद्द कर सकता है जिस पर स्ट्रीम की जा रही है. Chat, आपके चैट ऐप्लिकेशन को रद्द करने का सिस्टम कमांड इवेंट भेजता है, ताकि बैकएंड का काम रोका जा सके. साथ ही, आउटपुट का कुछ हिस्सा सेव किया जा सके या स्ट्रीम को मिटाया जा सके.
ज़रूरी शर्तें
Chat API की मदद से मैसेज स्ट्रीम करने के लिए, ये ज़रूरी शर्तें पूरी करें:
- Business या Enterprise Google Workspace खाता, जिसमें Google Chat का ऐक्सेस हो.
- अपना एनवायरमेंट सेट अप करने का तरीका:
- Google Cloud प्रोजेक्ट बनाएं.
- अपने चैट ऐप्लिकेशन के नाम, आइकॉन, और ब्यौरे के साथ Google Chat API को चालू और कॉन्फ़िगर करें.
- सेवा खाते के क्रेडेंशियल बनाएं और उन्हें
credentials.jsonके तौर पर सेव करें. मैसेज स्ट्रीमिंग के लिए, ऐप्लिकेशन की पुष्टि करना ज़रूरी है. इसके लिए,https://www.googleapis.com/auth/chat.botअनुमति का दायरा होना चाहिए. उपयोगकर्ता की पुष्टि करने की सुविधा काम नहीं करती.
- अपने चैट ऐप्लिकेशन को थ्रेड वाली Chat स्पेस (या 1:1 सीधी बातचीत जिसमें पहले से कम से कम एक मैसेज मौजूद हो) में जोड़ें. इसके बाद, जवाब देने के लिए ऐक्सेस किए जा सकने वाले मैसेज (
spaces/SPACE_ID/messages/MESSAGE_ID) का संसाधन नाम पाएं. Python के सैंपल के लिए, Python के लिए Google API क्लाइंट लाइब्रेरी और
google-authइंस्टॉल करें. इसके बाद, Chat API सेवा क्लाइंट को शुरू करें:pip install google-api-python-client google-authfrom 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, स्ट्रीम किए गए जवाब कोreferencedMessageके तौर पर उसी थ्रेड में पोस्ट करता है.progressText(ज़रूरी है): प्रोग्रेस इंडिकेटर के बगल में दिखने वाला सादे टेक्स्ट वाला स्टेटस लेबल (ज़्यादा से ज़्यादा 250 वर्ण). जैसे,"Thinking...". यह खाली नहीं होना चाहिए.markupSyntax(ज़रूरी नहीं): मैसेज के लिए टेक्स्ट फ़ॉर्मैटिंग सिंटैक्स, जैसे किMARKUP_SYNTAX_MARKDOWNयाMARKUP_SYNTAX_CHAT(अगरMARKUP_SYNTAX_UNSPECIFIEDहै, तो चैट ऐप्लिकेशन के कॉन्फ़िगर किए गए सिंटैक्स पर डिफ़ॉल्ट रूप से सेट होता है). अगर आपको इनलाइन उद्धरण शामिल करने हैं, तो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"
}
कॉन्टेंट के हिस्सों को जोड़ना
जब आपका चैट ऐप्लिकेशन, इंटरमीडिएट स्टेप या टेक्स्ट टोकन जनरेट करता है, तो spaces.streamMessages.appendStreamMessageContent को कॉल करें:
chunkTokenमेंnextChunkTokenका नया वर्शन पास करें. हर सफल कॉल, एक नया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"]
स्ट्रीम किए गए कॉन्टेंट या प्रोग्रेस टेक्स्ट को बदलना
अगर आपको पहले से स्ट्रीम किए गए कॉन्टेंट को फिर से लिखना है, तो spaces.streamMessages.patch को कॉल करें. उदाहरण के लिए, पोस्ट-प्रोसेसिंग या सुरक्षा फ़िल्टर चलाने के बाद या चंक जोड़े बिना सिर्फ़ progressText को अपडेट करने के बाद:
updateMaskको अपडेट किए जाने वाले फ़ील्ड की कॉमा लगाकर अलग की गई सूची पर सेट करें:progressText,streamContentChunksयाprogressText,streamContentChunks.StreamMessageअनुरोध के मुख्य हिस्से में नयाnextChunkTokenशामिल करें. साथ ही, जवाब में मिले नएnextChunkTokenको रिकॉर्ड करें.- जब
streamContentChunks,updateMaskमें होता है, तो उपलब्ध कराए गए चंक, पहले से स्ट्रीम किए गए कॉन्टेंट में जुड़ने के बजाय, उसे बदल देते हैं. जब
progressTextकी वैल्यूupdateMaskहो, तबprogressTextकी वैल्यू खाली नहीं होनी चाहिए. यह ज़्यादा से ज़्यादा 250 वर्णों का सादा टेक्स्ट होना चाहिए.
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"]
स्ट्रीम को फ़ाइनलाइज़ करना
जनरेशन पूरा होने पर, सबसे नए chunkToken के साथ spaces.streamMessages.commit को कॉल करें, ताकि स्ट्रीम को स्थायी 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 को बदला गया.
फ़ाइनल टेक्स्ट 32,000 बाइट से ज़्यादा नहीं हो सकता. |
step |
create, appendStreamMessageContent,
patch, commit |
elements.steps.steps[] |
सादे टेक्स्ट title (ज़रूरी है) और वैकल्पिक description के साथ इंटरमीडिएट प्रोसेसिंग चरण. |
citation |
create, appendStreamMessageContent,
patch, commit |
elements.citations[] |
इनलाइन
Citation, जिसमें अक्षर और अंक वाला id (63 से कम वर्ण, अंडरस्कोर इस्तेमाल किए जा सकते हैं) और citedSources शामिल हो. इसके लिए, text में markupSyntax: "MARKUP_SYNTAX_MARKDOWN" और इससे मैच होने वाले <chat-citation data-id="ID">...</chat-citation> टैग की ज़रूरत होती है. किसी मौजूदा id के साथ citation भेजने पर, पहले से मौजूद उद्धरण को ओवरराइट कर दिया जाता है. |
card |
सिर्फ़ commit |
cardsV2[] |
इंटरैक्टिव या जानकारी देने वाला
CardWithId कार्ड. |
accessoryWidget |
सिर्फ़ commit |
accessoryWidgets[] |
AccessoryWidget मैसेज के नीचे दिखने वाले बटन. जैसे, सुझाव/राय देने या शिकायत करने के बटन. |
citedSource |
सिर्फ़ commit |
elements.citedSources[] |
CitedSource फ़ुटर लिंक, मैसेज के नीचे दिखता है.
इसमें इनलाइन साइटेशन टैग नहीं होते. |
उपयोगकर्ता के अनुरोध पर स्ट्रीम रद्द करने की प्रोसेस को मैनेज करना
स्ट्रीम चालू होने पर, सिर्फ़ उस मैसेज को भेजने वाला व्यक्ति (referencedMessage) स्ट्रीम किए जा रहे मैसेज पर रोकें पर क्लिक कर सकता है. जब उपयोगकर्ता किसी स्ट्रीम को रोकता है, तो Chat आपके Chat ऐप्लिकेशन के एंडपॉइंट पर, सिस्टम कमांड इंटरैक्शन इवेंट भेजता है. इसमें cancelStream.streamMessage (रोकी गई स्ट्रीम का spaces/{space}/streamMessages/{stream_message} संसाधन नाम) शामिल होता है.
इनकमिंग JSON पेलोड का स्ट्रक्चर इस बात पर निर्भर करता है कि आपने चैट ऐप्लिकेशन को 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 इवेंट मिलता है, तब:
- बैकग्राउंड में काम करने वाले वर्कर को सिग्नल भेजें, ताकि वह
streamMessageके लिए और टोकन जनरेट करना या डाउनस्ट्रीम टूल चलाना बंद कर दे. - इनमें से किसी एक तरीके का इस्तेमाल करके, चालू स्ट्रीम को बंद करें:
- Keep partial output: सबसे नए
chunkTokenके साथspaces.streamMessages.commitको कॉल करें. इसके अलावा,"\n\n_Generation stopped._"जैसा कोई नोट भी जोड़ा जा सकता है. - जवाब को खारिज करना:
spaces.streamMessages.deleteको कॉल करें, ताकि थ्रेड में कुछ भी सेव न हो.
- Keep partial output: सबसे नए
- इंटरैक्शन इवेंट हैंडलर से, खाली एचटीटीपी
200 OKJSON रिस्पॉन्स ({}) दिखाएं.
सीमाएं
मैसेज स्ट्रीमिंग की ये सीमाएं हैं:
- प्लैटफ़ॉर्म की उपलब्धता: मैसेज स्ट्रीमिंग की सुविधा, सिर्फ़ Chat के वेब वर्शन पर उपलब्ध है. Android और iOS के लिए यह सुविधा जल्द ही उपलब्ध होगी.
- स्ट्रीम टाइम आउट: चालू
StreamMessage, बनने के 10 मिनट बाद बंद हो जाता है. आपके Chat ऐप्लिकेशन को स्ट्रीम शुरू होने के 10 मिनट के अंदर,spaces.streamMessages.commitयाspaces.streamMessages.deleteको कॉल करना होगा.