有意思的是,你精心写的每一行指令,在AI眼里都可能只是一句“建议”。
你的CLAUDE.md里写得清清楚楚:永远不要修改生产配置文件。结果呢?某天下午,AI真的就打开了那个文件,还改了里面的连接字符串。你没看错。它违反了你定下的规则,而且毫无心理负担。
这不是AI不听话的问题。这是概率性的本质问题。
概率性不是bug,是特性
每个LLM都这样。你喂进上下文窗口的所有内容——CLAUDE.md、技能定义、项目规则——说到底,都是建议。它们在上下文里和其他内容争夺模型的注意力。会话越长,规则被忽略的概率越高。
你可能想:那我写清楚点呗。
没错,写清楚是有用的。在我的另一篇文章里我详细讲过怎么把领域知识编码进Agent的上下文,那确实是最有效的手段之一。但再怎么有效,也改不了一个事实:指令永远不是确定性的。
没有模型能保证它在每一次对话中都严格遵守你写的规则。不是它不想,是它的架构决定了它做不到。
那怎么办?
这就是hooks登场的地方
Claude Code的hooks机制,是为这个概率性世界增加了一层确定性。
它们不是智能的。它们是死板的。
hooks是你在Agent生命周期各个节点插入的脚本、HTTP端点或LLM提示。当某个事件触发时,它们自动执行,拦截Agent当前的操作,决定是否允许它继续。
核心概念就这么几个:事件(什么时候触发)、匹配器(什么条件下触发)、处理器(做什么)。
比如说,你想阻止AI执行rm -rf命令。你在PreToolUse事件上挂一个Bash匹配器,再挂一个shell脚本。脚本检查命令是否包含rm -rf,如果是,返回deny。完事。
这不是概率性的。是硬规则。
Claude Code目前支持的事件有几十个,几乎覆盖了整个会话生命周期:
• SessionStart:会话开始或恢复• UserPromptSubmit:你提交提示时• PreToolUse:工具调用执行前(这是最常用的拦截点)• PostToolUse:工具调用成功后• Stop:AI结束响应时• SessionEnd:会话终止时
每个事件点都可以插hooks。这意味着你能在Agent做任何事之前,把它拦下来查一查。
用hooks搭一个安全护城河
说几个实用场景吧。
场景一:阻止对敏感路径的写操作
你的项目有个secrets/文件夹,里面存的都是生产密钥。AI绝对不能碰。你可以在PreToolUse事件上贴一个hooks,匹配Edit工具,检查文件路径是否包含secrets/。如果是,直接拒绝。
场景二:强制执行CI/CD策略
你的CI/CD管道要求每次提交的代码都必须通过lint检查。你可以用一个PostToolUse hooks,在AI写完代码后自动跑一遍lint。跑不过?告诉Agent重写。
场景三:审计日志
把每一个Bash工具调用的命令记录到审计日志里。方便事后复盘,也方便排查问题。
你发现了吗?这些场景有一个共同点:规则不是“最好遵守”的,而是“必须遵守”的。传统的方法——那些靠上下文窗口承载的规则——做不到这一点。
hooks做了AI自己做不到的事:在自己有权限做坏事之前,被自己拦下来。
确定性的代价
当然,hooks不是完美的。
首先,你得写脚本。这不是零配置的东西。每一个hook都是你手动写、手动配的,这意味着你需要投入工程时间。
其次,hooks是命令阻塞的。如果hook脚本写得慢,Agent的响应时间会受拖累。对用户体验敏感的场景,这需要优化。
第三,匹配器只能是精确字符串或正则。如果某天AI学会了奇技淫巧绕过规则——比如用find . -delete代替rm -rf——你的hooks可能就拦截不到了。
但这些都是工程问题。可解。真正不可解的问题是:你的规则到底能不能被100%执行?
在纯指令世界,答案是“不能”。在hooks世界,答案是“能”——只要你愿意为确定性付出代价。
不只是Claude Code
有意思的是,这个思路不是Claude Code独有的。
Cursor IDE提供了类似的机制,叫“Agent Rules”。JetBrains的Fleet也在做。本质上,大家都在往同一个方向走:给AI代理加一个运营层,让确定性覆盖概率性的盲区。
为什么?因为随着AI编码工具越来越强大,它们能做的事越来越多。能做的越多,能犯的错也越多。企业级应用不会容忍那些错。hooks这个设计模式,恰恰是用最笨的方法解决最聪明的问题。
好吧,其实也没那么笨。它把AI的“智能”和环境的“安全”解耦了。智能决定什么时候做什么,安全决定什么事不能做。两个系统各司其职。
护城河自己挖
AI编码工具正以每个月更新一代的速度在进步。我们的职责不是阻止它进步,而是确保它进步的时候,不会把我们的生产线一起冲垮。
hooks就是那道护城河。
你不是要写最完美的指令。你要在护城河的那一头,确保AI翻不过墙的意思不是碰运气,而是硬规则。
这是工程。不是祈祷。
觉得有用,点个「在看」❤️
夜雨聆风