Claude Code 学习站

Claude Code Hooks 完全指南:用 Shell 命令精准控制 AI 行为

Claude Code Hooks 让你在 AI 生命周期的关键节点自动执行 Shell 脚本,实现代码格式化、通知提醒、危险命令拦截等确定性自动化,还支持 prompt-based 和 agent-based 两种智能判断模式。

本页目录9
要点速览
  • Hooks 是挂载在 Claude Code 生命周期节点的 Shell 命令,实现「必然执行」而非「AI 自主决定」的确定性自动化
  • 核心事件包括 PreToolUse(工具执行前可拦截)、PostToolUse(执行后)、Stop(回复结束)、Notification(等待输入时)等
  • 退出码行为因事件而异:exit 0 正常通过;exit 2 在 PreToolUse、UserPromptSubmit、Stop/SubagentStop 等事件上阻断操作,但 PostToolUse、SessionStart、Notification 等无法被阻断,只展示 stderr;其他非零码记录错误并继续
  • Hook 有五种类型:command(Shell 脚本)、http(HTTP 回调)、mcp_tool(调用已连接的 MCP 工具)、prompt(让 Claude 模型单轮判断,默认 Haiku、可用 model 字段切换)、agent(派生子 Agent 执行复杂验证,默认超时 60 秒、最多 50 轮工具调用)
  • 配置写入 settings.json 的 hooks 块,支持按工具名过滤(matcher)和条件表达式(if),分用户级、项目级、本地级三个作用域
  • 安全注意:Hooks 以当前用户权限执行任意命令,只配置可信脚本;避免将未经验证的外部输入直接拼入 Shell 命令

本文是对官方文档 https://code.claude.com/docs/en/hooks-guide 的中文要点摘要,完整内容以原文为准。

什么是 Hooks

Hooks 是用户自定义的 Shell 命令,在 Claude Code 工作流的特定节点自动触发。与依赖 LLM「自己决定是否运行某个工具」不同,Hooks 提供确定性控制——无论 AI 怎么判断,该执行的操作一定会执行。

典型用途:

  • 每次文件保存后自动运行 prettier / black 格式化
  • Claude 等待输入时发送桌面通知
  • 拦截危险的 rm -rf 类命令
  • 每次任务结束后运行测试套件
  • 将 Claude 的操作日志发送到外部系统

需要更灵活判断的场景,还可以用 prompt-based hooks(让 Claude 模型评估条件)或 agent-based hooks(派生子 Agent 执行复杂验证)。

Hook 事件类型

类别事件名触发时机
会话级SessionStart会话开始或恢复时
会话级SessionEnd会话终止时
每轮UserPromptSubmitClaude 处理用户输入前
每轮StopClaude 完成一轮回复时
每轮NotificationClaude 等待用户输入时
工具执行PreToolUse工具执行前(可拦截)
工具执行PostToolUse工具成功执行后
工具执行PermissionRequest弹出权限确认对话框时
配置/文件ConfigChange配置变更时

PreToolUse 是最常用的拦截点,可以在此阻止危险命令或不合规操作。

配置格式

Hooks 配置写在 settings.jsonhooks 字段中:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "/path/to/validator.sh",
            "timeout": 30
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude finished\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

关键字段说明:

  • matcher:按工具名过滤,支持正则,多个用 | 分隔;不填则匹配所有
  • type:command(Shell)、http(HTTP 回调)、mcp_tool(MCP 工具)、prompt(模型判断)、agent(子 Agent)
  • timeout:超时秒数
  • if:条件表达式,使用权限规则语法进一步过滤

退出码与 JSON 输出

Hook 脚本通过退出码和 stdout JSON 控制 Claude 的行为:

退出码含义效果
0成功正常继续,可通过 JSON 传递额外上下文
2阻断错误行为因事件而异,详见下文
其他非零非阻断错误记录 stderr,继续执行

