前面几篇文章里,我们聊过很多 Claude Code 的能力。

CODE
比如 CLAUDE.md,可以让 Claude 记住项目规则;
比如 Slash Commands,可以把常用操作变成快捷命令;
比如 Checkpoint & Rewind,可以让你大胆试错;
比如 Subagents,可以让 Claude 把复杂任务拆给不同分身;
比如 Skills 和 MCP,则是在扩展 Claude 的能力边界。

但这些能力,本质上都有一个共同点:它们大多是在指导 Claude 怎么做。

你可以在 CLAUDE.md 里写:每次修改代码后,请自动格式化。大多数时候,Claude 会照做。但问题是,大多数时候,不等于每一次——它可能忘了;可能觉得这次不需要;可能上下文太长,它没有执行;也可能你让它连续改了很多文件,中间某一步漏掉了。

如果这件事只是建议,问题不大。但如果这件事是规则,那就不能靠提醒,这就是 Hooks 存在的意义。Hooks 不是告诉 Claude 应该做什么,而是规定某些事情必须发生。

什么是 Hooks?

Hooks 可以理解成 Claude Code 里的自动触发器。

当 Claude Code 运行到某个节点时,系统会自动执行你预先配置好的命令。比如:

CODE
Claude 准备修改文件之前,先检查它是不是在动生产配置
Claude 修改文件之后,自动运行格式化工具
Claude 执行 Bash 命令时,把命令记录下来
Claude 完成一次任务后,给你发一个通知
你提交 Prompt 的时候,先做一次规则校验

这有点像我们平时用一些自动化工具,当某件事发生时,就自动做另一件事。在 Claude Code 里,这个某件事可以是工具调用、文件修改、任务结束、通知触发等等。

所以 Hooks 的本质不是一个新功能按钮,而是一套事件机制。更简单一点说,它让 Claude Code 从听话的助手,变成带流程约束的执行系统。

Hooks 和 CLAUDE.md 最大的区别

很多人刚开始会有一个疑问,既然我已经有 CLAUDE.md 了,为什么还需要 Hooks?因为它们解决的问题不一样。

CLAUDE.md 更像是团队文档,告诉 Claude 我们项目里一般怎么做。Hooks 更像是系统规则,直接规定只要发生这件事,就必须执行这个动作。

比如你在 CLAUDE.md 里写:修改代码后,请运行 Prettier。Claude 大概率会照做,但它依然是读懂后再决定。而 Hooks 是:只要 Claude 使用 Edit、MultiEdit 或 Write 修改了文件,就自动执行格式化脚本。Claude 不需要记得,也不需要判断,事情发生了,Hooks 就跑。 

这就是 Hooks 最关键的特性——确定性,英文里叫 deterministic。听起来有点技术,但意思很简单:它每次都会发生,不靠 Claude 自觉。 

这点非常重要。因为 AI 很适合处理开放任务,比如理解需求、分析代码、生成方案。但在工程流程里,有些事情不能开放。 比如:

CODE
代码格式必须统一
危险命令必须拦截
生产环境文件不能随便改
Bash 命令必须留审计记录
某些任务完成后必须通知相关人

这些事情,最好不要靠一句请注意,要靠机制。

Hooks 通常用来做什么?

Hooks 的用途很多,但对于大多数团队和个人开发者来说,最常见的是下面几类。

1、自动格式化 

这是最容易理解,也最实用的场景。你让 Claude 修改代码,它改完之后,自动运行对应的格式化工具。比如:

CODE
TypeScript / JavaScript 用 Prettier
Go 用 gofmt
Python 用 black
Rust 用 rustfmt

这样你不用每次提醒 Claude:改完记得格式化一下,Hook 会帮你兜底。尤其是当 Claude 一次性修改很多文件时,自动格式化非常有价值。否则最后你打开项目,可能代码是能跑的,但格式很乱。

2、记录执行过的命令 

如果你在公司项目里使用 Claude Code,这点会很重要。Claude 可能会执行 Bash 命令,比如:

CODE
npm install
npm run build
git status
rm -rf dist

有些命令没问题,有些命令就需要小心。通过 Hook,你可以把 Claude 执行过的命令记录下来,比如写进一个日志文件,这样后面如果项目出了问题,你至少知道 Claude 当时执行了什么,什么时候执行的,在哪个目录执行的,结果如何。

这对团队协作、合规审计、问题排查都很有帮助。 

3、阻止危险操作 

