《Claude Code Hooks:AI编程工具的高级控制指南》

Claude Code Hooks 完全详解:让 AI 编程工具真正听你的话

摘要:Claude Code Hooks 是 Anthropic 为 Claude Code 设计的一套"生命周期钩子"机制,允许开发者在 AI 执行各类操作的关键节点插入自定义逻辑。本文从架构原理到实战落地,系统拆解 Hooks 的每一个细节,附 15+ 可直接使用的配置案例。


目录

  1. [什么是 Claude Code Hooks?](#什么是 Claude Code Hooks?)
  2. [Hooks 的架构设计](#Hooks 的架构设计)
  3. 完整生命周期事件图谱
  4. [四种 Hook 类型详解](#四种 Hook 类型详解)
  5. 配置文件与作用域
  6. [通信协议:stdin / stdout / 退出码](#通信协议:stdin / stdout / 退出码)
  7. [Matcher 匹配器完全指南](#Matcher 匹配器完全指南)
  8. 核心事件深度解析
  9. [实战案例:15+ 即用配置](#实战案例:15+ 即用配置)
  10. [异步 Hooks 与高级模式](#异步 Hooks 与高级模式)
  11. 工程化分层设计
  12. 安全考虑与避坑指南
  13. 调试方法
  14. 总结

1. 什么是 Claude Code Hooks?

Claude Code 是 Anthropic 推出的命令行 AI 编程工具。当你让它修改文件、执行命令、分析代码时,它实际上是在背后调用一系列"工具"(Tool)来完成这些操作。

Hooks(钩子) 就是在这些工具执行的前后,甚至会话的开始与结束,插入你自定义代码的机制。

复制代码
┌──────────────────────────────────────────────────────────┐
│  你的请求("帮我格式化所有 .ts 文件")                       │
│         ↓                                                 │
│  Claude 分析请求                                           │
│         ↓                                                 │
│  ← PreToolUse Hook 触发(你的代码在这里运行)→              │
│         ↓                                                 │
│  Claude 调用 Edit / Write 工具                             │
│         ↓                                                 │
│  ← PostToolUse Hook 触发(你的代码在这里运行)→             │
│         ↓                                                 │
│  Claude 完成响应                                           │
│         ↓                                                 │
│  ← Stop Hook 触发(你的代码在这里运行)→                    │
└──────────────────────────────────────────────────────────┘

Hooks 能做什么?

能力 描述 典型场景
🛡️ 拦截与阻止 在工具执行前判断是否允许 阻止删除生产配置文件
🔄 修改工具输入 在执行前修改参数 将危险命令替换为安全版本
📊 观测与日志 记录每一次操作 统计最常执行的命令
🔔 通知与提醒 触发外部通知 任务完成后发 Slack 消息
✅ 质量把关 执行后自动检查 文件修改后自动运行 ESLint
🤖 触发子代理 启动新的 AI 子任务 代码变更后自动跑测试

2. Hooks 的架构设计

2.1 整体架构图

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                         Claude Code 生命周期                         │
│                                                                      │
│  Session Start ─→ [SessionStart Hook]                                │
│       │                                                              │
│       ↓                                                              │
│  用户输入 ─→ [UserPromptSubmit Hook] ─→ LLM 推理                     │
│                                           │                         │
│                                           ↓                         │
│                              ┌─────────── 工具执行管线 ───────────┐  │
│                              │                                    │  │
│                              │  [PreToolUse Hook]                 │  │
│                              │          ↓                         │  │
│                              │   工具实际执行(Bash/Edit/...)      │  │
│                              │          ↓                         │  │
│                              │  [PostToolUse Hook]                │  │
│                              │                                    │  │
│                              └────────────────────────────────────┘  │
│                                           │                         │
│                                           ↓                         │
│  Claude 响应完成 ─→ [Stop Hook] ─→ 会话结束 ─→ [SessionEnd Hook]    │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

2.2 核心设计理念

Hooks 的通信采用**进程间通信(IPC)**模型,非常优雅:

  • Claude Code 作为主进程,在关键事件点 fork 出 Hook 子进程
  • 主进程通过 stdin 向子进程传递 JSON 格式的事件数据
  • 子进程通过 stdout 返回 JSON 格式的决策结果
  • 子进程的 退出码(exit code) 决定是否阻止主进程的操作

这种设计让 Hooks 可以用任何编程语言实现,只需能读取 stdin、写入 stdout 即可。


3. 完整生命周期事件图谱

Claude Code 提供了 27 个可用的 Hook 事件,覆盖从会话启动到文件变更的完整生命周期。

3.1 事件分类总览

复制代码
会话级事件
├── SessionStart          # 会话开始/恢复时
├── SessionEnd            # 会话终止时
├── UserPromptSubmit      # 用户提交提示前
├── UserPromptExpansion   # 斜杠命令展开时
├── Stop                  # Claude 完成响应时(可阻止)
├── StopFailure           # API 错误导致中止时
├── PreCompact            # 上下文压缩前(可阻止)
└── PostCompact           # 上下文压缩后

工具执行级事件
├── PreToolUse            # 工具执行前(可阻止)⭐ 最常用
├── PermissionRequest     # 权限对话框显示时(可阻止)
├── PermissionDenied      # 自动模式拒绝权限时
├── PostToolUse           # 工具执行成功后⭐ 最常用
└── PostToolUseFailure    # 工具执行失败后

多智能体协作事件
├── SubagentStart         # 子代理启动时
├── SubagentStop          # 子代理完成时(可阻止)
├── TaskCreated           # 任务创建时(可阻止)
├── TaskCompleted         # 任务完成时(可阻止)
└── TeammateIdle          # 队友空闲时(可阻止)

环境与工作区事件
├── InstructionsLoaded    # CLAUDE.md 加载时
├── ConfigChange          # 配置文件变更时(可阻止)
├── CwdChanged            # 工作目录变更时
├── FileChanged           # 监视文件变更时
├── WorktreeCreate        # 工作树创建时(可阻止)
└── WorktreeRemove        # 工作树移除时

MCP 交互事件
├── Elicitation           # MCP 请求用户输入时(可阻止)
├── ElicitationResult     # 用户响应 MCP 后(可阻止)
└── Notification          # 发送通知时

3.2 可阻止事件汇总表

事件 退出码 2 的效果
PreToolUse 阻止工具执行,stderr 内容反馈给 Claude
UserPromptSubmit 阻止提示处理
Stop 阻止 Claude 停止,迫使其继续工作
SubagentStop 阻止子代理结束
TaskCreated 回滚任务创建
TaskCompleted 阻止任务标记完成
ConfigChange 阻止配置变更生效
PreCompact 阻止上下文压缩
PermissionRequest 拒绝权限申请
WorktreeCreate 任何非零退出码都失败

4. 四种 Hook 类型详解

4.1 Command Hook(命令钩子)

最常用的类型,执行一个 shell 命令。

json 复制代码
{
  "type": "command",
  "command": "/path/to/your-script.sh",
  "shell": "bash",
  "timeout": 600,
  "async": false
}
字段 说明 默认值
command 要执行的 shell 命令 必填
shell "bash""powershell" "bash"
timeout 超时秒数 600
async 是否后台异步运行 false
asyncRewake 异步失败时是否唤醒 Claude false

最小示例(Python 实现):

python 复制代码
#!/usr/bin/env python3
import sys
import json

# 从 stdin 读取 Claude Code 传来的事件数据
hook_input = json.loads(sys.stdin.read())

tool_name = hook_input.get("tool_name", "")
tool_input = hook_input.get("tool_input", {})

# 例:检查 Bash 命令中是否包含危险操作
if tool_name == "Bash":
    command = tool_input.get("command", "")
    if "rm -rf /" in command:
        # 退出码 2 = 阻止操作,stderr 内容会反馈给 Claude
        print("危险命令已被拦截!", file=sys.stderr)
        sys.exit(2)

# 退出码 0 = 允许操作,stdout 中的 JSON 会被解析
print(json.dumps({"continue": True}))
sys.exit(0)

4.2 HTTP Hook(HTTP 钩子)

将事件数据 POST 到一个 HTTP 端点,适合对接企业内部系统、审计服务等。

json 复制代码
{
  "type": "http",
  "url": "http://localhost:8080/hooks/pre-tool-use",
  "timeout": 30,
  "headers": {
    "Authorization": "Bearer $MY_TOKEN",
    "Content-Type": "application/json"
  },
  "allowedEnvVars": ["MY_TOKEN"]
}

HTTP 响应处理规则:

响应状态 行为
2xx + 空 body 成功,等同 exit 0
2xx + 纯文本 成功,文本作为上下文传给 Claude
2xx + JSON 成功,按 JSON Schema 解析
2xx 非阻塞错误,继续执行
连接超时 非阻塞错误,继续执行

⚠️ 注意 :HTTP Hook 无法通过 HTTP 状态码触发阻止,若需阻止必须返回 2xx + JSON body,并在 JSON 中设置 decision: "block"

4.3 Prompt Hook(提示钩子)

调用 LLM 对事件进行智能评估,适合需要语义理解的判断场景。

json 复制代码
{
  "type": "prompt",
  "prompt": "判断以下命令是否安全:$ARGUMENTS\n如果安全返回 {\"ok\": true},否则返回 {\"ok\": false, \"reason\": \"理由\"}",
  "model": "claude-haiku-4",
  "timeout": 30
}

使用 $ARGUMENTS 占位符注入事件的 JSON 数据。

4.4 Agent Hook(代理钩子)⭐ 实验性

生成一个带工具访问权限的子代理,适合需要复杂推理或多步操作的场景。

json 复制代码
{
  "type": "agent",
  "prompt": "运行项目测试套件(npm test),如果有测试失败,报告失败原因,不要修改任何文件。",
  "timeout": 60
}

5. 配置文件与作用域

5.1 配置文件位置

复制代码
作用域层级(优先级从高到低)
│
├── 托管策略(Managed Policy)
│   └── 组织级强制策略,企业管控用
│
├── 用户全局配置
│   └── ~/.claude/settings.json      ← 对所有项目生效
│
├── 项目配置(可提交 Git)
│   └── .claude/settings.json        ← 团队共享
│
├── 项目本地配置(不提交 Git)
│   └── .claude/settings.local.json  ← 个人本地覆盖
│
└── 插件 / Skill
    └── hooks/hooks.json             ← 插件激活时生效

5.2 配置文件结构

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/hook-script.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$(cat | jq -r '.tool_input.file_path')\""
          }
        ]
      }
    ]
  }
}

配置结构说明:

复制代码
hooks
  └── <事件名>                    # Hook 事件(如 PreToolUse)
       └── [ 规则组数组 ]
            ├── matcher           # 匹配过滤器(可选)
            └── hooks             # 该规则下的 Hook 数组
                 ├── type         # Hook 类型
                 ├── command      # 执行命令
                 └── ...          # 其他配置字段

5.3 选择配置位置的原则

放在哪里 适合放什么
Managed(托管) 安全底线:敏感路径禁访、高风险命令禁令、审计规则
Project(项目) 团队共识:提交前测试/lint、目录写保护、框架检查
User(用户) 个人偏好:格式化习惯、个人观测 Hook、环境初始化
Local(本地) 临时实验:本机特有工具、临时加强/放松约束

6. 通信协议:stdin / stdout / 退出码

这是理解 Hooks 运行机制最关键的部分。

6.1 输入:Claude Code → Hook(via stdin)

所有 Hook 事件都通过 stdin 接收以下公共字段:

json 复制代码
{
  "session_id": "abc123",
  "transcript_path": "/path/to/conversation.jsonl",
  "cwd": "/your/project/root",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test",
    "description": "Run test suite"
  },
  "tool_use_id": "toolu_01ABC..."
}

6.2 输出:Hook → Claude Code(via stdout)

Hook 退出时,Claude Code 根据退出码决定行为:

复制代码
退出码 0  ─→  解析 stdout 中的 JSON,按 JSON 决策字段执行
退出码 2  ─→  忽略 stdout,阻止当前操作,将 stderr 反馈给 Claude
其他      ─→  显示"hook error"通知,但不阻止操作,继续执行

stdout JSON 输出格式(通用字段):

json 复制代码
{
  "continue": true,           // false 时 Claude 完全停止处理
  "stopReason": "...",         // continue: false 时的说明消息
  "suppressOutput": false,     // 是否从调试日志隐藏 stdout
  "systemMessage": "⚠️ 请注意:...", // 向用户展示的警告消息
  "decision": "block",         // 决策(block / allow)
  "reason": "阻止原因"          // 配合 decision 使用
}

6.3 PreToolUse 特有输出

json 复制代码
{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",     // allow / deny / ask / defer
    "permissionDecisionReason": "生产数据库禁止写操作",
    "updatedInput": {                 // 可修改工具的实际输入
      "command": "npm run lint"
    },
    "additionalContext": "当前环境: production"
  }
}

permissionDecision 四种取值:

含义
allow 允许执行
deny 拒绝执行
ask 弹出确认对话框
defer 让其他 Hook 决定(仅非交互模式有效)

