跳至主要内容

SSE 傳輸協定

POST /chat/control/stream 使用 伺服器傳送事件(SSE)(text/event-stream)回應:這是一種長時間連線回應,會在文字生成時持續傳送內容,同時傳送地點、地圖操作和路線的結構化事件。

本頁定義該串流的協議。如果使用 kaleidr.js,聊天面板會自動解析串流,無須閱讀本頁。自行開發用戶端時請參考此文檔。Node 和 Python 的可用用戶端示例請參閱讀取串流;要求主體請參閱端點列表。

/chat/summary/stream 和 /chat/button/stream 使用相同的框架格式,但事件種類較少。詳見本頁末尾。

串流開始之前​

被拒絕的要求不會進入流式回應。身份驗證、權限範圍、額度、速率限制、參數驗證及大小限制等錯誤,會回傳帶有 JSON 回應主體和 4xx 狀態碼的普通 HTTP 回應(請參閱錯誤)。請先檢查狀態碼,只有狀態為 200 時才將回應主體按 SSE 解析。

要求大小上限為:最多 400 條消息、單條消息最多 64,000 個字符、所有消息內容合計最多 200,000 個字符。超限要求會回傳 422 及 conversation_too_long 等錯誤代碼;要求主體超過 2 MiB 會回傳 413。完整限制請參閱端點列表。

成功回應包含以下回應標頭:

HTTP/1.1 200 OK
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache, no-transform

框架格式​

一個框架由一行或兩行內容組成,後面跟一個空行。每一行以 \n 結束。

event: place
data: {"name": "Louvre Museum", "coordinates": {"lat": 48.8606, "lng": 2.3376}}

data: {"text": "The Louvre sits on the right bank"}

: keep-alive

  • 具名幀 包含一行 event:,隨後是一行 data:。
  • 文字框架 只有一行 data:,沒有 event: 行。
  • 註解 以冒號開頭。Kaleidr 使用 : keep-alive 作為心跳訊號;它不包含資料。
  • data: 始終在單獨一行中包含一個完整的 JSON 對象。 文字採用 UTF-8 編碼。

網絡資料塊不一定與框架邊界對齊。一次讀取可能只得到半個框架,也可能得到多個框架。應緩衝收到的資料,按換行符切分,並且只在遇到框架末尾的空行時處理該框架。

相容性規則​

忽略無法識別的事件名稱及不需要的欄位。 協議可能在不更改版本的情況下新增事件和欄位。遇到未知事件就報錯的用戶端可能因此無法正常工作。

穩定事件​

event:酬載含義
(無名稱){ text }下一段回答文字。追加到已有文字中。地點名周圍可能有 [[Name]] 標記。
phase{ type: "phase", phase: "thinking", session_id }要求已接受,處理已開始。phase 始終為 "thinking"。
start{ type: "start", session_id, purpose: "control" }即將開始傳送本文。
place{ name, coordinates?: { lat, lng }, address?, category?, icon?, source?, id?, unverified? }回答中提到的地點。按 name 合併;首次收到的坐標即為最終坐標。source: "vendor" 表示組織本身的資料中的地點;source: "map" 表示當前已發布地圖上已顯示的地點。
place_linked地點欄位加上 is_update?已傳送地點的補充信息。按相同的 name 合併;如果此前沒見過該地點則忽略。
early_actions{ type: "early_actions", actions: [ { type, payload } ], places_count, is_partial: true }可在回答完成前應用的地圖操作;至少兩個地點獲得坐標後傳送。
prompt_options{ type: "prompt_options", schema_version, kind, question, allow_free_text, options: [ { label, send_text } ] }要求含糊時傳送的選擇題。展示選項,並把所選選項的 send_text 作為下一條用戶消息傳送。
route_clear{}清除繪製過的路線;後續會傳送新路線。
route{ type: "route", schema_version, id?, profile, origin, destination, primary, alternatives[], comparison[], stops?, color?, label?, transit?, attribution? }計算得到的路線。導航問題中會在本文前到達,讓地圖能在文字生成期間繪製。
end{ type: "end", full_text, places[], actions[], question_type, response_time, total_tokens?, dropped_places? }回答完成。這是權威的最終結果。
error{ type: "error", message, code?, partial_text }回答失敗。代替 end 傳送。
quota伺服器金鑰使用 { type: "quota", product, meter, tier, used, limit, reset_at, period };工作階段權杖使用 { type: "quota", meter, reset_at }此調用計費後的組織 AI 點數使用情況。在 end 或 error 之後,作為串流最後一個事件傳送。請參閱 quota。
: keep-alive註解行靜默 10 秒後傳送的心跳訊號。忽略其內容,但應視為活動。

