Deepseek ArtifactsDeepseek Artifacts
基于官方 hooks 视频的图文攻略

Claude Code Hooks 攻略:settings.json 配置、5 类事件与退出码拦截

Hooks 是 Claude Code 的「确定性」层:不靠模型自觉,配置了就一定会执行。本攻略用 Anthropic 官方 hooks 视频做逐帧配图——五类事件、PreToolUse 拦截脚本、结构化 deny JSON,再到一份完整可抄的 PostToolUse 格式化配置。

太长不看:Claude Code hooks 是什么

  • Hooks 是确定性的:它在 Claude Code 生命周期的固定节点上必然执行。CLAUDE.md 里写「每次编辑后跑 Prettier」只是大多数时候会做——hook 是每一次都做。
  • 一共五类事件:UserPromptSubmit(提示词提交后、处理前)、PreToolUse(工具调用前)、PostToolUse(工具完成后)、Notification,以及 Stop(Claude 答完时)。
  • PreToolUse hook 以退出码 2 结束即拦截该次工具调用,stderr 会回传给 Claude,让它知道为什么被拦;退出码 0 放行。
  • Hook 写在 settings.json 里:事件 + 可选 matcher + 命令。放在项目的 .claude/settings.json 并提交进仓库,全团队自动继承同一套约束。

Hooks in Claude Code

频道:Claude (official Anthropic channel)3:22

观看

Claude Code Hooks, Explained Simply

频道:Agentic Lab8:32

观看

Claude Code - Getting Started with Hooks

频道:Greg Baugues11:53

观看

Hooks reference — Claude Code documentation

文档:code.claude.com

观看

本页配图截取自 Anthropic 官方 hooks 讲解视频;走查文字为独立撰写,并对照官方 hooks 参考文档核对。

截图版权归原作者所有,此处以署名方式用作可视化文档。每一步都带深链,可跳回来源视频的对应时间点。

一步步配置 Claude Code hooks

1 · 先看 hook 真实运行的样子

  1. 1

    看一个 hook 在回答结束时触发

    状态栏写着「Running stop hook · 39s · 484 tokens」——Claude Code 正在执行一个 Stop hook,然后才把回合交还给你。一张截图说明全部思想:你注册的命令在生命周期的固定节点执行,每次命中都跑,完全不依赖模型「记得去做」。

    Claude Code terminal showing a running Stop hook at 39 seconds with 484 tokens right after Claude finished composing an answer
    Stop hook 在 Claude 答完后执行——耗时 39 秒、484 tokens。在 0:10 观看
  2. 2

    认识五类 hook 事件

    UserPromptSubmit 在你提交提示词之后、Claude 处理之前触发;PreToolUse 在每次工具调用前;PostToolUse 在工具调用完成后;Notification 在 Claude 发出通知时;Stop 在 Claude 结束回答时。你写的每一个 hook 都挂在这五个节点之一上。

    Slide listing the five Claude Code hook events UserPromptSubmit, PreToolUse, PostToolUse, Notification and Stop from Anthropic’s official hooks tutorial
    官方 hooks 视频里的五类事件——所有配置都围绕这张清单展开。在 1:04 观看

