← 所有文章

在 UniRoute 排查 Claude 流式中断与空闲超时

通过 UniRoute 用量记录与诊断摘要排查 Claude 部分响应中断,核对费用和工具执行结果,再决定如何恢复任务。

UniRoute ·

使用 UniRoute 的 Claude Code 出现 claude api error: stream idle timeout - partial response received 时,先保留已收到的内容,在 UniRoute 控制台找到对应请求,再决定是否重新提交。本教程介绍如何定位记录、复制诊断摘要、区分流式中断与请求完成,以及如何恢复任务。

仅凭这条错误,无法确定是客户端、网络、网关还是上游停止了进展。超时也不能证明零消费。先核对已经发出的请求,收集下列信息无需再发起一次付费调用。

1. 在 UniRoute 找到中断的请求

打开 UniRoute 控制台,登录 Claude Code 所用 Key 对应的账户。在用量记录中选择覆盖事发时间的日期范围,寻找时间与模型匹配的请求。成功和失败记录都应核对:终端里的一次操作可能产生多次请求。

打开对应记录的查看详情,逐项比较:

字段如何使用
时间与模型按所在时区匹配事发时间,并核对客户端选择的完整模型 ID。
接口地址与可用的请求 ID确认请求路径,保留标识以供私有支持查询;区分网关与上游的不同 ID。
结果、HTTP 状态与脱敏错误响应记录服务端已观测的信息,不要根据终端提示补造缺失状态码。
可用的首 token 时间与耗时与终端停止时间比较;这些字段不是完整的 SSE 事件轨迹。
可用的输入、输出、缓存与实际费用逐条核对原请求及重试;缺失字段保持未知。

若未找到匹配记录,检查账户、Key、日期范围、模型,以及 Claude Code 实际配置的服务地址。直接发往 Anthropic 或其他网关的请求不会出现在您的 UniRoute 账户中。缺少记录不能证明没有到达某个服务,也不能证明免费。

在请求详情点击复制诊断摘要。摘要只复制可安全识别的时间、模型、请求 ID、已记录 HTTP 状态与可用消费记录等字段,不包含 Key、提示词、响应原文、作品链接或余额。缺失或无法安全提供的字段记为 null;摘要不代表钱包结算确认。检查复制内容后,仅保留给私有支持使用。

2. 确认客户端与输出停止的位置

记录 claude --version、模型 ID 与实际服务地址。UniRoute 用户可对照Claude Code 接入参考检查本地配置。在 Claude Code 内运行 /doctor 可检查本地设置,相关行为见官方排错文档。本地检查成功不代表中断的请求已经完成。

然后记录终端中实际出现的现象:

现象接下来核对
完全没有输出区分连接或首响应等待,与收到内容后的流式中断。
出现部分文字后停止保留内容,比较客户端时间、对应请求记录与可用网络日志。
出现工具调用或结果先核对文件变更或外部操作结果,再要求代理重复工作。
文字看似完整,随后报错检查是否开始了下一轮请求;报错可能属于后续轮次。
只有长任务失败比较上下文长度、输出量、工具轮次和已观测限制,每次只改变一个因素。

不要把凭据或整份配置贴到公开 issue。网络代理与 API 供应商是两项设置:前者传输流量,后者决定接口地址和认证。实际地址不明确时,查看UniRoute 接口地址参考。

3. 区分空闲时间与总耗时

如果您维护自己的接入程序并能观测事件,应分别记录:收到响应头或首事件之前的等待、距上次收到数据的间隔,以及总耗时。客户端所谓的“空闲”可能按字节、完整事件或可见文字计算,三种时钟可能不同。

例如,0.10 秒收到响应头,0.45 秒出现文字,1.00 秒收到最后事件,1.25 秒客户端停止。这些是假设数值,用于说明测量方式,并非 UniRoute 或 Claude Code 默认值。控制台的首 token 时间与总耗时无法还原全部事件轨迹。

按照 Messages 流式协议,message_stop 标记消息结束;ping 不代表新的回答文字。API 错误说明指出,HTTP 成功后仍可能出现 SSE 错误。未收到预期终止事件就发生 EOF,应视为流未完成;消息完成也可能仍需工具步骤才能完成用户任务。

