Skip to content

第十六部分 · Hooks / Skills / Plugins 生态(16.1)— 扩展点总览

导航:本部分共 8 节。本节建立钩子(Hooks)技能(Skills)、**插件(Plugins)**三者的边界与协作模型;后续各节深入 PreToolUse、Skills、Plugins、MCP 注入、斜杠命令、延迟加载与综合演练。


学习目标

完成本节学习后,你应该能够:

  1. 定义 Hooks:用户声明的 Shell / HTTP / LLM 回调,在运行时特定生命周期点被调度执行。
  2. 枚举 六个 Hook 事件SessionStartUserPromptSubmitPreToolUsePermissionRequestPostToolUseStop
  3. 对比 Skills(基于 Markdown 的轻量工作流,可声明 allowed-tools)与 Plugins(更重:自定义命令、独立目录配置、disable-model-invocation 等硬性标记)。
  4. 叙述 端到端管线:事件触发 → 收集注册 Hooks → matcher 过滤 → callback 执行 → 聚合决策allow / block / modify)。
  5. 预告 MCP 动态指令注入斜杠自定义命令defer_loading 与本部分的衔接章节。

生活类比:机场联检流水线

把一次完整的 Claude Code 会话想象成国际航班抵达通道

  • SessionStart:航班靠桥,边检系统开机自检(环境变量、工作区、MCP 连接)。
  • UserPromptSubmit:旅客递交入境卡——Hook 可预审表单(过滤敏感词、附加审计 ID)。
  • PreToolUse:行李过 X 光机:可 放行 / 扣留 / 改贴标签(改写工具名与参数)。
  • PermissionRequest:海关抽查需人工柜台——Hook 可自动批准或升级审批。
  • PostToolUse:行李离开传送带后二次拍照存档(写日志、同步外部工单)。
  • Stop:旅客离开隔离区——做清场与埋点

Skills像「海关张贴的多语言告示」:轻量、可复制、告诉模型遇到某类场景必须按某流程走Plugins像「航站楼里的特许经营店」:自带装修(目录结构)、员工手册(命令)、甚至「禁止总部代下单」(disable-model-invocation)。


三件套对比总表

维度HooksSkillsPlugins
载体配置 + 脚本/HTTP/LLMMarkdown + 元数据包/目录 + manifest
主要用途治理、审计、拦截工作流模板、工具白名单提示命令、深度集成、强约束
执行时机生命周期事件模型匹配场景时注入安装期 + 运行期
能否阻止工具是(尤其 PreToolUse)间接(提示 + allowed-tools)依实现;常配合 Hooks
典型用户平台/安全团队团队模板作者扩展开发者

六个 Hook 事件速查

事件触发时机(概念)典型用途
SessionStart会话建立后尽早环境探测、注入审计上下文
UserPromptSubmit用户消息进入管线前过滤、改写、附加标签
PreToolUse工具调用执行前拦截/改写/允许
PermissionRequest需要显式授权时自动策略、工单联动
PostToolUse工具返回后日志、同步外部 CMDB
Stop会话或任务终止清理、指标上报

Mermaid:Hook 管线总览


Mermaid:Skills / Plugins / MCP 共生


源码片段:Hook 注册表(示意)

typescript
// hooks-registry.ts(示意)
export type HookEvent =
  | 'SessionStart'
  | 'UserPromptSubmit'
  | 'PreToolUse'
  | 'PermissionRequest'
  | 'PostToolUse'
  | 'Stop';

export type HookCallback =
  | { kind: 'shell'; command: string }
  | { kind: 'http'; url: string; method: 'POST' | 'GET' }
  | { kind: 'llm'; model: string; promptTemplate: string };

export interface RegisteredHook {
  id: string;
  event: HookEvent;
  matcher?: ToolMatcher;
  callback: HookCallback;
  priority: number;
}
typescript
// hook-runner.ts(示意)
export async function dispatchHooks(
  event: HookEvent,
  payload: HookPayload,
  hooks: RegisteredHook[]
): Promise<HookDecision> {
  const candidates = hooks
    .filter((h) => h.event === event)
    .filter((h) => !h.matcher || matchTool(h.matcher, payload.tool))
    .sort((a, b) => a.priority - b.priority);

  let decision: HookDecision = { type: 'allow' };
  for (const h of candidates) {
    const partial = await runCallback(h.callback, payload);
    decision = mergeDecisions(decision, partial);
    if (decision.type === 'block') break;
  }
  return decision;
}

PreToolUse 为何被单独成章?

原因说明
权力最大可直接改变工具调用图
安全关键数据外泄、破坏性命令多在此拦截
复杂匹配支持 MCP 工具名如 mcp__server__tool
决策三态allow / block / modify

详见 16.2 PreToolUse


Skills 核心句柄:allowed-tools

Skills Markdown frontmatter 中常见:

yaml
---
name: sql-migration-review
allowed-tools: Bash, Grep, FileRead
---

运行时可将此清单与系统策略合并,迫使模型在匹配场景下优先调用声明工具(具体 enforcement 以版本为准)。


Plugins 的「重型」特征(节选)

特征含义
自定义命令新增斜杠或 CLI 子命令
独立目录资源隔离、版本升级
disable-model-invocation硬性禁止模型自动调用某些路径

详见 16.4 Plugins


MCP 与系统提示词

MCP 设备连接成功后,其 instructions 字段常被动态拼接进系统提示词,使模型「知道」此外设的约束与能力。见 16.5


defer_loading(预告)

工具注册表可使用 延迟加载避免冷启动时一次性解析全部工具定义,保护本地缓存与首屏时延。见 16.7


与本指南其他部分的衔接

概念参考
工具系统第六部分
权限模型第七部分
Feature Flags第十五部分

常见问题 FAQ

问题回答方向
Hooks 会显著拖慢吗?Shell/HTTP 可能;需超时与并发控制。
Skills 能替代单元测试?不能;它是流程与提示治理。
Plugins 与 MCP 冲突吗?正交;注意工具名空间去重。

小结

  • Hooks = 生命周期回调 + 决策聚合;PreToolUse 是皇冠上的明珠。
  • Skills = Markdown 轻量封装 + 工具白名单语义。
  • Plugins = 重型扩展面;MCP 动态注入 instructions;defer_loading 优化工具加载。

课后自测

  1. 将六个事件按时间顺序手写排列,并各举一例非安全类用途。
  2. 画一张 Venn 图文字描述:Skills 与 Plugins 的重叠与差异。
  3. 解释「matcher 过滤」在 O(n) Hook 列表下的性能注意点。

下一节16.2 PreToolUse — 拦截、放行与改写

本项目仅用于教育学习目的。Claude Code 源码版权归 Anthropic, PBC 所有。