
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.
このコンテンツについて、さらに観点や背景を補足しましょう。