METAL LAB

Claude Code的钩子机制,用代码堵住规则漏洞

Anthropic在Claude学院第5讲中公开了如何配置钩子事件,以强制执行CLAUDE.md规则

Claude Code的钩子机制,用代码堵住规则漏洞

摘要

  • Anthropic在Claude学院第5讲中介绍了Claude Code的钩子功能
  • 钩子是在重复执行循环的固定节点上运行的确定性代码,能让CLAUDE.md规则被无条件执行
Claude Code Hooks: Turn "Usually Follows" Into "Cannot Skip"

让Claude从"通常遵守规则"变成"必须遵守规则"

Anthropic官方网站

CLAUDE.md规则文件用虚线箭头指向Claude Code,Claude Code到工具执行之间的实线箭头上,有一个虚线圆圈表示的钩子检查关卡。关卡内有代表代码的尖括号符号,表示一旦违反规则,执行就会被拦截。CLAUDE.md规则文件用虚线箭头指向Claude Code,Claude Code到工具执行之间的实线箭头上,有一个虚线圆圈表示的钩子检查关卡。关卡内有代表代码的尖括号符号,表示一旦违反规则,执行就会被拦截。

用过Claude Code的开发者大概都有过这种感受:写在CLAUDE.md里的规则,Claude有时会遵守,有时却会跳过。正如这期视频标题所说,钩子这个工具能把Claude"通常会遵守"的规则,变成"无法绕过"的强制流程。

CLAUDE.md规则原本没有强制力

正如《卡帕西对LLM编程的批评,被一份CLAUDE.md文件解决了》一文所述,CLAUDE.md是把"禁止假设""最小化代码""最小化修改""成功标准"等原则整理进一份文件、用来指示Claude Code的方式。但这份文件终究只是Claude参考的指南,视具体情况而定,Claude仍有可能遗漏或绕开其中的规则。这期第5讲要解决的,正是用钩子来补上这个漏洞。

说得更直白一点:CLAUDE.md是开发者写给Claude Code、要求它遵守的规则文件,但Claude实际会不会照做,要看具体情况。而钩子则是把这些规则中必须遵守的部分用代码钉死,一旦Claude要违反规则,系统就会自动拦截或修正。

什么是钩子

钩子是在Claude Code反复执行的循环中、于特定节点触发运行的确定性代码。"确定性"意味着只要条件相同,行为结果就永远一致——这样即便没有人在旁边盯着执行过程,预先设定好的规则也不会被漏掉,而是会被强制执行。

常用的7种事件

事件触发时机主要用途
pre_tool_use工具调用之前允许、拒绝或确认高风险命令
post_tool_use工具调用成功之后自动格式化、代码检查
stopClaude打算结束任务时未满足条件时拒绝结束
subagent_stop子代理结束时将与stop相同的信号应用于子代理
pre_compact / post_compact压缩前后检查压缩过程
instructions_loaded加载CLAUDE.md等规则文件时审查实际进入上下文的内容
session_start会话开始时准备环境、在压缩后重新注入上下文

视频特别指出,如果想在压缩后重新注入上下文,应该用带有compact匹配器的session_start,而不是post_compact。

决定结果的退出代码

代码含义备注
0成功标准输出若为JSON会被解析;纯文本大多会被忽略,但在session_start、user_prompt_submit、user_prompt_expansion中会被加入上下文
1看似出错但不会阻断Claude会照常执行命令
2阻断性错误标准错误信息会作为上下文传给Claude,在几乎所有事件中都起到阻断作用(唯一例外是worktree_create,只要不是0都会中止)

pre_tool_use钩子会返回JSON,在permission decision字段中填入allow、deny、ask三者之一。虽然还有第四个值defer,但它只在非交互式的-p执行模式下、调用进程需要暂停工具再稍后恢复的特殊情况下才会用到。

两个实战案例

以隐藏敏感信息为例:在pre_tool_use钩子中,用匹配器指定bash工具,再用if语句缩小到特定命令,然后不返回deny,而是返回updated_input。这样一来,命令不会被整体拦截,只是把包含密码的部分抹除后继续执行。不过要注意,updated_input会替换整个输入对象,所以即便是不需要修改的字段,也必须原样放回去一并返回。

当对话变长、Claude执行压缩时,大量细节会随之丢失。这时带有compact匹配器的session_start钩子会在压缩完成后立即运行,把正在处理的文件的简短摘要重新放回上下文里。有了这份摘要,Claude就能接着做原本的工作,而不用从压缩前的状态重新开始。

编辑视角

如果说自动模式(auto mode)的变化,是让Claude在无需每次都获得批准的情况下持续行动,那么钩子就是与之配套的另一半——确保这份新扩大的自主权,唯独不能触碰某些特定规则。可以说,Anthropic正在朝着这样一个方向打磨Claude Code:既让它快速自主运作,又把该守的底线交由代码而非人工监督来划定。

"用一份CLAUDE.md文件整理规则"这种做法刚成为潮流没多久,现在又出现了把这些规则从"遵守更好"提升到"必须遵守"的机制。只配备了CLAUDE.md规则文件的团队,哪怕只接入一个pre_tool_use,也能立刻感受到高风险命令在执行前就被拦下的效果。

国内开发团队在引入Claude Code时经常遇到的抱怨是"它有时候会跳过规则",而这期讲座给出的答案是:先从pre_tool_use和stop这两个事件入手。与其一次性把多达30种事件全部用上,不如先设置好拦截危险命令的pre_tool_use、检查任务完成条件的stop,以及在压缩后恢复上下文的session_start这三项,就足以实际减少不少事故。

评论