Claude Code fallbackModel:三级故障转移配置(2026)

遇到 529 过载时,Claude Code 的 fallbackModel 最多可重试 3 个模型,但不处理 429。用 4 步(settings.json + CLI)完成配置,并搞清楚什么时候该交给网关。

用 4 步搭好三级故障转移

当 Anthropic 返回 529 overloaded_error 时,一个没做任何配置的 Claude Code 会话会重试同一个模型,然后把错误直接甩给你。而 fallback 链条会把这条死路变成降级通道:Opus 过载就重试 Sonnet,如果 Sonnet 也不可用,再退到 Haiku。

你能做到什么让 Claude Code 按顺序尝试最多三个备用模型,从而扛过 529 过载、保住这一轮对话
所需时间约 5 分钟
你需要什么Claude Code v2.1.197+(以支持 Sonnet 5 别名)、你列出的那些模型的账号访问权限,以及一个可编辑的 settings.json

整套配置就是一个数组:

{
  "model": "opus",
  "fallbackModel": ["sonnet", "haiku"]
}

这就是一条三级链:opus 是主模型,sonnethaiku 是 fallback。本指南剩下的部分讲的是这个数组本身看不出来的那些细节:到底哪些错误会触发它、为什么 429 不会、这条链在团队中的行为,以及单账号链条从哪里开始不再顶用。

配置完成后你能做什么(以及不能做什么)

fallback 链条是一个用途很窄的工具。在动手搭建之前,值得先把它的边界说清楚,因为它修复的那类故障,看起来和它无能为力的另外两类故障非常像。

fallback 链条能为你做的是:

  • 扛过一次临时性的 Anthropic 过载(529 overloaded_error),不丢掉这一轮对话。
  • 在某个特定模型不可用时继续工作,例如 settings 里钉死的某个模型如今已被下线。
  • 有意识地降级能力,让一个从 Opus 起步的高难度任务在 Sonnet 上收尾,而不是干脆做不完。

它不会为你做的是:

  • 帮你绕过 429 限流或用量上限。那是配额问题,而链条中的每个模型都从同一个账号配额里扣。
  • 故障转移到另一家供应商。链条各项都解析为同一账号下的 Claude 模型,所以一次彻底的 Anthropic 宕机会把整条链一起拖垮。
  • 永久改变你的主模型。切换是按轮次的,下一条消息又从你的主模型开始。

如果你反复遇到的痛点是”用量已达上限”而不是”过载”,那 fallback 链条就是用错了地方。请参阅另一篇关于 Claude Code 触发限流 的指南;而针对过载本身在 API 层面的版本,参阅 Claude API 529 错误

决策框架:何时该用这套配置(以及何时不该)

何时该用

  • 你在无人值守或脚本化的场景下跑 Claude Code(CI、长时间的 agent 运行、通宵任务),一次轮次中途的 529 会让整个作业中断。
  • 你在付费 API 或较高层级上,日常的中断来自过载而不是配额。
  • 你能接受这一轮剩余部分的质量下降,以换取这一轮能跑完。

何时不该用

  • 你的中断是 429 或”用量已达上限”。链条在这里什么也做不了,应该去修配额或缓存(token 优化才是那个杠杆)。
  • 出于可复现性,你需要每一轮都在某个特定模型上跑。运行途中悄悄降级到 Haiku 可能改变输出质量,而后续某一步可能正好依赖它。
  • 你需要供应商层面的韧性。一个账号无法向自己做故障转移,那需要网关(下文会讲)。

停手规则

如果你只想要过载时的单个自动备用,加一个条目就收手:"fallbackModel": ["sonnet"]。只有当你预期 Sonnet 会和 Opus 同时承压时,三级链条才有意义,而这种情况大多发生在一次波及面较广的平台事故中。

系统要求

