指南
串流接口詳解
幀格式、斷線續傳與增量處理。
幀格式
事件串流遵循 SSE 標準。每個事件是一組以空行結束的行:
id: turn_3f2a9c1e5b7d4e6f8a0b2c4d6e8f0a1b:1791190160355-0
event: agent.message
data: {"id":"evt_…","type":"agent.message","turn_id":"turn_3f2a…","created_at":"…","content":"…"}
: pingevent是事件類型,與 JSON 中的type相同。data是一行完整的事件 JSON。id是流內位置,用於斷線續傳。請把它當作不透明字串,不要解析,也不要與事件的id(evt_…)混用。- 以冒號開頭的行(如
: ping)是保活註解,空閒時大約每 15 秒一次,直接忽略即可。
何時開啟、何時關閉
- 在發送訊息之後開啟。 事件串流跟隨會話的當前一輪。如果在發送新訊息之前開啟,你看到的是上一輪:它會補發完上一輪的事件後關閉。
- 收到終止事件後伺服器端會關閉連接,這是正常結束。如果這一輪在開啟前就已結束,連接補發完它的事件後也會立即關閉。
- 會話還沒有發送過任何訊息時,連接立即關閉,不推送任何事件。
斷線續傳
網絡中斷後,用收到的最後一個 SSE id 作為 Last-Event-ID 請求頭重新連接,伺服器端會從它之後繼續推送,不會重複也不會遺漏。標準的 EventSource 客戶端會自動這樣做。
- 續傳只在同一輪內有效。如果
Last-Event-ID屬於其他輪次,或者格式不對,伺服器端會從當前一輪的開頭重新推送。 - 串流數據保留 24 小時。更早的內容以及跨輪的完整記錄,請用事件歷史取得。
- 如果連接在收到終止事件之前就結束了,以事件歷史和會話狀態為準核對。
增量的處理
推薦這樣渲染一輪的輸出:
- 收到
agent.message.delta:把content追加到一個「正在輸入」的臨時文字塊裡。 - 收到
agent.message:用它的content替換這個臨時塊,把它定為一段正式回覆;如果content為空,就刪除這個臨時塊。之後的增量開始一個新的臨時塊。 agent.thinking.delta與agent.thinking同理,單獨維護一個思考內容的臨時塊。- 收到終止事件時,如果還有臨時塊沒有被替換,說明這段文字沒有完成(例如在說話中途被取消),應當丟棄。
歷史與即時結合
用戶開啟一個已有會話時,推薦的做法是: