
2026 年 4 月,开发者圈流传过一起事故:一家做车辆租赁管理系统的公司 PocketOS,创始人让 AI 编程工具处理 staging 环境的凭证问题,AI 却在一个不相关的文件里找到了云平台 token,直接调用删除存储卷的接口,几秒钟内生产数据库连同备份一起没了。事后复盘,AI 自己承认了两条错误:没有验证就猜测,没被要求就执行了不可逆操作。
这类事故靠在 prompt 里多写几句“不要删库”是防不住的。Claude Code 给出的办法是 Claude Code Hooks:在 Claude Code 生命周期的固定节点挂上你自己的脚本,由代码而不是模型来决定一个操作能不能执行。
如果你已经在用 Claude Code,并且开始让它跑自动模式,这篇值得读一读。下面依次讲 Hooks 的工作方式、三个最实用的护栏(拦截危险操作、编辑后自动格式化、压缩后补回上下文),再介绍 prompt 类型和 MCP 工具类型的 hook,最后是几条容易踩的坑。

Claude Code Hooks 是什么
官方文档的定义是:在 Claude Code 生命周期的特定节点自动执行的、用户自定义的 shell 命令、HTTP 端点或 LLM prompt。实际用起来,它主要做两件事:
- 拦:模型准备执行某个操作,脚本判定不行,这个操作就不会发生;
- 补:模型做完一件事,脚本接着补上后续步骤,比如格式化代码、记日志、发通知。
它和 prompt 约束的区别在于确定性。CLAUDE.md 里的规则,模型在长对话或边缘情况下可能会忽略;hook 是代码层面的判断,PreToolUse 脚本只要以退出码 2 结束,这次工具调用就会被阻止,跟模型听不听话无关。
Hooks 事件有 30 多个,先掌握 5 个
截至 2026 年 10 月,官方文档列出的 Hooks 事件已经超过 30 个(原文写作时是 28 个),按触发频率大致分三档:
- 每个会话一次:
SessionStart、SessionEnd; - 每个回合一次:
UserPromptSubmit、Stop等; - 每次工具调用:
PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest等。
另外还有子 Agent、任务、上下文压缩、文件变化等专用事件。日常配置先掌握下面 5 个就够用:
| 事件 | 触发时机 | 常见用途 |
|---|---|---|
PreToolUse | 工具执行前 | 拦截操作、修改参数 |
PostToolUse | 工具执行后 | 格式化、日志、通知 |
SessionStart | 会话开始、恢复或压缩后 | 注入上下文 |
PreCompact | 上下文压缩前 | 保存关键信息 |
Notification | Claude 需要你确认时 | 桌面通知,不用一直盯终端 |
其余事件用到时再查官方参考文档。