要求详情
Claude Code 版本v2.1.197+ 才能让 sonnet 别名解析为 Sonnet 5;v2.1.154+ 对应 Opus 4.8。不确定就跑 claude update
模型访问权你列出的每个模型都必须在你的账号上可达。够不着的那一项会被跳过、并非致命,但一条全是够不着的模型的链条,跟没有链条一样会失败。
配置文件位置一个你能编辑的 settings.json~/.claude/settings.json(用户级)或 .claude/settings.json(项目级)。
供应商示例假定用的是 Anthropic API。在 Bedrock、Google Cloud 或 Foundry 上,别名会解析成不同版本,你可能需要完整的部署 ID。

三个别名在今天的 Anthropic API 上分别解析成什么:

别名模型API ID输入 / 输出(每 MTok)上下文Effort 默认值
opusOpus 4.8claude-opus-4-8$5 / $251Mhigh
sonnetSonnet 5claude-sonnet-5$3 / $151Mhigh
haikuHaiku 4.5claude-haiku-4-5-20251001$1 / $5200K(无 effort 控制)

这张表里有两个细节会影响一条合理链条的搭法。Sonnet 5 在 2026 年 8 月 31 日之前采用 $2 / $10 每 MTok 的推广价,所以中间这一级现在比标价更便宜。而 Haiku 4.5 的上下文窗口是 200K,不是 Opus 和 Sonnet 那样的 1M,所以一个已经超出 200K 的长会话,装不进 Haiku 这一级。搭链条时把这一点考虑进去:出于容量原因,Haiku 是最后的退路,而不只是质量上的退路。

分步配置

第 1 步:确认主模型和版本

claude --version
claude   # then run /status inside the session

/status 会显示当前生效的模型。如果 opus 没解析成 Opus 4.8,或者 sonnet 不是 Sonnet 5,先跑 claude update。预期结果:版本达到或高于 2.1.197,且主模型能被正确识别。

第 2 步:用命令行参数为单次会话测试链条

在把任何东西写死之前,先用 CLI 参数试一下链条。它接受逗号分隔的列表,且会覆盖任何已保存的配置,这让它成为最安全的试验方式。

claude --model opus --fallback-model sonnet,haiku

预期结果:会话从 Opus 起步。除非真的发生过载,否则你看不到 fallback 生效;一旦发生,Claude Code 会打印一条提示,说明它切换到了哪个模型。

第 3 步:把链条写进 settings.json

参数行为符合预期后,把它挪进 settings,让每个会话都继承。别名或完整模型 ID 都可以用;完整 ID 会钉死一个版本,别名变更时也不受影响。

{
  "model": "opus",
  "fallbackModel": ["claude-sonnet-5", "claude-haiku-4-5"]
}

预期结果:新会话都从 Opus 起步,带一条双模型 fallback 链,无需任何参数。对于你带参数启动的会话,--fallback-model 参数仍然胜出。

第 4 步:验证触发条件,而不是验证顺利路径

你没法按需造出一个真实的 529,所以要去验证你能推理的部分,而不是干等一次宕机。确认每一项都解析到你能访问的模型,并确认你清楚什么不会触发它。别指望靠报错来告诉你链条读进去了:Claude Code 在启动时不校验 fallbackModel(在 v2.1.208 上验证过),所以一个写坏的值会被静默忽略,而不是抛错。最后这一点,也就是什么不会触发它,正是大多数配置错误藏身的地方,所以它单开一节来讲。

什么会触发 fallback(以及什么不会)

这张表值得记进脑子里。fallback 只在可用性类失败上触发,其他一切都保持沉默。

条件HTTP触发 fallback?实际发生什么
过载529 overloaded_error切换到链条中的下一个模型
模型不可用不定跳到下一个可达的项
其他不可重试的服务器错误5xx切换到下一个模型
限流429正常带退避重试,然后抛出
认证401作为认证错误抛出
账单402/403作为账单错误抛出
请求体过大413作为体积错误抛出
传输 / 网络正常重试,然后抛出