决策优先级deny > defer > ask > allow


7. Matcher 匹配器完全指南

Matcher 决定哪些工具调用会触发你的 Hook。

7.1 Matcher 三种模式

评估方式 示例
"*" 或空字符串 匹配所有 每次都触发
仅含字母/数字/下划线/竖线 精确匹配或 ` ` 分隔的列表
含其他特殊字符 JavaScript 正则表达式 "^Notebook""mcp__memory__.*"

7.2 工具名称参考

复制代码
Bash        # 执行 Shell 命令
Edit        # 编辑文件(str_replace)
Write       # 写入/创建文件
Read        # 读取文件
Glob        # 文件路径通配匹配
Grep        # 内容搜索
Agent       # 调用子代理
WebFetch    # 抓取网页内容
WebSearch   # 网络搜索
AskUserQuestion  # 询问用户
ExitPlanMode     # 退出计划模式

7.3 MCP 工具匹配

MCP 工具的命名规律:mcp__<服务器名>__<工具名>

复制代码
mcp__memory__.*          # 匹配 memory 服务器的所有工具
mcp__.*__write.*         # 匹配任意服务器的写入工具
mcp__filesystem__.*      # 匹配文件系统服务器

7.4 if 字段(精细过滤)

if 字段使用权限规则语法进行更细粒度的过滤,可以减少不必要的进程创建:

