流式输出

按协议读取 SSE 增量,正确处理完成事件、工具参数、错误与连接中断。

查看 Markdown

流式输出的工作方式

在支持流式的文本模型上设置 stream: true,服务端使用 Server-Sent Events(SSE)逐步返回结果。SSE 是以空行分隔的事件,不是一份完整 JSON。一个网络数据块可能只包含半个事件,也可能包含多个事件;不能把每次网络读取直接交给 JSON 解析器。

流式不会减少模型需要生成的内容或保证降低费用,也不替代超时和并发控制。本文示例仅展示格式与处理方法,不提供实际延迟数据。

三种端点的事件差异

端点主要增量位置结束信号当前注意事项
POST /v1/chat/completionschoices[].delta.contentdata: [DONE],同时检查 finish_reason工具参数和推理文本有各自字段,不应并入最终文本
POST /v1/responsesresponse.output_text.delta 事件的 deltaresponse.completed当前桥接主要转换文本,不完整保留工具或推理事件
POST /v1/messagescontent_block_delta 的 delta.textmessage_stop区分文本、Thinking 与工具内容块;工具流为基础兼容实现

成功建立 SSE 后,响应 Content-Type 为 text/event-stream。建立前的鉴权、参数或上游连接错误仍可能返回普通 JSON 和非 2xx HTTP 状态。请先判断 HTTP 状态及内容类型,再选择解析器。

完整调用示例

curl -N 关闭客户端输出缓冲。Python 示例依赖 openai 包,关闭自动重试,并显式判断是否见到选择项的结束原因。环境变量 GFW_API_KEY 必须提前设置。

curl --no-buffer --fail-with-body --silent --show-error \
  --max-time 120 \
  https://api.gfw.net/v1/chat/completions \
  -H "Authorization: Bearer ${GFW_API_KEY:?请先设置 GFW_API_KEY}" \
  -H 'Content-Type: application/json' \
  -H 'Accept: text/event-stream' \
  --data '{
    "model": "deepseek-v4-pro",
    "messages": [{"role": "user", "content": "用三句话说明连接池的作用。"}],
    "max_tokens": 512,
    "stream": true
  }'

示例只处理文本。工具场景要额外收集 delta.tool_calls,推理场景要单独处理模型提供的推理字段。用量事件可能没有 choices,客户端必须允许空数组;也不要假设每次流式调用都能得到完整 usage。

事件与响应示意

下面为 Chat Completions SSE 结构示意,事件顺序与文本仅用于说明:

data: {"id":"chatcmpl_example","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl_example","choices":[{"index":0,"delta":{"content":"连接池"},"finish_reason":null}]}

data: {"id":"chatcmpl_example","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Responses 的文本事件结构示意:

event: response.output_text.delta
data: {"type":"response.output_text.delta","delta":"连接池"}

Anthropic Messages 的文本事件结构示意:

event: content_block_delta
data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"连接池"}}

解析命名事件时同时保留 event 名称和 JSON 内 type。不要将 message_stop、response.completed 与 Chat 的 [DONE] 混为一种统一的字符串终止符。

中断、错误与应用状态

流开始后 HTTP 状态已固定,后续异常可能表现为流内 error、连接断开,或缺失预期内容。HTTP 200 和收到结束事件都不足以证明答案完整;Chat 转发在部分异常结束后仍会补发 [DONE],Responses 桥接也可能发出最终标签。因此必须结合异常、内容、结束原因和应用校验判断。

推荐保存 receiving、completed、failed 等应用状态:收到增量时只追加到临时结果,完成并通过校验后再提交业务结果。连接中断时保留已经收到的文本,但标为不完整。重新发起请求可能重复生成与计费,不应自动把新流追加到旧流。

工具参数必须按调用索引收集完整 JSON 后再解析和执行。针对 Anthropic 工具流,当前桥接存在非完整原生事件兼容边界,复杂工具流程优先使用非流式返回。

接入注意与相关文档

保持 SDK 的连接读取超时,并为业务操作设置总时限。中间反向代理若启用了响应缓冲,界面可能直到结束才收到文本;排查时比较直接 cURL 输出与应用读取结果,不要据此推断模型没有流式能力。

用量和账单以 用量与调用日志 及 计费与充值 为准。相关文档:OpenAI 兼容 API、Responses API、Anthropic 兼容 API、工具调用、错误码与重试。

本页目录