Claude Code Hooks 新手指南:8 个检查点怎么用

写给第一次配置 Claude Code Hooks 的新手:先讲它像什么、什么时候触发、第一条应该怎么配,避免用一堆脚本把自己绕晕。

Claude Code Hooks 新手指南封面:把 Hooks 理解成工具旁边的检查门,按时间线串起会话开始、工具动手前后到会话结束的 8 个生命周期触发点

预计阅读 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 动手前,就别去改收尾事件;问题出在改完之后没人提醒你验收,就别把规则塞进会话开场。很多配置错误,本质上是触发时机想错了。

Claude Code Hooks 检查门概念图:从会话开始到会话结束按时间线排开 8 个生命周期触发点,包括 SessionStart、UserPromptSubmit、工具动手前的 PreToolUse、工具动手后的 PostToolUse、Stop、SubagentStop、PreCompact、SessionEnd

四、第一条 Hooks 放在哪里、长什么样

先回答两个问题。放哪里:第一条放项目级,不要放全局。 长什么样:它是一段 JSON,按「事件名 → 匹配器(matcher)→ 一组命令」三层嵌套。

四个配置层级和它们的影响范围如下:

配置位置 影响范围 能否提交 git
企业策略(managed policy) 整个组织 管理员控制
~/.claude/settings.json 你的所有项目 否(本机)
.claude/settings.json(项目根) 当前项目 ✅ 可提交
.claude/settings.local.json 当前项目 否(不进版本库)

新手最稳的入口,是先用 Claude Code 里的 /hooks 命令看一眼当前注册了哪些 Hooks。这个命令是只读的——官方文档说得很清楚,/hooks 菜单只能查看,要添加、修改、删除得直接编辑设置文件——但它能让你先看清现状,少踩 JSON 写错的坑。

一条最简单的 hook 长这样。下面这段配置的意思是:每次 Claude 用 EditWrite 工具改完文件后,自动跑一遍格式化。把它放进项目根目录的 .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 Code Hooks 第一条配置拆解图:左侧是一条 hook 的事件名、匹配器 matcher、命令三层嵌套结构,右侧是企业策略、全局、项目级、本地四个配置层级的影响范围,新手第一条建议放项目级

五、最小动作:先管危险命令

如果你不知道第一条该写什么,就从危险命令开始。原因不是它最酷,而是它最直观: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 理解,必须有硬边界的就用检查门。

提示词与 Claude Code Hooks 的分工对比图:左侧提示词和 CLAUDE.md 管「怎么理解」,处理表达风格、项目背景这类犯一次也能接受的需求;右侧 Hooks 管「到点执行」,用 PreToolUse 拦红线、PostToolUse 提醒验收,处理犯一次代价很高的硬边界

八、装了 Hooks 不代表系统就安全了

这里要说一句不好听但很重要的话:Hooks 不是护身符。 它只能在你写过规则的地方帮你检查,不能替你理解整个项目,也不能保证所有风险都被覆盖。

比如你只拦了删除命令,没拦发布命令,那发布仍然可能直接发生;你在改文件后提醒测试,但测试命令本身是错的,提醒也没用;你在项目级写了 Hooks,却从另一个目录启动 Claude Code,它可能根本没读到你以为的那份配置。

所以每加一条 Hooks,都要做一次真实演练。不要只看配置文件写得好不好,要看它是否真的触发。最简单的验收方式:让 Claude 做一个低风险动作,确认 hook 出现了你预期的提醒或拦截。

这里的「低风险」很关键。不要拿真实删除、真实发布来试。用一个临时文件、一个不影响项目的命令、一个假的发布动作来演练。你要验证的是检查门会不会响,不是验证自己能不能承受事故。

把第一次演练拆成三步:

  1. 造一个安全的试验场:用临时目录和临时文件,不碰真实项目。
  2. 触发一个低风险动作:让 Claude 写入临时文件,或准备执行一个明显会被提醒的命令。
  3. 看三件事:hook 是否在正确时机出现、提醒内容是否让人看得懂、任务是否还能继续。

