claw-code 源码详细分析:Hooks + Plugins + Skills——扩展三角里,哪一层该稳定、哪一层该开放?

涉及源码 :Python 占位包 src/hooks/src/plugins/src/skills/src/reference_data/subsystems/*.json;Rust 侧 rust/crates/plugins(manifest/permission/hooks runner)。


1. "扩展三角"是什么

把可扩展系统拆成三角形,有一个很实用的工程直觉:

  • Hooks(钩子):把扩展挂到"生命周期/事件点"上(例如工具调用前/后)。
  • Plugins(插件) :把扩展作为一个可安装、可启停、可权限化的分发单元(manifest + registry)。
  • Skills(技能):把扩展包装成"可被发现、可被路由/调用的能力块"(面向用户或面向 agent 的可复用能力)。

三者常常都会"能做同样的事",但成熟产品会刻意分工:一层稳定做约束,一层开放做生态,一层面向体验做组合


2. 先看本仓库的现实:Python 侧多为占位,Rust 侧更像产品骨架

2.1 Python:占位包 = 元数据锚点(对照归档)

Python 的 hooks/plugins/skills/ 当前都是统一模板:读取 reference_data/subsystems/*.json,暴露 MODULE_COUNTSAMPLE_FILES,用于 parity 对照与目录地图(见 result/12.md)。例如:

python 复制代码
# 1:16:src/hooks/__init__.py
\"\"\"Python package placeholder for the archived `hooks` subsystem.\"\"\"
...
MODULE_COUNT = _SNAPSHOT['module_count']
SAMPLE_FILES = tuple(_SNAPSHOT['sample_files'])

快照显示:

  • hooks 在归档中体量大(module_count: 104),且包含 toolPermission/*、通知类 hook 等(说明 hooks 往往是"横切层")。
  • plugins 在归档中体量很小(module_count: 2),更像"注册/捆绑索引"。
  • skills 中等体量(module_count: 20),多为 bundled skills 与加载目录逻辑。

这正好符合常见产品分工:hooks 多且细、plugins 少而硬、skills 处在体验与可发现层

2.2 Rust:插件与钩子的"可执行语义"已经长出来

Rust crates/plugins 提供了较完整的插件 manifest、权限与 hooks runner:

  • PluginManifest:含 permissionshookslifecycletoolscommands
  • PluginPermissionRead/Write/Execute
  • PluginToolPermissionread-only / workspace-write / danger-full-access(更贴近工具安全分级)。
  • HookRunner:支持 PreToolUse / PostToolUse,能运行外部 shell 命令并用 exit code 表示 allow/deny/warn。

例如 hooks runner:

rust 复制代码
// 65:93:rust/crates/plugins/src/hooks.rs
pub fn run_pre_tool_use(&self, tool_name: &str, tool_input: &str) -> HookRunResult {
    self.run_commands(
        HookEvent::PreToolUse,
        &self.hooks.pre_tool_use,
        tool_name,
        tool_input,
        None,
        false,
    )
}

pub fn run_post_tool_use(...)

以及"拒绝语义":exit code 2 → deny(并且立刻停止后续 hook):

rust 复制代码
// 174:186:rust/crates/plugins/src/hooks.rs
match output.status.code() {
    Some(0) => HookCommandOutcome::Allow { message },
    Some(2) => HookCommandOutcome::Deny { message },
    Some(code) => HookCommandOutcome::Warn { ... },
    None => HookCommandOutcome::Warn { ... },
}

这与 Python 文档 result/05.md 里谈的"拒绝要变成一等语义"高度一致:Rust 侧已经把 deny/allow/warn 变成 HookRunner 的稳定接口面。


3. 哪一层该稳定?(建议稳定面)

稳定层的核心是:一旦第三方依赖,就要尽量少破坏。在扩展三角里,建议优先稳定的是:

3.1 Hooks:稳定事件名 + 稳定 payload 形状

原因:hook 是"把系统切开一刀插针"的位置,生态会围绕 event 名与字段写脚本/插件。 \nRust 侧已经把事件名固定为 PreToolUse / PostToolUse,并构造 JSON payload:

  • hook_event_name
  • tool_name
  • tool_input(解析后的 JSON 或 raw)
  • tool_input_json
  • tool_output(post)
  • tool_result_is_error

这些字段一旦变动,外部脚本会大量断裂。因此:event 名与字段名应稳定,字段只做 additive 扩展

3.2 Plugins:稳定 manifest schema + 权限模型

原因:插件分发与安装/启停需要可预测性。Rust 的 PluginManifest 与 permission 枚举就是典型"应稳定"的内容:\n\n- manifest 路径规范(.claw-plugin/plugin.json)\n- defaultEnabled 等开关\n- 权限枚举(以及工具权限分级)

一旦变动,安装器、市场、配置系统都要联动,成本极高。\n\n### 3.3 Skills:稳定"发现协议"和"调用契约",而不是稳定内部实现

skills 作为可发现能力,稳定的重点是:\n\n- skills 如何被索引(bundled/目录扫描/manifest)\n- skills 对外暴露的名称、描述、输入输出约定\n\nskills 内部实现可以更开放、更快迭代(因为它更贴近"内容层/体验层")。


4. 哪一层该开放?(建议开放面)

开放层的核心是:允许第三方创新与快速迭代,同时不破坏稳定层。

4.1 Skills 应该最开放(生态与体验的承载层)

skills 天生适合承载:prompt 模板、工作流脚本、领域知识封装、对工具链的组合调用。 \n只要调用契约稳定,skills 的数量和内容可以高速增长,且不会迫使核心 runtime 频繁发布破坏性版本。

4.2 Plugins 的"内容部分"开放,但"框架部分"稳定

插件里可以开放:\n\n- 自定义工具定义(tool spec + input schema + command)\n- 自定义命令(command spec)\n- hook 命令链(脚本)

但插件框架要稳定:manifest/registry/permissions/安装位置/启停语义。

4.3 Hooks 本身不宜太开放(事件点数量要克制)

hook 点越多越"自由",但也越难维护:\n\n- 每多一个 hook 事件名,都是一个稳定 API 面。\n- hook 点过细会导致行为难以推理("为什么工具没执行?哦是某个 hook deny 了")。

因此 hooks 最佳实践是:事件点少而关键 (如 pre/post tool use、session start/stop),并配合强审计(见 result/06.md)。


5. 三角如何协作(推荐职责边界)

可以把三角的"职责边界"写成一句话:

  • Hooks 负责"什么时候/在什么事件点"(稳定)
  • Plugins 负责"谁能装、装了能做什么、权限是什么"(稳定+部分开放)
  • Skills 负责"怎么把能力组合成可复用体验"(开放)

一个成熟的工具调用链常见流程(抽象):\n\n1. 模型请求 tool_call\n2. Plugin registry 决定该 tool 是否存在/是否启用/权限等级\n3. HookRunner 在 PreToolUse 执行策略脚本 → allow/deny\n4. 真实工具执行\n5. HookRunner PostToolUse 记录或改写输出\n6. 运行史落盘(审计/回放)

claw-code 目前 Python 侧只把占位与审计位摆出来;Rust 侧已经具备 (2)(3) 的大量骨架。\n\n---

6. 与仓库现状的对齐建议(避免"开放把自己玩坏")

结合本仓库现状,比较稳的演进顺序是:\n\n1. 先稳定 hooks/插件的最小公共面 (事件名、payload、manifest、权限枚举)。\n2. 用 skills 承载快速迭代 (bundled skills、目录加载、模板化工作流)。\n3. 把拒绝与审计贯穿 :hook deny、plugin permission deny 都应进入统一的 PermissionDenial / event log(Python 文档已指出持久化缺口)。\n\n如果反过来(先让 hooks 事件点无限增长、先让插件 schema 频繁破坏性变更),就会在生态早期把自己拖进"兼容地狱"。


7. 小结

  • 该稳定的:hooks 的事件名与 payload、plugins 的 manifest/registry/权限模型、skills 的发现/调用契约。
  • 该开放的:skills 内容与组合方式;plugins 内的具体工具/命令实现;hook 命令脚本(在稳定 payload 上)。
  • 该克制的:hook 事件点数量(每个都是长久维护承诺)。

相关推荐
数据知道2 小时前
claw-code 源码详细分析:Command Graph 分段——复杂 CLI 产品如何把命令关系从脑子里搬到纸上?
ai·web·claw code
tryCbest2 小时前
Python之Flask开发框架(第五篇)- 使Flask + Vue 构建前后端分离项目教程
vue.js·python·flask
叹一曲当时只道是寻常2 小时前
Python 飞书开放平台自动化配置工具 feishu-auto 使用教程
python·自动化·飞书
2401_827499992 小时前
python核心语法05-模块
java·前端·python
Lauren_Blueblue2 小时前
第十六届蓝桥杯省赛Python研究生组-C变换数组
python·算法·蓝桥杯·编程基础
芯智工坊2 小时前
第10章 Mosquitto桥接模式
网络·数据库·人工智能·mqtt·开源·桥接模式
yaoxin5211232 小时前
375. Java IO API - 列出目录内容
java·开发语言·python
MicrosoftReactor2 小时前
技术速递|在 Copilot 应用科学中的智能体驱动开发
ai·自动化·copilot
小陈工2 小时前
2026年4月5日技术资讯洞察:AI商业模式变革、知识管理革命与开源生态反击
开发语言·人工智能·python·安全·oracle·开源