429 这一行是最容易把人绊倒的。限流意味着你已经耗尽了某个配额,而你链条里的每个模型都记在同一个账号上,所以从 Opus 切到 Haiku 并不会腾出空间。Claude Code 明白这一点,拒绝在这种情况下浪费一次 fallback。如果你的日志显示事故期间 fallback 从未触发,先查一下这次事故到底是不是 429。

同样的逻辑用流程图表示:

flowchart TD
    A[Model request] --> B{Response}
    B -->|529 / unavailable / non-retryable 5xx| C{More models in chain?}
    B -->|429 / auth / billing / size| D[Normal retry, then surface error]
    B -->|success| E[Return result for this turn]
    C -->|yes| F[Switch to next model, show notice]
    C -->|no| D
    F --> A
    E --> G[Next message tries primary first again]

选择链条顺序

数组的顺序就是 Claude Code 尝试的顺序,所以这个数组是一份优先级列表,而不是一个集合。两种默认配置能覆盖大多数情况,取决于你优化的目标。

能力优先(opus 主模型下配 ["sonnet", "haiku"])在可用性允许的前提下把质量保持得尽量高,只有当两个更大的模型同时过载时才落到 Haiku。适合交互式工作,此时降级是真正意义上的最后退路。

成本优先(sonnet 主模型,["haiku"] fallback)根本不会去够 Opus。适合 CI 和 agent 循环,这里吞吐和可预期的花销比能力天花板更重要。混合路由 的论点在这里同样成立:大多数轮次并不需要 Opus,所以仅仅为了凑出一条更长的链就把 Opus 设成主模型,会在常见情形上白白花钱。

有一条约束的优先级高于以上两种偏好,而且很容易被忽略:上下文窗口。Haiku 4.5 的窗口是 200K,对比 Opus 4.8 和 Sonnet 5 提供的 1M。一个已经涨过 200K 的会话根本落不到 Haiku 这一级,所以在长上下文的工作里,无论你把 Haiku 放在哪,它实际上都不在链条里。如果你的会话经常跑得很大,就把链条保持在 1M 窗口的层级上,并接受这样的代价:Opus 和 Sonnet 同时宕机时,这一轮会失败,而不是悄悄截断上下文。

切换发生时会看到什么

fallback 从来不是无声的。当它触发时,Claude Code 会在对话记录里打印一条提示,说明它切换到了哪个模型。因为切换的作用域限于这一轮,所以你在下一次过载时会再次看到这条提示,而不是一个悄悄稳定停在 Haiku 上的会话。配置错误则相反:一个写坏的 fallbackModel 值会被忽略、不带任何警告(在 v2.1.208 上验证过),所以一条坏掉的链看起来跟一条好用的链一模一样,直到一次过载正好撞上那个缺口。要确认一条链真的在生效,别去找启动报错,而要按下文所述,从一次 JSON 运行的 modelUsage 字段里去审计它。

在会输出 JSON 的非交互式运行(-p / --print)中,那条纯文本提示会被抑制,所以要从结果消息的 modelUsage 字段里读出真正作答的是哪个模型,而不是想当然地认为这一轮是主模型处理的。这是事后可靠审计的办法:一条链在一段时间内到底接住了多少次、以及是哪一级吸收了负载。如果一条链在一整段真实事故窗口里都没显示出任何一次接住,就重新查一下这次事故是不是 429,因为没有链条能覆盖 429。

配置期间的常见错误(及修复)

症状原因修复
宕机期间链条从不触发这次宕机是 429,不是 529fallbackModel 不覆盖限流;单独处理配额
你的全局链条悄悄没了项目级 .claude/settings.json 也定义了 fallbackModelfallbackModel 不跨文件合并;优先级最高的文件提供整条链
某个列出的模型被跳过它已被下线、不可达,或被 availableModels 排除替换已下线的 ID;被白名单排除掉的项在读取链条时会被丢弃
四个模型里只跑了三个去重后链条上限为三个精简列表;超过三个的多余条目会被忽略
拼错的链条项从不触发,也不报错fallbackModel 里拼错的项在读取链条时会被静默跳过自己反复核对拼写;用有效的别名(opus/sonnet/haiku)或带 claude- 前缀的 ID。启动时不会有报错来抓这个
脚本化运行里 fallback 被无视在非交互式下运行,被标记的请求会直接结束这一轮这是 Fable 5 分类器的路径,不是 fallbackModel;见下文的辨析

