登录·注册
BestRelay

返回刊物

长流式请求的稳定性取决于分层超时预算

第一步,沿着完整请求链路标出超时边界

长流式请求中途断开,不一定是模型生成太慢。客户端、应用服务器、反向代理、转发层和模型服务都可能设置独立的等待期限。连接仍然存在,不代表每一层都愿意继续等待。

先画出实际链路,逐层记录连接建立时间、响应头到达时间、首个流事件时间和最后一次收到数据的时间。排查时使用同一个请求标识串联日志,避免把客户端断开与上游失败误认为同一件事。

本文由 BestRelay 发布,其质量优先的转发方式是将请求交给其中指定的官方模型,不做模型替换,覆盖 Claude、GPT、Gemini、DeepSeek、Kimi、GLM、Qwen 和 Grok 等系列。即使模型身份明确,整条链路仍然需要逐层验证。

第二步,把等待预算拆成三个独立计时器

不要仅设置一个笼统的超时值。首片段预算约束开始输出前的等待,空闲预算约束相邻数据之间的间隔,总时长预算则约束整个任务的生命周期。连接建立还应有独立且较短的期限。

例如,可以先用九十秒等待首片段、四十五秒限制连续空闲、十二分钟限制任务总时长,再根据实际延迟分布调整。这些只是测试起点,不是所有模型都适用的推荐值。推理阶段、工具调用和长输入都可能改变等待特征。

还要区分首个协议事件与首段可见文本。前者到达只能说明流已启动,不能证明用户已经看到内容。检查所用客户端库的具体语义:读取超时可能限制单次读取等待,并不等于整个响应的总期限。

第三步,让代理实际转发数据而不只是维持连接

确认每一层都支持增量转发,并检查响应缓冲。上游已经逐段发送数据,代理却攒到一定大小才向下游输出,同样会让客户端触发空闲超时。压缩和内容检查也可能改变数据到达节奏。

协议允许时,可以发送客户端能够忽略的心跳事件,但不能把心跳当成万能续命机制。它只对实际收到这些数据、并据此重置计时器的链路段有效,无法解除上游绝对时长限制,也不能代替真正的生成进展。

分别记录最近收到任意字节和最近收到有效内容的时间。否则,持续心跳可能让一个已经没有进展的任务无限占用资源。

第四步,分开验证客户端等待与应用主动取消

BestRelay 可用于 Claude Code、Codex、Gemini CLI 和各类 OpenAI SDK,但兼容请求格式不等于共享相同的超时行为。逐项核对客户端版本、读取期限、自动重试,以及外层应用或任务队列的总期限。

用户取消或总预算耗尽时,应停止下游输出,并尝试向上游传播取消信号。连接关闭并不保证上游已经停止计算,因此需要记录取消发出与确认状态,而不是直接把任务标记为未产生费用。

第五步,通过故障注入验证重试与费用边界

测试至少覆盖四种情况:迟迟没有首片段、输出中途长暂停、代理突然断开、客户端主动离开。检查系统能否区分原因,并向用户说明结果是完整、部分完成,还是状态未知。

已经收到部分输出后,不要无条件重放整个请求。新请求可能再次生成内容;涉及工具操作时,还可能重复执行副作用。只有服务明确提供恢复能力时,才能按其语义续传,否则应保存部分结果并让用户决定是否重新发起。

BestRelay 按提供商报告的令牌数量按量计费,缓存读取与写入分别计价。因此,超时排查也应保留用量记录,不能把断流等同于零消耗。需要实测时,欢迎创建 BestRelay 账户。会员邀请他人充值可获得推荐佣金,但稳定性验收仍应以延迟、完整率和取消行为为准。

想亲自试试文中提到的模型? 注册