Claude Code Hooks 与 CLAUDE.md 指令:各自管什么
Claude Code hooks 与 CLAUDE.md 指令怎么分工:哪些规则必须做成 PreToolUse / PostToolUse hook,何时提示词就够,附三轴决策表。
更新于
一条规则必须每次都成立、而且程序能检查它,就用 Claude Code hook;一条规则属于偏好、需要判断,或者只有模型才能评估,就用 CLAUDE.md 指令。CLAUDE.md 是概率性的引导,模型可以推翻它;hook 是在工具调用之前或之后运行的代码,能确定性地拦截、修改或转换这次调用。
提示词强制 vs 程序化强制——就这一个区分,是 Claude Certified Architect – Foundations 考试里考得最重的概念之一。它归在领域 1(Agentic Architecture & Orchestration,27%)的 hooks 与强制执行部分,只要情景涉及 CLAUDE.md,它也会渗进领域 3。
CLAUDE.md 指令写得很清楚,为什么还会失效?
不是模型读错了。它失效的方式是:模型在具体上下文里判断这条指令不该适用。学习材料里的生产案例:“rm/drop/truncate 之前务必确认”,用户说”把项目清理一下”时就被跳过了,因为确认显得多余;“访问账户前先验证身份”,客户主动报了账号就被跳过了;“跑完整测试套件”,时间紧的时候变成”跑单元测试”。实测漏掉的比率在 4–15% 之间,措辞加重(“MANDATORY""UNDER NO CIRCUMSTANCES”)几乎不起作用,因为失败源于判断,不是理解。
考试把这个叫”主动推翻”问题。某数据集里 11% 的折扣上限违规拆开看:5% 是认错了客户等级(可修的 bug),6% 是模型正确识别了等级、然后为了安抚一位不满的客户选择超额。后一半没有任何提示词能修。参见模型会在 4-15% 的情况下无视你的指令。
Hook 究竟能做什么?
Claude Code 和 Agent SDK 暴露五个生命周期 hook,其中两个是强制执行的落点。
| Hook | 触发时机 | 能做 | 不能做 |
|---|---|---|---|
| SessionStart | 启动时一次 | 加载配置、预置上下文 | 逐次调用检查 |
| UserPromptSubmit | 每条用户消息 | 注入上下文、清洗输入 | 触碰工具调用 |
| PreToolUse | 工具运行前 | 拒绝、放行,或修改输入后放行 | 转换输出 |
| PostToolUse | 工具运行后 | 标准化、脱敏、记录结果 | 阻止执行 |
| SessionEnd | 关闭时 | 清理、归档 | 会话中途的任何事 |
拦截破坏性 shell 命令的最小 Claude Code 配置,写在 .claude/settings.json 里长这样:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "python .claude/hooks/block_destructive.py" }
]
}
]
}
}
脚本从 stdin 读取 JSON 格式的工具调用,输出一个决定。三种合法结果:
{ "hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "rm -rf outside /tmp is blocked. Move the target to /tmp/trash instead." } }
{ "hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": { "file_path": "/sandbox/src/main.py" } } }
什么都不返回(或返回空对象)表示”原样继续”。坏掉的 hook 大多是两个 bug 造成的:在 if 里打印一句 “Blocked!” 然后落到空返回,结果永远放行;返回了 updatedInput 却没有显式的 allow,被静默忽略。合法值只有 deny 和 allow;block、reject、抛异常都不算,异常还可能默认放行。每次 deny 都给模型一个理由和一条替代路径,它才会走替代方案而不是盲目重试。完整细节见 PreToolUse 返回值:deny、allow、modify——以及它们之间的 bug和五种 Hook 类型覆盖完整会话生命周期。
matcher 是正则、按子串匹配,所以 update 会匹配到 get_status_update。强制类 hook 要加锚点(^update_account$),还要记得 MCP 工具带前缀(mcp__payments__process_refund),光写 process_refund 会把 MCP 版本放过去。只有审计日志之类的全局关注点才省略 matcher。参见 HookMatcher:精准匹配节省 40% Hook 处理时间。
什么时候一条规则必须做成 hook?三轴测试
学习材料把这个选择压缩成三个问题:
- **后果。**漏掉一次会不会造成法律、财务、安全或数据完整性影响?
- **可验证性。**代码能不能确定性地检查合规(正则、名单、阈值、路径)?
- **主观性。**规则是否需要判断(“要有同理心""观点要平衡”)?
后果高且可验证:hook。主观:提示词,不管后果多大,因为代码评估不了。后果低:提示词,因为造 hook 是过度工程。合规率不在这三轴之内。
| 规则 | 后果 | 可验证 | 主观 | 机制 |
|---|---|---|---|---|
| 拦截超过 500 美元的退款 | 财务 | 是 | 否 | PreToolUse hook |
CI 中禁止写 src/ 之外的文件 | 数据完整性 | 是(路径检查) | 否 | PreToolUse hook |
| 从工具输出中脱敏 SSN | 法律 | 是(正则) | 否 | PostToolUse hook |
| 时间戳统一为 ISO 8601 | 正确性 | 是 | 否 | PostToolUse hook |
| 记录每次工具调用供审计 | 合规 | 是 | 否 | Pre + Post,不带 matcher |
| 公开 API 函数加输入校验 | api/public/ 下属安全,其他地方属建议 | 是 | 否 | 按路径区分的上下文感知 hook |
| 使用 camelCase | 风格 | 是 | 否 | CLAUDE.md |
| 遵循建议的报告大纲 | 格式 | 部分 | 部分 | CLAUDE.md |
| 用专业、有同理心的语气 | 质量 | 否 | 是 | CLAUDE.md |
| 度量单位换算成公制 | 取决于受众 | 是 | 是 | CLAUDE.md |
有两行值得说明。时间戳和货币有客观的换算规则,所以 PostToolUse hook 是对的,某次部署里日期比较错误从 12% 降到了 0.3%。度量单位取决于上下文(面向美国市场的报告可能有意用英制),所以即使换算本身是机械的,它仍然留在提示词里。参见按后果和可验证性选择,不是按合规率和 PostToolUse 标准化:日期错误从 12% 降到 0.3%,Token 减少 90%。
hook 加指令不是重复吗?
不是,考试很喜欢考这一点。一个拦截生产部署的 hook,和 CLAUDE.md 里一句”未经人工批准不得部署到生产”,干的是两件事。hook 保证结果。指令减少尝试次数,让模型主动去请求批准,而不是一头撞墙。两者一起是纵深防御:hook 确定性地抓已知模式,提示词是正则漏掉的新情况的概率网。删掉任何一个,系统都会变差。
过度使用 hook 呢?
反方向的失败模式也真实存在。有个团队在几次事故之后把什么都做成了 hook:引用格式、字数、段落长度、用词。每份报告触发十几次拒绝,大多是风格问题,一段 501 个词的内容就逼着重写,生产时间翻了三倍。修法是 hook 只留给合规项(来源核实、引用准确性),风格挪回 CLAUDE.md。
相关的纪律:先诊断,再迁移。如果”提交前先测试”的合规率从 97% 掉到 82%,先问为什么。如果模型在推理”这么小的改动不需要测试”,那是判断失误,值得上 hook。如果只是这条指令被埋在一份长得失控的 CLAUDE.md 里,重构文件是更便宜的修法。本站的 CLAUDE.md 怎么写一文讲的是这个决策里文件那一侧。
考试到底在考什么?
CCA-F 这一块的题目,几乎总是给你一条以某个比例被违反的规则,再给四个应对:把指令措辞写得更强硬、加重试、加 hook、加 hook 并删掉指令。得分的推理是:识别后果,检查代码能否验证,对高后果且可验证的规则选确定性机制,主观和低风险的规则留作提示词引导。也要认得几种干扰模式:拿 PreToolUse 做输出脱敏(不可能,输出还不存在)、拿 SessionStart 做逐次校验(只触发一次)、用一个”更简单”的大一统 hook(关注点混杂,且每次调用都触发),以及”有了 hook 指令就多余了”。
下一步
先过一遍领域 1 学习指南里 hooks 与强制执行的文章(任务 1.4 和 1.5),再做领域 1 练习题,看看三轴测试在情景题里是怎么伪装的。准备好了就去做免费的 60 题模拟考,领域 1 按官方 27% 的权重出题。125 美元报名费、120 分钟形式等考试信息,报名前请到 Anthropic / Pearson VUE 官方页面核对。
常见问题
加了 hook 之后,要不要删掉 CLAUDE.md 里对应的那条指令?
expand_more
通常两个都留。hook 是确定性的安全网;指令能减少模型尝试被拦动作的次数,也就是更少的拒绝、更顺畅的会话。提示词里的一行字几乎不花什么成本。
PreToolUse hook 能改工具写出来的内容吗?
expand_more
它能在执行前修改工具的输入,比如把文件路径改到沙箱目录,方法是返回 permissionDecision: allow 加 updatedInput。它碰不到输出,因为输出那时候还不存在;那是 PostToolUse 的活。
为什么考试说一条合规率 99% 的规则仍然需要 hook?
expand_more
因为选机制看的是后果,不是比率。数据隐私规则漏 1% 就是法律事故;用客户名字打招呼漏 4% 什么事都没有。合规率本身从来不决定用哪种机制。
动手练起来
做一套免费 60 题 Claude Certified Architect 模拟考,或按领域逐个啃 CCA-F 学习指南。
Certified Architect 是社区独立搭建的备考站点。文中考试信息来自 Anthropic / Pearson VUE 的公开资料,随时可能调整,报名前请以官方页面为准。