# 4.2 模型供应商接入与认证方式

在[第二章](https://yeasy.gitbook.io/openclaw_guide/di-yi-bu-fen-ji-chu-ru-men/02_setup/2.3_onboarding)中，`openclaw onboard` 向导已经帮你完成了内置供应商的密钥绑定，模型已经可以调用。本节的目标不是重复“接入”，而是讲清楚三件事：什么时候需要显式写 `models.providers`、什么时候不需要；密钥如何安全注入与轮换；以及如何用标准化命令验收接入状态。

## 4.2.1 三条路径：你真的需要 models.providers 吗？

OpenClaw 的内置供应商（OpenAI、Anthropic、Moonshot 等）已经发布了默认的模型目录（default catalog）。通过 `openclaw onboard` 完成认证后，密钥存入 `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`，无需在 `openclaw.json` 中手动配置 `models.providers`。

只有在以下情况下才需要显式写 `models.providers`：

* **覆盖内置供应商的默认行为**：需要自定义 baseURL、请求头、模型列表或速率限制时。
* **接入自定义/自托管供应商**：如 OpenRouter、Ollama 或自建代理，这些不在内置目录中。
* **配置多密钥轮换**：需要用 `keys` + `keyId` 做灰度发布时（详见 4.2.5）。

换句话说，对大多数用户而言，onboard 完成后只需要在 `agents.defaults.model` 中指定模型标识即可：

```javascript
{
  // 内置供应商已通过 onboard 认证，无需 models.providers
  agents: {
    defaults: {
      model: {
        primary: "openai-codex/gpt-5.4",
      },
    },
  },
}
```

模型标识统一使用 `provider/model` 格式，斜杠前的 `provider` 必须能在 `models.providers`（自定义供应商）或认证档案（内置供应商）中找到匹配。需要特别注意的是：**不同认证路径会影响 provider 前缀**。例如，在本次审计实例中，OpenAI 的订阅/OAuth 路径对应的是 `openai-codex/*`，而直接 API Key 路径通常仍写作 `openai/*`。常见的命名形态（以下名称仅为格式示例，实际可用模型以 `openclaw models status --check` 和各供应商官方目录为准）：

* `openai-codex/gpt-5.4`、`openai-codex/gpt-5.2`
* `anthropic/claude-sonnet-4-6`、`anthropic/claude-opus-4-6`
* `anthropic-vertex/claude-sonnet-4-6`（通过 Google Vertex AI 调用 Claude）
* `moonshotai/kimi-k2.5`
* `zai/glm-5`
* `chutes/<模型名>`（Chutes 平台，支持 OAuth 和 API Key 两种认证）
* `xai/grok-4.20`

## 4.2.2 需要显式配置的场景与示例

以下示例面向**确实需要** `models.providers` 的场景。如果你使用的是内置供应商且 onboard 已完成认证，可直接跳到 4.2.4 了解密钥注入的高阶形式。

**1. 覆盖内置供应商默认值**

当需要将 Anthropic 请求走自建代理、或为 OpenAI 指定特殊 headers 时：

```javascript
{
  models: {
    providers: {
      anthropic: {
        apiKey: "${ANTHROPIC_API_KEY}",
        baseUrl: "https://my-proxy.internal/anthropic/v1",
      },
    },
  },
}
```

> \[!NOTE] 如果只是想换一把密钥而不改其他默认值，也可以在 `models.providers` 中只写 `apiKey`，它会覆盖 auth-profiles 中的对应条目。

**2. Anthropic Vertex（通过 Google Cloud Vertex AI 调用 Claude）**

认证方式：GCP 服务账号或 Application Default Credentials 常用模型标识：`anthropic-vertex/claude-sonnet-4-6`、`anthropic-vertex/claude-opus-4-6`

```javascript
{
  models: {
    providers: {
      "anthropic-vertex": {
        // 使用 GCP Application Default Credentials（推荐）
        // 确保 GOOGLE_APPLICATION_CREDENTIALS 环境变量已设置
        // 或通过 gcloud auth application-default login 完成认证
        region: "us-east5",           // Vertex AI 区域
        projectId: "${GCP_PROJECT_ID}",
      },
    },
  },

  agents: {
    defaults: {
      model: {
        primary: "anthropic-vertex/claude-sonnet-4-6",
      },
    },
  },
}
```

> \[!TIP] Anthropic Vertex 适用于已有 GCP 基础设施的团队：流量走 Google 内网，可利用 GCP 的 IAM 权限体系和 VPC 网络策略，且计费合并到 GCP 账单中。

**3. 自托管 Ollama**

baseUrl：`http://localhost:11434/v1` API 适配器：`openai-completions` 常用模型标识：`ollama/llama2`、`ollama/mistral` 等（取决于本地部署）

```javascript
{
  models: {
    providers: {
      ollama: {
        baseUrl: "http://localhost:11434/v1",
        apiAdapter: "openai-completions",
      },
    },
  },

  agents: {
    defaults: {
      model: {
        primary: "ollama/mistral",
      },
    },
  },
}
```

## 4.2.3 OpenRouter

baseUrl：`https://openrouter.ai/api/v1` API 适配器：`openai-completions` 环境变量：`OPENROUTER_API_KEY` 常用模型标识：`openrouter/anthropic/claude-sonnet-4-6`、`openrouter/openai/gpt-5.4` 等

环境变量设置：

```bash
export OPENROUTER_API_KEY="sk-or-xxx..."
```

配置示例：

```javascript
{
  models: {
    providers: {
      openrouter: {
        baseUrl: "https://openrouter.ai/api/v1",
        apiAdapter: "openai-completions",
        apiKey: "${OPENROUTER_API_KEY}",
      },
    },
  },

  agents: {
    defaults: {
      model: {
        primary: "openrouter/anthropic/claude-sonnet-4-6",
      },
    },
  },
}
```

## 4.2.4 密钥注入：${} 插值与 SecretRef 凭据管线

配置支持在字符串字段里写 `${VAR_NAME}`，或是使用 `SecretRef` 对象。推荐把密钥放进环境变量或密钥系统，在配置里不写任何明文：这样配置文件可入库、可审计、可复现，且避免了密钥意外落盘。

**1. 基本形式：`${}` 环境变量插值**

配置示例：

```javascript
{
  models: {
    providers: {
      openai: {
        apiKey: "${OPENAI_API_KEY}",
      }
    },
  },
}
```

本地设置环境变量或写入 `.env` 文件：

```bash
# 方式 A：直接 export
export OPENAI_API_KEY="..."

# 方式 B：写入 ~/.openclaw/.env 或项目目录下的 .env
OPENAI_API_KEY="..."
```

> \[!NOTE] OpenClaw 在启动时会遵循优先级读取环境变量，规则为：`进程真实环境变量` > `当前目录 .env` > `~/.openclaw/.env`。**注意：`.env` 文件中的定义不会覆盖已经存在于进程中的同名环境变量。**

**2. 高阶形式：使用 SecretRef 对接统一凭据管线**

针对生产级部署，OpenClaw 提供了统一的 Secrets 管线。您不仅限于使用环境变量，而是可以使用 `SecretRef` 形式安全加载，这使您可以对接各类 secrets provider，并结合 `openclaw secrets` 体系进行管理与依赖性审计。

SecretRef 支持三种 `source` 类型：

* `"env"`：从环境变量读取（最常用）
* `"file"`：从文件路径读取内容
* `"exec"`：执行命令并取其标准输出

```javascript
{
  models: {
    providers: {
      openai: {
        // 方式 1：从环境变量读取
        apiKey: { source: "env", id: "OPENAI_API_KEY" },
      },
      anthropic: {
        // 方式 2：从文件读取
        apiKey: { source: "file", id: "/run/secrets/anthropic_key" },
      },
      custom: {
        // 方式 3：从命令执行结果读取
        apiKey: { source: "exec", id: "vault kv get -field=key secret/custom" },
      },
    },
  },
}
```

> \[!WARNING] **配置自写的落盘风险**：如果系统允许外部（如 AI）修改配置文件或执行了不当的同步行为，普通的内联 `${VAR_NAME}` 配置有极低概率在重写时被错误解引用而变成明文写回磁盘。而使用 `SecretRef` 对象语义则能严格隔离数据链路，有效防范脚枪。

注意：

* 结构化日志与诊断输出不打印明文密钥。
* 验证时请使用 `openclaw security audit` 或 `models status --check`。

## 4.2.5 多密钥与 keyId：为轮换与灰度预留结构

同一 provider 可以配置多把密钥，用 `keyId` 选择默认密钥。建议把“新增密钥”与“切换默认”拆成两个动作：先新增并小流量验证，再切换 `keyId`，最后吊销旧密钥。

配置示例（多密钥）：

```javascript
{
  models: {
    providers: {
      openai: {
        keys: {
          primary: {
            apiKey: "${OPENAI_API_KEY_PRIMARY}",
          },
          secondary: {
            apiKey: "${OPENAI_API_KEY_SECONDARY}",
          },
        },
        keyId: "primary",
      },
    },
  },
}
```

轮换建议：不要在故障窗口直接“替换同一个环境变量的值”，那会让排障证据变得不可追溯；更稳的是新增一把钥匙、切换 `keyId`、保留旧钥匙一段观测窗口后再回收。

## 4.2.6 接入验收：用 models status 做可观测验证

配置完成后用一组最小命令做验收（只看结果，不靠感觉）：

```bash
openclaw doctor
openclaw models status --check
openclaw status --deep
```

* `doctor` 失败：先修复“配置可读”与“运行依赖”，不要先调提示词或工作流。
* `models status --check` 失败：优先检查环境变量是否存在、`${}` 占位符的变量名是否拼对、provider 配置是否写在 `models.providers` 下。
* `status --deep` 中看不到预期的 provider/model：优先回看层级（`models.providers` 与 `agents.defaults.model` 是否写在正确位置）。

## 4.2.7 速率限制与配额管理

上游模型供应商通常对 API 调用实施速率限制（rate limit），OpenClaw 需要妥善处理这些限制，避免请求失败或服务中断。

**上游 429 响应处理**

当 OpenClaw 收到上游供应商返回的 HTTP 429（Too Many Requests）时，采用指数退避（exponential backoff）与冷却窗口（cooldown window）机制：

1. 首次 429 响应：立即进入冷却期，第一次重试等待 1 秒。
2. 重试失败再收 429：等待时间翻倍（1s → 2s → 4s → 8s）。
3. 达到最大重试次数或冷却时间上限（通常为 60 秒）后，将请求标记为失败并触发 fallback 链路（见 4.4）。

结构化日志会记录每次 429 及重试动作，便于事后分析与告警配置。

**配置速率限制策略**

某些供应商与自托管方案支持在 `models.providers` 中配置速率限制参数。配置示例：

```javascript
{
  models: {
    providers: {
      openai: {
        apiKey: "${OPENAI_API_KEY}",
        rateLimit: {
          requestsPerMinute: 60,
          tokensPerMinute: 100000,
        },
      },
      ollama: {
        baseUrl: "http://localhost:11434/v1",
        apiAdapter: "openai-completions",
        rateLimit: {
          requestsPerSecond: 10,
        },
      },
    },
  },
}
```

这些限制告诉 OpenClaw 在本地主动控制请求频率，防止触发上游 429 前就自我限流。

**多供应商 Fallback 规避单点限流**

最稳健的做法是为关键服务配置多个供应商，在单一供应商频繁限流时自动切换到次要供应商。见 4.4 关于 fallback 链路的详细说明。

```javascript
{
  agents: {
    defaults: {
      model: {
        primary: "openai-codex/gpt-5.4",
        fallbacks: [
          "openai-codex/gpt-5.2",
          "anthropic/claude-sonnet-4-6",
        ],
      },
    },
  },
}
```

如果你走的是直接 API Key 路径，也可以把这里的 `openai-codex/*` 整体替换为 `openai/*`。关键不是某个固定前缀，而是**要和当前认证方式、模型目录、auth profile 名称保持一致**。这样即便主链路因限流而暂时不可用，请求也能自动降级到次级模型或备用供应商，保证服务连续性。

> **💡 踩坑实录：环境变量 “明明设了却读不到”**
>
> 一个常见的部署陷阱：在 `.bashrc` 中 export 了 `ANTHROPIC_API_KEY`，但 OpenClaw 以 systemd 服务启动时读不到。原因是 systemd 不会加载用户 shell profile。解决方案：在 systemd unit 文件中用 `EnvironmentFile=/etc/openclaw/env` 显式指定，或使用 `openclaw secrets configure` 把密钥写入 SecretRef 体系。