不合并这一行为值得重点强调,因为它跟大多数数组类配置的做法正好相反。如果你在用户 settings 里精心调好了一条三级链,而某个仓库带来一个自带单模型 fallbackModel.claude/settings.json,那仓库会整个胜出,你的链条被丢弃、不带任何警告。优先级顺序是:受管配置,然后命令行参数,然后项目本地,然后项目,然后用户。把你真正想要的那条链,放进任一会话都会读取的、优先级最高的那个文件里。

团队 / 多开发者配置

对单个开发者来说,~/.claude/settings.json 里的 fallbackModel 就够了。跨团队时,有意思的问题是谁拥有这条链,以及个人能否覆盖它。

目标fallbackModel 放在哪备注
个人默认~/.claude/settings.json(用户级)优先级最低;任何项目文件都会覆盖它
每仓库默认.claude/settings.json(项目级,已提交)对在该仓库里工作的所有人覆盖用户设置
本机微调.claude/settings.local.json只对一台机器覆盖项目设置,通常被 gitignore
全队强制受管配置优先级最高;个人无法覆盖

有两个团队特有的相互作用需要注意。第一,如果你还用 availableModels 来限制开发者可运行的模型,那么在这个白名单之外的任何 fallback 项,都会在读取链条时被丢弃,所以一条强制的链和一份白名单必须相互一致。第二,因为 fallback 链条不合并,一条已提交的项目链会在该仓库内完全取代每个开发者的个人链。这对 CI 和共享 agent 通常正是你想要的,但它意味着一个调好了个人链的开发者,在该仓库里工作时会悄无声息地失去它。请把项目链写进文档,免得有人去排查一个其实是被设计所覆盖的”消失的” fallback。

一个适合在 CI 里跑 agent 的团队的合理已提交项目链:

{
  "model": "sonnet",
  "fallbackModel": ["haiku"],
  "availableModels": ["sonnet", "haiku"]
}

这让 CI 保持在更便宜的 Sonnet 层级,过载时退到 Haiku,并禁止任何人悄悄把某个 CI 作业切到 Opus。

进阶:通过网关实现跨供应商故障转移

fallback 链条有一个硬天花板:链里的每个模型都活在同一个 Anthropic 账号上。当 Anthropic 自身发生波及面较广的事故时,三级会同时过载,链里已经没有别的东西可试。2026 年 3 月 18 日那次持续超过三小时的宕机,就是同账号链条无法覆盖的那种失败形态。

供应商层面的韧性需要一层在 Claude Code 之上的东西。用 ANTHROPIC_BASE_URL 把 Claude Code 指向一个网关,由网关(而不是你那一个账号)来决定请求落到哪里。ANTHROPIC_BASE_URL 改变的是请求去往何处,而不是由哪个模型作答,所以一条 fallbackModel 链在它下面依然用于模型层面的故障转移,同时网关在上面加了一层供应商层面的故障转移。

ofox 这样的聚合网关,对外暴露一个同时兼容 OpenAI 和 Anthropic 的端点,对接多家供应商,于是当 Anthropic 整体不可用时,一条链就能从一个 Claude 模型跨到一个非 Claude 模型,这是原生 fallbackModel 链在物理上做不到的。代价是你现在多信任了一跳,而且你在网关处而不是 settings.json 里配置路由。这套配置在 Claude Code 一侧的做法,参阅 Claude Code + ofox 配置指南;同一套路由思路的成本驱动版本,参阅 混合模型路由

