AI API 流式输出总是中断怎么办?
AI API 接入能返回完整文本,不代表流式输出也稳定。很多开发者遇到的是页面显示到一半停止、SSE 连接被网关切断、用户刷新后重复扣费、日志里只看到客户端取消。排查时要把模型、代理、后端、前端和重试策略分开看。
适用场景:哪些中断值得单独排查
如果你只是偶尔遇到 401、404、429,先看 AI 模型接口报错排查清单。本文讨论的是更隐蔽的流式问题:HTTP 状态码看起来是 200,前端也能收到前几段内容,但一段时间后没有结束标记;或者后端日志显示请求成功,用户界面却停在“生成中”。这类问题常发生在长回答、代码生成、资料总结、客服长文本回复和 Codex 接入后的连续对话里。
流式输出链路一般经过浏览器、应用后端、反向代理、AI API 网关和模型服务。任何一层的空闲超时、缓冲设置、连接复用或异常关闭,都会让开发者 AI 调用看起来像“模型不稳定”。所以排查时不要一开始就换模型,也不要只调大 token 上限。
操作步骤:先确认断在哪一层
1. 用最小请求绕过前端
先用命令行直接请求同一个 AI 模型接口,确认模型服务是否能持续输出。把问题样本缩短成一个固定请求,保存请求体、模型名、base URL 和 request_id。如果命令行完整、网页中断,问题多半在前端或应用代理;如果命令行也中断,再看上游接口、网络和模型超时。
$headers = @{ Authorization = "Bearer $env:AI_API_KEY" }
$body = Get-Content -LiteralPath .\stream-sample.json -Encoding UTF8 -Raw
Invoke-WebRequest -Uri "$env:AI_API_BASE/v1/chat/completions" -Method Post -Headers $headers -Body $body -ContentType "application/json; charset=utf-8"
2. 给每段流日志加时间戳
只记录“请求成功”没有意义。后端至少要记录开始时间、首个 token 时间、最后一个 chunk 时间、结束原因、客户端是否断开、上游状态码和模型名。这样才能判断是 15 秒首包慢、60 秒代理空闲超时,还是 120 秒后模型仍在生成。上线前的日志字段可以参考 AI API 灰度验证清单。
3. 检查代理缓冲和超时
Nginx、Caddy、云函数、网关和负载均衡都可能默认缓冲响应或设置较短空闲超时。流式接口需要确认不会把响应攒到最后一次性返回,也不会因为一段时间没有新 chunk 就关闭连接。若业务需要长输出,前端也要显示心跳、取消按钮和失败提示,而不是让用户以为页面卡住。
常见问题和避坑
第一,不要对已经输出一半的内容盲目自动重试。用户可能会收到两段重复回答,费用也可能重复计算。更稳的做法是把失败状态写清楚,让用户选择“继续生成”或“重新生成”。第二,不要把所有 timeout 都设成很大。超时过大时,真实故障会占住连接,影响其它请求。第三,不要让前端只依赖最后的 done 标记,应该在每段内容到达时更新状态,并在超时后显示可理解的错误。
如果你已经做了多模型备用,可以结合 AI 模型接口多模型备用 设计降级;但流式中断时先判断是否适合切换模型。内容生成到一半再切模型,往往会造成上下文不一致,适合用“重新生成”而不是静默切换。
检查清单:上线前至少跑一遍
- 同一请求在命令行、后端接口和浏览器三处都能复现或排除。
- 日志能区分首包慢、过程中断、客户端取消、上游超时和输出格式错误。
- 代理层关闭响应缓冲,空闲超时符合最长生成场景。
- 前端有取消、重试、继续生成和错误提示,不把半截回答当完整结果。
- 失败重试不会自动重复提交高成本请求,费用和 request_id 可追踪。
验收标准很具体:固定三类样本,短回答、长摘要和代码生成,都能稳定收到结束状态;强制断网或刷新时,日志能看到客户端取消;超过阈值时,用户能看到明确提示。完成这些检查后,再把流式输出放进真实 AI 自动化办公或 Codex 辅助开发流程,会比只看一次成功响应更可靠。
补充排查:把“等待太久”和“真的断开”分开
很多用户反馈“卡住了”,实际有两种情况。第一种是上游还在生成,只是前端长时间没有收到新片段;第二种是连接已经断开,但界面没有更新状态。建议在前端保存最后收到内容的时间,如果 20 秒没有新内容,就显示“仍在等待模型输出”;如果连接关闭但没有结束标记,就显示“连接中断,可继续或重试”。这比一直转圈更容易让用户理解,也方便客服按日志定位。
后端也要避免把异常吞掉。比如上游连接被关闭、JSON 片段解析失败、客户端取消请求,这三种都不应该只记成 failed。可以给每次请求生成 request_id,并把 request_id 返回给前端错误提示。用户截图反馈时,开发者就能按 ID 找到完整链路,而不是只凭时间范围猜测。
适合 Codex 辅助检查的点
Codex 接入后,可以让它检查项目里哪些接口使用了流式响应、哪些代理配置影响超时、哪些前端组件只处理完成态。让 Codex 做这类检查时,要给它明确边界:只读取配置和日志,不修改生产超时;先列出风险点,再由开发者确认。若要改代码,仍然按 Codex 改完功能后的验收清单 跑完本地测试和页面验证。