Claude Code Hooks 新手指南:8 个检查点怎么用
写给第一次配置 Claude Code Hooks 的新手:先讲它像什么、什么时候触发、第一条应该怎么配,避免用一堆脚本把自己绕晕。
预计阅读 16 分钟。看完你会知道 Hooks 在什么时候出手、能帮你挡什么风险、第一条应该怎么写,以及配多了会不会把工具拖慢。
这篇会给你能直接抄的配置,但更想讲清楚判断。新手真正卡住的地方,往往不是少了一段配置,而是不知道自己为什么要配、配多了会不会出乱子、出事时该先看哪里。
一、先讲清楚:Claude Code Hooks 是工具旁边的检查门
一句话先回答:Claude Code Hooks 是一组在固定时刻自动运行的命令——Claude 准备读文件、改文件、跑命令、结束回答之前或之后,检查门会先执行你设好的检查,决定放行、拦截,还是顺手记一笔。
要点速览
- Hooks 是「到点一定执行」的检查门,靠程序执行,不靠模型临场想起来。
- 新手只需先记两个点:动手前的
PreToolUse用来拦风险,动手后的PostToolUse用来提醒验收。 - 第一条 hook 放项目级、从最怕的那个动作出发;先 3 条以内,跑顺了再加。
- 配多了会拖慢 Claude,慢检查切异步、matcher 配精准。
把它理解成「检查门」比理解成「生命周期钩子(lifecycle hook)」容易记。钩子这个词听起来像开发框架,但你真正用它时,感受更像给自己装了几个固定动作:每次 Claude 想执行命令前,先看一眼有没有明显危险;每次它改完文件后,提醒你跑测试;每次会话开始,把项目规则重新塞回上下文。
它和提示词的根本区别是确定性。提示词像口头约定,你说「不要做危险操作」,Claude 多数时候会记得,但它终究是在理解你的话。Hooks 是程序,到那个时刻一定执行,不靠它临场想起来。Anthropic 官方文档对 Hooks 的定位也是这句话:它为 Claude Code 的行为提供「确定性控制,确保某些操作始终发生,而不是依赖模型选择去运行它们」。
🔥 翔宇判断:我的判断是,新手最该破除的误区,就是把 Hooks 当成「让 AI 更聪明」的开关。它不让 AI 更聪明,它让一部分关键动作变得更可控。这两件事差很远——想清楚,你就不会一上来配一堆花哨的自动化。
新手别一开始就追求「自动化很完整」。先让它解决一个你真的害怕的问题:你最怕 Claude Code 误删文件,那第一条 Hooks 就只盯危险命令;你最怕它改完忘测,那第一条就只提醒测试。先解决一个真实担心,比一次配十个高级动作有用得多。
二、新手为什么会需要 Hooks
先回答:当你开始让 Claude Code 真正动手改文件、跑命令,而不只是问它问题时,你就需要 Hooks 了。 因为「会动手」就意味着会有动手前后的风险,而你不可能全程盯着屏幕。
很多人第一次用 Claude Code 会经历一个微妙的阶段:它能干活,你很兴奋;它真的开始改文件、跑命令,你又有点不放心。你盯着终端,心里一直在想:它刚才要做的动作我看懂了吗?它会不会跳过我的要求?是不是已经改了什么我没注意的东西?
这种感觉很真实。你不是不信任工具,而是还没建立「哪里由人决定、哪里交给工具」的分界线。Hooks 的价值就在这里:它把一些分界线变成看得见的动作。你不用靠记忆提醒自己,也不用每次都重新叮嘱 Claude。
所以它最适合放在高风险、重复、容易忘的地方:危险命令、发布动作、写入线上配置、改完代码后的检查提醒,都属于这一类。至于「代码风格要自然」「回答要简洁」这种偏表达的要求,继续放在 CLAUDE.md(项目记忆文件)里就够了,不需要动用 Hooks。这两者怎么分工,下面第七节会专门讲。
三、八个常用钩子不用背,按时间顺序记
先给结论:新手不用记英文名,只要记住它们发生在「会话开始 → 你提问 → 工具动手前 → 工具动手后 → 收尾」这条时间线上的哪个点。 知道问题发生在哪一刻,就知道该配哪个钩子。
下面这张表按时间顺序排好了 8 个最常用的钩子。Claude Code 的生命周期事件目前已经扩展到几十个,但新手把这 8 个搞懂,足够覆盖绝大多数场景。
| 触发时刻 | 钩子(hook) | 干什么用 | 新手优先级 |
|---|---|---|---|
| 会话开始 | SessionStart |
补项目背景、提醒当前目录规则 | 中 |
| 你提交问题前 | UserPromptSubmit |
追加上下文,或挡住明显不合适的问题 | 低 |
| Claude 用工具前 | PreToolUse |
拦危险动作(最常用、最重要) | ⭐ 高 |
| 工具成功执行后 | PostToolUse |
提醒验收、自动格式化改过的文件 | ⭐ 高 |
| Claude 结束回答前 | Stop |
收尾检查,比如确认任务真做完了 | 低 |
| 子任务结束时 | SubagentStop |
子 agent(子智能体)跑完后的处理 | 低 |
| 压缩上下文前 | PreCompact |
上下文要被压缩前留住关键信息 | 低 |
| 会话结束时 | SessionEnd |
清理临时文件、收尾记录 | 低 |
你不需要一次用完它们。第一天只记住两类就行:动手前的 PreToolUse 用来挡风险,动手后的 PostToolUse 用来提醒检查。等这两个真的跑顺了,再考虑开场、收尾、压缩这些场景。
💡 通俗讲:
PreToolUse是门卫,在 Claude 出门干活前拦一下看证件;PostToolUse是验收员,等它干完活回来检查成果。新手先把这一进一出两个岗位安排好,其他岗位以后再说。
按时间顺序记还有一个好处:你能判断「我想解决的问题到底发生在哪一刻」。问题出在 Claude 动手前,就别去改收尾事件;问题出在改完之后没人提醒你验收,就别把规则塞进会话开场。很多配置错误,本质上是触发时机想错了。

