OpenClaw 源码解析(十四):Provider 系统与模型能力接入机制

发布时间:2026/6/21 8:39:16

OpenClaw 源码解析(十四):Provider 系统与模型能力接入机制 1. 本期目标上一期我们分析了 OpenClaw 的 Plugins 插件系统。Plugin 解决的是“如何把外部能力接入 OpenClaw”的问题其中一个非常重要的能力就是Model Provider。这一期继续分析 OpenClaw 的 Provider 系统。简单来说Tool 决定 Agent 能调用什么动作 Skill 决定 Agent 如何组织动作 Plugin 决定 OpenClaw 如何扩展能力 Provider 决定 OpenClaw 使用哪个模型、如何认证、如何请求、如何处理模型差异。OpenClaw 支持多个 LLM Provider配置模型时使用provider/model形式例如anthropic/claude-opus-4-6、google/gemini-3-flash-preview、lmstudio/my-local-model等。官方文档也明确说明OpenClaw 可以使用多个 LLM providers通常先完成 provider 认证然后把默认模型设置为provider/model。(OpenClaw)本期重点分析1. Provider、Model、Runtime、Plugin 的区别 2. provider/model 模型引用格式 3. 模型选择与默认模型配置 4. models.providers 如何注册自定义模型服务 5. Provider Plugin 如何接管 provider-specific logic 6. OpenAI-compatible、本地模型、CLI runtime 的区别 7. Tool calling 与 Provider 兼容性处理 8. 多模态能力、上下文窗口、token 限制如何描述 9. Model fallback 与 auth profile rotation 10. 一次 Agent 推理请求的完整 Provider 链路2. Provider 是什么可以先给一个直观定义Provider 是模型能力的供应方。它可以是OpenAI Anthropic Google Gemini OpenRouter Moonshot DeepSeek Qwen Groq Mistral Ollama LM Studio vLLM SGLang LiteLLM 某个 OpenAI-compatible 私有代理 某个本地模型服务。Provider 的任务不是“生成 prompt”而是解决模型调用相关的问题这个模型在哪里 怎么认证 请求发到哪个 baseUrl 使用什么 API 协议 模型支持文本还是图片 上下文窗口多大 最大输出多少 token 是否支持 reasoning 是否支持 tool calling 失败后能不能 fallback所以 Provider 可以理解为OpenClaw 与具体模型后端之间的适配层。3. Provider、Model、Runtime、Plugin 的区别这几个概念很容易混淆。Provider 模型服务提供方例如 anthropic、google、openai、lmstudio。 Model Provider 下的具体模型例如 claude-opus-4-6、gemini-3-flash-preview、my-local-model。 Runtime 执行 Agent 推理循环的运行时例如 OpenClaw 自己的 runtime、Codex harness、Claude CLI、Gemini CLI。 Plugin 把 Provider、Runtime、Tool、Skill 等能力注册进 OpenClaw 的扩展机制。举个例子anthropic/claude-opus-4-6 anthropic 是 Provider claude-opus-4-6 是 Model 这个模型可以通过 OpenClaw runtime 调用也可以在某些配置下通过 claude-cli runtime 调用 Anthropic provider 相关逻辑可以由 provider plugin 注册。再看一个 OpenAI 例子openai/gpt-5.5OpenClaw 文档中特别区分了 OpenAI provider 与 runtimeopenai/model默认可以走 native Codex app-server harness如果通过 provider/model runtime policy 显式选择agentRuntime.id: openclaw则使用 OpenClaw 内置 runtime 的 API-key 或兼容路由。(OpenClaw)所以要记住Provider 解决“模型从哪里来” Model 解决“具体用哪个模型” Runtime 解决“用哪套推理执行链路” Plugin 解决“这些能力如何接入 OpenClaw”。4. 为什么需要 Provider 系统如果 OpenClaw 只支持一个模型接口那么 Agent 推理链路会很简单构造 messages ↓ 发送给固定 API ↓ 读取输出但现实中不同模型服务差异很大认证方式不同 请求协议不同 tool calling schema 支持不同 reasoning 字段不同 图片输入格式不同 流式输出格式不同 错误码和限流信息不同 上下文窗口不同 OAuth 和 API key 管理不同 本地模型和云端模型延迟不同。Provider 系统的价值就是把这些差异收敛到统一入口OpenClaw core 保持通用推理循环 Provider plugin 处理具体模型服务差异。官方文档也说明大多数 provider-specific logic 会放在 provider plugins 中例如 onboarding、model catalog、auth env-var mapping、transport/config normalization、tool-schema cleanup、failover classification、OAuth refresh、usage reporting、thinking/reasoning profiles 等OpenClaw core 保留 generic inference loop。(OpenClaw)这说明 OpenClaw 的设计思路是不要把所有 Provider 特殊逻辑堆进 core 而是让 Provider Plugin 接管这些差异。5.provider/model模型引用格式OpenClaw 使用统一的模型引用格式provider/model例如anthropic/claude-opus-4-6 google/gemini-3-flash-preview openai/gpt-5.5 openrouter/deepseek/deepseek-chat lmstudio/my-local-model local/my-local-model官方文档把这作为 Quick rules 的第一条model refs 使用provider/model同时agents.defaults.models在设置后会作为 allowlistCLI 可通过openclaw onboard、openclaw models list、openclaw models set provider/model管理模型。(OpenClaw)这套格式的好处是第一模型引用不会和其他 Provider 的同名模型冲突。 第二配置、切换、fallback、allowlist 都可以用统一字符串表达。 第三Provider 逻辑可以根据 provider 前缀路由。例如qwen-max这个名字单独出现时不够明确因为它可能来自 Qwen 官方、OpenRouter、LiteLLM 代理或私有兼容接口。而qwen/qwen-max openrouter/qwen/qwen-max local/qwen-max就能明确说明请求应该走哪个 Provider。6. 默认模型配置OpenClaw 的默认模型通常配置在agents.defaults.model.primary例如{ agents: { defaults: { model: { primary: anthropic/claude-opus-4-6 } } } }如果希望提供 fallback可以写成{ agents: { defaults: { model: { primary: anthropic/claude-opus-4-6, fallbacks: [ google/gemini-3-flash-preview, openai/gpt-5.5 ] } } } }官方 Models CLI 文档列出的相关配置键包括agents.defaults.model.primary、agents.defaults.model.fallbacks、agents.defaults.imageModel.primary、agents.defaults.pdfModel.primary、agents.defaults.imageGenerationModel.primary、agents.defaults.videoGenerationModel.primary、agents.defaults.models和models.providers。(OpenClaw)可以理解为primary 默认首选模型。 fallbacks 主模型失败后可尝试的备用模型。 imageModel / pdfModel 图片理解、PDF 理解等专用模型。 imageGenerationModel / videoGenerationModel 媒体生成任务使用的模型。 agents.defaults.models 模型可见性、别名和 allowlist。 models.providers 自定义 provider 和模型目录。7.agents.defaults.models模型 allowlist 与 aliasagents.defaults.models很容易被误解。它不是“注册 Provider”的地方而是更偏向允许哪些模型出现 给模型设置 alias 给 provider/model 设置额外元数据 限制用户在 /model 中能选什么。官方文档说明如果设置了agents.defaults.models它会成为/model和 session overrides 的 allowlist当用户选择不在 allowlist 中的模型时OpenClaw 会提示 model is not allowed并要求加入 allowlist、清除 allowlist 或从/model list选择。(OpenClaw)示例{ agents: { defaults: { model: { primary: anthropic/claude-opus-4-6 }, models: { anthropic/claude-opus-4-6: { alias: Opus }, google/gemini-3-flash-preview: { alias: Gemini Flash } } } } }如果想允许某个 Provider 下的全部模型可以使用{ agents: { defaults: { models: { openai/*: {}, vllm/*: {} } } } }官方文档也说明可以添加provider/*entries让/model、/models和 model pickers 只展示这些 Provider 的发现模型这适合希望限制 Provider 但不想手动列出所有模型的场景。(OpenClaw)8.models.providers注册自定义 Provider如果要接入自定义模型服务就要看models.providers它用于添加OpenAI-compatible proxy Anthropic-compatible proxy Google-compatible endpoint 本地 LM Studio vLLM SGLang LiteLLM 企业内部模型网关 自己写的模型代理服务。官方文档说明可以通过models.providers或models.json添加自定义 Provider 或 OpenAI/Anthropic-compatible proxies如果 bundled provider plugin 已经发布默认 catalog只有在需要覆盖 base URL、headers 或 model list 时才需要显式写models.providers.id。(OpenClaw)一个典型配置如下{ models: { mode: merge, providers: { custom-proxy: { baseUrl: http://localhost:4000/v1, apiKey: LITELLM_KEY, api: openai-completions, models: [ { id: llama-3.1-8b, name: Llama 3.1 8B, reasoning: false, input: [text], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128000, contextTokens: 96000, maxTokens: 32000 } ] } } } }这里要注意models.providers.id.models[].id 是 Provider 内部模型 ID 真正引用时才写 provider/model。例如models.providers.local.models[].id my-local-model agents.defaults.model.primary local/my-local-model本地模型文档也强调models.providers.id.models[].id是 provider-local 值不要在这里包含 provider 前缀。(OpenClaw)9. Provider 配置字段一个 Provider 配置通常包含这些字段baseUrl 模型服务地址。 apiKey 认证凭据。 api 请求协议适配器。 models 该 Provider 下的模型目录。 headers 额外请求头。 auth 认证策略。 contextWindow 默认上下文窗口。 contextTokens 运行时有效上下文上限。 maxTokens 最大输出 token。 timeoutSeconds 模型请求超时时间。OpenClaw 的配置文档列出了这些字段models.providers.*.api可选openai-completions、openai-responses、anthropic-messages、google-generative-ai等apiKey是 Provider credentialbaseUrl是 upstream API base URLheaders可用于 proxy 或 tenant routingtimeoutSeconds用于控制模型 HTTP 请求超时。(OpenClaw)其中最重要的是api 决定如何构造请求和解析响应。 baseUrl 决定请求发往哪里。 models 决定该 Provider 具体有哪些模型。比如一个本地 vLLM 服务通常使用{ api: openai-completions, baseUrl: http://127.0.0.1:8000/v1 }如果后端明确支持 Responses API则可以使用{ api: openai-responses }本地模型文档也说明MLX、vLLM、SGLang、LiteLLM、OAI-proxy 或自定义网关只要暴露 OpenAI-style/v1/chat/completionsendpoint就可以使用 Chat Completions adapter只有后端明确支持/v1/responses时才使用 Responses API。(OpenClaw)10.models.mode: merge 与 replacemodels.mode决定 OpenClaw 如何处理配置中的 Provider catalog。merge 默认模式把配置里的 Provider 与内置 catalog 合并。 replace 替换模式只使用显式配置的 Provider / Model。官方文档说明自定义 providers 会写入 agent 目录下的models.json默认以 merge 模式合并除非设置models.mode为replace。(OpenClaw)一般建议日常使用 用 merge。 企业内网严格控制模型来源 可以考虑 replace。 本地模型加云端 fallback 用 merge。 完全离线环境 可以用 replace。例如本地优先但保留云端 fallback{ agents: { defaults: { model: { primary: lmstudio/my-local-model, fallbacks: [anthropic/claude-opus-4-6] } } }, models: { mode: merge, providers: { lmstudio: { baseUrl: http://127.0.0.1:1234/v1, apiKey: lmstudio, api: openai-responses, models: [ { id: my-local-model, name: Local Model, reasoning: false, input: [text], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192 } ] } } } }官方本地模型文档也建议即使运行本地模型也保留 hosted models 配置并使用models.mode: merge这样 fallback 仍然可用。(OpenClaw)11. 本地模型 ProviderOpenClaw 对本地模型的支持可以分成几类LM Studio Ollama vLLM SGLang MLX LiteLLM 自定义 OpenAI-compatible server。以 LM Studio 为例官方文档推荐启动本地 server默认地址通常是http://127.0.0.1:1234/v1然后在models.providers中配置lmstudioProvider。文档也给出建议加载较大的本地模型、启动本地 server、确认/v1/models能列出模型、把实际 model ID 写入配置并保持模型已加载以减少冷启动延迟。(OpenClaw)本地模型的优势是数据不离开本机 推理成本可控 适合隐私敏感场景 适合离线或内网环境 可以和云端模型做 fallback。但本地模型也有局限硬件要求高 推理速度不稳定 tool calling 能力取决于模型和服务实现 上下文窗口和多模态能力需要手动配置 本地服务挂掉时需要 fallback 或显式报错。所以本地 Provider 更适合作为隐私优先场景的 primary 低成本任务的 primary 云端不可用时的 fallback 开发调试环境。12. Provider Plugin 与registerProvider上一期讲 Plugin 时我们提到插件可以注册很多能力其中就包括 Provider。Provider Plugin 的核心是registerProvider(...)官方文档明确说明Provider-specific logic 大多由 provider plugins 处理OpenClaw 保留 generic inference loop。(OpenClaw)源码类型中也可以看到 Provider 相关 hooks 非常多例如 dynamic model resolution、transport normalization、runtime auth、usage snapshot、tool schema normalization、reasoning output mode、stream wrapper 等。这说明 Provider Plugin 不只是“声明一个 baseUrl”而是可以参与请求前后的多个关键环节。(GitHub)可以把 Provider Plugin 能力理解为模型目录 告诉 OpenClaw Provider 下有哪些模型。 认证 告诉 OpenClaw 使用哪些 env var、OAuth token、API key。 请求适配 告诉 OpenClaw 如何构造请求。 响应适配 告诉 OpenClaw 如何解析流式输出、usage、reasoning。 工具兼容 告诉 OpenClaw 如何清理或改写 tool schema。 错误分类 告诉 OpenClaw 哪些错误可以 fallback哪些应该直接失败。 用量统计 告诉 OpenClaw 如何查询 Provider usage 或 quota。13. Generic inference loop 与 Provider-specific logicOpenClaw 的设计可以抽象成两层OpenClaw core 负责通用 Agent 推理循环。 Provider plugin 负责具体 Provider 差异。通用推理循环包括读取 session 构造 messages 注入 system prompt 构造 tools 调用模型 处理 streaming 处理 tool call 写入 session state 发送回复。Provider-specific logic 包括这个 Provider 怎么认证 这个模型 ID 需不需要别名归一化 这个请求要用 Chat Completions 还是 Responses 这个模型是否支持 developer role 这个 Provider 的 tool schema 哪些字段不兼容 这个 Provider 的 rate limit 文本如何识别 这个 Provider 的 reasoning 字段如何处理。可以画成Agent run ↓ OpenClaw core 构造通用请求上下文 ↓ Provider registry 解析 provider/model ↓ Provider plugin 处理认证、模型元数据、transport 兼容 ↓ Shared model runtime 发起请求 ↓ Provider plugin 处理流式输出、错误分类、usage ↓ OpenClaw core 继续工具调用或回复投递一句话概括OpenClaw core 管流程Provider plugin 管差异。14. Tool calling 与 Provider 兼容Tool calling 是 Provider 系统中非常关键的部分。因为不同 Provider 对 function calling / tool calling 的支持并不完全一致有的支持 JSON Schema 的全部字段 有的只支持简化 schema 有的要求 tool call id 格式严格 有的对 developer role 支持不好 有的要求 messages.content 是字符串 有的无法处理复杂嵌套参数 有的 streaming tool call 格式与 OpenAI 不一致。OpenClaw 的 Provider 类型中有 provider-owned tool-schema normalization 相关上下文注释说明它运行在 replay、compaction、inference 的工具注册前允许 Provider 改写其 transport family 不支持的 schema keywords。(GitHub)这说明Tool schema 不是原样发给所有模型 Provider 可以在请求前做兼容性清理。例如删除某些 Provider 不支持的 JSON Schema 关键字 把复杂 schema 改写成更简单的形式 对 tool call replay 做 provider-specific sanitation 处理 reasoning model 对 tool call 的特殊要求。所以 Tool 系统和 Provider 系统是互相耦合的Tool 定义动作 Provider 决定这个动作 schema 如何传给模型 Model 决定能不能稳定地产生 tool call Runtime 决定如何执行和回放 tool call。15. 多模态能力input 字段模型是否支持图片输入不应该靠名字猜而应该在 catalog metadata 中描述。OpenClaw 配置文档说明models.providers.*.models.*.input用于描述模型输入模态文本模型使用[text]原生图像/视觉模型使用[text, image]只有当选中的模型标记为 image-capable 时图片附件才会注入到 agent turns 中。(OpenClaw)例如{ id: vision-model, name: Vision Model, input: [text, image], reasoning: false, contextWindow: 128000, maxTokens: 8192 }如果本地模型实际支持图片但配置写成input: [text]那么图片可能不会以原生视觉输入方式进入模型。反过来如果模型不支持图片却配置成input: [text, image]就可能导致请求失败。所以多模态能力要靠 catalog metadata 显式表达。16. 上下文窗口与运行时 token capProvider 配置中常见两个容易混淆的字段contextWindow contextTokens可以这样理解contextWindow 模型原生支持的最大上下文窗口。 contextTokens OpenClaw 运行时实际使用的上下文上限。官方配置文档说明contextWindow是模型原生上下文窗口元数据contextTokens是可选的运行时上下文 cap当你希望有效上下文预算小于模型原生窗口时可以设置contextTokens。(OpenClaw)例如{ id: big-context-model, contextWindow: 200000, contextTokens: 80000, maxTokens: 8192 }含义是模型理论上支持 200k 上下文 但 OpenClaw 运行时只使用 80k 最多输出 8192 tokens。这样做的原因可能是降低成本 减少延迟 避免超长上下文导致模型质量下降 给工具输出和系统提示词保留余量 兼容某些代理服务的实际限制。17. AuthAPI Key、OAuth 与 Auth ProfileProvider 认证通常有几类API key OAuth 本地 CLI 登录状态 AWS SDK 自定义 header 代理服务 token。OpenClaw 的 model failover 文档说明它使用 auth profiles 存储 API keys 和 OAuth tokenssecrets 位于 agent 目录下的auth-profiles.jsonruntime auth-routing state 位于auth-state.json而 config 中的auth.profiles/auth.order只是 metadata 和 routing不保存 secret。(OpenClaw)这说明 OpenClaw 把认证拆成两层配置层 描述有哪些 profile、优先顺序是什么。 秘密层 保存真实 API key 或 OAuth token。 运行状态层 记录 cooldown、disabled、lastUsed 等状态。这对多账号、多 key 轮换很重要。例如同一个 Provider 可以有多个 profileanthropic:default anthropic:backup-key google:usergmail.com openai-codex:userexample.comOpenClaw 可以在限流或失败时尝试其他 profile。18. Auth profile rotation当一个 Provider 有多个 auth profile 时OpenClaw 不一定每次都用同一个 key。官方 failover 文档说明Provider 有多个 profile 时OpenClaw 会根据显式配置、配置 profiles、已存储 profiles 等来源确定顺序如果没有显式 order会使用一种 round-robin 排序并考虑 OAuth/API key 类型、lastUsed、cooldown/disabled 等因素。(OpenClaw)可以理解为优先使用配置指定的 profile 没有配置时使用可用 profiles 限流或失败的 profile 会进入 cooldown disabled 的 profile 会被跳过 session 可能固定某个 profile 以保持缓存友好。这解决了一个实际问题同一个 Provider 下可能有多个账号或 key 某个 key 触发限流时不应该立刻让整个 Agent 失败 可以先尝试其他 profile再考虑模型 fallback。19. Model fallbackProvider 失败后不一定马上失败给用户。OpenClaw 的 fallback 分两层第一层当前 Provider 内部的 auth profile rotation。 第二层切换到 agents.defaults.model.fallbacks 中的下一个模型。官方文档明确说明OpenClaw 处理失败分两阶段先在当前 Provider 内做 auth profile rotation如果当前 Provider 因 failover-worthy error 被耗尽再移动到agents.defaults.model.fallbacks中的下一个模型。(OpenClaw)可以画成primary model 请求失败 ↓ 判断错误类型 ↓ 如果是 rate limit / auth / timeout 等可 fallback 错误 ↓ 尝试同 Provider 的其他 auth profile ↓ 当前 Provider 耗尽 ↓ 尝试 fallbacks 中的下一个 provider/model ↓ 成功则继续回复 ↓ 失败则继续 fallback 或报错这里要注意不是所有错误都应该 fallback。比如上下文过长 请求格式明显错误 用户手动指定的 strict model 不可用 工具 schema 永久不兼容。这些情况可能更适合直接暴露错误而不是悄悄换模型。20. Session model switching/model用户也可以在会话中切换模型。常见命令/model /model list /model 3 /model openai/gpt-5.5 /model status官方文档说明/model可以在当前 session 中切换模型如果 Agent 空闲下一次 run 会立刻使用新模型如果 run 已经激活OpenClaw 会把 live switch 标记为 pending并在干净的 retry point 切换。文档还强调用户通过/model选择的模型对当前 session 是 strict 的如果不可达会显式失败而不是静默使用默认 fallback。(OpenClaw)这点很关键配置里的 primary 可以 fallback 用户手动指定的 session model 更偏严格选择。原因也很合理用户主动说“我要用这个模型” 系统不应该悄悄换成另一个模型还假装成功。21. 一次模型调用的完整链路我们把 Provider 系统放进 Agent run 里看一次完整链路大致是用户消息进入 Channel ↓ Session 创建或恢复 ↓ 确定当前 Agent ↓ 读取 session model override ↓ 如果没有 override读取 agents.defaults.model.primary ↓ 构造 fallback candidate chain ↓ 解析 provider/model ↓ 从 model registry 找 Provider 和 model metadata ↓ 加载 Provider config 和 auth profile ↓ 构造 system prompt、messages、tools ↓ Provider plugin 处理 tool schema / transport / auth / reasoning 兼容 ↓ 调用 shared model runtime 或 provider-specific runtime ↓ 接收 streaming 输出 ↓ 如果模型产生 tool call进入 Tool pipeline ↓ 如果模型产生 final response进入回复投递 ↓ 如果失败进入 auth rotation 或 model fallback ↓ 写入 session state 和日志这条链路说明Provider 系统不是单独存在的 它贯穿模型选择、认证、工具调用、失败恢复和输出生成全过程。22. 自定义 Provider 配置示例假设我们有一个本地 OpenAI-compatible 服务http://127.0.0.1:8000/v1模型 ID 是qwen3-30b可以配置{ agents: { defaults: { model: { primary: local/qwen3-30b }, models: { local/*: {} } } }, models: { mode: merge, providers: { local: { baseUrl: http://127.0.0.1:8000/v1, apiKey: sk-local, api: openai-completions, timeoutSeconds: 300, models: [ { id: qwen3-30b, name: Qwen3 30B Local, reasoning: false, input: [text], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 120000, contextTokens: 80000, maxTokens: 8192 } ] } } } }这里的重点是Provider ID 是 local 模型本地 ID 是 qwen3-30b 完整模型引用是 local/qwen3-30b api 使用 openai-completions baseUrl 指向本地服务 agents.defaults.models 用 local/* 允许该 Provider 下的模型。23. 常见问题一为什么模型不出现在/model list可能原因有Provider 没有配置成功 models.providers 没有写入 models.mode 使用 replace 导致内置 catalog 被覆盖 agents.defaults.models allowlist 限制了可见模型 插件未启用 Gateway 没有重启 模型 ID 写错 Provider auth 不可用 session 仍然 pinned 到旧模型。排查思路openclaw models list openclaw models status openclaw config get models.providers openclaw config get agents.defaults.models openclaw gateway status --deep --require-rpc openclaw gateway restart如果当前 session 仍然使用旧模型可以用/model status /model provider/model /reset官方文档也提醒修改agents.defaults.model.primary不会重写已有 session selection如果 status 显示当前 session pinned 到某模型需要用/model Y切换当前 session或者通过/reset清理旧 session 状态。(OpenClaw)24. 常见问题二为什么图片没有进入模型可能原因当前模型 input 只写了 [text] 所选 Provider 不支持原生图片输入 模型实际支持图片但 catalog metadata 没写 WebChat 或 node-origin attachment path 发现模型不是 image-capable 使用了错误的模型 ref 图片理解模型和聊天模型配置混淆。解决方向{ id: my-vision-model, input: [text, image] }官方配置说明中也明确提到如果 custom 或 proxy model 接收图片需要在该模型上设置input: [text, image]这样 WebChat 和 node-origin attachment paths 才会把图片作为原生模型输入传递而不是文本媒体引用。(OpenClaw)25. 常见问题三为什么 fallback 没有发生可能原因用户用 /model 手动指定了 strict 模型 fallbacks 没有配置 错误类型不属于 failover-worthy 上下文过长这类错误应该走 compaction/retry而不是 model fallback 所有 fallback 都不在可用 Provider 中 auth profile 全部 disabled fallback 模型也失败了。需要区分配置 primary 失败 可以走 fallbacks。 用户手动 /model 选择失败 更倾向直接报错。 rate limit / timeout / auth 失败 更可能触发 fallback。 request too large / context overflow 更可能触发压缩或报错。官方 failover 文档也说明agent primaries 如果没有显式 fallbacks以及显式用户选择、model picker、one-off CLI provider/model overrides 等场景通常是 strict如果不可达或失败会报告失败而不是从无关 fallback 回答。(OpenClaw)26. 常见问题四models.providers和agents.defaults.models混淆这是初学者最常见的问题。models.providers 注册 Provider 和模型目录。 agents.defaults.models 控制模型可见性、别名、allowlist 和 metadata。错误写法{ agents: { defaults: { models: { local/qwen3-30b: {} } } } }如果只这样写但没有{ models: { providers: { local: { baseUrl: ..., models: [ { id: qwen3-30b } ] } } } }那么 OpenClaw 可能知道你“允许 local/qwen3-30b”但并不知道localProvider 如何连接也不知道qwen3-30b在哪里。官方文档也明确提醒agents.defaults.models[provider/model]只控制模型可见性、aliases 和 per-model metadata不会单独注册新的 runtime model自定义 Provider 模型还需要添加models.providers.provider.models[]并且至少包含匹配的id。(OpenClaw)27. Provider 相关源码阅读路线这一期建议从这些方向读源码第一组Provider Plugin 类型 src/plugins/types.ts ProviderPlugin registerProvider ProviderRuntimeModel ProviderRuntimeProviderConfig 第二组模型目录与 registry src/agents/model-catalog.* src/model-catalog/* src/llm/model-registry.* 第三组Provider 配置解析 src/config/* models.providers models.mode agents.defaults.models 第四组模型选择与命令 src/auto-reply/commands /model /models openclaw models list openclaw models status 第五组OpenAI / Anthropic / Google 等插件 extensions/openai/* extensions/anthropic/* extensions/google/* extensions/ollama/* extensions/lmstudio/* extensions/openrouter/* 第六组本地模型支持 local models OpenAI-compatible adapters openai-completions openai-responses 第七组fallback 和 auth model failover auth profiles auth-state.json auth-profiles.json cooldown disabledUntil 第八组工具兼容 provider tool schema normalization reasoning output mode transport normalization stream wrapper阅读时可以带着这些问题1. provider/model 是在哪里解析成 provider 和 modelId 的 2. model registry 如何合并内置 catalog、plugins 和 models.providers 3. agents.defaults.models allowlist 在什么阶段生效 4. Provider Plugin 的 registerProvider 注册了哪些 hooks 5. Provider 如何声明支持的 models 6. OpenAI-compatible provider 如何选择 openai-completions 或 openai-responses 7. Provider 如何处理 tool schema 不兼容 8. auth profile rotation 在失败后如何选择下一个 key 9. fallback candidate chain 是如何构造的 10. /model 切换如何影响当前 session28. 我的理解我认为 OpenClaw 的 Provider 系统最值得学习的地方是它没有把“模型调用”简单写成一个 API 请求函数。很多 Agent 项目最初会这样设计callLLM(messages, tools)但随着模型后端增加这个函数会越来越复杂如果是 OpenAI就这样 如果是 Anthropic就那样 如果是 Gemini要转换图片格式 如果是 OpenRouter要处理模型名前缀 如果是本地模型要调整 baseUrl 如果是 CLI runtime要走命令行 如果是 OAuth要刷新 token 如果 rate limit要换 key 如果 tool schema 不兼容要删字段 如果 streaming 格式不同要重新解析 ……OpenClaw 的做法是把这些差异拆出去OpenClaw core 只保留通用 Agent loop Provider Plugin 负责每个模型服务的特殊规则 models.providers 负责自定义连接 agents.defaults.models 负责可见性和选择策略 fallback 系统负责失败恢复 auth profiles 负责多账号和多 key 轮换。这样 Provider 系统就不只是“模型列表”而是一套完整的模型接入控制层。29. 本期重点理解这一期可以总结为五点第一Provider 是模型服务供应方Model 是 Provider 下的具体模型Runtime 是执行 Agent 推理的后端链路Plugin 是把这些能力接入 OpenClaw 的机制。 第二OpenClaw 使用 provider/model 作为统一模型引用格式例如 anthropic/claude-opus-4-6。 第三models.providers 用来注册自定义 Provider 和模型目录agents.defaults.models 用来控制模型可见性、alias 和 allowlist。 第四Provider Plugin 通过 registerProvider 接管认证、模型目录、transport normalization、tool schema cleanup、错误分类、usage reporting、reasoning profile 等 provider-specific logic。 第五模型失败时OpenClaw 会先尝试当前 Provider 内部的 auth profile rotation再根据 agents.defaults.model.fallbacks 尝试其他模型。一句话概括OpenClaw 的 Provider 系统本质上是一个模型接入与模型治理层它把不同模型服务的认证、目录、协议、能力、错误和 fallback 策略统一纳入 Agent 执行链路。30. 本期小结本期主要分析了 OpenClaw 的 Provider 系统。Provider 决定模型从哪里来、如何认证、使用什么协议、支持哪些输入模态、上下文窗口多大、是否支持工具调用以及失败后如何切换。OpenClaw 使用provider/model作为统一模型引用格式通过agents.defaults.model.primary和fallbacks设置默认模型与备用模型通过agents.defaults.models管理模型 allowlist 和 alias通过models.providers接入自定义或本地模型服务。Provider-specific logic 主要由 Provider Plugin 负责包括 model catalog、auth env mapping、transport normalization、tool schema cleanup、failover classification、OAuth refresh 和 usage reporting 等。这样 OpenClaw core 可以保持通用推理循环而不同 Provider 的差异由插件隔离处理。这一期可以用一句话总结Provider 让 OpenClaw 能把不同云端模型、本地模型、CLI 后端和代理服务统一纳入同一套 Agent 推理、工具调用和失败恢复机制中。

相关新闻