json 复制代码
{
  "type": "command",
  "if": "Bash(rm *)",
  "command": "/path/to/block-rm.sh"
}

Bash(rm *) 表示:只有当 Bash 工具的命令以 rm 开头时才触发这个 Hook。


8. 核心事件深度解析

8.1 SessionStart ------ 会话初始化

json 复制代码
// stdin 输入(额外字段)
{
  "source": "startup",    // startup | resume | clear | compact
  "model": "claude-sonnet-4-6",
  "agent_type": "代理名称"
}

// stdout 输出(可注入额外上下文)
{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext": "当前是生产环境,任何数据库操作都需要双重确认"
  }
}

典型用途:初始化日志、检查环境变量、注入项目上下文。

持久化环境变量 (通过 CLAUDE_ENV_FILE):

bash 复制代码
#!/bin/bash
if [ -n "$CLAUDE_ENV_FILE" ]; then
  echo 'export NODE_ENV=production' >> "$CLAUDE_ENV_FILE"
  echo 'export DEBUG_LOG=true' >> "$CLAUDE_ENV_FILE"
fi
exit 0

8.2 PreToolUse ------ 工具执行前(最关键)

PreToolUse 是使用最频繁的事件,支持拦截、修改、放行三种模式。

Bash 工具的完整输入结构:

json 复制代码
{
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test",
    "description": "运行测试套件",
    "timeout": 120000,
    "run_in_background": false
  },
  "tool_use_id": "toolu_01ABC..."
}

Edit 工具的完整输入结构:

json 复制代码
{
  "tool_name": "Edit",
  "tool_input": {
    "file_path": "/project/src/app.ts",
    "old_string": "const debug = true",
    "new_string": "const debug = false"
  }
}

三种决策模式示例:

python 复制代码
import sys, json

data = json.loads(sys.stdin.read())
cmd = data.get("tool_input", {}).get("command", "")

# 模式 1:直接阻止
if "DROP TABLE" in cmd.upper():
    print("禁止执行 DROP TABLE 命令", file=sys.stderr)
    sys.exit(2)