这是 Hooks 最有价值的能力之一。比如你不希望 Claude 做这些事:

CODE
修改生产环境配置
删除关键目录
执行 rm -rf
直接往 main 分支提交代码
修改某些受保护文件
在没有确认的情况下执行部署命令

如果只是写在 CLAUDE.md 里,它可能会遵守,但不能保证 100%。而通过 Hook,你可以在 Claude 真正执行工具之前,把危险动作拦下来。也就是说,Claude 准备做某件事时,Hook 会先检查这个动作能不能放行,能,就继续;不能,就阻止。

这就不是提醒了,而是护栏。

4、任务完成后通知你 

还有一种很实用的场景——通知。比如你让 Claude Code 跑一个比较长的任务:

CODE
重构一个模块
扫描整个项目
修复一批测试
生成一组文档
分析一堆日志

你不想一直盯着终端看,这时可以配置 Stop 或 Notification 类 Hook。当 Claude 完成任务,或者发出通知时,自动触发一个脚本。这个脚本可以:

CODE
播放提示音
发桌面通知
发 Slack / 飞书 / 企业微信消息
写入任务完成记录

这类 Hook 不一定是刚需,但对长任务很舒服。

Hooks 是在什么时候触发的?

Claude Code 里有不少 Hook 事件,完整来看可以分成几类:

CODE
Tool Hooks:和工具调用有关
Session Hooks:和会话开始、结束有关
Task Hooks:和任务创建、完成有关
Lifecycle Hooks:和配置变化、目录变化、通知等生命周期事件有关

新手不用一上来记住所有事件,先记住这几个最常用的就够了。

1、PreToolUse 

工具调用之前触发,适合做:

CODE
权限检查
危险命令拦截
生产文件保护
敏感操作确认

比如 Claude 准备执行 Bash 命令,Hook 可以先检查命令里有没有 rm -rf。 如果有,直接阻止。 

2、PostToolUse 

工具调用完成后触发,适合做:

CODE
自动格式化
写日志
安全扫描
自动测试
结果检查

比如 Claude 用 Write 写了一个文件,Hook 可以马上运行 Prettier,这是最常用的一类 Hook。

3、UserPromptSubmit 

你提交 Prompt 后、Claude 正式处理之前触发,适合做:

CODE
校验你的输入
给 Prompt 加规则
检查是否包含敏感信息
做一些团队内部的提示规范

这个场景相对进阶一点,比如团队可以要求大家在让 Claude 改生产代码前,必须在 Prompt 里写清楚影响范围。

4、Stop 

Claude 完成一次响应时触发,适合做:

CODE
发送通知
记录任务完成
保存日志
触发后续自动化动作

比如 Claude 做完一个复杂任务后,自动弹出系统通知: Claude 任务已完成。 

5、Notification 

Claude 发送通知时触发,适合把 Claude Code 的通知转发到其他地方,比如 Slack、飞书、企业微信等。 

如果你是团队负责人,或者同时盯多个任务,这个会很实用。

Hooks 配在哪里?

Hooks 通常配置在 settings.json 里。你可以通过两种方式配置:

第一种方式,是在 Claude Code 里使用: 

CODE
/hooks

这是更推荐新手使用的方式,因为它会引导你选择事件、匹配规则和命令。 

第二种方式,是直接编辑 settings.json。比如项目里可以有:

CODE
.claude/settings.json

也可以放在你自己的用户目录: 

CODE
~/.claude/settings.json

放在用户目录主要对你自己生效,而放在项目目录,可以跟着项目走,团队共享。团队项目里,我更推荐把项目级 Hooks 放在 

CODE
.claude/settings.json

然后把需要的脚本也放到项目的 

CODE
.claude/hooks/

目录里,这样别人拉下代码后,也能得到同样的规则。

一个最常见的例子:修改后自动格式化

假设你的项目里,Claude 经常会修改 TypeScript、JavaScript、Go 文件,你希望它每次改完文件后,都自动格式化,这个时候可以配置一个 PostToolUse Hook。大概思路是:

CODE
事件:PostToolUse
匹配工具:Edit|MultiEdit|Write
执行动作:运行格式化脚本

示例配置可以长这样:

CODE
{
 "hooks": {
   "PostToolUse": [
     {
       "matcher": "Edit|MultiEdit|Write",
       "hooks": [
         "$CLAUDE_PROJECT_DIR/.claude/hooks/format-after-edit.sh"
       ]
      }
    ]
  }
 }

