TL;DR 极速速查
- 流式核心原理:大模型流式输出依赖 HTTP Server-Sent Events(SSE)。任意一环开启了 HTTP 响应缓冲或设置了过短的空闲超时,长连接都会被强行掐断。
- 现象 1:吐出几个字就卡住或报 fetch failed:多为本地代理软件(Clash/V2Ray 等)拦截了流式长连接,开启 TUN 模式或将 API 域名加入直连绕过代理即可解决。
- 现象 2:等待约 100 秒后稳定报 524 / 504 Gateway Timeout:触发了 Cloudflare 边缘节点默认的 100 秒源站响应超时,属于模型长推理(如 o1 / 复杂思考链)的常见现象。
- 现象 3:所有内容一次性吐出,没有打字机效果:反向代理(Nginx/Caddy)未关闭
proxy_buffering,导致整个响应包生成完才下发。
图 1:AI API 流式长连接四层排查拓扑(示意图)
分阶段排查:从离你最近的一端开始
流式中断的排查必须遵循严格由近及远的顺序:本地客户端 → 本地代理环境 → 公网传输链路 → 中转网关与上游源站。跳跃排查往往会浪费大量时间修改无关配置。
阶段一:排查本地客户端与网络代理
超过 60% 的流式断流问题出在开发者本地的科学上网或代理工具上:
- 代理软件缓存了 SSE 数据流:普通 HTTP 代理在处理 chunked 流式数据时,有时会尝试凑齐一定大小的缓冲区再转发给应用,导致客户端看起来像是「一直没响应」,随后因客户端自身的请求超时直接抛出
timeout。 - 应对方法:将使用的 API 域名(如
api.shana.baby)直接加入本地代理软件的直连规则(Direct),或者使用全局 TUN 虚拟网卡模式,避免应用层 Socket 被暴力重置。 - 拉长客户端超时时间:客户端默认的 HTTP 请求超时往往设定在 30~60 秒。在进行代码复杂重构或调用长上下文模型时,首次 token 生成可能需要 20 秒以上。请在客户端设置中将
Request Timeout调整为 180 秒或以上。
阶段二:排查网关与 CDN 边缘超时(504 / 524)
当请求通过网络到达中转网关后,涉及长连接保活机制:
1. Cloudflare 100 秒硬限制(Error 524)
大多数中转服务套设了 Cloudflare 边缘防御。Cloudflare 免费版与 Pro 版对源站 HTTP 连接有严格的 100 秒空闲超时限制。如果模型前置思考(Reasoning)时间过长,源站在 100 秒内没有向客户端发送任何哪怕一个字节的保持活动(Keep-Alive)数据,Cloudflare 将立即切断连接并返回 524 错误。遇到此问题,建议在客户端中选择响应速度更快、无需长时间预推理的模型。
2. 反向代理的响应缓冲(Proxy Buffering)
如果你在自建网关或自建反代,Nginx 必须显式禁用缓存并开启 chunked 传输:
location / {
proxy_pass http://upstream_backend;
proxy_buffering off;
proxy_cache off;
proxy_set_header X-Accel-Buffering no;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}未配置 proxy_buffering off 时,流式输出会被压缩包形式拦截,破坏 SSE 数据流的时序。
阶段三:用一条 curl 命令排查是网络问题还是网关问题
运行以下带有流式标记("stream":true)的 cURL 测试,并在终端观察数据块是否实时滚动:
curl -N -X POST "https://api.shana.baby/v1/chat/completions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"写一首关于秋天的四言绝句"}],"stream":true}'参数说明:-N(或 --no-buffer)会强制 cURL 实时将每一块数据打印到屏幕上。如果能实时看到一行行 data: {"choices":[...]} 迅速刷出,证明网络链路与中转服务的流式输出完全正常,问题仅出在你的图形化客户端配置上。
常见问题
为什么非流式调用正常,一旦开启 stream 就频繁断开?
非流式调用只是一个标准的单一 HTTP 请求/响应周期;而流式调用需要维持数秒到数分钟的长连接通道。只要本地网络中存在不稳定的 Wi-Fi 丢包、NAT 路由超时或代理软件重连,长连接就会被操作系统内核强行中断(TCP RST)。
报错「fetch failed」或「terminated before completion」怎么解决?
这是 Node.js / Electron 底层连接中断抛出的典型异常。请依次执行:1. 重启客户端;2. 检查本地代理软件是否开启了 TUN 模式;3. 将 API Base URL 切换为直连或优化后的中转域名;4. 检查账户余额是否足够支撑模型的高并发计费,具体状态码含义参见 中转 API 常见 429/502/530 状态码速查表。
流式输出时经常出现中途乱码或字符截断?
UTF-8 编码的一个汉字由 3 个字节组成。在极少数高频流式切割情况下,字节流被切分在了字符边界中间。现代成熟客户端(如 Cursor、Cherry Studio)内置了 TextDecoder 缓存拼装机制,通常能够自动处理;若自写脚本遇到乱码,切忌直接对每个 chunk 单独解码,必须使用支持流式解码的解码器。
相关阅读
• 中转 API 的 Base URL 到底带不带 /v1?主流客户端配置对照
• 中转 API 常见 429/502/530 状态码速查表(附自检命令)
维护说明
本文根据 2026 年主流 CDN 边缘网络规则、反向代理配置及本地网络环境实测总结。若模型推理架构或网关策略调整,我们将及时复测并更新调优建议。