
docs.anthropic.com
Hooks — Claude Code 官方文档
Customize and extend Claude Code's behavior by registering shell commands to execute at key points in Claude's lifecycle.

Claude Code 的 Hooks 机制让你用 Shell 命令在 AI 生命周期的五个节点植入确定性控制——写文件后自动格式化、任务完成发通知、危险操作前强制拦截。本文完整拆解五种事件类型、配置结构、stdin 数据格式与 JSON 决策输出,附三个即开即用配置示例。
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse | Claude 生成工具参数后、工具执行前 | 拦截风险命令、记录审计日志、强制格式检查 |
PostToolUse | 工具成功执行后 | 写完文件自动 lint/format、提交后发通知 |
Stop | Claude 完成响应、会话结束时 | 任务完成通知、收尾清理脚本 |
Notification | Claude 发送通知时 | 将 AI 通知转发到外部渠道 |
UserPromptSubmit | 用户提交 prompt 前 | 注入时间上下文、预处理输入 |
Stop 是自动化场景里使用最频繁的。把耗时 20 分钟的 Claude 任务交给后台跑,完成后触发一条 Telegram 消息,比你盯着终端划算得多。2~/.claude/settings.json:用户全局,对所有项目生效.claude/settings.json:项目级,可提交 git 供团队共享.claude/settings.local.json:本地个人配置,建议加入 .gitignore{
"hooks": {
"PostToolUse": [
{
"matcher": "Write(*.py)",
"hooks": [
{
"type": "command",
"command": "python -m black \"$file\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash ~/send-telegram.sh 'Claude finished the task'"
}
]
}
]
}
}matcher 字段只对 PreToolUse 和 PostToolUse 有效,支持精确字符串(Write)和正则(Edit|Write、Notebook.*);省略则匹配该事件下的所有工具调用。Stop 和 Notification 没有 matcher 概念,直接列出 hooks 数组即可。Ctrl-R)里展示给用户PreToolUse 这意味着工具调用被取消,Claude 会看到你的错误信息并重新决策;对于 Stop 则会阻止 Claude 停止并要求它继续处理PreToolUse 钩子可以输出:{
"decision": "block",
"reason": "检测到生产环境配置文件写入,已拦截。请确认操作范围后重试。"
}Stop 钩子支持 "decision": "block"——这可以用来实现「任务完成前强制验证」:Claude 认为自己做完了,但你的验证脚本发现测试没过,钩子返回 block + reason,Claude 收到信息后继续修复。{
"hooks": {
"PostToolUse": [
{
"matcher": "Write(*.py)",
"hooks": [
{
"type": "command",
"command": "python -m black \"$file\""
}
]
}
]
}
}.py 文件,Black 立即跑一遍,不需要 Claude 记住「要格式化」这件事。{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "say 'Claude has finished the task'"
}
]
}
]
}
}say 命令,零依赖。适合后台跑长任务时切出去做别的事。Telegram/Slack 通知同理,把 say 替换成对应 API 调用脚本即可。{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "python3 -c \"\nimport json, sys\ndata = json.load(sys.stdin)\npath = data.get('tool_input', {}).get('file_path', '')\nif 'production' in path or '.env' in path:\n print(json.dumps({'decision': 'block', 'reason': f'拦截生产文件写入: {path}'}))\nelse:\n print(json.dumps({'decision': 'approve'}))\n\""
}
]
}
]
}
}tool_input.file_path,检查路径是否包含 production 或 .env,命中则 block 并把原因告诉 Claude。| 字段 | 所有事件 |
|---|---|
session_id | 当前会话 ID |
transcript_path | 完整对话记录文件路径 |
PreToolUse 和 PostToolUse 额外携带:tool_name:工具名称(Write、Bash、Edit 等)tool_input:工具入参,结构随工具类型变化(比如 Write 包含 file_path 和 content)tool_response(仅 PostToolUse):工具执行结果mcp__[服务器名]__[工具名]。matcher 支持正则,可以批量匹配一个服务器的所有写操作:{
"matcher": "mcp__.*__write.*",
"hooks": [{ "type": "command", "command": "/scripts/validate-mcp-write.py" }]
}// .claude/settings.json
{
"permissions": {
"allow": ["Bash(git:*)", "Bash(npm:*)"]
},
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "say 'Claude has finished'"
}
]
}
]
}
}/hooks 命令里也可以交互式配置,不需要手写 JSON。添加 Stop 通知,然后把 Claude Code 分配给一个耗时任务,自己去做别的事——这比「什么是 PreToolUse 的 JSON schema」更快让你感受到 Hooks 的价值。--dangerously-skip-permissions 慎用:在自动化脚本里跑 Claude Code 时经常会用到这个标志来绕过所有权限确认,风险较高,务必配合 permissions.allow 白名单使用,而不是图省事什么都放行。2Stop 钩子的 stop_hook_active 字段:如果你在 Stop 钩子里触发了新的 Claude 操作,可能导致无限循环。官方文档里会在 Stop 事件的 stdin 携带 stop_hook_active 标记,用来检测当前是否已经在一次钩子触发的流程里。1decision: block 让 Claude 继续处理、或 Stop 钩子里触发了新任务,都会产生额外的 token 消耗。docs.anthropic.com/en/docs/claude-code/hooks,生命周期事件的 stdin 数据结构和 JSON 输出 schema 都在里面,写复杂拦截脚本前值得读一遍。
Customize and extend Claude Code's behavior by registering shell commands to execute at key points in Claude's lifecycle.
Add more perspectives or context around this Drop.