AGTCloud API Docs
文件指南API Reference整合與資源更新與幫助

Streaming

逐步接收模型輸出,並正確處理事件、增量、完成與斷流。

Streaming 讓用戶端在模型生成完整回答之前持續接收增量內容。它適合聊天介面、長文字生成和需要盡快顯示首段結果的情境,但用戶端必須正確處理事件邊界、內容串接、完成狀態和連線中斷。

Streaming 改變回傳方式,不改變任務本身

同一個任務通常可以選擇非串流或串流回傳。先完成非串流請求,再開啟 Streaming,更容易區分請求參數問題和串流解析問題。

使用前確認

  1. 在模型廣場確認目標模型支援所選協議和 Streaming。
  2. 根據協議使用對應端點和事件結構,不要讓同一個解析器猜測所有協議。
  3. 確認用戶端、反向代理和閘道不會緩衝整個回應後再一次回傳。

完整欄位分別由 Chat Completions、Responses、Anthropic Messages 和 Gemini Stream Generate Content Reference 維護。

送出最小串流請求

下面透過 Chat Completions 開啟串流輸出:

curl --no-buffer 'https://api.agtcloud.cn/v1/chat/completions' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer your-api-key' \
  --data '{
    "model": "MODEL_ID",
    "messages": [
      {"role": "user", "content": "分三點解釋指數退避。"}
    ],
    "stream": true
  }'

--no-buffer 讓 cURL 及時顯示已經收到的資料,不會改變伺服器端事件結構。

按事件讀取,而不是按網路資料包讀取

HTTP 連線每次交給用戶端的位元組數量並不等於一個完整事件。一個 JSON 物件可能被拆成多個資料區塊,多個事件也可能在同一個資料區塊中收到。

對於 SSE,用戶端應先以空行辨識完整事件,再讀取其中的 data: 內容:

const response = await fetch('https://api.agtcloud.cn/v1/chat/completions', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    Authorization: 'Bearer your-api-key',
  },
  body: JSON.stringify({
    model: 'MODEL_ID',
    messages: [{ role: 'user', content: '解釋什麼是指數退避。' }],
    stream: true,
  }),
});

if (!response.ok || !response.body) {
  throw new Error(`請求失敗:${response.status}`);
}

const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

while (true) {
  const { value, done } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const events = buffer.split('\n\n');
  buffer = events.pop() ?? '';

  for (const event of events) {
    const data = event
      .split('\n')
      .filter((line) => line.startsWith('data:'))
      .map((line) => line.slice(5).trimStart())
      .join('\n');

    if (!data || data === '[DONE]') continue;
    const chunk = JSON.parse(data);
    const delta = chunk.choices?.[0]?.delta?.content;
    if (delta) process.stdout.write(delta);
  }
}

正式環境程式碼還應處理取消請求、讀取逾時、心跳、非 JSON 事件以及流結束時尚未消費的緩衝區。

四種協議的串流結構

Chat 通常回傳 Chat Completion Chunk。文字位於 choices[].delta.content,工具參數可能出現在 choices[].delta.tool_calls,結束原因位於 finish_reason;事件流可能以 [DONE] 結束。

協議入口存在不代表所有模型都會回傳上述所有內容類型。只實現應用實際使用、並已由目標模型回傳的分支。

串接文字和工具參數

  • 文字增量按候選、輸出項或 Content Block 的索引分別串接。
  • 工具名稱、呼叫 ID 和參數可能分多次到達,應為每個呼叫維護獨立緩衝區。
  • 工具參數只有在完整結束後才能解析為 JSON,不能逐塊執行。
  • 推理摘要、Thinking Block 和最終回答使用不同緩衝區,不能混成一段文字。
  • 如果協議在最後回傳 Usage,應在收到完成事件前繼續讀取連接。

判斷成功、失敗和中斷

現象用戶端處理
收到協議規定的完成事件儲存完整結果和 Usage,標記請求成功
收到錯誤或失敗事件儲存已顯示內容,同時將本次請求標記為失敗
連接提前關閉標記為不完整,不把已有文字冒充完整回答
使用者主動停止取消讀取並在介面標記“已停止生成”
長時間沒有新事件按應用逾時策略取消,保留必要的疑難排解資訊

串流請求已經向使用者顯示部分內容後,不應自動無限重放。重試可能產生另一份不同回答,也可能重複觸發工具或其他有副作用的行為。

上線前檢查

  • 頁面能夠逐步顯示文字,而不是等到連接關閉才顯示。
  • 中文和多位元組字元不會因資料區塊切分而亂碼。
  • 工具參數按呼叫 ID 正確串接,並在執行前完成驗證。
  • 使用者取消、網路斷開、逾時和伺服器端錯誤都有明確狀態。
  • 記錄不會記錄 API Key、完整敏感 Prompt 或未經去識別化的工具參數。

下一步可閱讀 Tool Calling 和錯誤與疑難排解。

本頁目錄