# 模式 2:修改输入(悄悄改掉命令)
if cmd.startswith("grep "):
    safer_cmd = cmd.replace("grep ", "rg ", 1)
    result = {
        "hookSpecificOutput": {
            "hookEventName": "PreToolUse",
            "permissionDecision": "allow",
            "updatedInput": {"command": safer_cmd},
            "additionalContext": "自动将 grep 替换为更快的 rg"
        }
    }
    print(json.dumps(result))
    sys.exit(0)

# 模式 3:直接放行
sys.exit(0)

8.3 PostToolUse ------ 工具执行后

PostToolUse 无法阻止操作(工具已执行),但可以触发后续行为。

json 复制代码
// stdin 输入额外字段
{
  "tool_name": "Write",
  "tool_input": { "file_path": "src/app.ts" },
  "tool_response": {
    "success": true,
    "content": "文件写入成功"
  }
}

典型用途:格式化代码、运行 lint、git add、记录日志。

8.4 Stop ------ 响应完成时

Stop 事件在 Claude 完成响应时触发,可以阻止 Claude 停止,强制它继续工作。

json 复制代码
// stdin 输入额外字段
{
  "stop_hook_active": true,      // 重要!当前是否已被 Stop Hook 触发过
  "last_assistant_message": "我已完成了代码修改..."
}

⚠️ 防止无限循环 :必须检查 stop_hook_active,避免 Stop Hook 无限触发自身!

python 复制代码
import sys, json

data = json.loads(sys.stdin.read())

# 防止无限循环
if data.get("stop_hook_active"):
    sys.exit(0)

last_msg = data.get("last_assistant_message", "")

# 检查是否遗漏了测试
if "已完成" in last_msg and "测试" not in last_msg:
    result = {
        "decision": "block",
        "reason": "请先运行测试套件,确认没有回归问题,再结束本轮对话"
    }
    print(json.dumps(result))
    sys.exit(2)

sys.exit(0)

8.5 FileChanged ------ 文件监视

通过 matcher 设置监视的文件名列表,支持动态扩展监视范围:

json 复制代码
{
  "hooks": {
    "FileChanged": [
      {
        "matcher": ".env|.envrc|.env.local",
        "hooks": [
          {
            "type": "command",
            "command": "echo '⚠️ 环境变量文件已变更,请检查安全性' | notify-send -",
            "async": true
          }
        ]
      }
    ]
  }
}

stdin 输入:

json 复制代码
{
  "file_path": "/absolute/path/.envrc",
  "event": "change"    // change | add | unlink
}

9. 实战案例:15+ 即用配置

以下所有案例均可直接复制到 .claude/settings.json 使用。

🛡️ 安全防护类

案例 1:阻止删除生产关键文件

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "CMD=$(cat | jq -r '.tool_input.command // empty') && if echo \"$CMD\" | grep -qEi '(rm\\s+-rf\\s+/|DROP\\s+TABLE|mkfs\\.|:\\(\\)\\{|chmod\\s+-R\\s+777\\s+/|dd\\s+if=.*of=/dev/)'; then echo \"BLOCKED: 危险命令被拦截: $CMD\" >&2; exit 2; fi"
          }
        ]
      }
    ]
  }
}

案例 2:保护敏感文件不被修改

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(cat | jq -r '.tool_input.file_path // empty') && if echo \"$FILE\" | grep -qE '(\\.env|\\.lock|secrets\\.yaml|credentials|id_rsa|\\.pem|\\.key)'; then echo \"BLOCKED: 禁止修改敏感文件: $FILE\" >&2; exit 2; fi"
          }
        ]
      }
    ]
  }
}

案例 3:只读操作自动放行(减少权限提示)

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "CMD=$(cat | jq -r '.tool_input.command // empty') && if echo \"$CMD\" | grep -qE '^(ls|cat|head|tail|wc|find|grep|rg|git\\s+(status|log|diff|show|branch|blame)|echo|pwd|which|file|stat|du|df)\\b'; then echo '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\"}}'; fi"
          }
        ]
      }
    ]
  }
}

🎨 代码质量类

案例 4:Prettier 自动格式化

json 复制代码
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \"$FILE\" ] && npx prettier --write \"$FILE\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

案例 5:ESLint 自动修复

json 复制代码
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \"$FILE\" ] && [[ \"$FILE\" =~ \\.(js|ts|jsx|tsx)$ ]] && npx eslint --fix \"$FILE\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

