乐于分享
好东西不私藏

OpenClaw 开发系列:第3篇-Provider 插件 — 接入 AI 模型与服务

OpenClaw 开发系列:第3篇-Provider 插件 — 接入 AI 模型与服务

前置阅读:第 1 篇 — Plugin SDK 入门

本篇讲解 Provider 插件的开发。Provider 是 OpenClaw 对外部 AI 服务的抽象——通过 Provider 插件,你可以接入新的 LLM 模型、语音合成、图像生成、媒体理解和网络搜索服务。

在进入技术细节之前,先理解 Provider 的角色。

OpenClaw 本身不提供 AI 能力——它是一个 “调度器” 和 “网关”。实际的 AI 能力(文本生成、图像理解、语音合成等)由外部服务提供。Provider 插件就是 OpenClaw 与这些外部 AI 服务之间的“翻译层”

例如:你想让 OpenClaw 使用 OpenAI 的 GPT-4,需要一个 OpenAI Provider 插件来调用 OpenAI 的 API;想让 OpenClaw 调用本地部署的 claude-cli,需要一个 CLI Backend Provider。

一个 Provider 插件可以同时注册多种能力。例如,OpenAI 官方插件同时注册了 LLM、图像生成、媒体理解和语音能力。

在阅读具体代码之前,先用两张图理解 :

1. Provider 在整个系统中的角色 以及 六种 Provider 之间的关系

2.当您开发一个 Provider 插件时,插件典型的内部组织如下:


01

Provider 能力全景

OpenClaw 通过六个注册方法覆盖了主要的 AI 服务类型:

一个插件可以同时注册多种 Provider 能力。例如,OpenAI 官方插件同时注册了 LLM、图像生成、媒体理解和语音能力。这个表格列出的就是 register(api) 回调中 api 对象上所有以 Provider 结尾的注册方法——它们都来自 api 对象,不需要额外的导入。


02

能力分层架构

Provider 系统采用三层架构:
  • 供应商插件层:负责与特定服务商的 API 交互,处理认证、速率限制、模型映射等

  • 核心能力层:提供统一的编排策略(如 Provider 回退、负载均衡、模型路由)

  • 通道/功能插件层:消费 Provider 提供的能力,面向用户呈现

这种分层使得更换底层 AI 服务商时,上层的通道和功能插件无需任何修改。


03

LLM Provider

LLM Provider 是最核心的 Provider 类型。通过 api.registerProvider() 注册——这个方法在 register(api) 回调中直接可用,无需额外导入。

注册结构

以下代码展示了注册一个 LLM Provider 的完整结构。每个字段的含义见注释:

