OpenClaw 插件开发进阶|理解 Plugin → Hook → Skill 三层扩展体系
本系列第十七篇:从“会写说明书”到“能改执行引擎”——打通 Skill、Hook、Plugin 三条脉络,构建真正的扩展能力
欢迎回到 OpenClaw 系列教程。经过前面十六篇的沉淀,你已经掌握了 OpenClaw 的核心安装、模型配置和基础 Skill 开发。你的“龙虾”已经从“空壳”变成了“有虾钳、有大脑、有记忆”的智能体。
但如果你是一个深度用户或团队协作开发者,很快就会遇到一个瓶颈:单个 Skill 能做的事情终究有限。
你想让 AI 在调用所有工具之前先做一次安全检查,想在模型生成回复之前注入特定的系统提示词,想把多个 Skill 打包成一个可复用的插件在团队中分发——这些都不是纯 Markdown 能解决的问题。
这正是 OpenClaw 三层扩展体系的用武之地。Skill、Hook、Plugin 三者看似都能“扩展”系统,实则分属不同层级、承担不同职责。混用会导致系统臃肿、冲突频发、维护困难。
本文将彻底理清 OpenClaw 三层扩展的边界与分工,提供 Skill(策略层)、Hook(拦截层)、Plugin(系统层)三个层级的完整开发模板,帮助开发者根据需求选择合适的扩展方式,构建稳定、安全、可维护的自定义扩展。
一、三层架构:从“策略”到“流程”再到“系统”
OpenClaw 的扩展体系采用分层架构,从上层到下层依次为 Skill(策略层)→ Hook(拦截层)→ Plugin(系统层) ,每层各司其职、互不越界,共同构成完整的扩展生态。
用一句话概括三层的关系:Skill 教 AI 怎么做事(策略),Hook 在运行时拦截并调整流程(控制),Plugin 把新能力注入系统内核(注册)。
1.1 Skill(策略层):教 AI“怎么做事”
Skill 不是代码实现,而是告诉 Agent 如何使用能力的规则集合,相当于 AI 的操作手册与工作流定义。
-
核心作用:定义能力边界、使用条件、调用步骤、优先级规则
-
适合场景:组织现有工具、规范 Agent 行为、设定任务执行逻辑
-
本质:纯策略层,无系统级注册,不修改运行流程
-
技术形态:Markdown 文件 + YAML frontmatter
-
示例:让 Agent 优先用 pnpm、规定搜索后必须生成摘要、限定社交媒体工具仅读取不发布
1.2 Hook(拦截层):在运行时“卡位”调整流程
Hook 是嵌入 Agent 生命周期的逻辑切点,在特定时机插入自定义代码,不新增能力只调整流程。
-
核心作用:拦截/修改 prompt、监听事件、调整运行参数、补充上下文
-
适合场景:在模型调用前注入规则、在工具执行前后做校验、修改系统提示词
-
本质:流程控制层,基于事件触发,不注册新功能
-
技术形态:TypeScript 脚本 + HOOK.md 元数据
-
关键生命周期:
before_model_resolve、before_prompt_build、before_agent_start等
1.3 Plugin(系统层):把新能力“注册”进内核
Plugin 是真正把能力注入 OpenClaw 内核的系统模块,负责注册新功能、服务、接口,是所有扩展的载体。
-
核心作用:注册 tool、HTTP 路由、CLI 命令、后台服务、RPC 方法、模型 Provider
-
适合场景:新增原生不支持的能力、对接外部系统、修改内核行为、提供全局服务
-
本质:能力注册层,唯一能真正扩展系统边界的模块
-
技术形态:TypeScript 包 + openclaw.plugin.json 清单
-
承载对象:可包含 Skill、Hook、Tool、Service 等所有扩展类型
💡 极简判断口诀(来自社区公认最实用的选择指南):
只教 Agent 怎么做事 → 用 Skill
只改运行时流程 → 用 Hook
要加新功能/新服务 → 用 Plugin
二、Skill 开发速成:策略层
Skill 是三层中最上层、也最容易上手的扩展方式。第 16 篇我们已经详细讲解了 Skill 的开发流程,此处仅作快速回顾,方便对比三层差异。
2.1 Skill 的核心定位
Skill 解决的是“方法问题”——Agent 在某类任务里怎么做更稳,如何复用一套提示、步骤和工作习惯,如何把常见任务沉淀成可调用的能力块。
Skill 只改变 Agent 的思考方式,不改变其执行范围。它让 Agent“更会做”,而不是“能做更多”。
典型适用场景:
|
|
|
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2.2 Skill 的技术实现(极简版)
Skill 只需一个带 YAML frontmatter 的 Markdown 文件:
markdown
---name: weather_querydescription: Query real-time weather for any city. Use when user asks about weather.---# Weather Query Skill## 使用说明1. 识别用户查询的城市名称2. 使用 `curl` 命令调用 wttr.in API3. 用自然语言向用户汇报结果## 查询命令curl "wttr.in/城市名?format=3"
2.3 什么时候用 Skill?
-
Agent 执行某类任务时总是不按你的方式做
-
需要沉淀团队内部的标准化工作流程
-
想让 AI 记住特定的输出格式或分析框架
什么时候不用 Skill? 如果需要访问外部数据库、修改系统状态、执行复杂的业务逻辑——这些需要调用真实 API 或操作文件系统,Skill 的纯策略层无法满足,需要用 Tool 或 Plugin 实现。
三、Hook 开发:流程拦截层
Hook 是 OpenClaw 扩展体系中容易被忽略但极其强大的能力层。它可以让你在 Agent 运行的各个关键节点插入自定义逻辑,实现流程控制、内容过滤、上下文注入等功能。
3.1 Hook 的核心定位
Hooks 是在 Gateway 网关内部发生某些事件时运行的小型脚本。它们会从目录中自动发现,有两种类型:
-
内部 Hooks:当智能体事件触发时在 Gateway 内部运行,如
/new、/reset、/stop或生命周期事件 -
Webhooks:外部 HTTP 端点,让其他系统(GitHub、Gmail、cron 任务等)触发 OpenClaw 中的工作
Hooks 通过事件驱动实现响应式自动化,取代了传统 AI Agent 框架中低效的轮询模型。OpenClaw Hooks 系统由三个核心组件构成:Event Producers(事件生产者,生成标准化 JSON 事件对象)、Gateway Event Bus(网关事件总线,接收事件并分发到订阅的 Hook)、Hook Executor(Hook 执行器,在隔离沙箱中运行脚本并捕获结果)。
3.2 Hook 的事件类型与生命周期
OpenClaw 支持丰富的 Hook 事件类型,覆盖了 Agent 运行的完整生命周期:
|
|
|
|---|---|
command:new |
/new
|
command:reset |
/reset
|
command:stop |
/stop
|
session:compact:before |
|
session:compact:after |
|
session:patch |
|
agent:bootstrap |
|
gateway:startup |
|
message:received |
|
message:transcribed |
|
message:preprocessed |
|
message:sent |
|
3.3 Hook 开发实战:消息过滤拦截
下面创建一个拦截敏感词的 Hook,在模型处理之前过滤掉包含敏感内容的用户消息。
步骤一:创建 Hook 目录结构
bash
mkdir -p ~/.openclaw/workspace/hooks/sensitive-filtercd ~/.openclaw/workspace/hooks/sensitive-filter
每个 Hook 是一个目录,包含两个核心文件:HOOK.md(元数据 + 文档)和 handler.ts(处理逻辑)。
步骤二:编写 HOOK.md 元数据
markdown
---name: sensitive-filterdescription: 过滤包含敏感词的用户消息,在模型处理前拦截metadata:openclaw:emoji: "🛡️"events: ["message:received"]requires:bins: ["node"]---# 敏感词过滤 Hook
在 `message:received` 事件触发时检查消息内容,若包含预设的敏感词,则返回拦截消息,不进入模型处理流程。
步骤三:编写 handler.ts 处理逻辑
typescript
// 敏感词列表(可从外部配置文件读取)const SENSITIVE_WORDS = ["恶意关键词1","恶意关键词2"];const handler = async (event: any) => {// 仅处理 message:received 事件if (event.type !== "message:received") {return;}const content = event.context?.content || "";// 检查是否包含敏感词const matchedWords = SENSITIVE_WORDS.filter(word =>content.toLowerCase().includes(word.toLowerCase()));if (matchedWords.length > 0) {// 拦截消息:清空原有消息列表,替换为拦截提示event.messages = [];event.messages.push(`⚠️ 消息已被拦截:包含敏感词 [{matchedWords.join(", ")}`);return;}console.log(`[sensitive-filter] 消息通过检查`);};export default handler;
步骤四:启用 Hook
bash
# 列出所有可用的 Hooksopenclaw hooks list# 启用 Hookopenclaw hooks enable sensitive-filter# 检查 Hook 状态openclaw hooks check# 查看 Hook 详细信息openclaw hooks info sensitive-filter
3.4 更多 Hook 实战场景
场景一:在模型调用前注入系统提示词(before_model_resolve)
在 Agent 调用模型之前,动态修改或追加系统提示词,让 AI 拥有更丰富的上下文。
typescript
const handler = async (event: any) => {if (event.type !== "before_model_resolve") return;// 在上下文中注入额外的系统提示if (event.context.prompt) {event.context.prompt += "\n\n[额外系统指令] 请以技术博客作者的口吻回答。";}};export default handler;
场景二:工具调用前后做权限校验(Hook + Plugin 结合)
通过 Hook 拦截所有工具调用,在真正执行前做权限检查(类似 ClawBands 的人机验证机制),结合 Plugin 注册的权限服务,实现细粒度的工具访问控制。
typescript
const handler = async (event: any) => {if (event.type !== "before_tool_execute") return;const toolName = event.context.toolName;const isApproved = await checkPermission(toolName);if (!isApproved) {event.block = true;event.messages.push(`❌ 工具 {toolName} 后重试`);}};
3.5 Hook 的 CLI 管理命令
bash
# 列出所有可用的 Hooksopenclaw hooks list# 启用一个 Hookopenclaw hooks enable# 禁用一个 Hookopenclaw hooks disable# 测试 Hook 的执行效果openclaw hooks test# 检查 Hook 配置是否有效openclaw hooks check# 获取 Hook 详细信息openclaw hooks info
3.6 什么时候用 Hook?
-
需要拦截或修改用户消息内容(敏感词过滤、内容审计)
-
需要在模型调用前后注入/修改系统提示词
-
需要在工具执行前后做日志记录或权限校验
-
需要在会话开始时(
/new)注入默认配置 -
需要在会话压缩前后做自定义处理
什么时候不用 Hook? 如果需求涉及注册全新的能力(如新增消息渠道、新增模型 Provider),这超出了 Hook 的职责范围,需要用 Plugin。
四、Plugin 开发:系统扩展层
Plugin 是三层的底层,也是唯一能真正扩展系统边界的模块。当 Skill 的纯策略无法满足需求、Hook 的流程控制不足以支撑新功能时,就是 Plugin 出场的时候。
4.1 Plugin 的核心定位
Plugin 是“打包与分发层”,不只是“会被加载的一段配置”。插件的真正价值在于“可治理的复用”——个人用 Skills 即可,团队协作必须用 Plugins 才能确保版本一致、权限可控、来源可信。
插件可为 OpenClaw 扩展新能力:渠道、模型提供商、语音、实时转录、实时语音、媒体理解、图像生成、视频生成、网页抓取、网页搜索、智能体工具,或这些能力的任意组合。
4.2 Plugin 的四种形态
根据插件实际注册的行为(而非仅静态元数据),OpenClaw 将插件划分为不同的形态:
|
|
|
|---|---|
| 单能力插件 |
|
| 混合能力插件 |
|
| 仅钩子插件 |
|
| 非能力插件 |
|
你可以使用 openclaw plugins inspect <id> 命令查看插件的形态和能力拆分。
4.3 Plugin 开发实战:注册自定义 Tool
下面创建一个最小 Plugin,注册一个可以被 Agent 调用的自定义工具。
步骤一:创建 Plugin 目录和 package.json
bash
mkdir -p ~/.openclaw/workspace/extensions/my-first-plugincd ~/.openclaw/workspace/extensions/my-first-plugin
创建 package.json(Plugin 的清单文件):
json
{"name": "@myorg/openclaw-my-plugin","version": "1.0.0","type": "module","openclaw": {"extensions": ["./index.ts"],"compat": {"pluginApi": ">=2026.3.24-beta.2","minGatewayVersion": "2026.3.24-beta.2"}}}
步骤二:编写 Plugin 入口文件 index.ts
typescript
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";import { Type } from "@sinclair/typebox";export default definePluginEntry({id: "my-first-plugin",name: "My First Plugin",description: "注册一个自定义工具,计算两个数的和",register(api) {// 注册一个 Agent Toolapi.registerTool({name: "add_numbers",description: "将两个数字相加并返回结果",parameters: Type.Object({a: Type.Number({ description: "第一个数字" }),b: Type.Number({ description: "第二个数字" })}),async execute(_id, params) {const result = params.a + params.b;return {content: [{ type: "text", text: `计算结果:{params.b} = ${result}` }]};}});}});
步骤三:测试 Plugin
bash
# 验证 Plugin 可被正常加载openclaw plugins inspect my-first-plugin# 重启 Gateway 使 Plugin 生效openclaw gateway restart
4.4 Plugin 能力注册完整 API
一个单一的 Plugin 可以通过 api 对象注册任意数量的能力。OpenClaw 的公共能力模型定义了 Plugin 可注册的核心能力类型:
|
|
|
|
|---|---|---|
|
|
api.registerProvider(...) |
|
|
|
api.registerSpeechProvider(...) |
|
|
|
api.registerMediaUnderstandingProvider(...) |
|
|
|
api.registerImageGenerationProvider(...) |
|
|
|
api.registerWebSearchProvider(...) |
|
|
|
api.registerChannel(...) |
|
4.5 Plugin 的发现与加载优先级
OpenClaw 采用分层发现机制,按以下顺序查找 Plugin,先找到的先加载:
-
显式配置路径:
plugins.load.paths中声明的路径 -
工作区扩展:
<workspace>/.openclaw/extensions/ -
全局扩展:
~/.openclaw/extensions/ -
内置插件:OpenClaw 打包的默认插件
Plugin 使用 jiti 模块加载器动态加载,支持原生 TypeScript/JavaScript 执行,每个 Plugin 获得独立的 PluginRuntime 隔离上下文,实现沙箱化和版本隔离。
4.6 Plugin 开发前置条件
-
Node.js ≥ 22 和包管理器(npm 或 pnpm)
-
熟悉 TypeScript(ESM 模块)
-
若需在仓库内开发 Plugin,需克隆 OpenClaw 仓库并执行
pnpm install
4.7 什么时候用 Plugin?
-
需要接入新的消息渠道(如飞书、钉钉、企业微信)
-
需要接入新的模型提供商
-
需要将多个 Skills 和 Hooks 打包成可复用的分发单元
-
需要为团队提供版本一致、权限可控的扩展包
-
需要新增原生不支持的底层能力(如 WebSocket 服务、后台定时任务)
五、三层协作实战:从 Skill 到 Plugin 的完整路径
以一个完整的“日报自动生成”需求为例,展示三层如何协作:
需求:每天早晨 9 点自动抓取项目进度、生成日报摘要、发送到飞书。
|
|
|
|
|---|---|---|
| Skill |
|
|
| Hook |
|
message:sent 前检查日报内容是否包含敏感信息 |
| Plugin |
|
|
| Tool
|
|
|
| Provider
|
|
|
这是三层协作的典型模式:Skill 定义策略(怎么做),Hook 控制流程(在什么时候做额外处理),Plugin 提供能力支撑(能做什么)。
六、三层架构总览
|
|
|
|
|
|---|---|---|---|
| 一句话定位 |
|
|
|
| 核心问题 |
|
|
|
| 触发方式 |
|
|
|
| 技术形态 |
|
|
|
| 修改范围 |
|
|
|
| 用户可见性 |
|
|
|
| 版本管理 |
|
|
|
| 团队复用 |
|
|
|
| 安全边界 |
|
|
|
依赖关系:Plugin 可包含 Skill 和 Hook,Hook 可调用 Skill,Skill 不依赖 Hook 和 Plugin。从上到下能力递增,从下到上抽象递增。
七、插件化重构:OpenClaw 从“项目”到“平台”的蜕变
2026 年初,OpenClaw 通过 PR #661 完成重大插件化重构,核心是将模型提供商从核心代码中解耦,转化为可独立分发的插件包。
重构前的单体架构存在三个核心问题:
-
紧耦合的代码结构:添加新模型提供商需同时修改 4 个核心文件
-
路由逻辑恶性膨胀:
model-router.ts中堆积大量 else-if 分支 -
测试隔离难题:修改一个 Provider 可能引发其他无关 Provider 的测试失败
重构后,基于标准接口+动态加载的新架构实现了依赖隔离、并行开发与版本自治,标志着 OpenClaw 从“单一项目”向“开放平台”的蜕变。
新版公开插件 SDK(openclaw/plugin-sdk/*)正式上线,废弃了旧有的扩展 API,提供了稳定的插件开发接口。
八、安全注意事项
Skill 的安全边界:Skill 只改变 Agent 的思考方式,不改变其执行范围,本身不引入系统级风险。但 Skill 中定义的流程可能触发高风险 Tool,需配合沙箱使用。
Hook 的安全约束:Hook 在 Gateway 进程内部运行,需确保 Handler 逻辑不会引入安全漏洞。敏感词过滤 Hook 应定期更新词库,避免绕过。
Plugin 的权限管理:Plugin 是唯一能真正扩展系统边界的模块,应遵循权限最小化原则,每个 Plugin 声明所需的能力类型,避免过度授权。在 Plugin 清单中声明 compat.pluginApi 和 minGatewayVersion 确保兼容性。
九、常见问题与排查
Q1:Skill、Hook、Plugin 混用时出现冲突怎么办?
三层遵循“上层不依赖下层”的设计原则,冲突通常源于命名冲突或事件重复处理。建议:使用唯一命名前缀(如 @myorg/)、Hook 中检查 event.messages 避免重复注入、Plugin 注册时检查是否已被其他插件占用。
Q2:Hook 执行后不生效?
检查 Hook 是否已启用:openclaw hooks list;检查 HOOK.md 中的 events 字段是否正确匹配事件类型;检查 Handler 是否正确导出默认函数;运行 openclaw hooks check 诊断。
Q3:Plugin 加载失败?
检查 Plugin 清单文件中的 compat.pluginApi 版本是否与当前 OpenClaw 版本兼容;确认 Plugin 入口文件正确导出 definePluginEntry;运行 openclaw plugins inspect <id> 查看详细错误信息。
Q4:如何判断我应该用 Skill 还是写一个 Plugin?
-
只要教 AI 怎么做事 → Skill
-
需要一个可复用的、团队共享的扩展包 → Plugin
Q5:Hook 的优先级如何设置?
Hook 的执行顺序由注册顺序决定。如需控制优先级,可使用 openclaw hooks list 查看顺序,通过调整 Hook 目录名(如 01-safety-filter、02-logger)来控制加载顺序。
十、下一步做什么?
恭喜!你已经掌握了 OpenClaw 三层扩展体系的完整知识。接下来可以根据需要继续探索:
-
第 18 篇:OpenClaw 技能编排实战——如何组合多个技能完成复杂任务链
-
第 19-22 篇:多平台集成——微信、飞书、Telegram 等渠道接入
-
第 23 篇:多 Agent 架构实战——配置多个智能体实现分工协作
-
第 27 篇:安全配置指南——沙箱隔离、执行审批与权限最小化最佳实践
💡 最终提醒:Skill、Hook、Plugin 三层各司其职、互不越界。Skill 教 AI 怎么做事(策略层),Hook 在运行时卡位调整流程(拦截层),Plugin 把新能力注册进内核(系统层)。混用层级会导致系统臃肿、冲突频发、维护困难——用对层级,比写对代码更重要。
夜雨聆风
