Hooks 系统

完整掌握 Claude Code Hooks — 17 种生命周期事件、3 种处理器类型、10+ 实战 Recipe 与企业级配置

更新于 2026-09-03
本页目录

Hooks 允许你在 Claude Code 的关键生命周期节点插入自定义逻辑 — 自动格式化代码、拦截危险命令、发送通知、审计日志等。Hooks 是 Claude Code 最强大的扩展机制之一。


一、核心概念

每个 Hook 由三部分组成:

事件(When)  →  匹配器(Which)  →  处理器(What)
PreToolUse       matcher: "Bash"     command: "check_safety.sh"
  • 事件:触发时机(如 PreToolUse — 工具执行前)
  • 匹配器:可选的工具名过滤(如只匹配 Bash 或 Write)
  • 处理器:Shell 命令、提示词注入 或 子代理

二、完整事件列表

核心事件

事件 触发时机 可阻断 典型用例
PreToolUse 工具执行前 是(exit 2) 安全拦截、参数校验
PostToolUse 工具执行后 否 自动格式化、日志记录
Notification Claude 发送通知 否 Slack/飞书/钉钉告警
Stop Claude 完成响应 否 质检、自动提交
UserPromptSubmit 用户提交提示 是 上下文注入、策略检查
SessionStart 会话启动 否 环境初始化、欢迎信息

扩展事件(2026 新增)

事件 触发时机 可阻断 典型用例
SubagentStop 子代理完成 否 收集子代理结果
SubagentToolUse 子代理使用工具 是 限制子代理权限
FileChanged 文件被修改 否 自动 lint、触发构建
CwdChanged 工作目录变更 否 加载目录特定配置
ModelChange 模型切换 否 记录模型使用统计
CompactComplete /compact 完成 否 上下文压缩后处理
ToolError 工具执行出错 否 错误收集、自动重试逻辑

三、Hook 处理器类型

类型 1:Command(Shell 命令)

最常用的类型,执行 Shell 命令:

{
  "type": "command",
  "command": "npx prettier --write $FILEPATH"
}

环境变量: | 变量 | 说明 | 可用事件 | |------|------|---------| | $FILEPATH | 操作的文件路径 | PreToolUse/PostToolUse | | $TOOL_INPUT | 工具输入 JSON | PreToolUse | | $TOOL_NAME | 工具名称 | PreToolUse/PostToolUse | | $SESSION_ID | 会话 ID | 所有 | | $NOTIFICATION_MESSAGE | 通知内容 | Notification |

stdin 输入:Hook 脚本还会从 stdin 收到一份 JSON,包含 session_id、tool_name、tool_input。需要结构化数据时读它,比解析环境变量更可靠。

退出码:

  • 0:允许继续
  • 2:阻断操作(仅 PreToolUse/UserPromptSubmit)
  • 其他:视为错误但不阻断

类型 2:Prompt(提示注入)

将文本注入 Claude 的上下文:

{
  "type": "prompt",
  "prompt": "记住:所有数据库操作必须使用事务"
}

适用场景:在 SessionStart 时注入额外的项目规则。

类型 3:Subagent(子代理)

生成子代理处理事件:

{
  "type": "subagent",
  "prompt": "审查刚刚修改的代码,检查是否有安全漏洞"
}

适用场景:PostToolUse 后自动审查代码质量。


四、配置方式

在 .claude/settings.json(项目级)或 ~/.claude/settings.json(用户级)中配置:

{
  "hooks": {
    "事件名": [
      {
        "matcher": "工具名(可选,支持 | 分隔多个)",
        "hooks": [
          {
            "type": "command|prompt|subagent",
            "command": "..."
          }
        ]
      }
    ]
  }
}

五、实战 Recipe

Recipe 1:文件保存后自动格式化

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $FILEPATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

Recipe 2:拦截危险的 Shell 命令

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo $TOOL_INPUT | grep -qE 'rm -rf /|sudo rm|git push --force|DROP TABLE|DROP DATABASE' && echo '危险命令已拦截' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

Recipe 3:保护敏感文件

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $TOOL_INPUT | grep -qE '\\.env|\\.env\\.|credentials|secrets?\\.ya?ml|private.key' && echo '敏感文件访问已拦截' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