护栏一:用 PreToolUse 拦截危险操作
开头那起事故,缺的正是一道 PreToolUse 拦截。官方文档的第一个示例就是拦截递归强制删除这类破坏性命令。配置写在 ~/.claude/settings.json 或项目内的 .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(YOUR_DANGEROUS_CMD *)",
"command": "bash .claude/hooks/guard.sh"
}
]
}
]
}
}
把 YOUR_DANGEROUS_CMD 换成你想拦的命令前缀即可。guard.sh 的逻辑很简单:从标准输入读取 hook 传来的 JSON,取出 tool_input.command,如果命中你列出的危险模式(递归删除目录、清空数据表、强制推送等),就把原因写到标准错误输出并以退出码 2 结束;没命中就以退出码 0 放行。
几个细节:
matcher匹配工具名,if再匹配具体命令。 只有命中前缀的 Bash 命令才会启动脚本,跑测试这类普通命令不会进来,省掉每次起进程的开销。- 拦截有两种写法。 一种是以退出码 0 结束,同时输出带
permissionDecision: "deny"的 JSON;另一种是直接以退出码 2 结束。官方文档写得很明确:只有退出码 2 是“阻止”信号,其他非零退出码只算非阻塞错误,操作照样执行。不少人习惯写退出码 1,这样是拦不住的。
同样的思路可以用来保护文件,官方示例叫 “Block edits to protected files”:PreToolUse 的 matcher 设为 Edit|Write,脚本检查 tool_input.file_path,路径落在环境变量文件、锁文件或数据库文件上就以退出码 2 拒绝。
hook 只是其中一层防线,云平台 token 的权限范围、生产环境的删除保护同样要收紧。关于 AI 编程工具的隔离边界,可以参考 AI 编程工具的沙箱不是完整安全边界。
护栏二:PostToolUse 编辑后自动格式化
这个 hook 配置一次就能一直省事:Claude 每改一个文件,格式化工具就跑一遍。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/format.sh"
}
]
}
]
}
}
format.sh 读取 tool_input.file_path,按扩展名分发:TS/JS 用 Prettier,Python 用 ruff format,Go 用 gofmt。这样 Claude Code 产出的代码始终是格式化过的,review 时不用再为缩进来回改。
另外,PostToolUse 和 PostToolUseFailure 的输入里有 duration_ms 字段,记录工具执行耗时(不含权限确认和 PreToolUse hook 的时间)。想知道哪些工具调用最慢,把它写进日志就能统计。
护栏三:上下文压缩后自动补回关键信息
长会话跑到一半上下文满了,Claude Code 会自动压缩(compact),把之前的对话浓缩成摘要。压缩之后模型经常“失忆”,项目规范、包管理器、手头的任务都可能忘掉。
解决办法是给 SessionStart 配一个 compact matcher:
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use pnpm, not npm. Run tests before commit.'"
}
]
}
]
}
}
SessionStart hook 输出到标准输出的文本,会作为上下文重新交给 Claude。除了固定提醒,也可以换成脚本,输出最近的提交记录、当前分支、未完成的 TODO 等动态信息。

进阶:prompt hook 和 MCP 工具 hook
除了 shell 命令,Hooks 还支持 http、prompt、agent 和 mcp_tool 几种类型。
prompt hook 把判断交给 LLM,适合规则写不死、但模型能判断的场景,比如提交前检查有没有硬编码的密钥。按官方当前文档,模型要返回 {"ok": true/false, "reason": "..."} 结构的 JSON,在 PreToolUse 上返回 ok: false 时会拒绝这次工具调用:
{
"type": "prompt",
"if": "Bash(git commit*)",
"prompt": "Check whether the pending commit includes hardcoded secrets or API keys. Input: $ARGUMENTS. Return ok=false with a reason if it does."
}
$ARGUMENTS 会被替换成 hook 的输入 JSON,prompt hook 默认超时 30 秒。
MCP 工具 hook 在事件触发时直接调用已配置 MCP server 上的工具,server 和 tool 两个字段必填,input 里可以引用工具输入中的字段:
{
"type": "mcp_tool",
"server": "my_server",
"tool": "security_scan",
"input": { "file_path": "tool_input.file_path 的值" }
}
注意,会话启动时的 SessionStart 触发在 MCP server 连接之前,这时 mcp_tool hook 会被跳过。启动阶段要用的逻辑请改用 command 类型。
如果不想手写 JSON,Claude Code 官方插件里的 hookify 能用自然语言生成规则,安装方法见 Claude Code 官方插件使用教程。
限制与注意事项
- 超时不会拦截:
PreToolUse上的 command、http、mcp_tool hook 超时后,工具调用不会被阻止,而是走正常的权限流程。想让失败也拦截,要设置onFailure: "block"。 PermissionRequest不认退出码 2:这个事件要返回 decision 对象来拒绝。- 字符串匹配有盲区:只按命令前缀匹配,换个参数顺序或者通过脚本间接执行就可能漏掉,生产环境一定要配合最小权限凭证。
- 示例未实测:以上配置整理自原文和官方文档,上线前先在测试项目里验证。
总结
AI 编程工具的护栏要写成代码,光写在 prompt 里不够。CLAUDE.md 里的规则可能在边缘情况下被忽略,hook 装上之后每次都会执行,也不会因为上下文太长被压缩掉。如果你用 Claude Code 超过一个月还没写过 hook,可以先从危险操作拦截和自动格式化这两个开始。
想在国内网络环境下直接使用 Claude Code 和 Codex,可以先在 AIGoCode 上完成接入,再配置这些 Hooks。
参考链接
- Hooks 官方参考文档:https://code.claude.com/docs/en/hooks
- Hooks 快速上手指南:https://code.claude.com/docs/en/hooks-guide