
摘要
- Anthropic在Claude学院第5讲中介绍了Claude Code的钩子功能
- 钩子是在重复执行循环的固定节点上运行的确定性代码,能让CLAUDE.md规则被无条件执行
让Claude从"通常遵守规则"变成"必须遵守规则"
用过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 | 工具调用成功之后 | 自动格式化、代码检查 |
| stop | Claude打算结束任务时 | 未满足条件时拒绝结束 |
| 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这三项,就足以实际减少不少事故。





评论