Claude Code 的钩子系统允许你在 29 个预定义事件发生时自动执行脚本、HTTP 请求或 LLM 提示,从而拦截、验证或增强 Claude 的行为。系统提供 5 种钩子类型,通过简单的 JSON 配置即可构建从代码格式化到安全策略执行的完整自动化工作流。

Claude Code Hooks 系统深度指南:29 个事件、5 种钩子类型与自动化工作流

Claude Code 的钩子(Hooks)是事件驱动的自动化脚本,能够在 Claude Code 会话的特定关键时刻自动执行,用于验证输入、修改输出、执行安全策略或集成外部系统。本文将深入解析其配置、事件、类型和实战应用。

一、钩子配置与匹配模式

钩子配置在多个层级的 settings.json 文件中,遵循特定的 JSON 结构。

配置层级(从高到低):

  1. 托管策略:组织级设置,用户无法覆盖。
  2. 用户设置~/.claude/settings.json,应用于所有项目。
  3. 项目设置.claude/settings.json,可提交到版本库。
  4. 本地项目设置.claude/settings.local.json,不提交。
  5. 插件钩子:插件目录下的 hooks/hooks.json
  6. 组件钩子:定义在技能(SKILL.md)、代理(agent.md)的 frontmatter 中。

基本配置结构:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "ToolPattern",
        "hooks": [
          {
            "type": "command",
            "command": "your-command-here",
            "timeout": 60
          }
        ]
      }
    ]
  }
}

匹配模式(Matcher)用于筛选触发钩子的工具:

模式 描述 示例
精确字符串 匹配特定工具 "Write"
正则表达式 匹配多个工具 "Edit|Write"
通配符 匹配所有工具 "*"""
MCP 工具 匹配 MCP 服务器工具 "mcp__memory__.*"

InstructionsLoaded 事件的匹配器值session_startnested_traversalpath_glob_match

二、五种钩子类型详解

Claude Code 支持五种钩子类型,各自适用于不同场景。

1. 命令钩子(Command Hooks)

默认类型,执行 Shell 命令。支持两种形式:

  • Shell 形式:通过 "command": "..." 执行。
  • Exec 形式(v2.1.139+):通过 "args": [...] 数组直接执行二进制文件,避免 Shell 注入。

两种形式互斥,只能使用其一。当需要使用管道、重定向或 && 链时用 Shell 形式;调用单个可执行文件时用 Exec 形式更安全。

2. HTTP 钩子(HTTP Hooks)

向远程 Webhook 端点发送 POST 请求,接收 JSON 响应。启用沙箱时会经过沙箱路由。出于安全考虑,URL 中使用环境变量需显式配置 allowedEnvVars 列表。

{
  "type": "http",
  "url": "https://my-webhook.example.com/hook"
}

3. 提示钩子(Prompt Hooks)

钩子内容是一段提示词,由 Claude LLM 评估。主要用于 StopSubagentStop 事件,进行智能的任务完成度检查。LLM 会返回一个包含 decisionreason 的结构化决策。

4. MCP 工具钩子(MCP Tool Hooks,v2.1.118+)

直接调用已配置的 MCP 服务器上的工具。输入数据(工具名、输入、会话上下文)作为 MCP 工具的参数传递。适合将验证逻辑封装在 MCP 服务中。

{
  "type": "mcp_tool",
  "server": "my-mcp-server",
  "tool": "validate_edit"
}

5. 代理钩子(Agent Hooks)

启动一个专用子代理(Subagent)来执行复杂的多步骤评估。与提示钩子的单轮 LLM 评估不同,代理钩子可以使用工具(如 Read、Grep、Bash)进行深入检查。

三、29 个钩子事件全表

Claude Code 提供了 29 个事件,覆盖从会话开始到结束的各个环节。以下是基于源文档的完整事件列表。

事件 触发时机 匹配器输入 可阻断 常见用途
SessionStart 会话开始、恢复、清理、压缩 startup/resume/clear/compact 环境设置
Setup 初始化环境(每会话一次) (无) 配置工具、安装依赖
InstructionsLoaded CLAUDE.md 或规则文件加载后 (无) 修改/过滤指令
UserPromptSubmit 用户提交提示时 (无) 验证用户提示
UserPromptExpansion 用户提示被扩展后 (无) 转换或检查扩展后的提示
PreToolUse 工具执行前 工具名称 是(允许/拒绝/询问) 验证、修改工具输入
PermissionRequest 权限对话框显示时 工具名称 自动批准/拒绝
PermissionDenied 用户拒绝权限提示时 工具名称 日志记录、策略执行
PostToolUse 工具执行成功后 工具名称 添加上下文、反馈
PostToolUseFailure 工具执行失败后 工具名称 错误处理、日志记录
PostToolBatch 一批工具使用完成后 (无) 聚合报告、批量验证
Notification 发送通知时 通知类型 自定义通知
SubagentStart 子代理启动时 代理类型名称 子代理初始化
SubagentStop 子代理完成时 代理类型名称 子代理验证
Stop Claude 完成响应时 (无) 任务完成检查
StopFailure API 错误结束轮次时 (无) 错误恢复、日志记录
TeammateIdle 团队代理空闲时 (无) 团队协调
TaskCompleted 任务标记为完成时 (无) 任务后操作
TaskCreated 通过 TaskCreate 创建任务时 (无) 任务跟踪、日志
ConfigChange 配置文件变更时 (无) 是(策略除外) 响应配置更新
CwdChanged 工作目录变更时 (无) 目录特定设置
FileChanged 监视的文件变更时 (无) 文件监视、重新构建
PreCompact 上下文压缩前 manual/auto 压缩前操作
PostCompact 压缩完成后 (无) 压缩后操作
WorktreeCreate 工作树创建时 (无) 是(返回路径) 工作树初始化
WorktreeRemove 工作树移除时 (无) 工作树清理
Elicitation MCP 服务器请求用户输入时 (无) 输入验证
ElicitationResult 用户响应诱导后 (无) 响应处理
SessionEnd 会话终止时 (无) 清理、最终日志