不同事件对 exit 2 的处理不同:PreToolUse 会阻止该工具调用、UserPromptSubmit 会阻断并清除该 prompt、Stop/SubagentStop 会阻止停止并让 Claude 继续。而 PostToolUse(工具已经执行完毕,无法回退)、SessionStartNotificationSessionEnd 等事件无法被 exit 2 阻断,此时只会把 stderr 展示给 Claude 或用户并继续。

若需要更精细的控制,可以改为 exit 0 并向 stdout 打印 JSON(注意:exit 2 时 Claude Code 会忽略 JSON,二者不要混用)。对于支持阻断的 StopSubagentStopUserPromptSubmit 等事件,可用顶层的 decision 字段并配 reason 反馈原因:

{
  "decision": "block",
  "reason": "禁止删除生产环境文件"
}

不同事件使用不同的决策字段:PreToolUsehookSpecificOutput.permissionDecision(取值 allow/deny/ask 等)。完整对照见参考文档的决策控制表。

Prompt-Based 与 Agent-Based Hooks

Prompt-based hooks 不执行固定脚本,而是把 Hook 事件上下文连同你的 prompt 发送给 Claude 模型(可用 model 字段指定所用模型),让模型做单轮判断:

{
  "type": "prompt",
  "prompt": "检查即将执行的命令是否可能损坏生产数据库。如果风险高,拒绝执行。"
}

模型只需返回一个放行/拒绝的 JSON 决策:放行则照常继续;拒绝则按事件类型处理——PreToolUse 会拒绝该工具调用并把 reason 作为工具报错返回给 Claude、Stop/SubagentStop 会把 reason 反馈给 Claude 让它继续工作、PostToolUse/UserPromptSubmit 等则结束本轮并把 reason 作为警告显示。

Agent-based hooks 更进一步,可以派生一个子 Agent 执行多步骤验证(如读取文件、搜索代码、运行命令),再根据结果决定是否允许操作。它复用与 prompt hooks 相同的放行/拒绝响应格式,但默认超时更长,可进行多轮工具调用。该特性目前仍属实验性,生产场景建议优先用 command hooks。

配置文件位置

文件路径作用域
~/.claude/settings.json用户级,对所有项目生效
.claude/settings.json项目级,可提交到版本库共享
.claude/settings.local.json项目本地级,建议加入 .gitignore
Plugin hooks/hooks.json随 Plugin 打包分发

实用示例

桌面通知(Notification 事件):

#!/bin/bash
osascript -e 'display notification "Claude 在等你" with title "Claude Code"'

拦截危险删除命令(PreToolUse + Bash):

#!/bin/bash
command=$(cat - | jq -r '.tool_input.command')
if [[ "$command" == rm\ -rf* ]]; then
  echo "禁止执行 rm -rf" >&2
  exit 2
fi
exit 0

自动格式化(PostToolUse + Write/Edit):

{
  "PostToolUse": [{
    "matcher": "Write|Edit",
    "hooks": [{
      "type": "command",
      "command": "prettier --write \"$CLAUDE_PROJECT_DIR\"/src"
    }]
  }]
}

提示:脚本中引用工程根目录请用官方提供的 $CLAUDE_PROJECT_DIR

安全注意事项

  • Hooks 以当前用户权限执行任意 Shell 命令,风险与执行本地脚本相同
  • 只配置来源可信的 Hook 脚本,不要将 GitHub 上的 Hook 直接复制进生产配置
  • 避免将 Hook 接收的 JSON 输入未经验证地拼入 Shell 命令(防止注入攻击)
  • 项目级 .claude/settings.json 中的 Hooks 在所有协作者机器上都会执行,提交前需团队审核

与其他扩展机制的关系

机制适合场景
Hooks确定性规则,每次必须触发
Skills给 Claude 提供额外指令和可执行命令
Subagents在隔离上下文中运行子任务
Plugins打包多个扩展分发给团队

完整事件 schema、JSON 输入输出格式、异步 Hooks、MCP 工具 Hooks 等高级特性,详见官方参考文档 Hooks reference