案例 6:替换低效命令(命令优化建议)

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "CMD=$(cat | jq -r '.tool_input.command // empty') && if echo \"$CMD\" | grep -qE 'find .* -name.*\\|.*grep'; then echo '建议:使用 fd 替代 find | grep,例如: fd --type f \"pattern\"' >&2; exit 2; fi"
          }
        ]
      }
    ]
  }
}

📋 Git 自动化类

案例 7:文件修改后自动 git add

json 复制代码
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=$(cat | jq -r '.tool_input.file_path // empty') && [ -n \"$FILE\" ] && [ -f \"$FILE\" ] && git add \"$FILE\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

案例 8:记录所有执行的 Bash 命令(审计日志)

json 复制代码
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "cat | jq -r '\"[\" + (now | strftime(\"%Y-%m-%d %H:%M:%S\")) + \"] \" + .tool_input.command' >> \"${CLAUDE_PROJECT_DIR:-.}/.claude/command_log.txt\""
          }
        ]
      }
    ]
  }
}

🔔 通知类

案例 9:macOS 桌面通知

json 复制代码
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code 任务已完成\" with title \"Claude Code\" sound name \"Glass\"'"
          }
        ]
      }
    ]
  }
}

案例 10:Slack Webhook 通知(适合长时间任务)

json 复制代码
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "MSG=$(cat | jq -r '.last_assistant_message // \"任务完成\"' | head -c 200) && curl -s -X POST \"$SLACK_WEBHOOK_URL\" -H 'Content-Type: application/json' -d \"{\\\"text\\\": \\\"✅ Claude Code 完成:${MSG}\\\"}\""
          }
        ]
      }
    ]
  }
}

🤖 智能验证类

案例 11:Stop Hook 任务完成度检查

json 复制代码
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "在结束前,请验证:\n1. 是否已运行测试?如果没有,先运行\n2. 是否更新了相关文档?\n3. 代码中是否还有 TODO 注释?\n如果有任何未完成项,请继续工作。\n重要:如果上下文中 stop_hook_active 为 true,直接完成不要再检查。"
          }
        ]
      }
    ]
  }
}

案例 12:Agent Hook 自动运行测试

json 复制代码
{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "运行项目测试套件(npm test)。如果有测试失败,报告哪些测试失败及建议修复方案。不要修改任何文件,只汇报结果。"
          }
        ]
      }
    ]
  }
}

📦 上下文管理类

案例 13:压缩后重新注入关键上下文

json 复制代码
{
  "hooks": {
    "PostCompact": [
      {
        "hooks": [
          {
            "type": "prompt",
            "command": "重要上下文(上下文压缩后重新注入):\n- 当前在 payments 微服务\n- 数据库:PostgreSQL 16 + pgvector\n- API 格式必须遵循 JSON:API 规范\n- 测试文件放在 __tests__/ 目录\n- 禁止使用 console.log,使用 Winston logger"
          }
        ]
      }
    ]
  }
}

🌐 HTTP 集成类

案例 14:对接企业审计服务

json 复制代码
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Edit|Write",
        "hooks": [
          {
            "type": "http",
            "url": "https://audit.yourcompany.com/claude-hooks",
            "headers": {
              "Authorization": "Bearer $AUDIT_TOKEN",
              "X-Project": "$CLAUDE_PROJECT_DIR"
            },
            "allowedEnvVars": ["AUDIT_TOKEN"],
            "timeout": 10
          }
        ]
      }
    ]
  }
}

案例 15:SessionStart 注入动态环境信息

json 复制代码
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"{\\\"hookSpecificOutput\\\": {\\\"hookEventName\\\": \\\"SessionStart\\\", \\\"additionalContext\\\": \\\"Git 分支: $(git branch --show-current 2>/dev/null || echo 'N/A'), Node 版本: $(node -v 2>/dev/null || echo 'N/A'), 当前时间: $(date)\\\"}}\"",
            "shell": "bash"
          }
        ]
      }
    ]
  }
}

10. 异步 Hooks 与高级模式

10.1 异步 Hook(async)

默认情况下,Hook 是同步的------Claude Code 会等待 Hook 执行完成。当任务较重时,可以设为异步:

json 复制代码
{
  "type": "command",
  "command": "/path/to/slow-analysis.sh",
  "async": true,
  "timeout": 120
}