四、第一条 Hooks 放在哪里、长什么样
先回答两个问题。放哪里:第一条放项目级,不要放全局。 长什么样:它是一段 JSON,按「事件名 → 匹配器(matcher)→ 一组命令」三层嵌套。
四个配置层级和它们的影响范围如下:
| 配置位置 | 影响范围 | 能否提交 git |
|---|---|---|
| 企业策略(managed policy) | 整个组织 | 管理员控制 |
~/.claude/settings.json |
你的所有项目 | 否(本机) |
.claude/settings.json(项目根) |
当前项目 | ✅ 可提交 |
.claude/settings.local.json |
当前项目 | 否(不进版本库) |
新手最稳的入口,是先用 Claude Code 里的 /hooks 命令看一眼当前注册了哪些 Hooks。这个命令是只读的——官方文档说得很清楚,/hooks 菜单只能查看,要添加、修改、删除得直接编辑设置文件——但它能让你先看清现状,少踩 JSON 写错的坑。
一条最简单的 hook 长这样。下面这段配置的意思是:每次 Claude 用 Edit 或 Write 工具改完文件后,自动跑一遍格式化。把它放进项目根目录的 .claude/settings.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
拆开看就三层:最外层 hooks 里按事件名分组(这里是 PostToolUse);每个事件下用 matcher 限定在哪类工具触发(Edit|Write 表示只在改文件后);最里层 hooks 数组写真正要跑的命令(这里用 jq 取出被改文件的路径,交给 prettier 格式化)。
为什么第一条要放项目级、而不是图省事写进全局?新手最容易把一个项目里的临时规则带到所有地方——某个项目要求每次改完都跑一个很慢的检查,写到全局,结果其他项目全被拖慢。项目级配置更容易观察,也更容易删;全局只该留非常稳定的个人习惯,比如统一的通知方式。
换个说法:全局配置适合稳定的个人习惯,项目级配置适合和项目强相关的约束——这个仓库的测试命令、这个内容库的发布检查、这个源码包不能写入哪些目录。先项目级,等你确认它适合所有项目,再上升到全局。