已移除:grounding(2026-09-05)。不再傳送該事件。

實時資料卡片和圖層​

涉及實時或測量資料的問題可能觸發以下事件。卡片會在本文之前到達;圖層可能在本文傳送期間或之後到達。這些事件是附加內容:支持的就繪製,不支持的就忽略。未來可能增加更多欄位。

event:酬載用途
weather_card包含 lat、lng、name、溫度(temp_c、temp_f)、conditions 和選用 forecast[] 的對象地點當前天氣。
weather_layer包含 layer、tile_path_template、tile_size、max_zoom、scope、attribution 的對象區域溫度疊加圖層。
satellite_card包含 name、norad_id、lat、lng、altitude_km、velocity_kms、observed_at 的對象指定衛星的位置。
constellation_layer包含 group、features[](元素為 { name, norad_id, lat, lng })及選用 track 的對象卡片中的衛星周圍的其他衛星。
building_card包含 lat、lng、選用 name、height_m、num_floors 的對象建築物相關資料。
trees_card包含 lat、lng、count、radius_m 的對象某點附近的普查樹木。
heritage_card包含 lat、lng、count、sites[] 的對象某點附近的文化遺產地點。
rail_card包含 lat、lng、lines[]、選用 nearest_station 的對象某點附近的鐵路線路。
arrivals_card包含 lat、lng、stop、departures[]、alerts[]、attribution 的對象某站點的公共交通發車信息。
vehicles_layer包含 operator、vehicles[]、shapes[]、attribution 的對象卡片中站點或線路的公共交通車輛位置。
streetview_card包含 lat、lng、image_id、image_lat、image_lng 的對象地點附近的街景影像。

傳送過這些事件時,end 會以相同名稱再次包含其中五種資料,便於漏收事件的用戶端讀取:weather_card、satellite_card、constellation_layer、weather_layer 和 vehicles_layer(例如 end.weather_card)。其他卡片不會在 end 中重復。平台 API 不提供實時活動列表,請參閱資料許可。

診斷和實驗性內容(不屬於協議)​

以下內容可能出現在傳輸資料中,但不屬於正式協議,請勿依賴。

event:酬載備注
debug{ scope, … }內部診斷信息。正常要求不會傳送。
place_name_found{ name, is_early }提前提示文字中出現某個地點名。應使用其後到達的 place 事件。

事件順序​

串流會經歷以下階段。標記為選用的階段不一定每次出現。

  1. 選用。 帶有 source: "vendor" 的 place 事件:如果金鑰包含 vendor 權限範圍,最多先傳送三個來自貴組織本身的資料的地點,以便地圖立即繪製。
  2. phase。始終是回答本身的第一個事件。
  3. 選用。 生成答案期間傳送 : keep-alive 註解。
  4. 選用。 本文之前的事件:prompt_options;或 route_clear 後跟 route,以及一張卡片。
  5. start。
  6. 本文文字框架,期間穿插 place、place_linked、early_actions,有時還有 route_clear、route 和圖層事件。閒置時通過保持連線訊號維持連接。
  7. 選用。 本文結束後,延遲到達的 place、place_linked、圖層及路線事件。
  8. end 或 error。
  9. 選用。 quota。
  10. 伺服器關閉連接。

這對用戶端有兩點影響:

  • end 不是最後一個事件。 請持續讀取,直到回應主體關閉,否則會錯過 quota。
  • 串流可能在既沒有 end 也沒有 error 的情況下關閉,例如網絡中斷。沒有終止事件就關閉的流應視為失敗。