同步 vs 异步对比:

特性 同步 异步
Claude 是否等待 否,立即继续
能否阻止操作
适合场景 安全检查、参数修改 日志记录、通知、测试
性能影响 有延迟 无延迟

10.2 asyncRewake 模式

asyncRewake: true 让异步 Hook 在退出码为 2 时"唤醒"Claude,适合后台任务完成后需要 Claude 介入的场景:

json 复制代码
{
  "hooks": {
    "FileChanged": [
      {
        "matcher": "package.json",
        "hooks": [
          {
            "type": "command",
            "command": "npm install && npm test",
            "async": true,
            "asyncRewake": true,
            "timeout": 120
          }
        ]
      }
    ]
  }
}

asyncRewake 执行流程:

复制代码
package.json 被修改
    ↓
FileChanged Hook 触发,后台运行 npm install && npm test
    ↓
Claude 继续其他工作(不等待)
    ↓
npm test 失败(退出码 2)
    ↓
Claude 被"唤醒",收到测试失败的 stderr 信息
    ↓
Claude 主动处理测试失败

10.3 环境变量参考

变量 说明 示例
$CLAUDE_PROJECT_DIR 项目根目录 /Users/you/myproject
${CLAUDE_PLUGIN_ROOT} 插件安装目录 ~/.claude/plugins/myplugin
${CLAUDE_PLUGIN_DATA} 插件数据持久化目录 更新后仍保留
$CLAUDE_CODE_REMOTE 是否是远程环境 "true"
$CLAUDE_ENV_FILE 环境变量持久化文件路径 写入后下次会话生效

11. 工程化分层设计

当项目复杂度上升时,需要系统性地组织 Hooks。推荐以下四层架构:

复制代码
┌────────────────────────────────────────────────────┐
│ 第四层:协作编排层                                    │
│ 触发 Scheduled Tasks、MCP 写外部系统、通知治理          │
│ 特点:异步处理,不阻塞主流程                            │
├────────────────────────────────────────────────────┤
│ 第三层:观测审计层                                    │
│ 工具失败统计、权限请求统计、文件变化记录                  │
│ 特点:轻量、异步入库、关注趋势                           │
├────────────────────────────────────────────────────┤
│ 第二层:质量守门层                                    │
│ 格式化、lint、小范围测试、关键目录验证                   │
│ 特点:快速执行,结果明确,团队共识                        │
├────────────────────────────────────────────────────┤
│ 第一层:底线安全层                                    │
│ 敏感路径保护、高风险命令拦截、未授权外联限制               │
│ 特点:规则少而硬,放 Managed/Project 层               │
└────────────────────────────────────────────────────┘

落地推荐顺序:

  1. 先建底线安全 Hook(最先受益)
  2. 再建质量守门 Hook(提升代码质量)
  3. 补充观测统计 Hook(积累数据)
  4. 最后接外部协作 Hook(系统集成)

11.1 Hooks vs Subagents vs MCP 的分工

工具 强项 职责
Hook 靠近事件边界、快速判断、同步守门 感知事件 → 决定是否允许/路由
Subagent 独立上下文、深度探索、并行推理 多文件分析、复杂调试、深度研究
MCP 标准化外部系统接入 连接数据库、API、工单系统

12. 安全考虑与避坑指南

12.1 安全最佳实践

由于 Hooks 以完整用户权限运行,需要特别注意安全:

bash 复制代码
# ✅ 正确:始终引用变量
FILE="$1"
cat "$FILE"

# ❌ 错误:未引用可能导致命令注入
cat $FILE

# ✅ 正确:使用绝对路径
SCRIPT="$CLAUDE_PROJECT_DIR/.claude/hooks/check.sh"
"$SCRIPT"

# ✅ 正确:阻止路径穿越
if echo "$FILE" | grep -q "\.\."; then
  echo "路径穿越攻击被阻止" >&2
  exit 2
fi

12.2 常见坑点