Recipe 4:任务完成后系统通知

macOS:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"$NOTIFICATION_MESSAGE\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Linux:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' \"$NOTIFICATION_MESSAGE\""
          }
        ]
      }
    ]
  }
}

Recipe 5:Slack 通知

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -s -X POST https://hooks.slack.com/services/xxx/yyy/zzz -H 'Content-Type: application/json' -d '{\"text\": \"Claude Code 任务完成\"}'"
          }
        ]
      }
    ]
  }
}

Recipe 6:ESLint 自动修复

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix $FILEPATH 2>/dev/null; npx prettier --write $FILEPATH 2>/dev/null; exit 0"
          }
        ]
      }
    ]
  }
}

Recipe 7:审计日志

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) | session=$SESSION_ID | tool=$TOOL_NAME | file=$FILEPATH\" >> ~/.claude/audit.log"
          }
        ]
      }
    ]
  }
}

Recipe 8:自动运行测试

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $FILEPATH | grep -qE '\\.(ts|tsx|js|jsx)$' && echo $FILEPATH | grep -qvE '\\.test\\.|\\.spec\\.' && npx vitest related $FILEPATH --run 2>/dev/null || exit 0"
          }
        ]
      }
    ]
  }
}

Recipe 9:保护迁移文件

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $FILEPATH | grep -qE 'migrations/|alembic/versions/' && echo '禁止修改已有迁移文件,请创建新迁移' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

Recipe 10:会话启动时注入上下文

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "重要提醒:本项目正在进行 v3.0 大版本重构,所有新代码必须使用 React Server Components,不再支持 pages/ 目录。"
          }
        ]
      }
    ]
  }
}

六、企业级 Hooks

managed-settings.d/ 配置

企业管理员可通过 managed-settings.d/ 目录强制全组织的安全策略:

# 在企业管理目录中创建策略文件
mkdir -p /etc/claude-code/managed-settings.d/
// /etc/claude-code/managed-settings.d/security.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/opt/claude-policy/check_command.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/opt/claude-policy/audit_log.sh"
          }
        ]
      }
    ]
  }
}

企业策略无法被用户或项目级配置覆盖。


七、调试与排错

Verbose 模式

按 Ctrl+O 开启 verbose 模式,可以看到:

  • Hook 被触发的时机
  • Hook 脚本的 stdout/stderr 输出
  • Hook 的退出码

常见问题

问题 原因 解决方案
Hook 不触发 matcher 拼写错误 检查工具名大小写:Bash、Write、Edit、Read
Hook 阻断了正常操作 exit code 逻辑错误 确保正常情况 exit 0,只在需要拦截时 exit 2
Hook 执行很慢 脚本耗时过长 Hook 应在 1-2 秒内完成,长任务用后台执行
环境变量为空 事件不提供该变量 检查上方环境变量表,确认变量在该事件中可用

测试 Hook 脚本

在终端中手动测试,再放入配置:

# 模拟 PreToolUse 的环境变量
FILEPATH="src/main.ts" TOOL_INPUT="rm -rf /" bash -c 'echo $TOOL_INPUT | grep -qE "rm -rf" && echo "blocked" && exit 2 || exit 0'

八、与 Codex Hooks 对比

维度 Claude Code Hooks Codex Hooks
事件数量 17 种 较少
配置方式 settings.json config.toml
处理器类型 command/prompt/subagent command
企业管理 managed-settings.d/ 无
阻断能力 exit code 2 有限

下一步

相关文档

安全最佳实践
全面掌握 Claude Code 的安全机制 — 权限控制、敏感文件保护、命令拦截、API Key 管理
Claude Agent SDK 入门
了解如何使用 Claude Agent SDK 构建 AI Agent 应用,通过 QCode.cc API 接入
自动化与 CI/CD
完整掌握 Claude Code 无头模式 — 参数参考、5 个 CI/CD 实战、Docker 隔离、会话恢复与 Codex 对比
🚀
开始使用 QCode — Claude Code & Codex
一份套餐同时加速 Claude Code 和 Codex,亚太低延迟
查看套餐定价 → 注册账号
团队 3 人以上?
企业团队版:独立域名 + 子Key管理 + 封号保障,人均低至 ¥250/月
了解企业版 →