For the complete documentation index, see llms.txt. This page is also available as Markdown.

12.1 插件开发体系:自定义扩展的工程机制

扩展能力的工程化关键不是“能不能加功能”,而是“扩展是否可控、可审计、可回滚”。OpenClaw 当前仍以插件体系作为扩展主入口:原生插件可以引入新的工具、渠道、模型供应商或运行时组件,并通过显式启用与白名单机制收敛风险;同时系统也能发现并导入兼容的 Codex、Claude、Cursor bundle,其中 Claude 支持默认目录布局的 manifestless bundle。需要特别区分的是:用户侧配置与 CLI 仍统一使用 plugins.* / openclaw plugins ...,而源码与发行产物中常会看到 extensions/ 目录这一实现形态。本节基于最新官方文档与源码说明原生插件的核心结构、兼容 bundle 的边界,以及一组可用于验收的命令。

12.1.1 插件是什么:长驻进程内的 TypeScript/JavaScript 模块

与仅提供文本提示思路的技能(Skills)截然不同,原生插件本质是运行在 Gateway 进程内的 TypeScript/JavaScript 扩展模块。它们通过运行时加载器动态装入,可直接挂载自定义 Agent tools、注册聊天渠道、实现后台轮询服务,甚至接管特定 Hook 或 HTTP/RPC 能力。

官方文档对原生插件的定位、能力范围与加载方式给出了完整说明。其中最核心的安全与工程设计在于引入了 openclaw.plugin.json 清单文件。它声明插件 idconfigSchemacontracts.tools、可选 uiHints 等元数据;运行时 api.registerTool() 注册的工具应与 manifest 中声明的工具所有权保持一致。系统在渲染配置表单或首轮校验时,无需执行第三方插件代码,直接通过清单文件进行 JSON Schema 验证。这避免了未经审查的代码自动执行的风险。同时也要注意,最新版本并不只有这一种插件格式;对兼容 bundle,OpenClaw 会识别 .codex-plugin/plugin.json.claude-plugin/plugin.json.cursor-plugin/plugin.json 以及 Claude manifestless 默认布局,并按兼容层规则导入可承接的能力。

如果插件通过 npm 包、压缩包等形式分发,发布包应在 package.jsonopenclaw.extensions 中声明插件入口列表;发布包的运行时文件路径可用 openclaw.runtimeExtensions 指向构建后的 JavaScript,并会在显式声明后受到校验。外部 ClawHub code plugin 还应维护 openclaw.compat.pluginApiopenclaw.build.openclawVersion 等兼容/构建元数据;pluginSdkVersionminHostVersion 则更多是兼容提示,不能替代运行时校验。分工明确:openclaw.plugin.json 负责“这是什么插件、怎么配”的元数据声明,package.json#openclaw.extensions / package.json#openclaw.runtimeExtensions 负责“源码入口与发布运行时代码入口在哪里”的打包指引。

工程上建议把插件当作严肃的代码级系统依赖对待:

  1. 插件版本进入版本控制与发布流程。

  2. 插件的 openclaw.plugin.json 严格约束参数,不合规清单在 Gateway 启动期直接拒载。

  3. 打包分发时维护 package.json 中的 openclaw.extensions,并在发布产物路径不同于源码入口时维护 openclaw.runtimeExtensions,避免安装后找不到入口。

  4. 插件的工具与副作用被工具策略与白名单彻底约束绑定。

12.1.2 配置与启用:entries、enabled、config 与 load.paths

插件的启用通过 plugins.entries 声明。这里应优先把 manifest 中的插件 ID 视为权威键,而不是想当然地把 npm 包名当作最终配置键。即便源码目录常命名为 extensions/<id>/,对用户稳定暴露的治理接口仍是 plugins.entries.<id>。每个条目包含启用开关与插件自定义配置;CLI 层的 openclaw plugins enable <id> / disable <id> 本质上也是切换 plugins.entries.<id>.enabled。官方文档还提供了 allowdenyload.paths 等字段的完整写法:https://docs.openclaw.ai/tools/plugin。需要补充的是:workspace 来源插件默认关闭,而 bundled plugin 遵循内建 default-on 集合,不应把“所有插件默认禁用”写成绝对规则。

下面示例展示了完整骨架:白名单准入 + 本地路径加载 + 启用插件并传入配置。

{
  plugins: {
    enabled: true,
    allow: ['my-plugin'],           // 白名单:仅允许列出的插件加载
    deny: ['untrusted-plugin'],     // 黑名单:deny 优先于 allow
    load: {
      paths: ['~/Projects/my-plugin'], // 本地开发中的插件目录
    },
    entries: {
      'my-plugin': {
        enabled: true,
        config: {
          // 插件自定义配置
        },
      },
    },
  },
}

为了降低供应链风险,建议配合白名单机制只允许经过审计的插件生效。

12.1.3 安全边界:插件白名单与工具策略协同