五、最小动作:先管危险命令
如果你不知道第一条该写什么,就从危险命令开始。原因不是它最酷,而是它最直观:Claude 准备跑命令前,hook 先看一眼命令内容,发现明显危险就拦下来。
hook 怎么「看到」命令?当事件触发时,Claude Code 会把这次操作的数据以 JSON 形式送进脚本的标准输入,里面有工具名 tool_name、参数 tool_input 等字段。对 Bash 命令来说,要执行的命令就在 tool_input.command 里。下面这个脚本读出命令,发现包含危险关键词就以 exit 2 退出,并把原因写到 stderr——Claude 会收到这段原因、放弃这次操作:
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
if echo "$COMMAND" | grep -qE 'rm -rf|drop table'; then
echo "已拦截:检测到高风险命令,请人工确认后再执行" >&2 # stderr 会反馈给 Claude
exit 2 # exit 2 = 阻断这次操作
fi
exit 0 # exit 0 = 不表态,照常走正常权限流程
退出码的含义就三种,记住它就懂了大半:
| 退出码 | 含义 |
|---|---|
exit 0 |
没意见,操作照常走正常权限流程(对 PreToolUse 不等于「批准」) |
exit 2 |
阻断这次操作,stderr 的内容反馈给 Claude 让它调整 |
| 其他码 | 操作继续,终端显示一条 hook 报错提示 |
把这个脚本存成 .claude/hooks/block-danger.sh、加上可执行权限,再在 .claude/settings.json 里用 PreToolUse 注册它,匹配 Bash 工具即可。
你不用一开始覆盖所有情况。先盯三类:删除大量文件、改系统目录、把内容发到外部服务。只要这三类有确认点,你会从「得一直盯着它」变成「关键动作至少会被拦一下」。
⚠️ 常见踩坑:新手最容易在第一条就追求「全自动强制拦截」,结果脚本逻辑写复杂了、误拦正常命令,几天后嫌烦全关掉。更稳的起步是只做提醒不做硬拦——
exit 2反馈一句「这个动作影响范围很大,请确认」,你看一眼路径确认无误再让它继续。新手阶段,清楚的提醒往往比复杂的策略有用,因为你还在建立判断感。
这里的重点不是让 Claude 永远不能做危险事,而是让危险事不能悄悄发生。真要删除、发布、改配置时,你仍然可以手动确认。自动化最怕的不是慢一点,而是快到你来不及看。
六、为什么不要一上来写很多脚本
先回答:因为 hook 写多了,Claude Code 会变慢,而且你会分不清是哪一条在影响结果。 它每次动手前后都可能触发脚本,脚本越多、检查越慢,你越容易觉得「这工具怎么卡卡的」。很多人配完一堆 hook,过两天又全关掉,就是第一步走太猛。
更现实的问题是排查。hook 多了以后,Claude 没跑某条命令,是它自己判断不跑,还是某条 hook 拦了?它回答里多了一段上下文,是你写在 CLAUDE.md 里,还是 UserPromptSubmit 注入的?说不清,排查就很痛苦。
所以第一周只保留三条以内。更稳的节奏是先只开一条危险命令拦截,跑上几天确认它不碍事、真能拦住该拦的,再加第二条。每加一条,都问自己一句:没有它,我真的会经常犯这个错吗?答案是否定的,就先别加。
判断一条 hook 该不该留,有个朴素标准——这条 hook 触发时,你是否愿意停下来读它。如果你自己都不想读,它就只是噪音。很多人都踩过这个坑:一口气配十几条,前两天觉得专业,一周后发现每次操作都在等一堆脚本跑完,最后全删了。好的 hook 应该像门口的红灯,少出现,但一出现你就知道要认真看。一组可操作的经验值:把单个 hook 控制在一秒内、总数先压在十个以内,超过就会明显感到延迟。
七、什么时候用提示词,什么时候用 Hooks
这是新手最该想清楚的一道分界。一句话先答:提示词管「怎么理解」,Hooks 管「到点执行」。 同一类需求落在哪边,看你能不能接受它偶尔不发生。
下面这张表把三者的分工摆清楚:
| 需求 | 放哪里 | 为什么 |
|---|---|---|
| 回答更短、先给结论、语气自然 | 提示词 / CLAUDE.md |
表达风格,靠理解就能处理 |
| 项目背景、测试命令说明、目录约定 | CLAUDE.md |
长期生效的工作习惯,犯一次不致命 |
| 改完文件提醒跑测试(它总忘) | PostToolUse hook |
靠提醒不可靠时,升级成到点执行 |
| 不许删数据库、不许把密钥打进日志 | PreToolUse hook |
红线,犯一次代价很高,必须硬边界 |
比如你希望 Claude 回答更短、先给结论,这适合写进 CLAUDE.md,靠理解就能处理。你希望它改完文件提醒你跑测试,可以先写进 CLAUDE.md,但如果发现它总忘,就升级成 PostToolUse。再比如「不要删数据库」「不要把密钥打进日志」,这类是红线,不该只靠提醒——你可以在 CLAUDE.md 写一遍让它理解,也可以在 Hooks 里做硬检查。一个讲道理,一个守门。
🔥 翔宇判断:我自己的分法很简单——犯一次也可以接受的,用文字规则;犯一次代价很高的,用 Hooks。这句话对新手特别有用,因为你不用纠结「哪个更先进」。不是 Hooks 比提示词高级,它们管的事根本不一样:能靠理解解决的让 Claude 理解,必须有硬边界的就用检查门。