坑点 描述 解决方案
Matcher 大小写 "bash" 无效,必须 "Bash" 工具名使用 PascalCase
未读取 stdin 直接写 jq 而不用 `cat ` 管道
Stop Hook 死循环 Stop Hook 反复触发自身 检查 stop_hook_active 字段
Shell 配置污染 ~/.bashrc 的输出污染 JSON 解析 --norc 或清理 bashrc 的标准输出
超时时间不够 默认 600s,调用外部 API 需增大 设置合适的 timeout
jq 未安装 解析 stdin 需要 jq 提前安装 jqbrew install jq
异步 Hook 不能阻止 async Hook 无法拦截操作 需要拦截的必须用同步 Hook

13. 调试方法

13.1 使用 /hooks 命令

在 Claude Code 中输入 /hooks 可打开钩子浏览器,查看当前所有注册的 Hooks 及其来源(User/Project/Local/Plugin)。

13.2 启用 Debug 日志

bash 复制代码
# 方式 1:启用调试模式
claude --debug

# 方式 2:指定日志路径
claude --debug-file /tmp/claude-debug.log

# 方式 3:详细日志级别
CLAUDE_CODE_DEBUG_LOG_LEVEL=verbose claude

日志位置:~/.claude/debug/<session-id>.txt

13.3 手动测试 Hook 脚本

bash 复制代码
# 模拟 PreToolUse 输入,直接测试你的脚本
echo '{
  "session_id": "test",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "rm -rf /important"
  },
  "cwd": "/project",
  "permission_mode": "default"
}' | python3 .claude/hooks/check-command.py

echo "退出码: $?"

13.4 调试检查清单

复制代码
□ Matcher 大小写是否正确(Bash 不是 bash)
□ command 路径是否正确(脚本是否有执行权限)
□ stdin 是否正确读取(cat | jq ...)
□ JSON 输出格式是否合法(jq . 验证)
□ 退出码是否符合预期(0/2/其他)
□ 脚本中是否有多余的 echo 污染 stdout
□ 超时设置是否合理
□ ~/.bashrc 是否有输出到 stdout 的语句

14. 总结

Claude Code Hooks 是一个设计精良的生命周期钩子系统,它的核心价值在于:

为什么 Hooks 重要?

复制代码
没有 Hooks:AI 是一个黑盒,你只能信任或不信任
有了 Hooks:AI 是一个可观测、可控制、可扩展的协作伙伴

核心能力总结

能力维度 对应机制 价值
可控性 PreToolUse 拦截 确保 AI 不做危险操作
可观测性 PostToolUse 日志 了解 AI 在做什么
可扩展性 四种 Hook 类型 连接任何外部系统
可协作性 SubagentStop/TaskCreated 多 Agent 工作流
可调试性 debug 日志 + /hooks 命令 快速定位问题

推荐的起步组合

  1. 🔔 Stop + 桌面通知 → 立即提升体验,任务完成知道通知
  2. 🛡️ PreToolUse + 敏感文件保护 → 安全底线,绝不侥幸
  3. 🎨 PostToolUse + Prettier → 消除最常见的手动干预

从这三个开始,随着使用深入再逐步添加更复杂的 Hooks,构建属于你团队的 AI 开发规范体系。


参考资料


作者:技术博客 | 最后更新:2026年4月

相关推荐
Agent产品评测局1 小时前
销售拓客全流程赋能:企业级销售智能体落地完整解决方案 —— 2026技术路径与选型实测指南
人工智能·ai·chatgpt
王侯 将相1 小时前
受控式文档驱动 Vibe Coding 方案设计
人工智能·vibe coding·ai coding
NOCSAH2 小时前
统好AI:以长期主义践行能力持续进化
人工智能
跨境卫士-小汪2 小时前
旺季前成本项变多跨境卖家如何设定更稳的备货优先级
大数据·人工智能·产品运营·跨境电商·亚马逊
人工智能AI技术2 小时前
Git 基础:分支、提交、合并、回滚完整教程
人工智能
逍遥德2 小时前
skill模板-基于java maven项目
java·人工智能·自然语言处理·maven
GitCode官方2 小时前
Qwen3.6-27B 开源:昇腾适配已到位,AtomGit AI 开放体验
人工智能·开源
Swift社区2 小时前
如何设计 Agent 的权限系统与业务系统解耦?
人工智能·agent
地球资源数据云2 小时前
1951-2025年中国逐年1千米逐月总降水量区域统计数据集_年表_县
大数据·数据结构·数据库·数据仓库·人工智能