跳至主要內容

指南

串流接口詳解

幀格式、斷線續傳與增量處理。

幀格式

事件串流遵循 SSE 標準。每個事件是一組以空行結束的行:

id: turn_3f2a9c1e5b7d4e6f8a0b2c4d6e8f0a1b:1791190160355-0
event: agent.message
data: {"id":"evt_…","type":"agent.message","turn_id":"turn_3f2a…","created_at":"…","content":"…"}

: ping
  • event 是事件類型,與 JSON 中的 type 相同。
  • data 是一行完整的事件 JSON。
  • id 是流內位置,用於斷線續傳。請把它當作不透明字串,不要解析,也不要與事件的 id(evt_…)混用。
  • 以冒號開頭的行(如 : ping)是保活註解,空閒時大約每 15 秒一次,直接忽略即可。

何時開啟、何時關閉

  • 在發送訊息之後開啟。 事件串流跟隨會話的當前一輪。如果在發送新訊息之前開啟,你看到的是上一輪:它會補發完上一輪的事件後關閉。
  • 收到終止事件後伺服器端會關閉連接,這是正常結束。如果這一輪在開啟前就已結束,連接補發完它的事件後也會立即關閉。
  • 會話還沒有發送過任何訊息時,連接立即關閉,不推送任何事件。

斷線續傳

網絡中斷後,用收到的最後一個 SSE id 作為 Last-Event-ID 請求頭重新連接,伺服器端會從它之後繼續推送,不會重複也不會遺漏。標準的 EventSource 客戶端會自動這樣做。

  • 續傳只在同一輪內有效。如果 Last-Event-ID 屬於其他輪次,或者格式不對,伺服器端會從當前一輪的開頭重新推送。
  • 串流數據保留 24 小時。更早的內容以及跨輪的完整記錄,請用事件歷史取得。
  • 如果連接在收到終止事件之前就結束了,以事件歷史和會話狀態為準核對。

增量的處理

推薦這樣渲染一輪的輸出:

  1. 收到 agent.message.delta:把 content 追加到一個「正在輸入」的臨時文字塊裡。
  2. 收到 agent.message:用它的 content 替換這個臨時塊,把它定為一段正式回覆;如果 content 為空,就刪除這個臨時塊。之後的增量開始一個新的臨時塊。
  3. agent.thinking.delta 與 agent.thinking 同理,單獨維護一個思考內容的臨時塊。
  4. 收到終止事件時,如果還有臨時塊沒有被替換,說明這段文字沒有完成(例如在說話中途被取消),應當丟棄。

歷史與即時結合

用戶開啟一個已有會話時,推薦的做法是:

  1. 分頁讀取事件歷史並渲染,記下所有事件的 id。
  2. 如果會話狀態是 RUNNING,開啟事件串流。流會先補發本輪已發生的事件,其中 id 已經見過的跳過即可。
  3. 之後按增量的處理渲染新事件,直到終止事件。