这里有两个点需要注意。

第一,PostToolUse 表示工具执行之后再触发,因为格式化通常要等文件真的被修改之后再做。 

第二,matcher 里写的是:Edit|MultiEdit|Write,意思是只要 Claude 使用这些工具修改文件,就触发这个 Hook。

然后你可以在项目里放一个脚本: 

CODE
.claude/hooks/format-after-edit.sh

示意脚本可以这样写:

CODE
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
if [ -z "$file_path" ]; then
  exit 0
fi

case "$file_path" in
  *.js|*.jsx|*.ts|*.tsx)
    npx prettier --write "$file_path"
    ;;
  *.go)
    gofmt -w "$file_path"
    ;;
  *.py)
    black "$file_path"
    ;;
esac

exit 0

这个脚本做的事很简单:先从 Claude Code 传进来的信息里拿到文件路径,然后根据文件后缀判断要用什么格式化工具。如果是 JS / TS,就跑 Prettier。如果是 Go,就跑 gofmt。如果是 Python,就跑 black。

当然,这只是一个示意,真实项目里,你可以根据自己的技术栈调整。配置好之后,别忘了给脚本执行权限:

CODE
chmod +x .claude/hooks/format-after-edit.sh

这样以后 Claude 每次改完相关文件,格式化都会自动发生,这比你在 Prompt 里反复写记得格式化靠谱得多。

真正厉害的是 PreToolUse:它可以拦截危险动作

如果说 PostToolUse 更像善后,那 PreToolUse 就更像门禁,它会在 Claude 真正执行工具之前先运行,这意味着你可以用它来阻止某些危险行为。比如:

CODE
禁止执行 rm -rf
禁止修改 production 目录
禁止直接操作 .env.production
禁止在 main 分支提交
禁止执行部署命令

举个例子,你可以配置一个 Hook,专门检查 Bash 命令和文件路径: 

CODE
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Edit|MultiEdit|Write",
        "hooks": [
          "$CLAUDE_PROJECT_DIR/.claude/hooks/block-dangerous-actions.sh"
        ]
      }
    ]
  }
}

然后写一个脚本: 

CODE
#!/bin/bash

input=$(cat)

tool_name=$(echo "$input" | jq -r '.tool_name // empty')
command=$(echo "$input" | jq -r '.tool_input.command // empty')
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')

if [[ "$command" == *"rm -rf"* ]]; then
  echo "Blocked: rm -rf is not allowed. Please use a safer delete command." >&2
  exit 2
fi

if [[ "$file_path" == *"production"* ]]; then
  echo "Blocked: production files cannot be modified by Claude Code." >&2
  exit 2
fi

exit 0

这里最关键的是 exit 2,在 Claude Code 的 Hook 机制里,退出码很重要: 

CODE
exit 0:正常放行
exit 2:阻止这次操作
其他退出码:显示错误,但不一定阻止操作

更重要的是,当 Hook 用 exit 2 阻止操作时,脚本输出到 stderr 的内容会反馈给 Claude。也就是说,Claude 不只是被拦下来,它还会知道为什么被拦。

比如你给它的反馈是:

CODE
Blocked: production files cannot be modified by Claude Code.

Claude 就会明白:我不能修改生产文件,需要换一种方案。这就是 Hooks 很强的地方,它不是简单粗暴地打断流程,而是把团队规则变成 Claude 能理解的反馈。

Hooks 适合放什么,不适合放什么?

Hooks 很有用,但不要滥用。它适合处理那些明确、稳定、必须执行的事情。比如:

CODE
格式化
日志
安全检查
权限拦截
通知
简单测试
简单校验

它不适合处理复杂业务逻辑,比如:

CODE
根据复杂业务规则生成方案
做很多分支判断
执行特别长的任务
大量调用外部服务
在 Hook 里写一整套审批系统

原因很简单,Hook 是流程里的自动动作,它应该短小、明确、可靠。如果 Hook 太复杂,反而会让 Claude Code 的工作流变得不可控。

我的建议是,Hooks 里只放硬规则,不放大脑,大脑还是交给 Claude,规则交给Hooks。

团队共享 Hooks:别只在自己电脑上好用

如果你是一个人用 Claude Code,把 Hook 配在自己的 ~/.claude/settings.json 里就可以。但如果是团队项目,Hooks 最好放在项目里。比如:

CODE
your-project/
   .claude/
      settings.json
      hooks/
       format-after-edit.sh
       block-dangerous-actions.sh
       log-bash.sh

