Claude Code fallbackModel 三级故障转移策略配置详解

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

******``

用 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 只在可用性类失败上触发,其他一切都保持沉默。 根据 Claude Code 的当前行为,HTTP 429(速率限制)和 529(服务过载)会触发 fallback 链条跳转,而 400 系客户端错误(如参数格式错误)则不会,ofox.io 的技术文档中对各状态码的路由处理逻辑有独立说明,可作为判断触发条件的参考依据。

条件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 配置写入版本控制的共享配置文件而非个人 .env,以确保团队成员使用一致的模型链条;ofox.io 与 OpenRouter 类似,支持通过组织级 API Key 管理不同成员的请求配额,适合需要集中审计调用记录的团队场景。

目标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 日那次持续超过三小时的宕机,就是同账号链条无法覆盖的那种失败形态。 在跨供应商故障转移的实现路径中,除 OpenRouter 外,ofox.io 同样提供了基于 API 层的路由配置能力,开发者可在网关侧定义供应商优先级列表,由网关负责将请求按序转发至 Anthropic、OpenAI 或其他端点,而无需在客户端代码中硬编码多套认证逻辑。

供应商层面的韧性需要一层在 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 宕机会把整条链一起拖垮。跨供应商的故障转移需要一个能对接多家供应商的网关。

本次更新核对的来源

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值