คู่มือนี้จะอธิบายวิธีสตรีมข้อความแบบเพิ่มขึ้นทีละรายการใน Google Chat โดยใช้ทรัพยากร StreamMessage ใน Chat API การสตรีมช่วยให้แอป Google Chat แสดงตัวบ่งชี้ความคืบหน้าแบบเรียลไทม์ ขั้นตอนการให้เหตุผลหรือการเรียกใช้เครื่องมือระดับกลาง และการตอบกลับข้อความแบบเพิ่มทีละส่วนก่อนที่จะสรุปข้อความ
การสตรีมออกแบบมาสำหรับแอป Chat ที่ทำงานด้วย Generative AI หรือเวิร์กโฟลว์แบ็กเอนด์ที่ใช้เวลานาน ซึ่งการสร้างคำตอบที่สมบูรณ์จะใช้เวลาหลายวินาทีหรือหลายนาที
วิธีการทำงานของสตรีมข้อความ
ข้อความสตรีมมิงจะดำเนินไปตามสถานะสตรีมมิงที่ใช้งานอยู่ก่อนที่จะกลายเป็นทรัพยากร Message มาตรฐานในพื้นที่ทำงาน ดังนี้
- เริ่มสตรีม (
spaces.streamMessages.create): แอปใน Chat จะสร้างStreamMessageในพื้นที่ทำงานแบบแยกชุดข้อความ โดยอ้างอิงข้อความการโต้ตอบของผู้ใช้ที่แอปตอบกลับ API จะแสดงสัญญาณบอกสถานะความคืบหน้าแบบเรียลไทม์ในชุดข้อความ และแสดงผลชื่อทรัพยากรStreamMessageและnextChunkTokenเริ่มต้น - อัปเดตสตรีม (
appendStreamMessageContentหรือpatch): เมื่อแอปใน Chat สร้างเอาต์พุต แอปจะส่งการอัปเดตตามลำดับโดยใช้nextChunkTokenล่าสุด ดังนี้- เรียกใช้
spaces.streamMessages.appendStreamMessageContentเพื่อเชื่อมโยงกลุ่มข้อความใหม่ เพิ่มขั้นตอนกลาง เพิ่มการอ้างอิงในบรรทัด หรืออัปเดตprogressText - เรียก
spaces.streamMessages.patchเพื่อแทนที่กลุ่มเนื้อหาที่สตรีมหรืออัปเดตprogressTextในตำแหน่งเดิม
- เรียกใช้
- สรุปหรือทิ้งไลฟ์สด (
commitหรือdelete)- เรียกใช้
spaces.streamMessages.commitเพื่อสรุปสตรีมและแปลงเป็นทรัพยากรMessageถาวร นอกจากนี้ คุณยังแนบองค์ประกอบแบบคอมมิตเท่านั้น เช่น การ์ด วิดเจ็ตเสริม และแหล่งที่มาของส่วนท้ายเมื่อคอมมิตได้ด้วย - เรียกใช้
spaces.streamMessages.deleteเพื่อทิ้งสตรีมที่ใช้งานอยู่โดยไม่บันทึกข้อความในพื้นที่ทำงาน
- เรียกใช้
ขณะที่สตรีมทำงานอยู่ เฉพาะผู้ส่งข้อความที่อ้างอิง (referencedMessage) ที่กำลังสตรีมอยู่เท่านั้นที่จะคลิกหยุดเพื่อยกเลิกการสร้างได้ Chat จะส่งเหตุการณ์คำสั่งระบบการยกเลิกไปยังแอป Chat เพื่อให้คุณหยุดงานแบ็กเอนด์และคอมมิตเอาต์พุตบางส่วนหรือลบสตรีมได้
ข้อกำหนดเบื้องต้น
หากต้องการสตรีมข้อความด้วย Chat API ให้ทำตามข้อกำหนดเบื้องต้นต่อไปนี้ให้เสร็จสมบูรณ์
- บัญชี Google Workspace แบบ Business หรือ Enterprise ที่มีสิทธิ์เข้าถึง Google Chat
- ตั้งค่าสภาพแวดล้อมดังนี้
- สร้างโปรเจ็กต์ Google Cloud
- เปิดใช้และกำหนดค่า Google Chat API ด้วยชื่อ ไอคอน และคำอธิบายสำหรับแอปใน Chat
- สร้างข้อมูลเข้าสู่ระบบของบัญชีบริการและบันทึกเป็น
credentials.jsonการสตรีมข้อความต้องใช้การตรวจสอบสิทธิ์แอปที่มีขอบเขตการให้สิทธิ์https://www.googleapis.com/auth/chat.botโดยระบบไม่รองรับการตรวจสอบสิทธิ์ผู้ใช้
- เพิ่มแอปใน Chat ลงในพื้นที่ใน Chat แบบแยกชุดข้อความ (หรือข้อความส่วนตัวแบบ 1:1 ที่มีข้อความอย่างน้อย 1 ข้อความอยู่แล้ว) และรับชื่อทรัพยากรของข้อความที่เข้าถึงได้เพื่อตอบกลับ (
spaces/SPACE_ID/messages/MESSAGE_ID) สำหรับตัวอย่าง Python ให้ติดตั้งไลบรารีของไคลเอ็นต์ Google API สำหรับ Python และ
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 ของคุณต้องเข้าถึงได้ Chat จะโพสต์การตอบกลับที่สตรีมในชุดข้อความเดียวกับreferencedMessageprogressText(ต้องระบุ): ป้ายกำกับสถานะข้อความธรรมดาที่ไม่ใช่ค่าว่าง (สูงสุด 250 อักขระ) ที่แสดงข้างตัวบ่งชี้ความคืบหน้า เช่น"Thinking..."markupSyntax(ไม่บังคับ): ไวยากรณ์การจัดรูปแบบข้อความสำหรับข้อความ เช่นMARKUP_SYNTAX_MARKDOWNหรือMARKUP_SYNTAX_CHAT(ค่าเริ่มต้นเป็นไวยากรณ์ที่กำหนดค่าไว้ของแอปใน 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"
}
เพิ่มกลุ่มเนื้อหาต่อท้าย
เมื่อแอปใน 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อยู่ในupdateMaskprogressTextต้องเป็นข้อความธรรมดาที่ไม่ใช่ค่าว่างและมีความยาวไม่เกิน 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"]
สรุปไลฟ์สด
เมื่อสร้างเสร็จแล้ว ให้เรียกใช้ 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 จะระบุช่อง 1 ช่องในยูเนียน 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 ต้องมีแท็ก 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 ระบบจะดำเนินการดังนี้
- ส่งสัญญาณให้ผู้ปฏิบัติงานในเบื้องหลังหยุดสร้างโทเค็นเพิ่มเติมหรือเรียกใช้เครื่องมือดาวน์สตรีมสำหรับ
streamMessage - แก้ไขสตรีมที่ใช้งานอยู่โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
- เก็บเอาต์พุตบางส่วน: เรียกใช้
spaces.streamMessages.commitด้วยchunkTokenล่าสุด (เลือกเพิ่มหมายเหตุ เช่น"\n\n_Generation stopped._"ได้) - ทิ้งการตอบกลับ: เรียกใช้
spaces.streamMessages.deleteเพื่อไม่ให้มีการบันทึกข้อมูลใดๆ ลงในชุดข้อความ
- เก็บเอาต์พุตบางส่วน: เรียกใช้
- แสดงผลการตอบกลับ JSON ของ HTTP
200 OKที่ว่างเปล่า ({}) จากตัวแฮนเดิลเหตุการณ์การโต้ตอบ
ข้อจำกัด
การสตรีมข้อความมีข้อจำกัดดังต่อไปนี้
- ความพร้อมให้บริการของแพลตฟอร์ม: การสตรีมข้อความจะปรากฏใน Chat บนเว็บเท่านั้น และจะรองรับ Android และ iOS ในเร็วๆ นี้
- หมดเวลาสตรีม:
StreamMessageที่ใช้งานอยู่จะหมดเวลาหลังจากสร้าง 10 นาที แอป Chat ของคุณต้องเรียกใช้spaces.streamMessages.commitหรือspaces.streamMessages.deleteภายใน 10 นาทีหลังจากเริ่มสตรีม