2m read
Agent 防遗忘 Hook 机制
agentclaude-codehooks
Prompts are soft constraints — once the context gets long, the model starts ignoring rules you've repeated a hundred times. Hooks fix that by enforcing at the event level: this post shows three concrete hooks (auto-format after Edit/Write, block rm -rf with exit code 2, desktop notification on task end) and when to graduate a rule from CLAUDE.md to a hook.
模型的提示词是软约束。上下文一长,规则优先级会被稀释,导致格式化要求、安全约束逐渐被忽略。
Hook 是 Claude Code 的强制执行层,补这个缺口。
四层能力模型
| 层级 | 类型 | 约束力 |
|---|---|---|
| 提示词(Prompts) | 软约束 | 弱 |
| Hook | 强制执行 | 强 |
| 工具(Tools) | 功能扩展 | — |
| MCP 服务器 | 外部集成 | — |
Prompt 是提示,Hook 是强制执行。在 Agent 生命周期关键节点挂上外部 Shell 脚本,脚本返回退出码,Agent 据此决定下一步。常见事件类型:
| 事件类型 | 触发时机 | 典型用途 |
|---|---|---|
| Pre Tool Use | 工具执行前 | 拦截危险命令 |
| Post Tool Use | 工具执行后 | 自动格式化 |
| Stop | Agent 任务完成 | 桌面通知 |
示例
自动格式化(Post Tool Use)
CLAUDE.md 里反复强调"代码要格式化"效果有限。直接在 Hook 里配置:每次 Edit 或 Write 之后跑 prettier。
hljs json{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "prettier --write ${CLAUDE_TOOL_INPUT_FILE_PATH}"
}
]
}
}
提示词里再提格式化就是多余的,Hook 一定会跑。
危险命令拦截(Pre Tool Use)
防止 Agent 跑 rm -rf。Pre Tool Use Hook 匹配 Bash 命令,命中危险模式直接返回 退出码 2。
hljs json{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"command": "if echo \"$CLAUDE_BASH_COMMAND\" | grep -qE 'rm .*-rf|sudo rm'; then exit 2; fi"
}
]
}
}
退出码规则:0 放行,1 放行但警告,2 直接拒绝。
任务结束通知(Stop)
构建、测试这类慢任务跑完,Stop 事件触发桌面通知,避免错过。
hljs json{
"hooks": {
"Stop": [
{
"command": "osascript -e 'display notification \"Claude 任务完成\" with title \"Claude Code\"'"
}
]
}
}
使用原则
- 只做确定性动作,能写成固定 Shell 脚本、每次都必须执行的事
- Hook 不可以滥用,只有提示词反复失效的时候才考虑
- 转换信号,某条规则在 CLAUDE.md 里强调了三次还被忽略,就值得改成 Hook
- 保持简单,一个 Hook 干一件事,脚本不要写太多