乐于分享
好东西不私藏

OpenClaw 插件开发进阶|理解 Plugin → Hook → Skill 三层扩展体系

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“更会做”,而不是“能做更多”。

典型适用场景:

场景
示例
资料检索
固定检索策略、数据源优先级
长文整理
特定的分段、摘要、格式化规则
分析框架
SWOT、PEST、五力模型等结构化分析
固定写作模板
周报、PRD、技术文档模板
常见问答流程
FAQ 标准化回答流程

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
Workspace bootstrap 文件注入前
gateway:startup
渠道启动完成、Hooks 加载后
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 Tool    api.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,先找到的先加载:

  1. 显式配置路径:plugins.load.paths 中声明的路径

  2. 工作区扩展:<workspace>/.openclaw/extensions/

  3. 全局扩展:~/.openclaw/extensions/

  4. 内置插件: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
注册定时任务和飞书渠道
通过 Plugin 注册 Cron 定时任务、注册飞书渠道
Tool

(Plugin 内)
执行具体的数据抓取
调用 Jira API 抓取项目进度
Provider

(Plugin 内)
调用模型生成日报
注册模型 Provider,调用 LLM 生成日报文本

        这是三层协作的典型模式:Skill 定义策略(怎么做),Hook 控制流程(在什么时候做额外处理),Plugin 提供能力支撑(能做什么)。

六、三层架构总览

维度
Skill(策略层)
Hook(拦截层)
Plugin(系统层)
一句话定位
教 AI 怎么做事
在运行时卡位调整流程
把新能力注册进内核
核心问题
方法问题
流程问题
能力问题
触发方式
AI 根据用户意图自主决定
事件驱动,自动触发
系统启动时加载
技术形态
Markdown + YAML
TypeScript 脚本 + HOOK.md
TypeScript 包 + 清单文件
修改范围
思考方式、输出格式
消息流、生命周期行为
系统边界、内核能力
用户可见性
是(结果返回给用户)
通常不可见
取决于注册内容
版本管理
手动管理
Hook 级别管理
完整 semver
团队复用
手动复制
Hook 目录共享
npm 包分发
安全边界
无系统权限
受事件上下文限制
需权限声明

依赖关系:Plugin 可包含 Skill 和 Hook,Hook 可调用 Skill,Skill 不依赖 Hook 和 Plugin。从上到下能力递增,从下到上抽象递增。

七、插件化重构:OpenClaw 从“项目”到“平台”的蜕变

        2026 年初,OpenClaw 通过 PR #661 完成重大插件化重构,核心是将模型提供商从核心代码中解耦,转化为可独立分发的插件包。

重构前的单体架构存在三个核心问题:

  1. 紧耦合的代码结构:添加新模型提供商需同时修改 4 个核心文件

  2. 路由逻辑恶性膨胀:model-router.ts 中堆积大量 else-if 分支

  3. 测试隔离难题:修改一个 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 把新能力注册进内核(系统层)。混用层级会导致系统臃肿、冲突频发、维护困难——用对层级,比写对代码更重要。