在讲替代方案之前先做一个辨析。Claude Code 还有一个功能字面上就叫 “automatic model fallback”,它不是本文说的这个。那套机制专属于 Fable 5:当安全分类器标记了一个请求(最常见于网络安全或生物学相关的工作),Claude Code 会在 Opus 上重跑它并显示一条提示。它跟过载或 fallbackModel 链毫无关系。如果你在一个 Fable 5 会话上看到了你没配置过的 fallback,那就是分类器。运行 claude --safe-mode 会禁用你本地的定制(CLAUDE.md、skills、hooks、MCP),所以它能隔离出是不是这些东西在触发;但安全模式仍然会发送诸如你的 git 状态和目录名之类的信息,所以即便如此,仓库内容本身也可能触发分类器。

处理故障转移的替代方案

fallbackModel 是内置、零依赖的选项,应当作为你在模型层面做过载韧性的首选。当你需要更多时,这些是它之上的各层。

  • ofox 对外暴露一个同时兼容 Anthropic 的单一端点,对接多家供应商,因此在一次彻底的 Anthropic 事故期间,故障转移能从 Claude 跨到另一个模型家族。适合供应商层面的韧性比锁定单一厂商更重要的场景。
  • LiteLLM 是一个开源代理,自带跨供应商的重试和 fallback 列表。适合你想自托管路由层、且已经在运行相关基础设施的场景。
  • OpenRouter 是一个聚合器,为给定模型提供自动的供应商 fallback。适合追求模型目录广度、且希望配置最少的场景。
  • Portkey 是一个网关,带可配置的 fallback 和负载均衡策略。适合你想要路由规则而不是一份静态列表、并附带可观测性的场景。

这四者都位于 Claude Code 之上,是对 fallbackModel 链的补充而非替代:保留这条链用于低成本的 CLI 内模型故障转移,再加一个网关来应对供应商层面的情况。

FAQ

Claude Code 里的 fallbackModel 是什么?

它是 settings.json 里的一个配置项,也对应一个 --fallback-model CLI 参数,用来列出主模型过载或不可用时 Claude Code 按顺序尝试的备用模型。最多可列三个。一次切换只在当前这一轮内生效,下一条消息会重新优先尝试你的主模型。

Claude Code 碰到 529 错误时会自动降级吗?

只有配置了 fallbackModel 才会。529 是 overloaded_error,属于触发切换的条件之一。没有任何配置时,Claude Code 会带退避重试同一个模型,然后把错误抛出。

fallbackModel 能解决限流(429)错误吗?

不能。认证、账单、限流(429)、请求体过大以及传输类错误都不会触发切换。429 意味着你已经用完了自己的配额,而链条里的每个模型都记在同一个账号上,所以切换层级并不会腾出空间。

Claude Code 最多能用几个 fallback 模型?

三个。去重之后链条上限为三个,多出来的条目会被忽略。常见链条是 opus,然后 sonnet,然后 haiku

在 Claude Code 里如何设置 fallback 模型?

只针对单次会话,用 claude --fallback-model sonnet,haiku 启动。要长期生效,就在 settings.json 里加一个 fallbackModel 数组,例如 ["claude-sonnet-5", "claude-haiku-4-5"]。参数胜过配置项。

fallback 模型会在整个会话期间一直生效吗?

不会。切换只对当前这一轮生效,所以一次临时过载不会把会话锁死在较低的层级上。

fallbackModel 和 automatic model fallback 有什么区别?

fallbackModel(fallback 模型链条)针对可用性,在过载或不可用时触发。automatic model fallback 是另一套专属于 Fable 5 的机制,即安全分类器把被标记的请求改路到 Opus。两者只是共用了 fallback 这个词。

Claude Code 能降级到非 Anthropic 的模型吗?

通过 fallbackModel 不行。每一项都解析成同一账号下的某个 Claude 模型,所以一次彻底的 Anthropic 宕机会把整条链一起拖垮。跨供应商的故障转移需要一个能对接多家供应商的网关。

本次更新核对的来源