插件引入的是能力,能力的使用边界仍应由确定性的策略系统兜底。官方插件文档提供了 plugins.allowplugins.deny 的白名单机制;官方工具文档提供了工具的允许、拒绝与分层策略机制,并强调拒绝规则优先:

实践中建议采用“双层收敛”:

  1. 先用 plugins.allow 收敛可加载插件集合。

  2. 再用工具策略把插件提供的工具按风险分组,并在默认档案中拒绝高风险组。

进而可以将“扩展可用性”与“扩展可执行性”拆开管理,避免某个插件被安装后立即具备不受控副作用。

具体例子:Jira 插件的灰度上线流程

假设团队开发了一个 Jira 集成插件 jira-sync(npm 包名 @yourteam/jira-sync),能让智能体查询和创建工单。安全的上线路径如下:

  1. 阶段一:白名单准入 ——只在 plugins.allow 中添加该插件,但在 tools.deny 中拒绝其写入工具,先只允许查询功能:

  1. 阶段二:小范围放开写入 ——在内部 Telegram 群中,通过 toolsBySender 只允许管理员触发创建工单:

  1. 阶段三:全量放开 ——在内部验证 2 周无异常后,移除 tools.deny 中的 Jira 写入限制,但保留审计日志与幂等键。

12.1.4 Hook 架构:插件的核心运行机制

插件的真正力量不在于“注册工具”,而在于 Hook(钩子)系统——插件通过在执行管线的关键节点注册钩子函数来拦截、修改或观测系统行为。书中这一节讨论的是原生 OpenClaw 插件的 Hook 运行时;兼容 bundle 中的 hooks 只会映射到 OpenClaw 可以安全承接的那一部分,不应把 bundle 文档里的任意钩子语义直接等同为 OpenClaw 原生运行时。

常用钩子摘要(不是完整列表;以当前 docs/plugins/hooks 和类型定义为准):

智能体生命周期钩子

钩子名称
执行模式
典型用途

before_model_resolve

修改型

覆盖模型/供应商选择

agent_turn_prepare

修改型

在一次 agent turn 前准备上下文

before_prompt_build

修改型

注入上下文与系统提示词

before_agent_reply

claim 型

可返回 { handled: true } 合成或静默本轮回复

before_agent_finalize

修改/检查型

最终回答检查、补充处理或终止前清理

model_call_started / model_call_ended

观测型

观测模型调用生命周期

llm_input

观测型

审计 LLM 精确输入

llm_output

观测型

审计 LLM 精确输出

agent_end

观测型

分析已完成会话

before_compaction

观测型

观测或标注消息压缩过程(前置)

after_compaction

观测型

观测或标注消息压缩过程(后置)

消息处理钩子

钩子名称
执行模式
典型用途

message_received

观测型

消息到达后的旁路处理(即发即忘)

inbound_claim

claim 型

让插件按 first-claim-wins 规则接管入站消息

message_sending

修改型

修改或取消待发消息

reply_dispatch

claim / dispatch 决策型

决定是否接管或改写回复投递目标;需要重写 outbound dispatch 时优先看 before_dispatch

message_sent

观测型

消息发送后的确认

before_message_write

同步型

JSONL 写入前的同步阻断

工具调用钩子

钩子名称
执行模式
典型用途

before_tool_call

修改型

拦截或修改工具参数

after_tool_call

观测型

观测工具执行结果

tool_result_persist

同步型

链式修改持久化消息

子智能体钩子

钩子名称
执行模式
典型用途

subagent_spawning

顺序型

配置线程绑定

subagent_delivery_target

顺序型

解析路由目标

网关生命周期钩子

钩子名称
执行模式
典型用途

gateway_start

观测型

网关启动时触发

gateway_stop

观测型

网关停止时触发

非 bundled 插件若需要读取完整 conversation 内容,通常还需要显式配置 plugins.entries.<id>.hooks.allowConversationAccess=true。涉及终端、审批或安装前控制的 hooks(如 before_install)也有各自门控,不能只看函数名判断权限。

五种执行模式

  • 观测型(Void Hooks):并行执行,不能修改状态,用于审计与旁路处理(如 llm_inputmessage_sent)。

  • 修改型(Modifying Hooks):按优先级顺序执行(高优先级先执行),但并非所有修改结果都会作为下一钩子的输入;before_tool_call / message_sending 等会把多个 handler 的返回合并应用,只有 tool_result_persistbefore_message_write 等特定同步 hooks 才是真正链式传递。

  • claim 型:按优先级执行,首个返回 handled: true 的 handler 获胜并短路后续 handler。inbound_claimbefore_agent_reply 都属于这类语义;不要用它们实现“多个插件依次改写最终答案”的需求。

  • 顺序型:与修改型类似按优先级链式执行,但专用于子智能体路由场景——如 subagent_spawning(配置线程绑定)和 subagent_delivery_target(解析路由目标),每个钩子可以补充或覆盖路由决策。

  • 同步型:在热路径上同步执行,系统会检测并拒绝意外的异步处理器。包括 tool_result_persist(链式修改持久化消息)和 before_message_write(JSONL 写入前的同步阻断)。