2 · 写下你的第一批 hook

  1. 3

    在 settings.json 里加一个 hooks 块

    一个 hook 就是 settings.json 里的三件事:事件名、可选的 matcher(限定作用到哪个工具)、要执行的命令。截图里 PreToolUse 的 matcher 正在补全为 Edit——这个 hook 只会在文件编辑类工具调用时触发。不想手写 JSON 的话,/hooks 菜单可以交互式编辑同一份配置。

    Claude Code settings.json with a PreToolUse hooks array open in VS Code while the matcher field autocompletes Edit for a tool-scoped hook
    matcher 自动补全为 Edit,把 PreToolUse hook 限定在文件编辑上。在 0:14 观看
  2. 4

    用退出码 2 拦截危险命令

    PreToolUse hook 会从 stdin 收到工具名和输入的 JSON。这个脚本用 jq 取出 .tool_input.command,grep 匹配破坏性模式——rm -rf、git push --force——命中就向 stderr 输出原因并以退出码 2 结束。退出码 2 表示拦截,stderr 文本会回传给 Claude 作为反馈,模型因此知道被拦原因并自行调整。

    Bash PreToolUse hook script using jq to read tool_input.command from stdin and exit 2 to block destructive rm -rf and git push --force commands in Claude Code
    jq 从 stdin 读命令;命中 rm -rf 或 --force 就写 stderr 并退出 2。在 2:02 观看
  3. 5

    改用结构化 deny 输出

    要更精细的控制,hook 可以输出 JSON 决定而不是只靠退出码。这里 PreToolUse hook 抓到 DROP TABLE,hookSpecificOutput 携带 permissionDecision「deny」和原因——「改用 migration」——直接进入模型的上下文。同样是硬拦截,但附带了一条可执行的指引。

    Claude Code PreToolUse hook denying a DROP TABLE SQL command with hookSpecificOutput permissionDecision deny JSON that tells the model to use a migration instead
    permissionDecision 为 deny 时拦下 SQL 命令,并告诉模型替代方案。在 2:16 观看
  4. 6

    把 hook 提交进仓库,全团队共享

    配置在项目 .claude/settings.json 里的 hook 属于项目级,可以提交进版本库。任何克隆仓库的人自动运行同一套 hook——包括拦截类的。辅助脚本放 .claude/hooks/ 目录,命令里用 CLAUDE_PROJECT_DIR 环境变量引用,这样无论 Claude 当前工作目录在哪,路径都能解析。

    VS Code explorer showing a project .claude folder with a hooks directory and settings.json open next to CLAUDE.md for team-shared Claude Code hooks
    项目的 .claude 目录里放着 settings.json 和共享脚本的 hooks/ 目录。在 0:17 观看
  5. 7

    抄一份完整可用的 hooks 配置

    这份配置同时干两件事。PostToolUse 块匹配 Edit|Write|MultiEdit,以 30 秒超时运行 .claude/hooks/auto-format.sh——Claude 碰过的每个文件都会被格式化。下面第二个 hook 匹配 Bash,把每条执行过的命令记进日志——这就是合规审计的套路。timeout 和 async 字段保证慢速格式化工具不会卡住会话。

    settings.json hooks block with a PostToolUse matcher of Edit|Write|MultiEdit running an auto-format.sh script at timeout 30 plus a Bash command logging hook
    PostToolUse 自动格式化(30 秒超时),外加记录每条命令的 Bash hook。在 2:46 观看

3 · 像团队一样用起来

  1. 8

    把退出码约定背下来

    退出码 0 放行;退出码 2 拦截——stderr 会作为反馈喂给 Claude,模型可以据此改道,这让 exit-2 hook 不只是「报错」而是「教学」;其他任何退出码只把 stderr 显示给你看,工具调用继续——适合「提醒但不拦截」的软约束。

  2. 9

    用 /hooks 菜单核对,挑好你的配方

    /hooks 命令会交互式打开同一份配置,方便核对哪些 hook 注册在哪个作用域。接下来是四个最常用的配方:编辑后自动格式化(PostToolUse)、记录所有执行过的命令(PostToolUse on Bash)、拦截危险操作(PreToolUse + exit 2)、任务完成时发通知(Stop)。一句话原则:必须每次都发生的事,别写进提示词,写成 hook。

一张表说清退出码约定

每个 hook 命令都通过退出码通信,三种情况覆盖全部场景:

  • exit 0放行。工具调用照常执行,hook 的 stdout 在 transcript 模式(Ctrl-R)下可见。
  • exit 2拦截。工具调用被拒绝,hook 的 stderr 作为反馈回传给 Claude,模型可以据此纠正——这让 exit-2 hook 不只是「报错」,而是「教学」。
  • exit 1其他任何退出码:只警告不拦截。stderr 显示给你但调用继续,适合「这文件一般是生成的,确定要改?」这类提醒。

还有一条进阶路:不用退出码,hook 直接输出 JSON 决定(hookSpecificOutput + permissionDecision),带上结构化原因做拦截,见第 5 步。退出码是简单约定,JSON 决定是类型化约定。

四个值得今天就提交的配方

官方视频点名了四个用例,按可直接抄写的意图整理如下:

  1. 1编辑后自动格式化——PostToolUse hook 匹配 Edit|MultiEdit,按扩展名分发格式化器:TypeScript 用 Prettier、Go 用 gofmt、Python 用 Ruff。
  2. 2记录每条执行过的命令——PostToolUse hook 挂在 Bash 上,把每条命令追加到日志文件。合规团队最爱;排查「上周二到底跑了什么」的你也会爱。
  3. 3拦截危险操作——PreToolUse hook + exit 2,守住生产配置目录、rm -rf 模式、对 main 的提交。这些从「建议」变成「保证」。
  4. 4任务完成发通知——Stop 或 Notification hook 触发桌面通知或提示音,长任务不用人守着。

四个配方可以共存在同一份 .claude/settings.json 里。先上格式化那个——它是你每次保存都能感受到的 hook。

Claude Code hooks 常见问题

相关攻略