12.2 Hooks 的最小工作单元:事件、处理器与结果回灌

面向经管学生、研究者与从业者的 AI 智能体设计教材

作者

李学恒、林建浩、严翊歆

发布于

2026-05-11

12.2 配图

Hook 的最小工作单元不是一个脚本,而是一条完整链路:

事件发生 -> 触发匹配 -> 执行处理器 -> 将结果回灌给当前工作流

配置入口是 .claude/settings.json,基本骨架如下:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo done"
          }
        ]
      }
    ]
  }
}

最外层 hooks 字段下,键名是事件类型,值是一组规则。每条规则包含 matcher(匹配条件)和 hooks(处理器列表)。

事件:Hook 从哪里开始

Claude Code 的生命周期事件覆盖多个阶段:

  • 会话与输入SessionStartUserPromptSubmit
  • 工具调用PreToolUsePostToolUsePostToolUseFailure
  • 权限与通知PermissionRequestNotification
  • 多代理协作SubagentStartSubagentStopTeammateIdle
  • 任务收尾TaskCompletedStopSessionEnd

初学时先抓住三个核心事件:PreToolUse(执行前同步判断)、PostToolUse(执行后检查)、PostToolUseFailure(失败后记录)。

处理器:事件触发后谁来执行

Claude Code 支持四类处理器:command(本地脚本)、http(外部服务)、prompt(追加提示)、agent(交给专门代理)。Hooks 不等于”运行 shell”,它提供的是事件驱动编排接口。

下面是一个 command 处理器示例——每次写入文件后自动记录日志:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date '+%H:%M:%S') WRITE $CLAUDE_FILE_PATH\" >> .claude/write-log.txt"
          }
        ]
      }
    ]
  }
}

$CLAUDE_FILE_PATH 是 Claude Code 注入的环境变量,指向本次写入的文件路径。

结果回灌:Hook 不是一次性副作用

处理结果会回到当前会话,影响模型下一步行动:

  • PreToolUse 检测到危险路径,直接阻断写入
  • PostToolUse 跑完检查脚本,把失败摘要回灌给任务
  • PermissionRequest 给出标准化理由,帮助一致决策

回灌能力依赖 Claude Code 在执行处理器时注入的环境变量:

环境变量 含义 适用事件
CLAUDE_TOOL_NAME 触发事件的工具名称 PreToolUse、PostToolUse
CLAUDE_TOOL_INPUT 工具调用的输入参数(JSON) PreToolUse、PostToolUse
CLAUDE_FILE_PATH 本次操作涉及的文件路径 Write、Edit 相关事件
CLAUDE_TOOL_OUTPUT 工具执行后的输出内容 PostToolUse
CLAUDE_SESSION_ID 当前会话的唯一标识 所有事件

matcher 与同步异步

matcher 的值对应工具名称,如 "Write""Bash"。省略 matcher 则匹配所有工具调用。PreToolUsePostToolUse 等工具调用事件支持 matcher;TaskCompletedSessionEnd 等事件通常没有 matcher,发生时直接运行。

同步 Hook 适合拦截和门禁(影响当前动作是否继续);异步 Hook 适合补充检查和通知(不应成为唯一裁决)。MCP 工具同样会进入 Hook 流程——只要是工具调用,不论来自内置工具还是 MCP Server,都可以被 Hook 观察和处理。

最小链路

Hook 的核心不是写脚本,而是把动作挂到事件上,并把结果重新带回当前工作流。