如果这三步里任何一步不清楚,就先别把它放进真实项目。Hooks 的配置不是写完就算数,必须经过一次小演练,确认它不是只存在于配置文件里,而是真的在你需要的时刻出现。

⚠️ 常见踩坑:提醒内容只输出一句「blocked by hook」,等于没说。新手最容易在这里偷懒,结果几周后自己都看不懂当时为什么被拦。提醒要写给人看:说清为什么拦、用户现在该确认什么。hook 不是为了证明脚本运行了,是为了让人做正确判断。

九、翔宇会怎么从 0 到 1 配

说明一下,这是个人路由,不是让你照抄——你的项目最怕的动作和我的不一定一样。但这套节奏对大多数新手适用。

面对一个新项目,先不搭「完整治理体系」,按三天来:

  • 第一天,只做危险命令提醒。目标是让自己敢把 Claude Code 放进项目里做小改动。
  • 第二天,加一个改文件后的检查提醒。不一定自动跑测试,先提醒也够,重点是养成「改完要验」的节奏。
  • 第三天,再看要不要会话开场提醒,比如自动告诉 Claude 先读当前目录规则。

这三步跑完,使用方式会明显变化:以前是「盯着 Claude 做事」,现在更像「给它一条窄路,让它在路里做事」。路窄一点并不耽误效率,反而让你更敢把明确任务交出去。

一个收尾提醒:三天做完没有明显痛点,就停,自动化不是越多越好。还有一种情况也要停——你发现自己在为了「看起来专业」加规则:每次读文件都提醒、每次搜索都记录、每次回答都补一段说明。这些短期有新鲜感,长期全是噪音。新手阶段,能让你少犯一个真实错误的规则才值得留。

十、出问题时先看三处

hook 不生效是新手最常遇到的事。先按「没注册、时机错、动作太重」这三处排,别一上来钻脚本细节——多数问题根本不在脚本里。

排查顺序 看什么 怎么看
第一 有没有注册 /hooks 看当前配置;很多问题是配置根本没被读到
第二 触发时机对不对 想动手前拦就看工具使用前的事件,想改完提醒就看工具使用后的事件
第三 脚本是不是太重 慢检查、联网检查、长时间扫描都会拖慢节奏;能轻就轻、能提醒就别硬拦

第一,看它有没有注册。用 /hooks 看当前配置,比盲猜快很多——很多问题不是脚本错,是配置没被读到(比如 JSON 写了多余的逗号、文件放错位置)。

第二,看触发点是不是选错了。想在命令执行前阻止危险动作,就看工具使用前的事件;想在改完文件后提醒测试,就看工具使用后的事件。触发点错了,脚本再对也不会在你期待的时候出现。

第三,看脚本是不是太重。Hooks 默认不是给你跑大工程的地方。能轻就轻,能提醒就别一开始强制。

排查完这三处还没找到原因,再看日志和具体脚本。官方也给了笨办法但好用的调试方式:在终端里手动把一段示例 JSON 用管道喂给你的脚本,看它退出码和输出对不对,比对着配置干猜快得多。

Claude Code Hooks 故障排查三步顺序图:第一步用 /hooks 确认有没有注册,第二步检查触发时机对不对(动手前看 PreToolUse、改完看 PostToolUse),第三步看脚本是不是太重,建议按顺序排查而不是一上来钻脚本细节

十一、这东西适合谁

先给判断:如果你已经开始让 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 只盯 EditWrite 这两个文件编辑工具,而 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 用管道喂给脚本,看退出码和输出对不对,比对着配置干猜快得多。

十三、下一步怎么学

你现在只要带走三句话:

  1. Hooks 是检查门,不是魔法。它在固定时刻出现,帮你拦风险、补提醒、做记录。
  2. 新手先学两个点:工具执行前(PreToolUse)挡危险,工具执行后(PostToolUse)提醒验收。别一开始追求全覆盖。
  3. 第一条 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,才会真的服务你的工作,而不是服务一份看起来很完整的清单。

订阅成功!请到邮箱查收确认链接。

订阅成功!请到邮箱查收确认链接。

订阅成功!请到邮箱查收确认链接。

订阅成功!请到邮箱查收确认链接。

操作成功。

操作已取消。