流式输出
通过配置 stream 参数以 Server-Sent Events(SSE)协议逐块接收文本回复,降低首字延迟。
在默认的同步调用模式下,服务端会在模型完成全部内容的生成后,将完整的 JSON 数据包一次性返回。当在请求体中传入 "stream": true 后,服务端将采用 Server-Sent Events(SSE)长连接协议,按生成进度逐块推送文本增量。这种方式可以显著缩短首字呈现时间,提升终端交互的流畅度。
Chat Completions、Responses 以及 Anthropic Messages 接口均支持通过 "stream": true 参数开启流式输出,各协议的增量数据格式略有不同。
Chat Completions 流式传输
curl https://console.anystarx.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID",
"stream": true,
"messages": [
{
"role": "user",
"content": "请从 1 数到 5。"
}
]
}'from openai import OpenAI
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://console.anystarx.com/v1",
)
stream = client.chat.completions.create(
model="MODEL_ID",
messages=[{"role": "user", "content": "请从 1 数到 5。"}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content if chunk.choices else None
if delta:
print(delta, end="", flush=True)import OpenAI from 'openai';
const client = new OpenAI({
apiKey: 'YOUR_API_KEY',
baseURL: 'https://console.anystarx.com/v1',
});
const stream = await client.chat.completions.create({
model: 'MODEL_ID',
messages: [{ role: 'user', content: '请从 1 数到 5。' }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content;
if (delta) process.stdout.write(delta);
}SSE 协议响应格式解析
Chat Completions 接口在流式模式下以标准的 SSE 事件流返回,每一行为一个带有 data: 前缀的独立 JSON 数据块。文本增量存储在 choices[0].delta.content 字段中,客户端依次拼接每个数据块中的文本即可还原完整回复:
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"role":"assistant","content":""}}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":"1"}}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{"content":"、2"}}]}
data: {"id":"...","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]在自主实现客户端解析逻辑时,应当注意以下规则:
- 仅解析以
data:开头的行,过滤心跳注释行与空行。 - 数据流以
data: [DONE]作为传输结束的标记,该行不是合法的 JSON 字符串,不能直接传给 JSON 解析器。 - 最后一个有效数据块的
delta可能为空对象,此时通过finish_reason(如stop或length)判断生成终止原因。
使用各语言的官方 SDK 时,底层已封装好事件分块与文本拼接逻辑,可以直接遍历接收流式对象。
流式用量统计配置
按照 OpenAI 官方标准,流式传输过程中默认不返回 usage 统计字段。如果需要在最后一个数据块中获取本次请求实际消耗的 token 数量,可以在请求体中增加 stream_options 配置:
{
"stream": true,
"stream_options": { "include_usage": true }
}部分上游模型可能尚未支持该扩展字段。如果设置后接口报错,移除该配置即可,实际消耗仍以控制台记录的账单明细为准。
Anthropic Messages 流式规范
在调用 Anthropic Messages 接口时,流式协议遵循 Anthropic 的专用事件格式:每个事件由 event: 类型声明行和随后的 data: 数据行组成,文本增量位于 content_block_delta 事件的 delta.text 字段中:
event: message_start
data: {"type":"message_start","message":{...}}
event: content_block_delta
data: {"type":"content_block_delta","delta":{"type":"text_delta","text":"1"}}
event: message_stop
data: {"type":"message_stop"}使用 Claude Code 等官方及衍生工具时,客户端内部已集成该协议的流式解析。通过代码自主调用时,同样在请求体中传入 "stream": true 即可启用。
常见流式问题排查
配置了流式参数但依然一次性返回结果
如果在发起流式请求后未观察到逐步输出效果,通常是请求链路中的中间代理开启了响应缓冲(Buffering):
- 检查自建的 Nginx 或反向代理服务是否开启了缓冲机制,可以配置
proxy_buffering off;禁用缓冲并实时透传分块数据。 - 在前端使用原生
fetch接收数据时,应使用response.body.getReader()进行可读流逐步读取,避免使用await response.json()等待完整响应。
长文本生成过程中连接意外断开
当模型生成超长内容时,持续时间可能超过客户端或反向代理设定的 HTTP 读取超时阈值(Read Timeout)。建议根据业务需求适当放宽中间件超时时间,并在请求中合理设置 max_tokens 参数控制输出长度。
客户端环境不支持流式传输
如果业务调用方运行在批处理脚本或无法处理 SSE 事件流的遗留系统中,直接在请求体中省略 stream 参数或将其设置为 false 即可,接口将按标准模式返回一次性的完整 JSON 数据。