乐于分享
好东西不私藏

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_resolvebefore_prompt_buildbefore_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"将两个数字相加并返回结果",      parametersType.Object({        aType.Number({ description"第一个数字" }),        bType.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-filter02-logger)来控制加载顺序。

十、下一步做什么?

恭喜!你已经掌握了 OpenClaw 三层扩展体系的完整知识。接下来可以根据需要继续探索:

  • 第 18 篇:OpenClaw 技能编排实战——如何组合多个技能完成复杂任务链

  • 第 19-22 篇:多平台集成——微信、飞书、Telegram 等渠道接入

  • 第 23 篇:多 Agent 架构实战——配置多个智能体实现分工协作

  • 第 27 篇:安全配置指南——沙箱隔离、执行审批与权限最小化最佳实践

💡 最终提醒:Skill、Hook、Plugin 三层各司其职、互不越界。Skill 教 AI 怎么做事(策略层),Hook 在运行时卡位调整流程(拦截层),Plugin 把新能力注册进内核(系统层)。混用层级会导致系统臃肿、冲突频发、维护困难——用对层级,比写对代码更重要。