Claude Code Hooks 是在 Claude Code 工作流关键节点自动执行脚本的机制,支持 27 种事件,可用于实现声音通知、日志记录、自动化验证等。通过配置 .claude/settings.json 中的 hooks 字段,可以注册 commandpromptagenthttp 类型的处理程序,并在 .claude/hooks/config/ 中精细管理启用状态。

Claude Code Hooks 完整指南:27 种事件、声音通知系统、Agent Hooks 配置

Hooks 允许你在 Claude Code 的特定生命周期点(如调用工具前、会话开始时、子代理完成时)自动运行自定义脚本。这是从被动响应转向主动控制和自动化工作流的关键步骤。

27 种 Hook 事件详解

Claude Code 提供了 27 个官方钩子事件,覆盖了从会话启动到结束的各个阶段。理解这些事件是配置有效钩子的基础。

# 事件名称 描述 匹配器 (matcher) 可选值 备注
1 PreToolUse 工具调用触发,可用于验证或拦截。 工具名(如 Bash, Edit, mcp__*
2 PermissionRequest Claude Code 需要用户授权时触发。 工具名
3 PostToolUse 工具调用成功后触发。 工具名
4 PostToolUseFailure 工具调用失败后触发。 工具名
5 UserPromptSubmit 用户提交提示,Claude 处理触发。 可用于修改提示词。
6 Notification Claude Code 发送通知时触发。 通知类型(如 permission_prompt
7 Stop Claude Code 完成一次回答后触发。 始终触发。
8 SubagentStart 子代理任务开始时触发。 子代理类型(如 Bash, Plan
9 SubagentStop 子代理任务完成时触发。 子代理类型
10 PreCompact 执行上下文压缩触发。 压缩触发器(manual, auto
11 PostCompact 执行上下文压缩触发。 压缩触发器
12 SessionStart 新建或恢复会话时触发。 来源(startup, resume, clear, compact
13 SessionEnd 会话结束时触发。 原因(clear, logout 等)
14 Setup 执行 /setup 命令初始化项目时触发。
15 TeammateIdle 队友代理空闲时触发。 需要实验性 Agent Teams 功能。
16 TaskCreated 通过 TaskCreate 工具创建任务时触发。 需要实验性 Agent Teams 功能。
17 TaskCompleted 后台任务完成时触发。 需要实验性 Agent Teams 功能。
18 ConfigChange 配置文件在会话期间更改时触发。 配置来源(如 project_settings
19 WorktreeCreate 代理工作树隔离创建新工作树时触发。
20 WorktreeRemove 代理工作树隔离移除工作树时触发。
21 InstructionsLoaded 加载 CLAUDE.md.claude/rules/*.md 文件时触发。 加载原因(session_start 等)
22 Elicitation MCP 服务器请求用户输入时触发。 MCP 服务器名
23 ElicitationResult 用户响应 MCP 询问后触发。 MCP 服务器名
24 StopFailure 因 API 错误(如速率限制)导致轮次结束时触发。 错误类型(rate_limit 等)
25 CwdChanged 会话中工作目录更改时触发。
26 FileChanged 被监视的文件在会话期间更改时触发。 文件基名(.envrc|.env 必须配置 matcher
27 PermissionDenied 自动模式分类器拒绝工具调用后触发。 工具名 可返回 {retry: true} 让模型重试。

关于实验性功能:事件 15-17 (TeammateIdle, TaskCreated, TaskCompleted) 需要在启动 Claude Code 时设置环境变量 CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 来启用。

四种 Hook 处理程序类型

每个钩子事件可以注册一个或多个处理程序,它们分为四种类型。

1. command 类型 运行一个 shell 命令。项目通过此类型执行 Python 脚本播放声音。

{
  "type": "command",
  "command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/scripts/hooks.py",
  "timeout": 5000,
  "async": true
}

2. prompt 类型 向 Claude 模型发送一个单次提示,要求返回 {"ok": true/false, "reason": "..."} 格式的判断。适用于需要推理而非确定规则的场景。

{
  "type": "prompt",
  "prompt": "检查所有任务是否完成。$ARGUMENTS",
  "timeout": 30
}

3. agent 类型 启动一个拥有文件读取、搜索等工具权限的子代理,进行多轮验证后返回决策。响应格式与 prompt 类型相同。

{
  "type": "agent",
  "prompt": "验证所有单元测试是否通过。$ARGUMENTS",
  "timeout": 120
}

4. http 类型 (v2.1.63+) 向指定 URL 发送 POST 请求,并接收 JSON 响应。适合与外部服务或 Webhook 集成。

{
  "type": "http",
  "url": "http://localhost:8080/hooks/pre-tool-use",
  "timeout": 30,
  "headers": {
    "Authorization": "Bearer $MY_TOKEN"
  },
  "allowedEnvVars": ["MY_TOKEN"]
}

注意promptagenthttp 类型仅支持部分事件(主要是工具相关和代理生命周期事件)。对于 ConfigChangeSessionStartFileChanged 等事件,只能使用 command 类型。

Agent Frontmatter Hooks 配置

从 Claude Code v2.1.0 开始,你可以在代理定义文件(.claude/agents/your-agent.md)的 frontmatter 中直接为特定代理配置钩子。这些钩子仅在该代理的生命周期内生效。

支持的 6 种事件

  • PreToolUse
  • PostToolUse
  • PermissionRequest
  • PostToolUseFailure
  • Stop
  • SubagentStop

配置示例.claude/agents/my-agent.md):

---
name: my-agent
description: 一个带有声音反馈的代理示例
hooks:
  PreToolUse:
    - type: command
      command: python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/scripts/hooks.py --agent=my-agent
      timeout: 5000
      async: true
  Stop:
    - type: command
      command: python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/scripts/hooks.py --agent=my-agent
      timeout: 5000
      async: true
---

你的代理指令写在这里...

代理钩子可以使用独立的声音文件夹(如 .claude/hooks/sounds/agent_pretooluse/),以实现与全局钩子不同的音效。

配置管理与启用/禁用

钩子配置位于 .claude/settings.jsonhooks 字段中。为了灵活管理,提供了两套独立的开关文件。

1. 全局禁用所有钩子

.claude/settings.local.json(此文件被 git 忽略,个人本地配置)中设置:

{
  "disableAllHooks": true
}

2. 精细控制单个钩子

通过两个配置文件管理:

  • .claude/hooks/config/hooks-config.json:团队共享的默认配置(提交到 git)。
  • .claude/hooks/config/hooks-config.local.json:个人覆盖配置(被 git 忽略)。

hooks-config.json 文件中列出了所有可禁用的钩子开关。例如,禁用 PostToolUse 钩子和日志记录:

{
  "disableLogging": true,
  "disablePostToolUseHook": true
}

个人本地配置文件中的设置会覆盖共享配置。

3. 使用 /hooks 命令管理

在 Claude Code CLI 中运行 /hooks 命令,可获得一个交互式 UI 来查看、添加、删除钩子,并可以切换 disableAllHooks

声音通知系统实现原理

本项目通过 command 类型的钩子,调用一个 Python 脚本 (hooks.py) 来实现声音通知。脚本根据接收到的 hook_event_name,从对应的音效文件夹(如 .claude/hooks/sounds/pretooluse/)中随机选择一个 .wav 文件播放。

关键配置(来自 .claude/settings.json):

"PreToolUse": [{
  "hooks": [{
    "type": "command",
    "command": "python3 ${CLAUDE_PROJECT_DIR}/.claude/hooks/scripts/hooks.py",
    "timeout": 5000,
    "async": true,
    "statusMessage": "PreToolUse"
  }]
}]
  • async: true:声音播放在后台进行,不阻塞 Claude Code 执行。
  • timeout: 5000:为异步脚本设置最大执行时间。
  • statusMessage:在状态栏显示当前正在执行的钩子名称。

Matcher 与环境变量

匹配器 (matcher):用于筛选哪些特定事件会触发钩子。例如,FileChanged 钩子必须配置 matcher 来指定监视哪些文件:

"FileChanged": [{
  "matcher": ".envrc|.env|.env.local",
  "hooks": [...]
}]

不同事件的匹配器取值不同,详见上方表格。

常用环境变量:钩子脚本可通过以下环境变量获取上下文:

  • $CLAUDE_PROJECT_DIR:项目根目录。
  • $CLAUDE_ENV_FILE:用于为后续 Bash 命令持久化环境变量的文件路径。
  • ${CLAUDE_SKILL_DIR}:技能目录(用于技能钩子)。

高级钩子选项

  • once: true:确保钩子在整个会话中只执行一次(适用于 SessionStartSessionEnd 等事件)。
  • asyncRewake: true (v2.1.72+):钩子在后台运行,但如果以退出码 2 结束(阻塞错误),会唤醒模型来处理错误。
  • if 条件 (v2.1.85+):使用权限规则语法添加条件,仅当条件匹配时才执行钩子,减少不必要的进程启动。

验证与调试

  1. 检查配置:运行 /hooks 命令查看已注册的钩子列表。
  2. 查看日志:默认情况下,钩子事件会记录到 .claude/hooks/logs/hooks-log.jsonl。确保 hooks-config.json 中的 disableLoggingfalse
  3. 手动触发:通过执行会触发钩子的动作(如运行一个 Bash 命令)来测试声音是否正常播放。
  4. 重载配置:修改 settings.json 后,无需重启会话,可运行 claude hooks reload 命令使配置生效。

FAQ

Q: 如何调试我的钩子脚本? A: 首先,检查 .claude/hooks/logs/hooks-log.jsonl 日志文件,确认事件是否被记录。你可以临时将钩子的 command 改为简单的测试命令(如 echo "Hook fired" > hook-test.log),然后查看日志文件是否生成,以隔离问题。

Q: 钩子会影响 Claude Code 的性能吗? A: 如果钩子配置了 "async": true,它会在后台运行,不会阻塞 Claude Code 的主执行流程。对于同步钩子,应确保其执行时间尽量短,并通过 timeout 设置上限。本项目所有钩子都使用异步模式播放声音,对性能影响极小。

Q: promptagent 类型的钩子与 command 类型有什么根本区别? A: command 类型运行的是本地系统命令。而 promptagent 类型会启动一个 Claude 模型实例(agent 类型还赋予其工具权限)来进行推理和判断。它们适用于需要基于上下文进行智能决策的场景,而不是简单的脚本执行。agent 类型还可以通过调用 ReadGrep 等工具来验证文件系统状态。