这里是 OpenClaw 插件系统的深度架构参考。如需实用指南,请从下面的专题页面开始。Documentation Index
Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt
Use this file to discover all available pages before exploring further.
安装和使用插件
用于添加、启用和排查插件的终端用户指南。
构建插件
使用最小可运行 manifest 的第一个插件教程。
频道插件
构建一个消息频道插件。
提供者插件
构建一个模型提供者插件。
SDK 概览
导入映射和注册 API 参考。
公共能力模型
能力是 OpenClaw 内部公开的原生插件模型。每个原生 OpenClaw 插件都会针对一种或多种能力类型进行注册:| 能力 | 注册方法 | 示例插件 |
|---|---|---|
| 文本推理 | api.registerProvider(...) | openai, anthropic |
| CLI 推理后端 | api.registerCliBackend(...) | openai, anthropic |
| 语音 | api.registerSpeechProvider(...) | elevenlabs, microsoft |
| 实时转录 | api.registerRealtimeTranscriptionProvider(...) | openai |
| 实时语音 | api.registerRealtimeVoiceProvider(...) | openai |
| 媒体理解 | api.registerMediaUnderstandingProvider(...) | openai, google |
| 图像生成 | api.registerImageGenerationProvider(...) | openai, google, fal, minimax |
| 音乐生成 | api.registerMusicGenerationProvider(...) | google, minimax |
| 视频生成 | api.registerVideoGenerationProvider(...) | qwen |
| Web 抓取 | api.registerWebFetchProvider(...) | firecrawl |
| Web 搜索 | api.registerWebSearchProvider(...) | google |
| 频道 / 消息 | api.registerChannel(...) | msteams, matrix |
| 网关发现 | api.registerGatewayDiscoveryService(...) | bonjour |
一个只注册零个能力、但提供 hooks、tools、discovery services 或后台服务的插件,是一个仅 hook 的旧式插件。该模式仍然完全受支持。
外部兼容性立场
能力模型已经进入核心,并且今天已被捆绑/原生插件使用,但外部插件兼容性仍需要比“它被导出了,因此它是冻结的”更严格的标准。| 插件情况 | 指引 |
|---|---|
| 现有外部插件 | 保持基于 hook 的集成可工作;这是兼容性基线。 |
| 新的捆绑/原生插件 | 优先使用显式能力注册,而不是厂商特定的直接访问或新的仅 hook 设计。 |
| 采用能力注册的外部插件 | 允许,但除非文档标记为稳定,否则将能力相关的辅助表面视为会演进。 |
插件形态
OpenClaw 会根据插件实际的注册行为(而不仅仅是静态元数据)将每个已加载插件归类为某种形态:plain-capability
plain-capability
恰好注册一种能力类型(例如像
mistral 这样的仅提供者插件)。hybrid-capability
hybrid-capability
注册多种能力类型(例如
openai 同时拥有文本推理、语音、媒体理解和图像生成)。hook-only
hook-only
只注册 hooks(类型化或自定义),不注册能力、工具、命令或服务。
non-capability
non-capability
注册工具、命令、服务或路由,但不注册能力。
openclaw plugins inspect <id> 查看插件的形态和能力拆分。详情请参见 CLI 参考。
旧式 hooks
before_agent_start hook 仍然作为仅 hook 插件的兼容路径被支持。现实中的旧插件仍依赖它。
方向:
- 保持其可用
- 将其文档化为旧式
- 模型/提供者覆盖工作优先使用
before_model_resolve - 提示词变更工作优先使用
before_prompt_build - 仅在真实使用量下降且 fixture 覆盖证明迁移安全后再移除
兼容性信号
当你运行openclaw doctor 或 openclaw plugins inspect <id> 时,可能会看到以下标签之一:
| 信号 | 含义 |
|---|---|
| config valid | 配置解析正常,插件可正常解析 |
| compatibility advisory | 插件使用了受支持但较旧的模式(例如 hook-only) |
| legacy warning | 插件使用了已弃用的 before_agent_start |
| hard error | 配置无效或插件加载失败 |
hook-only 和 before_agent_start 今天都不会破坏你的插件:hook-only 只是建议性质,before_agent_start 仅会触发警告。这些信号也会出现在 openclaw status --all 和 openclaw plugins doctor 中。
架构概览
OpenClaw 的插件系统有四层:清单 + 发现
OpenClaw 会从配置路径、workspace 根目录、全局插件根目录以及捆绑插件中查找候选插件。发现流程会优先读取原生
openclaw.plugin.json 清单以及受支持的 bundle 清单。运行时加载
原生 OpenClaw 插件以内进程方式加载,并将能力注册到中央注册表中。打包后的 JavaScript 通过原生
require 加载;第三方本地源码 TypeScript 则使用紧急的 Jiti 回退。兼容的 bundle 会被规范化为注册表记录,而不会导入运行时代码。- 解析时元数据来自
registerCli(..., { descriptors: [...] }) - 真正的插件 CLI 模块可以保持懒加载,并在首次调用时注册
- manifest/配置验证应当仅依赖manifest/schema 元数据,而不执行插件代码
- 原生能力发现可能会加载受信任的插件入口代码,以构建一个不激活的注册表快照
- 原生运行时行为来自插件模块的
register(api)路径,并且api.registrationMode === "full"
插件元数据快照和查找表
Gateway 启动会为当前配置快照构建一个PluginMetadataSnapshot。该快照仅包含元数据:它存储已安装插件索引、manifest 注册表、manifest 诊断、所有者映射、插件 id 规范化器以及 manifest 记录。它不包含已加载的插件模块、提供者 SDK、包内容或运行时导出。
插件感知的配置验证、启动时自动启用以及 Gateway 插件引导都会使用该快照,而不是独立重建 manifest/索引元数据。PluginLookUpTable 基于同一个快照派生,并为当前运行时配置添加启动插件计划。
启动后,Gateway 会将当前元数据快照作为可替换的运行时产物保留。重复的运行时提供者发现可以借用该快照,而无需在每次 provider-catalog 遍历时重建已安装索引和 manifest 注册表。当没有兼容的当前快照时,调用方会退回到冷路径的 manifest/索引流程。兼容性检查必须包含诸如 plugins.load.paths 和默认 agent workspace 之类的插件发现根目录,因为 workspace 插件属于元数据作用域的一部分。
该快照和查找表让重复的启动决策保持在快速路径上:
- channel 所有权
- 延迟的 channel 启动
- 启动插件 ids
- provider 和 CLI backend 所有权
- setup provider、命令别名、模型目录 provider,以及 manifest contract 所有权
- 插件配置 schema 和 channel 配置 schema 验证
- 启动时自动启用决策
PluginLookUpTable。该路径现在会按需重建注册表;如果调用方已经拥有当前查找表或显式 manifest 注册表,优先在运行时流程中传递它们。
激活规划
激活规划属于控制平面。调用方可以在加载更广泛的运行时注册表之前,询问哪些插件与某个具体命令、提供者、频道、路由、agent harness 或能力相关。 规划器保持当前 manifest 行为兼容:activation.*字段是显式的规划器提示providers、channels、commandAliases、setup.providers、contracts.tools和 hooks 仍然是 manifest 所有权回退- 仅 ids 的规划器 API 对现有调用方保持可用
- plan API 会报告原因标签,以便诊断能够区分显式提示和所有权回退
频道插件和共享消息工具
频道插件在正常聊天操作中不需要注册单独的发送/编辑/反应工具。OpenClaw 在核心中保留了一个共享的message 工具,而频道插件在其后面负责频道特定的发现和执行。
当前边界是:
- 核心拥有共享的
message工具宿主、提示词绑定、会话/线程记账以及执行分发 - 频道插件拥有作用域内的动作发现、能力发现以及任何频道特定的 schema 片段
- 频道插件拥有提供者特定的会话对话语法,例如对话 ids 如何编码线程 ids,或如何从父对话继承
- 频道插件通过其动作适配器执行最终动作
ChannelMessageActionAdapter.describeMessageTool(...)。这个统一的发现调用让插件能够将其可见动作、能力和 schema 贡献一起返回,从而避免这些部分彼此偏离。
当某个频道专属的 message-tool 参数携带媒体源,例如本地路径或远程媒体 URL 时,插件还应从 describeMessageTool(...) 返回 mediaSourceParams。核心会使用这个显式列表应用沙箱路径规范化和出站媒体访问提示,而无需硬编码插件拥有的参数名。这里应优先使用按动作范围划分的映射,而不是整个频道的扁平列表,这样仅用于 profile 的媒体参数就不会在诸如 send 之类不相关的动作上被规范化。
核心会在该发现步骤中传入运行时作用域。重要字段包括:
accountIdcurrentChannelIdcurrentThreadTscurrentMessageIdsessionKeysessionIdagentId- 可信的入站
requesterSenderId
message 工具中硬编码频道特定分支。
这也是为什么嵌入式运行器的路由变更仍然属于插件工作:运行器负责将当前聊天/会话身份传递到插件发现边界,以便共享的 message 工具为当前轮次暴露正确的频道拥有表面。
对于频道拥有的执行辅助函数,捆绑插件应将执行运行时保留在自己的扩展模块中。核心不再拥有 src/agents/tools 下的 Discord、Slack、Telegram 或 WhatsApp 消息动作运行时。我们不发布单独的 plugin-sdk/*-action-runtime 子路径,而捆绑插件应直接从其扩展拥有的模块导入自己的本地运行时代码。
同样的边界也适用于一般的以提供者命名的 SDK 接缝:核心不应导入 Slack、Discord、Signal、WhatsApp 或类似扩展的频道特定便捷 barrel。如果核心需要某种行为,要么消费捆绑插件自己的 api.ts / runtime-api.ts barrel,要么将需求提升为共享 SDK 中一个狭窄的通用能力。
捆绑插件遵循相同规则。捆绑插件的 runtime-api.ts 不应重新导出其自己的品牌化 openclaw/plugin-sdk/<plugin-id> facade。这些品牌化 facade 仍然是面向外部插件和旧消费者的兼容性 shim,但捆绑插件应使用本地导出,以及诸如 openclaw/plugin-sdk/channel-policy、openclaw/plugin-sdk/runtime-store 或 openclaw/plugin-sdk/webhook-ingress 之类狭窄的通用 SDK 子路径。除非现有外部生态的兼容边界确有要求,否则新代码不应添加插件 id 特定的 SDK facade。
针对 poll,存在两条执行路径:
outbound.sendPoll是适用于符合通用 poll 模型的频道的共享基线actions.handleAction("poll")是适用于频道特定 poll 语义或额外 poll 参数的首选路径
能力所有权模型
OpenClaw 将原生插件视为 公司 或 功能 的所有权边界,而不是把各种互不相关的集成杂糅在一起的“杂物袋”。 这意味着:- 公司插件通常应拥有该公司所有面向 OpenClaw 的表面
- 功能插件通常应拥有其引入的完整功能表面
- 通道应消费共享的核心能力,而不是临时性地重新实现提供方行为
厂商多能力
厂商多能力
openai 拥有文本推理、语音、实时语音、媒体理解和图像生成。google 拥有文本推理以及媒体理解、图像生成和网页搜索。qwen 拥有文本推理以及媒体理解和视频生成。厂商单能力
厂商单能力
elevenlabs 和 microsoft 拥有语音;firecrawl 拥有网页抓取;minimax / mistral / moonshot / zai 拥有媒体理解后端。功能插件
功能插件
voice-call 拥有通话传输、工具、CLI、路由以及 Twilio 媒体流桥接,但它消费共享的语音、实时转录和实时语音能力,而不是直接导入厂商插件。- OpenAI 保持在一个插件中,即使它横跨文本模型、语音、图像以及未来的视频
- 其他厂商也可以用同样的方式覆盖它们自己的范围
- 通道不关心哪个厂商插件拥有该提供方;它们消费由核心暴露的共享能力契约
- plugin = 所有权边界
- capability = 可由多个插件实现或消费的核心契约
能力分层
在决定代码应该放在哪里时,可以使用这个心智模型:- 核心能力层
- 厂商插件层
- 通道/功能插件层
共享编排、策略、回退、配置合并规则、交付语义以及类型化契约。
- core 拥有回复时 TTS 策略、回退顺序、偏好设置以及通道交付
openai、elevenlabs和microsoft拥有合成实现voice-call消费电话 TTS 运行时辅助工具
多能力公司插件示例
从外部看,公司插件应该是内聚的。如果 OpenClaw 对模型、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取和网页搜索拥有共享契约,那么某个厂商可以在一个地方拥有它的全部表面:- 一个插件拥有厂商表面
- core 仍然拥有能力契约
- 通道和功能插件消费
api.runtime.*辅助工具,而不是厂商代码 - 契约测试可以断言插件注册了它声称拥有的能力
能力示例:视频理解
OpenClaw 已经将图像/音频/视频理解视为一个共享能力。相同的所有权模型也适用于这里:
这样可以避免把某个提供方的视频假设写进 core。插件拥有厂商表面;core 拥有能力契约和回退行为。
视频生成已经使用了相同的顺序:core 拥有类型化的能力契约和运行时辅助工具,而厂商插件围绕它注册
api.registerVideoGenerationProvider(...) 实现。
需要一个具体的落地清单吗?请参见 能力食谱。
契约与约束
插件 API 表面被有意设计为类型化并集中在OpenClawPluginApi 中。该契约定义了插件可用的注册点,以及插件可以依赖的运行时辅助工具。
这之所以重要,是因为:
- 插件作者获得了一个稳定的内部标准
- core 可以拒绝重复所有权,例如两个插件注册相同的 provider id
- 启动时可以针对格式错误的注册提供可执行的诊断信息
- 契约测试可以强制执行打包插件的所有权并防止悄然漂移
运行时注册约束
运行时注册约束
插件注册表会在插件加载时校验注册。示例:重复的 provider id、重复的 speech provider id 以及格式错误的注册会生成插件诊断,而不是未定义行为。
契约测试
契约测试
在测试运行期间,会将打包插件捕获到契约注册表中,以便 OpenClaw 能明确断言所有权。当前这用于模型提供方、语音提供方、网页搜索提供方以及打包注册所有权。
契约中应该包含什么
- 好的契约
- 坏的契约
- 类型化
- 小而精
- 面向特定能力
- 由 core 拥有
- 可被多个插件复用
- 通道/功能可消费且无需了解厂商细节
执行模型
原生 OpenClaw 插件与 Gateway 进程内运行。它们不在沙箱中。已加载的原生插件与 core 代码拥有相同的进程级信任边界。 兼容的 bundle 默认更安全,因为 OpenClaw 目前将它们视为元数据/内容包。在当前版本中,这主要意味着 bundled skills。 对于非 bundled 插件,请使用允许列表和明确的安装/加载路径。将 workspace 插件视为开发时代码,而不是生产默认项。 对于 bundled workspace 包名,保持插件 id 与 npm 名称绑定:默认使用@openclaw/<id>,或者在包有意暴露更窄插件角色时,使用已批准的类型化后缀,例如 -provider、-plugin、-speech、-sandbox 或 -media-understanding。
信任说明:
plugins.allow 信任的是 插件 id,而不是来源证明。与 bundled 插件同 id 的 workspace 插件在该 workspace 插件启用/加入允许列表时,会有意覆盖 bundled 副本。这是正常且有用的,适用于本地开发、补丁测试和热修复。bundled 插件的信任来源于源快照——加载时磁盘上的 manifest 和代码——而不是安装元数据。损坏或被替换的安装记录不能在不知不觉中将 bundled 插件的信任范围扩大到超出实际源码声明的程度。导出边界
OpenClaw 导出的是能力,而不是实现便利性。 保持能力注册为公开。裁剪非契约型的辅助导出:- 打包插件特定的辅助子路径
- 不打算作为公共 API 的运行时管道子路径
- 供应商特定的便利辅助工具
- 作为实现细节的设置/引导辅助工具
plugin-sdk/gateway-runtime、plugin-sdk/security-runtime 和 plugin-sdk/plugin-config-runtime。