然后把这些文件提交到代码仓库,这样团队里每个人使用 Claude Code 时,都能继承同一套规则。这件事很重要,因为 AI 工具在团队里最大的问题,不是某个人用得好不好,而是大家的使用方式是否一致。 一个人让 Claude 随便改,一个人要求先测试,一个人允许改生产配置,一个人禁止碰关键文件……最后项目一定会乱。 

Hooks 可以把这些规则收拢起来,团队不需要每个人都记住一堆注意事项,只要规则写进 Hooks,Claude Code 就会按机制执行。

还有一个小技巧——在脚本路径里尽量使用:

CODE
$CLAUDE_PROJECT_DIR

而不是写死某个本地路径。 因为每个人的项目目录都不一样。 你电脑上可能是: 

CODE
/Users/huang/project/demo

同事电脑上可能是: 

CODE
/Users/team/workspace/demo

如果路径写死,别人就跑不起来。用 $CLAUDE_PROJECT_DIR,脚本就能基于项目根目录执行,更适合团队共享。

安装和调试时,最容易踩的坑

Hooks 本身不难,但第一次配置时,经常会卡在一些小问题上。

1、脚本没有执行权限 

这是最常见的问题,你写好了脚本,但系统不允许它执行。解决方式:

CODE
chmod +x .claude/hooks/your-hook.sh

2、路径写错了 

尤其是项目级配置和用户级配置混用时,很容易写错路径,建议优先使用:

CODE
$CLAUDE_PROJECT_DIR/.claude/hooks/xxx.sh

这样更稳定。

3、settings.json 格式错误 

settings.json 是 JSON 文件,多一个逗号、少一个引号,都可能导致配置不生效。不确定时,可以先用 

CODE
/hooks

命令生成配置,再去看它写出来的格式。 

4、脚本本地没测试 

不要一上来就把复杂脚本放进 Hook,先在终端里单独测试,确保脚本本身能跑,再接入 Claude Code。 

5、Hook 做得太重 

比如每次 Claude 改一个文件,你都跑完整测试,如果项目很大,体验会很差。

更合理的方式是,小改动后自动格式化;关键目录变更后再跑测试;危险操作前做拦截;任务结束后再做完整检查。

Hooks 要做兜底,不要把每一步都变成负担。

一个适合新手的 Hooks 起步方案

如果你刚开始用 Hooks,不建议一口气配置很多,可以先从三个 Hook 开始。

第一个:自动格式化 

CODE
事件用: PostToolUse
匹配: Edit|MultiEdit|Write
作用: Claude 改完文件后,自动格式化。

这是收益最高、风险最低的 Hook。

第二个:拦截危险 Bash 命令 

CODE
事件用: PreToolUse
匹配: Bash
作用: 检查命令里是否包含危险内容,比如:
                rm -rf
                sudo
                deploy

当然,不是所有这些命令都一定危险,但你可以根据项目情况设置规则。对新手来说,先拦截明显危险的命令就够了。

第三个:记录 Claude 执行过的命令 

CODE
事件用: PostToolUse
匹配: Bash
作用: 把 Claude 执行过的命令写入日志文件。比如:
              .claude/logs/bash-history.log

这对复盘很有用,你以后可以知道 Claude 做了什么,什么时候做的,是否执行了某些高风险命令。

这就是 AI Coding 里很重要的一点,不只是让 AI 做事,还要让 AI 的行为可追踪。


Hooks 可以理解成 Claude Code 的自动化触发器,它会在特定事件发生时,自动执行你配置好的命令。最常见的用法包括:

CODE
用 PostToolUse 在 Claude 修改文件后自动格式化
用 PostToolUse 记录 Claude 执行过的命令
用 PreToolUse 在危险操作发生前进行拦截
用 Stop 或 Notification 在任务完成后发送通知
CODE
把项目级 Hooks 放进 .claude/settings.json,让团队共享同一套规则

请记住,凡是需要 Claude 每次都必须做的事情,不要只写进Prompt,也不要只写进 CLAUDE.md,应该写进 Hooks。Prompt 是提醒,CLAUDE.md 是习惯,Hooks 才是规则。

当你开始使用 Hooks,就意味着你不再只是让 AI 帮你写代码,而是在给 AI 建立一套可执行、可追踪、可约束的工作流。

这一步,才是真正从会用 Claude Code,走向管理 Claude Code。