酬載詳細說明​

文字與標記​

文字框架只攜帶文字,不會在本文中嵌入結構化資料。本文可能用雙中括號標記地點名稱,例如 near [[Louvre Museum]];聊天面板會將其轉換為地圖標記鏈接。若要顯示純文字,請去掉中括號並保留名稱。

place​

欄位類型備注
namestring用於合併記錄的鍵。
coordinatesobject { lat, lng }十進制度數。可能缺失。 無法定位的地點會在沒有坐標的情況下傳送,並標記 unverified: true。不要為其繪製地圖標記。
addressstring選用。
categorystring選用。
iconstring選用。地點的表情符號。
sourcestring選用。"vendor" 表示來自貴組織本身的資料的地點。"map" 表示已發布地圖中已有的地點;聊天面板不會重復繪製標記,因為地圖已經繪製。
idstring選用。自有資料中的地點會包含此欄位。
unverifiedboolean選用。如果地點位置尚未確認,則為 true。

地點還可能包含其他欄位,不需要的欄位可以忽略。

同一地點名稱可能出現多次:先包含坐標,後續再補充信息。每個名稱只保留一條記錄;一旦獲得坐標就不要移動其地圖標記,後續事件可補充其他欄位。

動作​

early_actions.actions 和 end.actions 都是 { type, payload } 對象列表。

操作類型酬載處理方式
map.fitBounds{ coordinates: [[lng, lat], …], padding, maxZoom, duration }讓相機視野包含這些坐標。
places.highlight{ places: [ { name, lat, lng } ], options }突出顯示這些地點。
map.showRoute{ id, label, profile, coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[], transit?, attribution? }繪製路線,並展示 attribution。
route.clear{ id? }刪除具有該 id 的路線;如未指定 id 則刪除所有路線。

還可能出現其他操作類型。無法處理的類型應跳過。注意兩種坐標格式:地點使用 coordinates: { lat, lng },線條使用由 [lng, lat] 組成的列表。

route​

primary 包含要繪製的線條:{ coordinates: [[lng, lat], …], distance_m, duration_s, turn_by_turn[] }。turn_by_turn 的每一步包含 text,還可能包含 direction_type、distance_m、duration_s、lat 和 lng。origin 與 destination 各自包含 label。alternatives[] 是帶有 route_id 的其他路線;comparison[] 給出每條備選路線相對於主路線的 delta_duration_s。如有 stops[],它是多站路線中按順序排列的 { lat, lng, name } 點位。

道路路線包含 attribution: { text, url, license }。每次繪製路線時,都應顯示鏈接到 url 的 text 署名。公共交通路線的運營方署名則位於 transit 中。

每個 route 事件都有 id。繪製具有相同 id 的路線會替換已有路線。

end​

欄位類型備注
full_textstring完整答案。優先使用此值,而不是手動拼接的本文幀。
placesarray按順序排列的最終地點列表。按名稱與已收到的地點合併。
actionsarray最終地圖操作。應以此替換 early_actions 並應用。
dropped_placesarray of strings選用。此前傳送但不屬於最終答案的地點名稱。請移除它們的地圖標記。
question_typestring問題類型標籤,僅供參考。
response_timenumber回答耗時,以秒為單位。
total_tokensnumber選用。回答使用的權杖數,也是計費依據。

error​

event: error
data: {"type": "error", "code": "upstream_stall", "message": "The AI service stopped responding. Please try again.", "partial_text": "The Louvre sits"}

message 可以直接展示給用戶。partial_text 是出錯前已經生成的文字。code 只在一種情況下出現:

情況code處理方式
回答停止推進或串流已達到最大長度"upstream_stall"提示用戶重新嘗試。
回答期間發生的其他錯誤無顯示 message;重新嘗試可能成功。

error 之後不會再有 end,但仍可能收到 quota 事件。

quota​

欄位取決於開啟串流時使用的憑證。

欄位類型伺服器金鑰或舊版金鑰工作階段權杖
type字符串, "quota"是是
meter字符串是是
reset_at字符串,含時區偏移的 ISO 8601是是
product字符串是否
period字符串是否
tier字符串是否
used數值是否
limit數值是否

