流式响应依赖持久的 HTTP 长连接来持续传输数据,比普通的一次性请求更容易受到代理、防火墙、超时配置和客户端解析逻辑等因素的影响。本文整理了常见的流式异常场景及对应的排查与修复方法。
常见问题
可能原因
- 代理或防火墙缓冲了响应:中间节点等待响应完成后再转发,破坏了流式推送
- 客户端超时设置过短:连接在生成完成前被客户端主动断开
- 网络不稳定:长连接在传输过程中意外断开
处理建议
- 检查请求链路上是否存在反向代理(Nginx、CDN 等)或企业网络的正向代理,确认其是否支持流式(chunked transfer encoding)
- 增大客户端超时设置,参考 请求超时处理建议
- 在流式读取中实现重连机制,记录已接收内容,断连后从断点续传(若业务允许)
收到 data: [DONE] 前未接收到完整内容
可能原因
max_tokens 设置过小:模型在生成完整回答前达到了 Token 上限,提前停止输出
finish_reason 为 length:表示因达到长度限制而截断,而非正常完成
处理建议
检查每个数据块中的 finish_reason 字段:
finish_reason: "stop" — 正常完成
finish_reason: "length" — 因达到 max_tokens 限制而截断,需增大该参数值
finish_reason: null — 数据块尚未结束,继续读取
可能原因
- 未按 SSE 规范逐行解析数据,将多行合并处理
- 未过滤空行(SSE 以空行作为事件分隔符)
- 未处理注释行(以
: 开头的行)
- 直接对整个响应体执行
JSON.parse,而非逐行解析
处理建议
参考下方「SSE 正确解析逻辑」章节。
curl 默认会缓冲输出,导致流式数据无法实时显示。解决方法
添加 --no-buffer 参数禁用输出缓冲:
SSE 正确解析逻辑
HHAPI 的流式响应遵循 Server-Sent Events(SSE) 格式。每个数据块的格式如下:
解析规则:
- 按换行符
\n 逐行读取响应体
- 跳过空行(SSE 事件分隔符)
- 跳过以
: 开头的注释行
- 对以
data: 开头的行,提取 data: 之后的内容
- 若提取内容为
[DONE],停止读取
- 否则将其作为 JSON 字符串解析,提取
choices[0].delta.content
Python 完整示例(使用 openai SDK):
若需手动解析 SSE(不使用 SDK):
代理环境注意事项
某些正向代理(如企业网络中的 HTTP 代理)会将响应完整缓冲后再转发给客户端,导致流式效果完全失效——表现为长时间没有输出,最后一次性接收全部内容。如果你处于代理网络环境中,请联系网络管理员确认代理是否支持 chunked transfer encoding 或 SSE 透传,或考虑绕过代理直接访问 HHAPI。
相关资源