api.registerProvider({  id"my-provider",         // Provider 的唯一标识,用户通过此 ID 引用  name"My LLM Provider",   // 人类可读的名称,会出现在配置界面中  models: [                  // 该 Provider 支持的模型列表    {      id"my-model-large",  // 模型 ID,用于用户配置中引用      name"My Large Model"// 模型的人类可读名称      contextWindow128000// 模型的上下文窗口大小(token 数)      supportsVisiontrue,  // 声明模型是否支持图像输入      supportsStreamingtrue// 声明模型是否支持流式输出      supportsToolUsetrue// 声明模型是否支持工具调用(Function Calling)    },    {      id"my-model-small",      name"My Small Model",      contextWindow32000,    },  ],  async createCompletion(params) {    // 核心方法:当 Agent 需要推理时,OpenClaw 核心会调用此方法    // params 包含 messages(对话消息数组)、model(模型 ID)、temperature 等参数    // 你的实现需要将这些参数转换为对应 AI 服务的 API 调用,并返回标准化的 completion 结果  },});

模型引用

注册后,用户可以在配置中通过 <provider-id>/<model-id> 的格式引用模型。这种格式让 OpenClaw 可以唯一确定要使用哪个 Provider 的哪个模型:

my-provider/my-model-large       # 使用你注册的 Provider 和模型openai/gpt-4o                    # 使用 OpenAI 官方插件的 GPT-4oanthropic/claude-sonnet-4-20250514 # 使用 Anthropic 官方插件的 Claude

在 OpenClaw 配置文件(~/.openclaw/config.json 或项目级 .openclaw/config.json)中,用户可以这样指定默认模型:

{  "agents": {    "defaults": {      "model": "my-provider/my-model-large"    }  }}

认证配置

Provider 插件通常需要用户的 API Key 或 Token 来调用外部服务。这些认证信息需要在清单文件(openclaw.plugin.json)中声明,这样 OpenClaw 才能知道需要用户提供哪些凭据,以及如何在配置界面中展示它们。

以下是一个典型的认证配置——声明了一个 API Key 类型的认证方式:

{  "id": "my-provider",  "providerAuthChoices": [    {      "provider": "my-provider",      "method": "api-key",      "choiceId": "my-provider-api-key",      "choiceLabel": "My Provider API Key",      "optionKey": "myProviderApiKey",      "cliFlag": "--my-provider-api-key"    }  ],  "uiHints": {    "myProviderApiKey": {      "label": "API Key",      "placeholder": "mpk-...",      "sensitive": true    }  }}

用户可以通过配置文件、CLI 参数或管理界面设置认证信息。插件在运行时通过 api.pluginConfig 访问这些值。具体来说,用户在配置文件中的写法如下:

{  "plugins": {    "entries": {      "my-provider": {        "config": {          "apiKey": "your-api-key-here"        }      }    }  }}

然后在插件代码中通过 api.pluginConfig.apiKey 读取。

能力声明

在清单文件的 contracts 字段中声明 Provider 能力。contracts 是一个静态声明机制——它告诉 OpenClaw 核心这个插件会提供哪些能力,方便系统进行初始化验证和能力发现:

{  "contracts": {    "providers": ["my-provider"]  }}

04

CLI Backend Provider

CLI Backend 是一种特殊的 Provider——它不调用远程 API,而是将本地安装的 CLI 工具注册为推理后端。这使得 OpenClaw 可以使用 claude-clicodex-cli 等本地 AI 工具作为模型提供商。

适用场景:你有本地部署的 AI 工具,希望 OpenClaw 直接通过命令行调用它们,而不是走网络 API。

注册结构

api.registerCliBackend({  id: "my-cli-backend",          // 后端 ID,用于模型引用(如 my-cli-backend/fast)  name: "My CLI Backend",        // 显示名称  command: "my-cli",             // CLI 可执行文件名(必须在系统 PATH 中可用)  args: ["--model""$MODEL"],   // 参数模板,$MODEL 占位符会在运行时被替换为实际模型名  modelMapping: {                // 将 OpenClaw 的模型 ID 映射为 CLI 工具接受的模型参数    "my-cli/fast""fast",       // 用户引用 my-cli/fast 时,传给 CLI 的参数是 fast    "my-cli/quality""quality",  },  normalizeConfig(config) {    // 可选的配置规范化函数    // 用于兼容旧版本的配置格式,避免用户升级时需要手动改配置    if (config.legacyFlag) {      config.newFlag = config.legacyFlag;      delete config.legacyFlag;    }    return config;  },});

配置优先级

CLI Backend 的配置遵循以下优先级:

  1. 用户配置agents.defaults.cliBackends.<id>)优先级最高

  2. 插件默认配置(通过 registerCliBackend 注册)次之

  3. OpenClaw 将用户配置合并到插件默认配置之上

  4. 如果定义了 normalizeConfig,在合并后执行规范化

模型引用

注册后,CLI Backend 的模型通过 <backend-id>/<model-name> 引用:

claude-cli/opuscodex-cli/gpt-4my-cli/quality

05

语音 Provider

语音 Provider 覆盖两个方向——文本转语音(TTS)和语音转文本(STT)。一个语音 Provider 可以同时实现这两个方向,也可以只实现其中一个:
api.registerSpeechProvider({  id"my-speech",  name"My Speech Provider",  // 文本转语音(TTS):将 Agent 的文字回复转为语音输出  async synthesize(text, options) {    // text: 要转换的文本    // options: 语速、音色等可选参数    // 返回:音频流(Buffer)或音频文件的 URL  },  // 语音转文本(STT):将用户的语音输入转为文字  async transcribe(audioBuffer, options) {    // audioBuffer: 音频数据    // options: 语言、采样率等可选参数    // 返回:识别出的文本字符串  },});
典型的语音 Provider 场景:ElevenLabs 用于 TTS、Azure Speech Services 用于 STT、Whisper 用于语音转录。

06

媒体理解 Provider

媒体理解 Provider 让 Agent 能够「看」和「听」——它接收图片、音频或视频,返回结构化的文本描述。这与 LLM Provider 的 supportsVision 不同:视觉能力是 LLM 的一部分,而媒体理解 Provider 是独立的能力,可以被任何 Agent 使用, regardless of 使用什么 LLM。
api.registerMediaUnderstandingProvider({  id"my-media-understanding",  name"My Media Understanding",  async understand(mediaInput) {    // mediaInput 可以是图片、音频或视频    // mediaInput.type 指示媒体类型:"image" | "audio" | "video"    // mediaInput.url 或 mediaInput.buffer 提供媒体数据    // 返回:文本描述字符串  },});
媒体理解 Provider 处理图像、音频、视频的非文本输入,返回结构化的文本描述。典型应用:图片描述、视频摘要、音频转录分析。

07

图像生成 Provider

图像生成 Provider 让 Agent 能够生成图片。当用户要求 Agent 「画一个…」或 「生成一张…」的图片时,OpenClaw 核心会调用已注册的图像生成 Provider。
api.registerImageGenerationProvider({  id"my-image-gen",  name"My Image Generator",  async generate(params) {    // params 包含 prompt(生成提示词)、size(图片尺寸)、style(风格)等    // 返回:生成的图像 URL 或 base64 编码的图像数据  },});

08

网络搜索 Provider

网络搜索 Provider 让 Agent 能够搜索互联网。当 Agent 需要获取实时信息(最新新闻、文档、事实核查等)时,会调用已注册的网络搜索 Provider。
api.registerWebSearchProvider({  id"my-search",  name"My Web Search",  async search(query, options) {    // query: 搜索关键词    // options: 可选参数(如 limit、language 等)    // 返回:搜索结果数组,每条结果包含 title、url、snippet    return [      { title"..."url"..."snippet"..." },      // ...    ];  },});

09

多能力 Provider 实战

到目前为止,我们分别介绍了六种 Provider 类型。在实际开发中,一个 Provider 插件往往会同时注册多种能力。例如,OpenAI 生态同时提供 LLM、图像生成、媒体理解和语音能力——一个插件全部覆盖。

下面是一个同时注册多种能力的示例——虽然简化了实际 API 调用部分,但展示了多能力注册的完整结构。注意 register(api) 回调中可以多次调用不同的注册方法:

import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";export default definePluginEntry({  id"unified-ai",  name"Unified AI Provider",  version"1.0.0",  register(api) {    const apiKey = (api.pluginConfig as { apiKey?: string })?.apiKey;    // 注册 LLM Provider    api.registerProvider({      id"unified-ai",      name"Unified AI",      models: [        {          id"ua-pro",          name"Unified AI Pro",          contextWindow200000,          supportsVisiontrue,          supportsStreamingtrue,          supportsToolUsetrue,        },      ],      async createCompletion(params) {        // 实现 LLM 调用逻辑      },    });    // 注册图像生成    api.registerImageGenerationProvider({      id"unified-ai",      name"Unified AI Image",      async generate(params) {        // 实现图像生成逻辑      },    });    // 注册网络搜索    api.registerWebSearchProvider({      id"unified-ai",      name"Unified AI Search",      async search(query, options) {        // 实现搜索逻辑      },    });    // 在清单中声明所有能力    // contracts 字段在 openclaw.plugin.json 中声明  },});
对应的清单文件:
{  "id": "unified-ai",  "providerAuthChoices": [    {      "provider": "unified-ai",      "method": "api-key",      "choiceId": "unified-ai-key",      "choiceLabel": "Unified AI API Key",      "optionKey": "apiKey",      "cliFlag": "--unified-api-key"    }  ],  "contracts": {    "providers": ["unified-ai"],    "imageGenerationProviders": ["unified-ai"],    "webSearchProviders": ["unified-ai"]  }}

10

配置规范化

Provider 插件经常需要处理配置兼容性问题。normalizeConfig 函数在用户配置合并到插件默认配置之后执行,允许插件将旧格式的配置转换为新格式:
api.registerCliBackend({  id"my-backend",  normalizeConfig(config) {    // 旧版使用 modelSize 字符串,新版使用 model 枚举    if (typeof config.modelSize === "string") {      const mappingRecord<stringstring> = {        fast"ua-small",        quality"ua-pro",      };      config.model = mapping[config.modelSize] ?? config.modelSize;      delete config.modelSize;    }    return config;  },});
这保证了向后兼容——老用户不需要改配置就能升级插件。

11

小结

本篇覆盖了 Provider 插件的完整体系:

  • 六种 Provider 类型覆盖文本、语音、图像、媒体、搜索

  • 三层架构实现 Provider 与通道的解耦

  • LLM Provider 是核心,通过 registerProvider() 注册

  • CLI Backend 让本地 AI 工具成为模型提供商

  • 多能力插件可以同时注册多种 Provider

  • 认证配置和配置规范化保证用户体验


下一篇:Channel 插件 — 连接任意消息平台。我们将学习如何通过 Channel 插件将 OpenClaw 连接到新的消息平台。