流式返回是什么
stream=true 时服务不再等整段生成完才返回,而是用 SSE 分块把增量 token 逐个下发,客户端边收边显示。它改变的是结果到达方式,不是总生成时间:首字延迟的体感明显改善,完整回答的耗时不会因此变短。链路上任何一层做了响应缓冲,流式都会退化成一整块返回。
基本信息
| 字段 | stream: true / false(OpenAI 兼容接口) |
|---|---|
| 传输 | HTTP 长连接 + SSE(text/event-stream) |
| 收益 | 首字延迟体感下降,长回答可边看边读 |
| 要求 | 网关、CDN、应用框架都不得缓冲响应 |
| 结束标志 | OpenAI 兼容实现通常在末尾发送 data: [DONE] 后关闭连接 |
典型使用场景
- 交互式对话前端:需要边生成边显示,避免用户盯着空白等十几秒
- 长回答场景(报告、代码、要点整理):让用户尽早看到开头并决定是否继续等
- 降低网关与客户端空闲超时风险:持续有数据流动,连接不容易被中间层掐断
- 观测与埋点:按块记录到达时间,直接得到 TTFT 与生成速率
- 客户端可提前中断:用户点停止时能立刻断开,省下后续算力
Python SDK 流式消费
Python SDK 流式消费
stream = client.chat.completions.create(
model="<模型名>",
messages=[{"role": "user", "content": "写一首短诗"}],
stream=True,
)
for chunk in stream: # 每块是一个增量片段
delta = chunk.choices[0].delta.content
if delta: # 首块与末块可能没有正文
print(delta, end="", flush=True)
# 校验:打印首块到达时间,与不开流式的耗时对比
流式链路上的缓冲点
| 层级 | 典型症状 | 处置方向 |
|---|---|---|
| Nginx 反代 | 内容被攒成一整块返回 | 关闭响应缓冲,使用 HTTP/1.1 长连接 |
| CDN 或企业代理 | 表现与时延都不稳定 | 确认回源不缓冲,或让流式请求绕过该层 |
| 应用框架中间件 | 框架层聚合了响应体 | 改为逐块透传,不做整体读取 |
| 客户端 | 一次性拿到全部文本再渲染 | 按事件逐个解析,不要先读完整响应 |
用量字段(token 计数)在流式里出现的位置随实现而异:有的放在最后一个数据块里,有的需要显式开启。网关按块累计用量容易漏计,做计费时要单独对齐口径。
流式请求中途断开不一定等于失败:用户主动取消、超时切断都可能发生,服务端与客户端都要按「部分结果」处理,而不是当成完整回答落库。