OpenAI 兼容 API 流式输出(stream)失败排查
先分清是哪种症状
四种症状对应不同根源:
- 完全无输出:请求未携带
stream: true,或客户端未正确发送。 - 内容一次性全出:服务端已流式返回,但中间层缓冲后合并发送(常见于未关闭缓冲的反向代理或 Serverless 平台)。
- 中途断流:超时、网络抖动或上游限制导致连接提前关闭。
- 客户端解析报错:未按 SSE 逐行读取、未处理
data: [DONE],或把每块增量当作完整 JSON 解析。
用 curl 判定服务端是否真在流
执行以下命令(-N 禁用缓冲):
bash
curl -N -X POST https://api.treenew.online/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-xxx" \
-d '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"test"}],"stream":true}'若终端中 data: 逐块陆续出现,说明「树新在线」网关与上游均正常,问题在客户端或自建中间层。
自己套了反向代理的话
Nginx 必须关闭缓冲,否则会出现“一次性全出”:
nginx
location /v1/ {
proxy_pass https://api.treenew.online;
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_http_version 1.1;
proxy_set_header Connection "";
}proxy_buffering on(默认)会把 SSE 事件攒到一块再返回,导致症状 (b)。
客户端解析要点
- 按行读取响应,跳过空行。
- 每行以
data:开头,去掉前缀后解析。 - 遇到
data: [DONE]即结束。 - 每块内容是
delta增量字段,而非完整消息对象。
中途断流
调大客户端超时(建议 300s+),实现指数退避重连:首次等待 1s,之后 2s、4s,最多重试 3 次。