Claude Code Hooks 机制概述
Hooks 本质上是在 Claude Code 中自定义的脚本或命令,能够在特定生命周期节点自动触发执行。该机制支持 4 种类型,覆盖 4 个生命周期事件,帮助开发者轻松实现项目初始化、上下文注入、输入预处理及清理等自动化任务。

四种 Hook 类型详解
| Hook 类型 | type 字段值 |
功能说明 |
|---|---|---|
| Shell 命令 | "command" |
最直接的方式,执行 Shell 命令,标准输出即为返回结果 |
| HTTP 请求 | "http" |
向指定 URL 发送 POST 请求,Hook 输入以 JSON 格式放入请求体 |
| LLM 提示 | "prompt" |
让大语言模型评估一段 Prompt,返回结构化结果 |
| Agent 验证 | "agent" |
利用 Agent 执行验证任务,例如检查测试是否全部通过 |
四个生命周期事件详解
Setup 事件
在 Claude Code 启动时仅执行一次,适用于项目初始化操作,比如自动安装依赖或创建目录结构。
{"hooks": {"Setup": [{"matcher": "","hooks": [{ "type": "command", "command": "npm install", "timeout": 60 }]}]}}触发时机为进程启动后、REPL 渲染之前。Hook Input 包含以下字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
hook_event_name |
"Setup" |
— |
trigger |
"init" | "maintenance" |
触发来源 |
session_id |
string | 当前会话 ID |
cwd |
string | 工作目录路径 |
transcript_path |
string | 会话日志文件路径 |
注意:Setup 事件的 stdout 内容不会传递给模型,仅用于执行初始化动作。
SessionStart 事件
每次会话开始时都会触发,包括新启动、通过 /resume 恢复会话以及使用 /clear 清空后。它的 stdout 内容会作为系统消息(system message)注入到模型上下文中。
{"hooks": {"SessionStart": [{"matcher": "","hooks": [{ "type": "command", "command": "cat .claude/session-context.md", "timeout": 10 }]}]}}触发场景包括以下几种:
| source 值 | 触发场景 |
|---|---|
startup |
进程首次启动 |
resume |
通过 --resume 或 /resume 恢复会话 |
clear |
执行 /clear 后 |
compact |
上下文压缩完成后 |
Hook Input 字段如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
hook_event_name |
"SessionStart" |
— |
source |
"startup" | "resume" | "clear" | "compact" |
触发来源 |
agent_type |
string (optional) | Agent 类型 |
model |
string (optional) | 当前使用的模型 |
这里的 stdout 会注入为系统消息,模型能够读取到。
UserPromptSubmit 事件
在用户每次提交消息之前执行,可对用户输入进行预处理,例如追加安全检查或补充上下文信息。
{"hooks": {"UserPromptSubmit": [{"matcher": "","hooks": [{"type": "command","command": "node scripts/validate-input.js","timeout": 10,"statusMessage": "Validating input..."}]}]}}Hook Input 字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
hook_event_name |
"UserPromptSubmit" |
— |
prompt |
string | 用户输入的原始文本 |
同样,它的 stdout 会作为系统消息注入,模型能够看见。
SessionEnd 事件
会话结束时触发,例如进程退出或执行 /clear。主要用于清理资源和记录日志。
{"hooks": {"SessionEnd": [{"matcher": "","hooks": [{ "type": "command", "command": "node scripts/cleanup.js", "timeout": 5 }]}]}}Hook Input 字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
hook_event_name |
"SessionEnd" |
— |
reason |
"clear" | "resume" | "logout" | "prompt_input_exit" | "other" |
结束原因 |
此事件的 stdout 不会注入给模型,静默执行。默认超时时间为 1.5 秒,可通过环境变量 CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS 进行自定义配置。
Hook 命令通用字段
所有类型的 Hook 都支持以下通用字段:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
type |
"command" | "http" | "prompt" | "agent" |
✅ | Hook 类型 |
command / prompt / url |
string | ✅ | 具体的命令、Prompt 或 URL(根据 type 不同而设置) |
timeout |
number | ❌ | 超时时间,单位秒 |
statusMessage |
string | ❌ | 执行时 spinner 显示的自定义消息 |
once |
boolean | ❌ | 仅执行一次后自动移除 |
if |
string | ❌ | 条件过滤,使用权限规则语法(如 "Bash(git *)") |
async |
boolean | ❌ | 后台异步执行,不阻塞主流程(仅适用于 command 类型) |
asyncRewake |
boolean | ❌ | 后台执行,当 exit code 为 2 时唤醒模型(仅 command 类型,隐含 async) |
HTTP 类型专属字段
| 字段名 | 类型 | 说明 |
|---|---|---|
url |
string | POST 请求的目标 URL(Hook 输入以 JSON 形式发送到请求体) |
headers |
object | 自定义请求头,支持 $VAR 环境变量引用 |
allowedEnvVars |
string[] | 允许在 header 值中插值的环境变量白名单 |
Prompt 类型专属字段
| 字段名 | 类型 | 说明 |
|---|---|---|
prompt |
string | 供 LLM 评估的 Prompt,使用 $ARGUMENTS 占位符引用 Hook 输入的 JSON |
model |
string | 使用的模型(默认使用小模型) |
配置位置说明
Hooks 配置存放在 settings.json 中,支持用户级和项目级两个层级:
用户级配置(全局生效)
配置文件位于 ~/.claude/settings.json:
{"hooks": {"SessionStart": [{"matcher": "","hooks": [{ "type": "command", "command": "echo 'Hello from global hook'", "timeout": 5 }]}]}}
项目级配置(仅当前项目)
配置文件位于项目根目录下的 .claude/settings.json:
{"hooks": {"Setup": [{"matcher": "","hooks": [{ "type": "command", "command": "npm install", "timeout": 120 }]}],"SessionStart": [{"matcher": "","hooks": [{ "type": "command", "command": "cat .claude/instructions.md", "timeout": 5 }]}],"UserPromptSubmit": [{"matcher": "","hooks": [{"type": "command","command": "scripts/lint-check.sh","timeout": 15,"if": "Write"}]}],"SessionEnd": [{"matcher": "","hooks": [{ "type": "command", "command": "scripts/cleanup.sh", "timeout": 5 }]}]}}
实用示例展示
示例 1:每次启动加载项目文档
这是一个常见场景——让 Claude Code 启动时自动读取项目文档,确保模型对项目背景有充分了解。
{"hooks": {"SessionStart": [{"matcher": "","hooks": [{"type": "command","command": "cat .claude/project-guide.md","timeout": 5,"statusMessage": "Loading project guide..."}]}]}}
示例 2:提交前自动执行代码规范检查
在用户每次提交前,自动运行代码规范检查脚本,提前发现并修复问题。
{"hooks": {"UserPromptSubmit": [{"matcher": "","hooks": [{"type": "command","command": "node scripts/check-code-style.js "$CLAUD_PROMPT"","timeout": 10}]}]}}
示例 3:通过 HTTP webhook 发送通知
会话结束时,通过 HTTP 请求通知外部系统,例如将会话摘要推送到团队协作平台。
{"hooks": {"SessionEnd": [{"matcher": "","hooks": [{"type": "http","url": "https://api.example.com/claude-end","timeout": 5,"headers": {"Authorization": "Bearer $MY_API_TOKEN"},"allowedEnvVars": ["MY_API_TOKEN"]}]}]}}
示例 4:项目初始化时自动安装依赖
新项目首次启动时,自动检测并安装依赖,省去手动操作步骤。
{"hooks": {"Setup": [{"matcher": "","hooks": [{"type": "command","command": "test -f package.json && npm install || echo 'No package.json found'","timeout": 120,"statusMessage": "Installing dependencies..."}]}]}}
注意事项与避坑指南
最后总结几个容易忽略的关键点:
- 超时控制:
timeout字段单位为秒。Setup 和 SessionStart 默认无严格限制,但 SessionEnd 默认只有 1.5 秒,且存在 5 秒的 failsafe 兜底机制。 - stdout 注入差异:SessionStart 和 UserPromptSubmit 的 stdout 会作为系统消息发送给模型;而 Setup 和 SessionEnd 不会,设计意图明确,避免不必要的信息干扰模型。
- 异步执行选项:设置
async: true的命令 Hook 将在后台运行,不阻塞主流程。asyncRewake: true更高级,当 exit code 为 2 时还能唤醒模型处理错误。 - 条件过滤:
if字段使用权限规则语法(如"Bash(git *)"、"Write"),仅在匹配条件时才执行,避免无关操作触发 Hook。 - once 一次性执行:设置为
true的 Hook 执行一次后自动从配置中移除,适合只需运行一次的场景。 - 安全注意事项:HTTP Hook 的 header 中如需引用环境变量,必须在
allowedEnvVars中显式声明,否则不会生效。
