8.1 Hooks 的设计哲学

AI 是概率性的,这是它的本质
你在 CLAUDE.md 里写:"提交前必须跑 lint"。
Claude Code 看到这条规则,大概率会遵守。但"大概率"不是"一定"——它可能判断某次提交太小不值得跑,可能上下文太长忘记了这条规则,可能就是出了个什么幺蛾子。
这不是 bug,这是 LLM 的本质特性:它是概率性的,不是确定性的。
对于"写出好代码"这类任务,概率性没问题——偶尔的小偏差你 review 一下就发现了。
但对于"提交前必须跑 lint"、"不能修改 .env 文件"、"每次文件改动都要记录日志"这类必须百分之百执行的规则,概率性就不够用了。
这就是 Hooks 存在的理由。
Hooks 是确定性的
Hook 是一个 shell 命令,在 Claude Code 的生命周期特定时间点强制执行。
不管 AI 做了什么判断,不管上下文里有没有相关规则,只要事件触发,Hook 就跑。
Claude Code 不能"选择"不执行 Hook,就像你的 git pre-commit hook 不管你愿不愿意都会跑一样。
三种机制的本质区别
学到这里,你手里有三种影响 Claude Code 行为的方式,它们的本质完全不同:
| 机制 | 本质 | 可靠性 |
|---|---|---|
| CLAUDE.md | 给 AI 看的文字指令 | 概率性,AI 可能不遵守 |
| Skills | 给 AI 看的工作流程 | 概率性,AI 可能走偏 |
| Hooks | 强制执行的 shell 脚本 | 确定性,一定执行 |
不是说 CLAUDE.md 和 Skills 没用——它们对于引导 AI 的判断非常有效。但对于不允许出错的规则,只有 Hooks 才能真正保证。
什么时候用 Hooks
用 Hooks 的场景:
- ✅ 必须 100% 执行的操作(格式化、lint、保护文件)
- ✅ 和 AI 判断无关的纯机械操作(记录日志、发通知)
- ✅ 安全边界(阻止某些危险操作)
- ✅ 上下文压缩后的信息恢复
不需要用 Hooks 的场景:
- ❌ 需要 AI 判断的操作("如果代码质量差就拒绝提交"——这需要理解,不是规则)
- ❌ 偶尔为之的任务(一次性的操作用 Skill 就够了)
- ❌ 已经用 CLAUDE.md 写了且 AI 一直遵守的规则(没必要重复保障)
一个帮助判断的问题
每次考虑要不要写 Hook 时,问自己:
"如果 Claude Code 这次没做这件事,会发生什么严重后果?"
如果答案是"会有 bug 漏进代码库"、"敏感文件可能被修改"、"团队收不到通知"——写 Hook。
如果答案是"有点不方便,但不严重"——CLAUDE.md 就够了。
下一节,我们来看 Hooks 的四种事件类型,以及如何用它们控制 Claude Code 的每个关键时间点。
