Skip to content

无人值守别无限等:CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS 给 429/529 等待封顶 ​

在 CI、评测脚本或远程 worker 里跑 Claude Code,很多人会打开 CLAUDE_CODE_RETRY_WATCHDOG=1:遇到限流或过载就一直等,别让任务半路失败。问题是「一直等」有时真的是一直——流水线挂在那里几个小时,占着 runner,也没人知道它在干嘛。

CLI 2.1.295 新增 CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS,给这种等待设一个上限。

先回顾:watchdog 模式在做什么 ​

按官方文档,CLAUDE_CODE_RETRY_WATCHDOG 设为 1 时:

  • 遇到 429、529 这类容量错误会无限重试,而不是在 CLAUDE_CODE_MAX_RETRIES 次之后放弃;
  • 两次尝试之间最多退避 5 分钟;如果响应里带了限额重置时间,就等到重置为止,所以撞上用量上限的会话会把剩下的窗口等完;
  • 2.1.199 起,服务器错误、超时、断连等其他瞬时错误的默认重试次数提到 300 次(大约三小时的退避),并取消 CLAUDE_CODE_MAX_RETRIES 15 次的上限;
  • 2.1.239 起,标准速度请求收到「花费上限 / 用量额度耗尽」的 429 会立刻失败,不再无限等待重置。

这套机制适合「宁可慢,也要跑完」的任务。但如果你的 CI 有整体超时,或者你更希望尽早失败、尽早告警,无限等待就不合适了。

新变量:每个请求最多等多久 ​

CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS 的含义(以官方文档为准):

  • 在已设置 CLAUDE_CODE_RETRY_WATCHDOG 的前提下生效;
  • 限制的是每个 API 请求花在等待 429 和 529 上的总时间,单位毫秒;
  • 时间用完之后,下一次这类错误就会结束这个请求;
  • 取值是正整数,直接写数字,例如 1800000 表示 30 分钟;
  • 不设置时,等待没有上限(也就是之前的行为)。

怎么设置 ​

一次性运行:

bash
CLAUDE_CODE_RETRY_WATCHDOG=1 \
CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS=1800000 \
claude -p "跑完测试并修复失败用例"

在 GitHub Actions 这类 CI 里,放进 job 的环境变量即可:

yaml
env:
  CLAUDE_CODE_RETRY_WATCHDOG: "1"
  CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS: "1800000"

也可以写进 settings.json 的 env,让同一台机器上的无人值守会话共用。

数值怎么定: 一个简单的思路是让它明显小于 CI 的 job 超时。比如 job 限 60 分钟,单个请求最多等 20~30 分钟,剩下的时间留给真正干活和收尾,失败时流水线也能正常报错,而不是被平台强杀。

和 529 退避变量不是一回事 ​

前几天介绍过 CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS,2.1.296 又加了配套的最大延迟变量。它们调的是普通重试模式下,529 两次重试之间隔多久。文档写明:设置了 CLAUDE_CODE_RETRY_WATCHDOG=1 时,基础延迟变量不起作用。

可以这么区分:

变量管什么
CLAUDE_CODE_OVERLOADED_RETRY_BASE_DELAY_MS普通模式下 529 退避的起始间隔
CLAUDE_CODE_RETRY_WATCHDOG打开无人值守模式,429/529 无限重试
CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MSwatchdog 模式下,每个请求等 429/529 的总时长上限

watchdog 这几个版本的修复 ​

如果你长期在用 watchdog,下面这些修复也值得知道:

  • 2.1.281:修复一连串 429/529 等待之后,遇到第一个 5xx 或断连就失败;以及 5xx 带很长 Retry-After 时不设上限、悄悄睡下去。
  • 2.1.288:修复很长的响应流失败后重试数小时;现在会重新发起流式请求,连续三次超时后放弃。
  • 2.1.295:新增 CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS。

小结 ​

  • watchdog 模式默认对 429/529「等到天荒地老」;2.1.295 起可以用 CLAUDE_CODE_RETRY_WATCHDOG_MAX_WAIT_MS 给每个请求的等待封顶。
  • 值用毫秒、纯数字;建议明显小于 CI job 的总超时。
  • 它只在 CLAUDE_CODE_RETRY_WATCHDOG 打开时有意义,和普通模式下的 529 退避变量互不替代。

升级后用 claude --version 确认 ≥ 2.1.295。

Claude-cn.org,专注于 Claude Code 中文教程