Hooks 系统
用 Hooks 在 Claude Code 生命周期中自动执行自定义逻辑
Hooks 是 Claude Code 的生命周期脚本。它适合做确定性的项目规则,例如格式化、审计命令、阻止敏感文件读取,而不是再让模型临场猜应该怎么处理。
常用事件
| 事件 | 触发时机 | 常见用途 |
|---|---|---|
SessionStart | 会话开始或恢复 | 注入本机上下文、检查环境 |
UserPromptSubmit | 用户提示词提交后 | 拦截敏感请求、补充上下文 |
PreToolUse | 工具执行前 | 阻止危险命令、要求确认 |
PostToolUse | 工具执行后 | 自动格式化、记录审计日志 |
Notification | Claude 需要通知用户 | 桌面提醒、IM 通知 |
Stop | 主 Agent 完成响应 | 收尾检查、总结状态 |
SubagentStop | 子 Agent 完成响应 | 汇总子任务状态 |
PreCompact | 上下文压缩前 | 保存关键信息 |
具体事件会随 Claude Code 版本扩展,最终以 /hooks 菜单和官方文档为准。
配置结构
Hooks 写在 settings.json 的 hooks 字段下。每个事件对应一个数组,数组里可以配置 matcher 和真正执行的 hooks。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/format-written-file.py"
}
]
}
]
}
}注意这里是内层的 "hooks" 数组,不是旧版草稿里常见的单个处理器对象。
交互式配置
在 Claude Code 中输入:
/hooks它会打开交互式菜单,帮你选择事件、matcher 和命令。对团队项目来说,先用 /hooks 生成,再把最终配置整理到项目级 .claude/settings.json,比手写整段 JSON 更稳。
Command Hook
当前最常用、也最容易版本兼容的是 command hook:
{
"type": "command",
"command": "python3 .claude/hooks/check-bash.py"
}Hook 命令会通过 stdin 收到一段 JSON,里面包含事件名、工具名、工具输入等上下文。复杂逻辑建议放进脚本里解析 JSON,不要把很长的 shell 管道塞进 settings.json。
Matcher
matcher 用来限制 Hook 对哪些工具生效:
"Bash":匹配 Bash 工具"Edit|Write":匹配编辑和写入"Read|Grep|Glob":匹配只读工具"mcp__github__.*":匹配某个 MCP server 的工具
PreToolUse 和 PostToolUse 通常需要 matcher;会话类事件可以不写 matcher。
示例
写文件后格式化
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/format-written-file.py"
}
]
}
]
}
}脚本里可以从 stdin JSON 取出被写入的文件路径,只对支持的后缀运行格式化器。这样比依赖 $FILE 这类隐式环境变量更可靠。
执行命令前审计
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/check-bash-command.py"
}
]
}
]
}
}这类脚本适合阻止:
git push --forcerm -rf- 生产数据库迁移
- 上传
.env、私钥、证书 - 没有测试保护的发布命令
会话开始时检查环境
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/session-start.py"
}
]
}
]
}
}可以在这里检查 Node、pnpm、Python、当前分支、未提交改动等环境信息,再把结果打印给 Claude。
返回结果
不同事件支持的返回语义不完全一样。实务上可以按这个原则设计:
- 普通提示类 Hook:退出码
0表示通过,非零表示失败并把 stderr 交给用户或 Claude PreToolUse:可以阻断工具调用,适合安全策略- 需要精细控制时:优先使用官方支持的结构化 JSON 输出,而不是只靠 stderr 文案
Hook 是确定性自动化,不是权限系统的替代品。高风险操作仍然应该配合 permissions.deny、permissions.ask、沙盒和人工确认一起使用。