全局 Hook Runner:Gateway 启动时创建单例 Hook Runner,所有执行路径通过它统一调度。多数观测型钩子失败后会记录日志并继续运行;但 before_tool_call 这类守卫钩子可以 fail-closed,在必要时阻断被保护的操作。

插件注册钩子的方式

结果合并策略因钩子类型而异:before_model_resolve 采用首个非空结果获胜;before_prompt_build 拼接上下文与系统提示词;before_tool_call 合并参数与阻断状态但不会把上一个 handler 的修改作为下一个 handler 的输入;message_sending 首个取消操作获胜。

渠道插件是一种特殊插件类型,通过 api.registerChannel() 注册,可提供 15+ 种适配器接口(配置、网关、出站、消息处理等)。渠道插件深度集成子智能体路由——通过 subagent_spawning 钩子配置每会话的线程绑定,通过 subagent_delivery_target 钩子解析消息路由目标。

插件加载的完整生命周期

  1. 发现:从 plugins.load.paths、workspace plugins、global plugins、bundled plugins 等来源收集候选插件;同 ID 的 workspace 插件在显式启用或 allowlist 后可有意 shadow bundled copy,duplicate 诊断用于提示来源冲突。

  2. 校验:读取 openclaw.plugin.json 清单,验证配置是否符合 JSON Schema。

  3. 入口解析:按插件目录或 package.json#openclaw.extensions / package.json#openclaw.runtimeExtensions 解析入口,并执行边界检查。

  4. 注册:同步调用插件的 register(api) 函数,插件通过 API 注册工具、钩子、渠道、服务、HTTP 路由等。

  5. 激活:所有插件注册完成后,构建 PluginRegistry,初始化全局 Hook Runner。

  6. 运行:在每个钩子点,系统通过 Hook Runner 调度已注册的处理器。

对应的生命周期可以简化为下面这张图:

图 12-1:插件从发现到运行期调度的生命周期

12.1.5 插件市场与 Bundle 兼容

除了手动在 load.paths 中指定本地路径外,OpenClaw 还支持从 ClawHub / marketplace 来源一键安装,也支持直接安装本地路径、压缩包与 npm 规格。ClawHub 是 OpenClaw 发行与发现的主路径;--marketplace 更适合 Claude-compatible marketplace 或 bundle 来源。对原生插件来说,最核心的识别文件仍是 openclaw.plugin.json;对兼容 bundle 来说,OpenClaw 会额外识别 .codex-plugin/plugin.json.claude-plugin/plugin.json.cursor-plugin/plugin.json 与 Claude manifestless 默认布局等入口。

当前官方 CLI 支持多种市场来源:Claude 已知 marketplace 名称、本地 marketplace 根目录或 marketplace.json、GitHub 仓库简写,以及 git URL。远程 marketplace 中的插件条目必须留在克隆出来的 marketplace 仓库内,并使用相对路径来源;不应把 HTTP(S)、绝对路径或二次 git 源写进远程 manifest。--pin 只适用于 npm 安装,不适用于 --marketplace。依赖安装发生在显式 install / update / doctor repair 流程中,而不是普通运行时隐式执行。写书时不应把某一种来源写成唯一官方形态。

安装方式:

此外,OpenClaw 可以发现并安装兼容的 Codex、Claude 和 Cursor bundle。系统会尝试把 bundle 中的技能、命令、settings 以及部分 hooks/agents 信息映射到 OpenClaw 可承接的能力面,但这种映射是“尽力兼容”而不是“逐字段等价”。根据当前官方插件 CLI 文档,已经明确说明会在 inspect / doctor 输出里展示被识别出的 bundle 能力,其中并非所有能力都会自动接入运行时执行。

[!NOTE] Bundle 兼容性是选择性的:技能文件(如 SKILL.md)通常最容易映射;但涉及特定框架 API、运行时命令模型或平台专属 hooks 的部分,可能只会被部分加载,甚至被安全策略直接跳过。建议安装后通过 openclaw plugins inspect <id> 查看识别出的 bundle capabilities,再用 openclaw plugins doctor 排查加载错误、manifest/discovery 诊断与兼容性提示。

12.1.6 验收与排障:用插件诊断与状态深查做成完整流程

插件相关问题不应靠“对话试出来”。官方 CLI 提供了插件列表与诊断命令,可用于上线前验收与线上排障:https://docs.openclaw.ai/cli/plugins

建议把以下命令固定为插件变更后的最小验收集:

当插件加载失败时,优先看 plugins doctorplugins inspectgateway status --deep --require-rpc 输出;当插件加载成功但行为异常时,再结合 inspect --runtime --json 和结构化日志按 traceId 回放单次链路。openclaw plugins enable <id> / openclaw plugins disable <id> 只更新配置并刷新 cold registry;要让已运行 Gateway 的 live runtime surfaces 生效,应显式重启或重载 Gateway,并用 openclaw plugins inspect <id> --runtime --jsonopenclaw gateway status --deep --require-rpc 复验。

最后更新于