八、装了 Hooks 不代表系统就安全了
这里要说一句不好听但很重要的话:Hooks 不是护身符。 它只能在你写过规则的地方帮你检查,不能替你理解整个项目,也不能保证所有风险都被覆盖。
比如你只拦了删除命令,没拦发布命令,那发布仍然可能直接发生;你在改文件后提醒测试,但测试命令本身是错的,提醒也没用;你在项目级写了 Hooks,却从另一个目录启动 Claude Code,它可能根本没读到你以为的那份配置。
所以每加一条 Hooks,都要做一次真实演练。不要只看配置文件写得好不好,要看它是否真的触发。最简单的验收方式:让 Claude 做一个低风险动作,确认 hook 出现了你预期的提醒或拦截。
这里的「低风险」很关键。不要拿真实删除、真实发布来试。用一个临时文件、一个不影响项目的命令、一个假的发布动作来演练。你要验证的是检查门会不会响,不是验证自己能不能承受事故。
把第一次演练拆成三步:
- 造一个安全的试验场:用临时目录和临时文件,不碰真实项目。
- 触发一个低风险动作:让 Claude 写入临时文件,或准备执行一个明显会被提醒的命令。
- 看三件事:hook 是否在正确时机出现、提醒内容是否让人看得懂、任务是否还能继续。
如果这三步里任何一步不清楚,就先别把它放进真实项目。Hooks 的配置不是写完就算数,必须经过一次小演练,确认它不是只存在于配置文件里,而是真的在你需要的时刻出现。
⚠️ 常见踩坑:提醒内容只输出一句「blocked by hook」,等于没说。新手最容易在这里偷懒,结果几周后自己都看不懂当时为什么被拦。提醒要写给人看:说清为什么拦、用户现在该确认什么。hook 不是为了证明脚本运行了,是为了让人做正确判断。
九、翔宇会怎么从 0 到 1 配
说明一下,这是个人路由,不是让你照抄——你的项目最怕的动作和我的不一定一样。但这套节奏对大多数新手适用。
面对一个新项目,先不搭「完整治理体系」,按三天来:
- 第一天,只做危险命令提醒。目标是让自己敢把 Claude Code 放进项目里做小改动。
- 第二天,加一个改文件后的检查提醒。不一定自动跑测试,先提醒也够,重点是养成「改完要验」的节奏。
- 第三天,再看要不要会话开场提醒,比如自动告诉 Claude 先读当前目录规则。
这三步跑完,使用方式会明显变化:以前是「盯着 Claude 做事」,现在更像「给它一条窄路,让它在路里做事」。路窄一点并不耽误效率,反而让你更敢把明确任务交出去。
一个收尾提醒:三天做完没有明显痛点,就停,自动化不是越多越好。还有一种情况也要停——你发现自己在为了「看起来专业」加规则:每次读文件都提醒、每次搜索都记录、每次回答都补一段说明。这些短期有新鲜感,长期全是噪音。新手阶段,能让你少犯一个真实错误的规则才值得留。
十、出问题时先看三处
hook 不生效是新手最常遇到的事。先按「没注册、时机错、动作太重」这三处排,别一上来钻脚本细节——多数问题根本不在脚本里。
| 排查顺序 | 看什么 | 怎么看 |
|---|---|---|
| 第一 | 有没有注册 | 用 /hooks 看当前配置;很多问题是配置根本没被读到 |
| 第二 | 触发时机对不对 | 想动手前拦就看工具使用前的事件,想改完提醒就看工具使用后的事件 |
| 第三 | 脚本是不是太重 | 慢检查、联网检查、长时间扫描都会拖慢节奏;能轻就轻、能提醒就别硬拦 |
第一,看它有没有注册。用 /hooks 看当前配置,比盲猜快很多——很多问题不是脚本错,是配置没被读到(比如 JSON 写了多余的逗号、文件放错位置)。
第二,看触发点是不是选错了。想在命令执行前阻止危险动作,就看工具使用前的事件;想在改完文件后提醒测试,就看工具使用后的事件。触发点错了,脚本再对也不会在你期待的时候出现。
第三,看脚本是不是太重。Hooks 默认不是给你跑大工程的地方。能轻就轻,能提醒就别一开始强制。
排查完这三处还没找到原因,再看日志和具体脚本。官方也给了笨办法但好用的调试方式:在终端里手动把一段示例 JSON 用管道喂给你的脚本,看它退出码和输出对不对,比对着配置干猜快得多。

