502 Bad Gateway 表示作为网关或代理的服务没有从上游获得有效响应。stream disconnected 表示客户端没有得到完整的流式结果,也可能尚未收到首个事件。两者可能相关,但不能只凭错误文字判断是模型、网关、网络还是客户端超时。
Codex 或 Claude Code 断流时,先做同协议的非流式与流式短请求对照:两者都失败,先查 Key、模型权限和上游;只有流式失败,优先查 SSE 事件、代理缓冲、读取超时和长连接空闲超时。
stream disconnected before completion: bad gateway 怎么处理?
这条报错同时描述了“未完成流式结果”和“网关错误”,不等于已经确认模型降级。先记录发生时间、最终请求路径、HTTP 状态码和请求 ID,再区分中断阶段:
- HTTP 响应即为 502,尚无 SSE 事件:先查网关与上游,保存错误正文,不把它归为 SSE 解析失败。
- 已收到 200 和部分事件,随后出现错误事件或连接关闭:检查最后一个事件、读取超时、代理缓冲和协议结束条件;200 不代表任务成功。
- curl 同协议短请求正常,只有 Codex 或 Claude Code 失败:核对客户端版本、实际协议、工具调用与上下文压缩;不能用 Chat Completions 成功替代 Responses 或 Messages 验收。
以下 AI快站 HK 示例使用 https://www.aifast.hk/v1 和该站创建的 Key。模型 ID 从同一账号的实时目录复制,不混用其他站点的 Key、模型权限或计费配置。
upstream response stream was interrupted 怎么排查?
这条提示表示上游响应流被中断,但不能单凭文字确定是哪一层关闭连接。保留结构化错误里的 code 和 message、请求 ID 和最后一个事件;如果收到 upstream_stream_read_error,也需结合 HTTP 状态、已收到的数据和网关日志判断,不直接等同于模型故障。
| 中断位置 | 先保留的证据 | 下一步 |
|---|---|---|
| 尚未收到可用事件 | HTTP 状态、Content-Type、脱敏错误正文 | 先排除 HTML 错误页、空响应和协议不匹配 |
| 已输出一部分后中断 | 最后事件类型、时间、是否已有工具执行 | 查读取或空闲超时;有副作用时先核对执行状态,不整段重放 |
| 到固定秒数中断 | 客户端总时限、代理空闲时限、中断耗时 | 对照各层日志,区分本地诊断超时与上游主动中断 |
Claude Code 提示 Streaming response ended before any complete data was received
这表示客户端没有拿到可用的流式结果。 Claude Code 官方错误说明 指出,这类情况会尝试非流式重发。看到 Retrying without streaming 后即使得到了答案,也只能说明回退请求完成,不能说明 SSE 已修复;具体行为需结合客户端版本与日志核对。
先确认实际请求使用 Messages 兼容入口,记录 HTTP 状态与 Content-Type,再检查是否拿到可解析的消息事件,或被替换成 HTML、空正文、其他协议的 JSON。让网关管理员核对响应头和流式正文是否被改写,不要为排错关闭 TLS 校验或同时改动所有代理设置。
已有自动回退时,不再叠加无限手动重试。核对每次尝试的请求 ID 与用量记录,不能假设失败的流式请求免费,也不能仅凭警告认定重复扣费。下面的 Chat Completions 示例只验证该协议;Claude Code 的 Messages 与 Codex 的 Responses 仍需按对应检查表验收。
502 或 stream disconnected 先看哪三件事?
先用同一个 Key 和模型发送短请求,对照 stream: false 与 stream: true,并记录请求 ID、最后一个 SSE 事件和中断时间。非流式短请求也失败时,优先检查认证、模型权限和上游状态;只有流式失败时,优先检查 SSE 缓冲、读取超时和代理连接;只有长上下文失败时,优先检查上下文长度、任务总时限和重试策略。
用四组对照快速缩小范围
保持同一个 Key 和模型,只改变一个变量:
| 对照 | A | B | 能说明什么 |
|---|---|---|---|
| 输入长度 | 20 字短问题 | 真实长上下文 | 只在长输入失败,优先查上下文与超时 |
| 流式模式 | stream: false |
stream: true |
只在流式失败,优先查 SSE 和代理缓冲 |
| 客户端 | curl / SDK | Cursor、Dify 或 Agent | 只有客户端失败,查客户端超时和解析 |
| 任务类型 | 普通文本 | 工具调用或多轮 Agent | 只有复杂任务失败,查轮次、工具和总时长 |
先做一组短请求对照,只有需要确认可重复性且预算允许时,再对相关变量少量复测。每次记录时间、状态码、请求 ID 与中断位置;一次成功或失败不足以证明长期状态。真实请求可能计费,请使用临时限额 Key,分享日志前删除密钥、Cookie 和业务正文。
先跑非流式短请求
在本地设置 AIFAST_API_KEY,并把示例中的模型占位符替换为当前账号可用且支持 Chat Completions 的模型 ID。两例使用相同短输入,只切换流式模式;10 秒连接上限与 60 秒总时限是诊断参数,不是平台 SLA,也不适合直接作为所有长任务的生产配置。
(
: "${AIFAST_API_KEY:?请先设置临时限额 Key}"
curl -q -sS -i --connect-timeout 10 --max-time 60 \
https://www.aifast.hk/v1/chat/completions \
-H "Authorization: Bearer $AIFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "从控制台复制的模型ID",
"messages": [{"role": "user", "content": "只回复 ok"}],
"stream": false
}'
curl_status=$?
printf '\ncurl_exit=%s\n' "$curl_status"
exit "$curl_status"
)
- 短请求也稳定 502:保存请求 ID 和时间,检查平台或上游状态;
- 短请求成功、长请求失败:逐步缩短上下文并增加读取超时;
- 非流式成功、流式失败:进入 SSE 检查;
- curl 成功、应用失败:检查客户端、代理和 SDK 配置。
检查 SSE 流是否完整
使用 -N 禁用 curl 自身的输出缓冲;它不会关闭服务端或中间代理的缓冲:
(
: "${AIFAST_API_KEY:?请先设置临时限额 Key}"
curl -q -sS -i -N --connect-timeout 10 --max-time 60 \
https://www.aifast.hk/v1/chat/completions \
-H "Authorization: Bearer $AIFAST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "从控制台复制的模型ID",
"messages": [{"role": "user", "content": "只回复 ok"}],
"stream": true
}'
curl_status=$?
printf '\ncurl_exit=%s\n' "$curl_status"
exit "$curl_status"
)
curl_exit=0 只表示传输没有触发 curl 错误,不代表 HTTP 成功或模型任务完整。仍要检查响应状态、协议结束事件和错误正文。curl_exit=28 表示触发了超时条件;本例到 60 秒被截断可能只是本地总时限,不足以证明平台宕机。-q 放在第一个参数,避免个人 curl 配置自动加入重试等选项。
重点观察:
- 是否持续收到
data:事件; - 数据事件是否按当前协议可解析(
[DONE]这类结束标记除外); - 是否出现正常结束标记;
- 中断前是否返回错误事件;
- 反向代理是否缓冲或压缩了流。
更完整的客户端示例和代理检查见流式输出与 SSE 接入教程。
三种协议的正常结束条件不同
| 协议 | 成功结束的关键信号 | 不能混用的判断 |
|---|---|---|
| Chat Completions | data: [DONE],结合结束原因和错误内容判读 |
[DONE] 不是普通 JSON;结束标记不代替完整内容验收 |
| Responses | response.completed,核对最终响应状态;失败或不完整事件另行处理 |
不能强制要求 [DONE] 或把 response.failed 算成功 |
| Anthropic Messages | 完整内容块与最后的 message_delta、message_stop |
不能把 content_block_stop 或 ping 当作整条消息成功结束 |
结束事件出现仍需检查拒绝、截断、工具请求和实际任务是否完成。流内 error 事件需要独立记录;缺少末尾 usage 也不能直接按零 Token 或零费用处理。
把超时拆成三层
不要只设置一个笼统的 timeout=30:
| 超时 | 作用 | 常见误配 |
|---|---|---|
| 连接超时 | 建立 TCP/TLS 连接 | 设置过长,网络故障迟迟不失败 |
| 读取超时 | 等待下一个响应分片 | 设置过短,推理或工具阶段被误杀 |
| 任务总时限 | 限制完整业务任务 | 没有上限,Agent 可以无限运行 |
长推理和工具调用可能在两个文本分片之间等待更久,但这不意味着总时限应该无限增加。应分别设置合理的读取超时与业务截止时间。
Codex 或 Claude Code 报 stream disconnected
Codex 和 Claude Code 的长任务不只依赖普通文本流,还可能包含工具参数增量、工具结果回传、上下文压缩和连续会话。短聊天成功,不能证明 Agent 链路完整。
按下面顺序复测:
- 固定客户端版本、Base URL、模型 ID 和同一个只读任务。
- 先用非流式短请求确认认证、模型和基础路径正常。
- 再执行一次不调用工具的流式请求,保存完整 SSE 事件。
- 最后执行单次只读工具调用,检查参数增量、结束原因和工具结果是否完整。
- 如果只在上下文压缩后中断,保存中断前最后一个事件、会话长度和客户端日志,不要只提高超时。
Codex 还需要单独核对 Responses API 和连续响应事件;Claude Code 需要核对 Anthropic Messages 兼容入口。对应检查表见 Codex 网关检查清单 和 Claude Code 网关检查清单。
反向代理重点检查
如果应用前还有 Nginx、Cloudflare、Lucky 或其他代理,核对:
- 是否关闭了不适合 SSE 的响应缓冲;
- 上游读取超时是否短于客户端;
- 是否完整转发
Authorization和Content-Type; - 响应是否被错误压缩、拼接或缓存;
- 长连接是否被空闲超时提前关闭;
- 请求体大小限制是否小于真实上下文。
不要一开始就同时放大所有超时和请求体限制。先通过短请求、长请求和流式对照确认是哪一层触发。
502 应该怎么重试
只对可以安全重复的请求做有限重试,并加入抖动。以下情况要特别谨慎:
- 生图、视频等异步任务可能已经创建成功;
- 工具调用可能已经写入数据库或发送消息;
- 流式请求中断前已经向用户输出部分内容;
- 服务端已扣费但客户端没有收到完整响应。
对有副作用的任务,应使用幂等键、任务 ID 或业务去重机制。无法判断服务端是否执行时,不要直接重新发起。
修复完成的验收标准
- 短请求、真实上下文分别完成多次验证;
- 非流式与流式均能正常结束;
- 日志保留请求 ID、中断时间、首个分片和最后一个分片时间;
- 连接、读取和任务总时限职责清楚;
- 代理不会缓冲 SSE 或提前关闭长连接;
- 重试次数有限,有副作用任务具备去重机制。
如果同一入口持续出现异常,可以先运行模型质量检测保存协议与行为报告,再按API 对比测试模板从相同地区、模型和题集复测。检测报告用于定位兼容性问题,不等同于厂商身份认证或长期 SLA。