Claude Code Hooks 是在 Claude Code 工作流关键节点自动执行脚本的机制,支持 27 种事件,可用于实现声音通知、日志记录、自动化验证等。通过配置 .claude/settings.json 中的 hooks 字段,可以注册 command、prompt、agent 或 http 类型的处理程序,并在 .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"]
}
注意:
prompt、agent、http类型仅支持部分事件(主要是工具相关和代理生命周期事件)。对于ConfigChange、SessionStart、FileChanged等事件,只能使用command类型。
Agent Frontmatter Hooks 配置
从 Claude Code v2.1.0 开始,你可以在代理定义文件(.claude/agents/your-agent.md)的 frontmatter 中直接为特定代理配置钩子。这些钩子仅在该代理的生命周期内生效。
支持的 6 种事件:
PreToolUsePostToolUsePermissionRequestPostToolUseFailureStopSubagentStop
配置示例(.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.json 的 hooks 字段中。为了灵活管理,提供了两套独立的开关文件。
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:确保钩子在整个会话中只执行一次(适用于SessionStart、SessionEnd等事件)。asyncRewake: true(v2.1.72+):钩子在后台运行,但如果以退出码 2 结束(阻塞错误),会唤醒模型来处理错误。if条件 (v2.1.85+):使用权限规则语法添加条件,仅当条件匹配时才执行钩子,减少不必要的进程启动。
验证与调试
- 检查配置:运行
/hooks命令查看已注册的钩子列表。 - 查看日志:默认情况下,钩子事件会记录到
.claude/hooks/logs/hooks-log.jsonl。确保hooks-config.json中的disableLogging为false。 - 手动触发:通过执行会触发钩子的动作(如运行一个 Bash 命令)来测试声音是否正常播放。
- 重载配置:修改
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: prompt 和 agent 类型的钩子与 command 类型有什么根本区别?
A: command 类型运行的是本地系统命令。而 prompt 和 agent 类型会启动一个 Claude 模型实例(agent 类型还赋予其工具权限)来进行推理和判断。它们适用于需要基于上下文进行智能决策的场景,而不是简单的脚本执行。agent 类型还可以通过调用 Read、Grep 等工具来验证文件系统状态。