篇章二 · 2.4
重试与降级链
API 会失败、会限流、会过载——工业级系统对每一种失败都有预案,连撞三次过载还会自动换模型。
每次失败都有 B 计划,B 后面还有 C
重试不是「再跑一次」这么简单:退避多久?哪些错误值得重试?连续失败降不降级模型?这些问题的答案全部写在 withRetry.ts 里。
指数退避 · 公式与滑块
baseDelay = min(500ms × 2^(attempt-1), 32000ms) // 0.5s → 1s → 2s → … 封顶 32s
jitter = random() × 0.25 × baseDelay // 0~25% 随机抖动
delay = baseDelay + jitter // 防惊群:同一时刻的失败者错峰重试 等待 1~1.25s
五种错误码,五种对策
| 错误 | 含义 | 对策 |
|---|---|---|
| 401 | 凭证失效 | 刷新 OAuth token 后重试 |
| 429 | 限流 | 指数退避 + 尊重 retry-after;非企业用户不重试 |
| 529 | 服务过载 | 最多 3 次(MAX_529_RETRIES),超过触发 Fallback Model |
| 400 | 上下文超限 | 调小 max_tokens 后重试 |
| ECONNRESET | 连接重置 | 禁用 keep-alive 后重试 |
降级链 · Fallback Model 触发条件
连续 3 次 529MAX_529_RETRIES = 3
+
配置了 fallbackModel前提条件一
+
非订阅 + 用 Opus或开了 FALLBACK_FOR_ALL 环境变量
→
抛 FallbackTriggeredErrorqueryLoop 捕获 → 切换备用模型继续
还有两条特殊通道:Fast Mode 处理——短 retry-after(<20s)保持 fast 模式以保护 prompt cache,长的冷却 10 分钟;无人值守模式(CLAUDE_CODE_UNATTENDED_RETRY)——429/529 无限重试、退避封顶 5 分钟、每 30 秒 yield 心跳,专为 CI 长任务设计。
故障抽卡机 · 每次请求都是抽卡
?
点「发送请求」——看看这次撞上什么。抽到 429/529 看系统的自动处置;连抽三个 529 见证 Fallback。
⚡ Fallback Model 触发:Opus → 切换备用模型,对话无缝继续
本站要点:每种错误码一条对策、退避带抖动防惊群、529 三连自动换模型。下一站是篇章二最后一站:模型一次要调八个工具,谁先谁后、能不能一起跑。