Hooks 系统

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

Hooks 系统

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


一、核心概念

每个 Hook 由三部分组成:

事件(When)  →  匹配器(Which)  →  处理器(What)
PreToolUse       matcher: "Bash"     command: "check_safety.sh"
  • 事件:触发时机(如 PreToolUse — 工具执行前)
  • 匹配器:可选的工具名过滤(如只匹配 BashWrite
  • 处理器: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 |

退出码

  • 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 拼写错误 检查工具名大小写:BashWriteEditRead
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 有限

下一步

🚀
开始使用 QCode — Claude Code & Codex
一份套餐同时加速 Claude Code 和 Codex,亚太低延迟
查看套餐定价 → 注册账号
团队 3 人以上?
企业团队版:独立域名 + 子Key管理 + 封号保障,人均低至 ¥250/月
了解企业版 →