十一、这东西适合谁
先给判断:如果你已经开始让 Claude Code 改文件、跑命令、做多步任务,Hooks 就值得学;如果你只是偶尔让它解释代码,它不是第一优先级。
如果你只是让 Claude Code 偶尔解释代码,先把提问方式和项目规则写清楚,收益更直接。但只要你开始把它当「会动手的同事」,情况就不一样了:会动手,就有动手前后的检查;会碰文件,就要知道哪些文件不能碰;会跑命令,就要区分普通命令和危险命令。Hooks 不是给概念学习用的,是给真实执行用的。
团队场景更需要它,因为团队里不是每个人都记得同一套口头约定,Hooks 能把一部分底线变成统一动作。它不替代代码审查,也不替代测试,但能让危险动作更早被看见。
⚠️ 常见踩坑:团队里最容易把 Hooks 写成「管理者的焦虑清单」,什么都想管,结果人人嫌它碍事、变着法绕过。真正适合团队共享的,是大家都认可的底线:不能把密钥写进仓库、不能绕过测试直接发布、不能在不确认的情况下改线上配置。底线稳定,Hooks 才有价值。
个人场景也一样。你不需要把所有不放心都写成 hook。先挑一个最常发生、代价也比较高的问题:内容库怕误改已发布稿,源码库怕跳过测试,服务器项目怕直接改线上配置。每个项目的第一条 hook,应该来自这个项目最真实的风险。 这条风险被稳定守住以后,再加第二条。先稳,再扩。
十二、常见问题(FAQ)
下面这几个问题正文里没有专门展开,但配第一条 hook 时很容易撞上,单独答清楚。
退出码和那段 JSON,到底该用哪个来拦?
两条路,别混用。简单拦截用退出码最省事:脚本发现危险就把原因写到 stderr、exit 2 退出,Claude 收到原因后放弃这次操作。需要在「拦、放行、转人工确认」之间做选择,才用结构化 JSON:exit 0 退出、往标准输出打一段带 permissionDecision 的 JSON,取值 deny(拦)、allow(跳过询问,但仍受权限规则约束)、ask(照常弹确认)。官方明确提示:返回 exit 2 时 Claude 会忽略你打的 JSON,所以两种机制不要同时上。
改文件后的格式化 hook,为什么 Claude 用命令改的文件没被格式化?
因为 Edit|Write 这个 matcher 只盯 Edit、Write 这两个文件编辑工具,而 Claude 也可以通过 Bash 工具用命令(比如 sed、> 重定向)改文件,这条路不会触发 Edit|Write 的 hook。官方给的办法是:要覆盖每一次文件改动,再挂一个 Bash 的 matcher,或者用一个 Stop hook 在每轮结束时扫一遍工作区。新手够用的版本是先盯 Edit|Write,等真遇到漏网再补 Bash。
async 异步 hook 是什么,什么时候该用?
给某个 hook 的配置加上 "async": true,它就会在后台跑、不阻塞 Claude 继续干活。适合不需要等结果的活:写日志、发监控、跑较慢的检查。反过来,要当场决策的活(拦不拦、要不要往上下文里注入内容)必须同步等结果,不能异步。原则是能异步就异步,把会卡住主流程的慢操作挪到后台。
团队想统一治理,本地脚本之外还有别的方式吗?
有,就是 HTTP 钩子:把 type 设成 http 并给一个 url,事件数据会用 POST 发到那个网络地址,由远端服务处理,而不是在本地跑脚本。它适合团队统一的验证、审计、合规服务。但个人用或小团队,本地命令钩子最简单够用——远端一挂你的 Claude 就卡,本地脚本能解决的就别引入远程依赖。
配好了却报「command not found」或 hook 不触发,先查什么?
先用 /hooks 确认它真被注册了(这是只读查看器,不是编辑器)。报 command not found 多半是脚本路径问题,用绝对路径或 $CLAUDE_PROJECT_DIR 指向脚本;报 jq: command not found 就是没装 jq,装上即可。脚本压根没跑,往往是忘了给可执行权限(chmod +x)。还有一个官方推荐的笨办法:在终端里手动把一段示例 JSON 用管道喂给脚本,看退出码和输出对不对,比对着配置干猜快得多。
十三、下一步怎么学
你现在只要带走三句话:
- Hooks 是检查门,不是魔法。它在固定时刻出现,帮你拦风险、补提醒、做记录。
- 新手先学两个点:工具执行前(
PreToolUse)挡危险,工具执行后(PostToolUse)提醒验收。别一开始追求全覆盖。 - 第一条 Hooks 来自真实担心。你怕误删就拦删除,你怕忘测就提醒测试,你怕上下文乱就在会话开始补规则。
如果要继续学,可以先看 Claude Code 权限配置新手指南,再看 Claude Code MCP 工具配置新手指南。权限决定它能做什么,MCP(模型上下文协议,Model Context Protocol)决定它能接哪些外部工具,Hooks 则决定关键动作前后要不要检查。三者放一起看,才比较完整。
这篇专讲「在 Claude Code 里怎么配 Hooks」。如果你还在纠结更上一层的问题——同样一件事,到底该用 Skills、子代理还是 Hooks——那是另一道判断题,Skills、子代理、Hooks 什么时候用哪个那篇用一棵决策树专门讲取舍,可以搭配着读。命令和机制的细节,以官方 Claude Code Hooks 文档为准。
读的时候别急着复制配置。先问自己:我现在最怕哪一个动作出错?是误删、误发、误改配置,还是改完不验证?答案不同,第一条 Hooks 就不同。你从自己的真实担心出发,才不会被一堆英文事件名带着跑。
如果你只记住一个练习,就做这个:写下最近一次你不放心 Claude Code 的瞬间——它准备跑命令时你紧张,还是它改完文件你不知道有没有测?把这个瞬间翻译成一条检查门。这样配出来的 Hooks,才会真的服务你的工作,而不是服务一份看起来很完整的清单。