关键版本特性:

  • PostToolUse duration_ms(v2.1.119+)PostToolUsePostToolUseFailure 输入新增 duration_ms 字段,记录工具执行时间(毫秒)。
  • Stop 钩子连续阻断上限(v2.1.143+):如果 Stop 钩子连续 8 次返回阻断决策,会话将自动终止并发出警告,防止无限循环。可通过环境变量 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 调整阈值(设为 0 禁用)。
  • updatedToolOutput 重写所有工具输出(v2.1.121+)PostToolUse 钩子的 hookSpecificOutput.updatedToolOutput 字段现在可用于重写所有工具(如 Bash, Edit, Read)的输出,而不仅仅是 MCP 工具。

四、钩子输入输出与高级用法

输入 JSON 字段表(通过 stdin)

所有钩子都通过 stdin 接收 JSON 输入。关键字段包括 session_idtranscript_pathcwdhook_event_nametool_nametool_inputagent_idagent_typeworktreeeffort.level(v2.1.133+)。

退出码与行为

退出码 含义 行为
0 成功 继续,并解析 stdout 中的 JSON
2 阻断错误 阻断操作,stderr 显示为错误信息
其他 非阻断错误 继续,stderr 在详细模式下显示

输出 JSON 格式(stdout,退出码 0)

输出 JSON 可以控制钩子行为。例如,hookSpecificOutput 字段可用于:

  • PreToolUse:设置 permissionDecision(allow/deny/ask)和 updatedInput 修改工具输入。
  • PostToolUse:设置 additionalContext 为 Claude 添加额外信息,或通过 updatedToolOutput 重写工具输出。
  • Stop/SubagentStop:设置 continue: false 来阻断并要求 Claude 继续工作。

可恢复的阻断(continueOnBlock,v2.1.139+)

默认情况下,PostToolUse 钩子返回 "decision": "block" 会中止当前轮次。在钩子配置中设置 "continueOnBlock": true,可以将拒绝信息作为 tool_result 返回给 Claude,让模型读取反馈后重试或调整。

终端序列输出(terminalSequence,v2.1.141+)

输出 JSON 可包含 terminalSequence 字段,向宿主终端发送原始的 OSC 转义序列(如 OSC 9 桌面通知),用于提醒或窗口标题更新。

组件级钩子

钩子可以定义在技能、代理的 frontmatter 中,与其绑定。子代理(Subagent) frontmatter 中定义的 Stop 钩子会自动转换为 SubagentStop 钩子,确保仅在该特定子代理完成时触发。

五、实战示例:从验证到自动化

以下示例展示了如何组合使用钩子。所有脚本均可在 Claude HowTo 教程指南 中找到。

  1. 安全扫描(PostToolUse):在 WriteEdit 工具执行后,自动扫描代码中的硬编码密码或 API 密钥,并将警告作为上下文反馈给 Claude。
  2. 自动格式化(PostToolUse):在文件保存后,根据扩展名自动调用 Prettier、Black 或 gofmt 进行代码格式化。
  3. 提示验证(UserPromptSubmit):在 Claude 处理用户输入前,验证提示内容,阻断包含“删除数据库”等危险命令的请求。
  4. 智能停止检查(Prompt-Based Stop Hook):使用提示钩子让 LLM 评估 Claude 是否完成了所有请求的任务,确保任务闭环。
  5. 上下文用量跟踪(Hook 配对):结合 UserPromptSubmit(记录起始 token 数)和 Stop(计算增量)钩子,精确跟踪每次请求的 token 消耗。
  6. 会话结束日志(SessionEnd):在会话结束时提示用户记录学习模块进度,并保存到外部文件。

六、安全注意事项

钩子执行任意 Shell 命令,使用时需自行承担风险。关键安全实践包括:

  • 沙箱与信任:HTTP 钩子在启用沙箱时经过沙箱路由;statusLine 等输出需要工作区信任。
  • 环境变量管理:HTTP 钩子 URL 中使用环境变量需显式配置 allowedEnvVars
  • 策略控制:组织可通过托管策略的 disableAllHooks 设置全局禁用钩子,用户无法覆盖。
  • 命令注入防护:优先使用 args 数组形式(exec form)执行命令,避免 Shell 解析带来的注入风险。
  • 测试:务必在安全环境中测试钩子脚本。

FAQ

Q: 如何防止 Stop 钩子导致会话死循环? A: 从 v2.1.143 版本起,如果同一个 Stop 钩子连续 8 次返回阻断决策("decision": "block"continue: false),Claude Code 会自动终止会话并发出警告。你可以通过设置环境变量 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 来调整这个上限(例如设为 5),或者设为 0 来禁用此安全限制。

Q: 在钩子脚本中如何获取当前项目目录的路径? A: 所有钩子脚本都可以通过环境变量 $CLAUDE_PROJECT_DIR 获取项目根目录的绝对路径。在配置钩子命令时,应使用此变量而不是硬编码路径,例如 "$CLAUDE_PROJECT_DIR/.claude/hooks/your-script.sh",这样能确保脚本在不同机器上正确执行。