自建解析器应跨网络分片组装完整 SSE 帧,不要执行尚未完整的工具参数片段。调整超时前,先确认当前客户端或中间层确实读取该设置,并确认观测时间支持这一修改。增加限制不能解决所有网络或上游故障。

4. 恢复前核对执行结果与费用

将 UniRoute 请求记录与本地任务状态一起检查,单独一方都不能确定代理已经修改了什么。

当前状态继续前应做的事
输出前已被拒绝阅读拒绝原因,处理认证、权限、限流或服务问题,并检查是否还有其他尝试。
只有部分文字,未观测到工具保留回答;新回答属于新请求,应限制范围与预算。
出现工具参数或结果检查文件变更、命令日志与操作标识,先核对已经完成的动作。
可能执行了部署、付款、发消息或其他外部写入用稳定标识查询结果;状态未知时保持未知,不要直接重放。
缺少最终用量或实际费用等待记录或联系私有支持核查;缺少最终 usage 不等于零消费。

检查客户端、SDK、包装脚本与网关各自是否重试。确认是临时失败后,恢复过程应由一个执行方负责,并限制次数和总耗时。不要给本来就可能重试的操作再套无限循环。

再次付费调用前,查看UniRoute 当前模型与渠道价格。Claude Code 费用指南介绍输入、输出与缓存成本。多请求同时运行时,客户端估算或钱包余额差不能归因某一笔费用。若问题是开始流式输出前的 HTTP 500,可使用UniRoute 500 错误排查流程;若遇到 HTTP 529 或流式中途 overloaded_error,请参阅 Claude API 529 Overloaded 排查指南;若需核对 OpenRouter 会话配置或切换供应商,请参阅Claude Code 接入 OpenRouter 与切换供应商指南。

核对原请求后,若仍需要小请求对照,可在可信空目录中手动测试。先检查实际供应商、模型、权限与 hooks,使用简短且不含敏感信息的提示词,只运行一次,再核对用量。此类测试属于真实请求,可能产生费用及客户端重试;简短成功不能验证长任务。

5. 通过私有支持发送 UniRoute 诊断摘要

使用详情中的通过邮件联系私有支持,或将检查后的摘要发给 support@uniroute.app。复制的服务端字段不能说明终端中的全部情况,请补充:

  • 客户端版本、带时区的事发时间、服务主机名与完整模型 ID。
  • 是完全无输出、部分文字、工具调用,还是看似完整的回答。
  • 已知尝试次数、观测时间,以及是否确实见到 SSE 错误或终止事件。
  • 已核对的工具执行结果,以及已经做过的单变量对照。

缺失信息明确标为未知。不要包含 Key、Authorization 请求头、Cookie、提示词、私人代码、完整响应、账户余额或无关记录。请求 ID 仅通过私有支持分享,勿公开发布。由其他供应商处理的请求,应使用该服务的记录与支持渠道。

可选附录:在本地理解流式边界

若想在不使用 API Key、不产生模型费用的条件下观察时间差异,下载并检查 Python 3 本地流式探针,然后运行:

curl --fail --silent --show-error --proto '=https' \
  --output claude-stream-probe.py \
  https://uniroute.app/examples/claude-stream-probe.py
python3 claude-stream-probe.py --scenario all

下载使用公开网站。随后程序启动 127.0.0.1 临时服务,仅向该回环服务发送模拟请求。它不接受真实 Key 或远程 API 地址,不调用模型。它展示流式边界,不能诊断生产事故或验证 UniRoute 账户。

场景展示内容
normal流到达终止事件。
sse-errorHTTP 成功后出现 SSE 错误。
truncated连接在完成前结束。
idle-gap响应体数据暂停,超过探针的空闲限制。
delayed-first-event响应头早于首个完整事件。
ping-deadline心跳持续到总截止时间,仍未出现回答文字。
fragmented-multiline网络分片与多行数据需要组装完整帧。

可用 python3 claude-stream-probe.py --scenario idle-gap 查看单一场景。可选的 --idle-timeout 0.2 --total-timeout 0.6 以模拟秒数计,并非 Claude Code 配置。探针按未收到响应体字节的间隔计算空闲;ttfb_ms 近似表示收到完整响应头的时间,first_event_ms 记录首个完整 SSE 帧。在首事件延迟场景中,空闲限制先到,因此该字段为 null。结合结果与时间阅读;探针不打印响应内容,也不重试失败。