工作階段權杖由網頁訪客使用,可以從可公開使用的金鑰交換取得,也可以是已發布地圖的訪客工作階段。其 quota 事件僅說明本帳單週期何時重置,不會洩露組織的訂閱方案、使用量或限額。瀏覽器用戶端不應依賴 used 或 limit 欄位。429 quota_exceeded 回應主體也遵循相同規則,請參閱額度與速率限制。

保持連線訊號與逾時​

行為取值用戶端處理方式
聊天流心跳連續 10 秒沒有其他輸出後傳送 : keep-alive 註解收到任何字節時重置閒置計時器,包括註解。
閒置連接連接靜默約一分鐘時,傳輸過程中可能被關閉設置 30 到 60 秒的閒置(讀取)逾時,不要設置過短的整體逾時。
首段本文等待時間複雜問題可能需要幾十秒從 phase 開始顯示進度,不要將等待視為錯誤。
串流最長持續時間約 10 分鐘,此後伺服器傳送帶有 upstream_stall 的 error為保險起見,將整體逾時設置為略長於 10 分鐘。

中止串流與計費​

關閉連接即可中止串流。伺服器通常會在約十秒內發現中斷並停止生成答案。

  • 正常完成 的串流按回答消耗的權杖數計費,數值由 end.total_tokens 報告。
  • 中止或失敗 的串流在完成前結束時按估算值計費。估算至少涵蓋要求中提交的全部對話文字,也可能根據已傳送的內容計算。因此,最終費用可能高於預留額度:收到第一個框架後立即中斷,也不會讓一段較長的對話免費。
  • 自有資料中的地點(source: "vendor")不計入費用。

重新嘗試屬於新的要求,會再次計費。請參閱額度與速率限制。

摘要串流與按鈕串流​

這兩個端點用於 Kaleidr Chat 的地點卡片。它們使用相同的框架格式、無名稱文字框架和末尾的 quota 事件。與主要聊天流相比有三點不同:不傳送 phase,不傳送地點或操作事件,並且不傳送保持連線訊號。應設置 60 秒閒置逾時。

兩個端點都會在串流開始前以 422 field_too_long 拒絕過長欄位,並忽略未列出的欄位,請參閱端點列表。若流中止或失敗,費用基於已傳送文字估算,且不會高於預留額度。

POST /chat/summary/stream,描述地點:

  1. 選用。 address,酬載為 { type: "address", address, source }
  2. start,酬載為 { type: "start", poi_type }
  3. 選用,可能重復。 url,酬載為 { type: "url", website, source }
  4. 文字框架,酬載為 { text }
  5. end,酬載為 { type: "end", full_text, summary, poi_type, category, city, country, sources[], website?, total_tokens? };或 error,酬載為 { type: "error", message, partial_text }
  6. 選用。 quota

POST /chat/summary/stream,描述建築物(type: "building"):

  1. start,酬載為 { type: "start", address }
  2. 文字框架
  3. end,酬載為 { type: "end", full_text, parsed, total_tokens? },或 error
  4. 選用。 quota

POST /chat/button/stream:

  1. start,酬載為 { type: "start", query_type }
  2. 文字框架
  3. end,酬載為 { type: "end", full_text, reply, query_type, first_token_ms, total_ms, total_tokens? }
  4. 選用。 quota

按鈕流沒有 error 事件。如果開始後失敗,連接會在沒有 end 的情況下關閉。開始前失敗則回傳 HTTP 500,回應主體為 {"detail": "Button chat stream error"}。

POST /spot/overview/stream 會傳送上述地點摘要的框架,並在此之前傳送一個酬載為 { type: "place", name } 的 place 框架:name 是所描述地點或區域的完整名稱,例如 "Springfield, Ohio, United States of America",可用於標示或複製。此框架先於其他所有框架傳送,也可能不存在。它不同於聊天串流中的 place 事件,不含座標。如果無法描述某個 ref,它會用一幀 error(酬載為 { type: "error", message, ref })代替摘要。請參閱端點列表。

相關文件​