# 4.4 故障转移基础：回退链路与恢复策略

本节介绍回退链路的配置方法、触发时机及其与重试机制的联动关系。配置的核心在于利用 `agents.defaults.model.primary` 和 `agents.defaults.model.fallbacks` 设定主模型及按优先级排列的回退目标。此外，本节还将提供一套基于“故障注入与观测”的验证方案，确保持续可用性与回退机制的真实生效。

## 4.4.1 故障分类：把错误映射为动作

回退的关键不是“失败就换”，而是“不同失败用不同动作”。建议把错误先按“可操作性”分三类：

* **配置/鉴权类（快速失败）**：例如 401/403、密钥缺失、字段写错层级。应快速失败并给出可操作指引；不要在同一条链路里盲目重试放大故障窗口。
* **瞬时故障类（有界重试）**：例如短暂超时、抖动、偶发 5xx。可重试，但必须设预算（次数与总耗时）。
* **持续不可用类（触发回退）**：例如持续限流（429）、供应商长时间不可用、网络侧持续失败。应尽快切到回退目标以维持连续性。

把三类错误混在一起会导致两种反效果：该快速失败的问题被无意义重试拖垮；该回退的问题没有及时切流。

## 4.4.2 回退配置：agents.defaults.model.fallbacks

最小可用写法是：主模型 + 顺序回退列表。系统会在主模型失败时，按顺序尝试备选模型。

```javascript
{
  agents: {
    defaults: {
      model: {
        primary: "openai-codex/gpt-5.4",
        fallbacks: [
          // 第一回退：同供应商轻量模型（常用于应对并发限流）
          "openai-codex/gpt-5.2",
          // 第二回退：跨供应商模型（常用于应对上游或网络侧持续故障）
          "anthropic/claude-sonnet-4-6",
        ],
      },
    },
  },
}
```

建议按“连续性优先但要可解释”来排序：越靠前的回退目标越应该稳定、可用、并且成本与质量波动可接受。如果你的环境使用的是 `openai/*` 而不是 `openai-codex/*`，应整体替换成与当前 auth 路径一致的 provider 前缀，不要混写。

## 4.4.3 与重试联动：避免故障窗口内放大

回退链路要和重试一起设计，否则会出现“重试拖死”或“无声切换”。

* **有界重试**：限制最大次数与总时长，避免在不可用窗口里把队列与成本放大。
* **回退优先级**：把更稳的备用模型放在更前面；同供应商与跨供应商各留一条兜底。
* **可观测恢复**：当主链路恢复后再切回，避免反复抖动导致输出质量与成本不可预测。

## 4.4.4 Auth-profile 级冷却：同供应商多账号的内置轮转

除了跨模型的 `fallbacks` 链路，OpenClaw 还在 **同一 provider 内** 维护一套 auth-profile 轮转机制。当一个密钥或账号触发失败后，系统会自动切到同 provider 的下一个可用凭据，而不立即跨模型跳转。

冷却梯度：

| 失败次数 | 冷却时长     |
| ---- | -------- |
| 1    | 1 分钟     |
| 2    | 5 分钟     |
| 3    | 25 分钟    |
| 4+   | 1 小时（上限） |

billing 相关禁用（如 402 结算失败）有独立梯度：从 5 小时起步，每次失败翻倍，上限 24 小时；24 小时未出错则自动重置。

冷却状态持久化在 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` 的 `usageStats` 字段，重启后仍有效。更多 auth 级可靠性机制见第 11 章。

## 4.4.5 验证方法：故障注入与对账

回退不是写进配置就算完成，必须验证它真的会触发，并且能被对账。

1. **基线**：`models status --check` 通过，说明主/备 provider 的认证与网络都可用。
2. **观测**：跟随结构化日志，确保你能看到回退事件（常见事件名为 `model_fallback`）。
3. **注入**：人为制造“主链路失败、备链路仍可用”的条件（例如临时撤销主链路密钥或触发主模型限流）。
4. **对账**：确认日志里出现回退事件，并且命中目标与 `fallbacks` 顺序一致。

操作示例（观测窗口）：

```bash
openclaw models status --check
openclaw logs --follow --json
```
