作者:互联网 时间: 2026-07-14 09:05:53
你有没有遇到过这种情况:

明明在 CLAUDE.md 里写了"每次改完文件要跑格式化",Claude 前两次确实照做了,到第三次就开始"忘记"。你提醒它,它道歉,然后继续忘。
或者更恼火的:你让它去读一个外部 README,它回来之后好像"被洗脑了"——输出的代码风格突然变了,还带了一些奇怪的注释。
问题不在 Claude 不聪明,而在 CLAUDE.md 是建议,Hooks 是强制执行。
Anthropic 在官方 best practices 里说得很直白:凡是"每次都必须发生"的事,应该交给 hooks,而不是写在 CLAUDE.md 里等模型自觉 1。
一句话总结:
Hooks 是 Claude Code 的"确定性执行层"。你定义的规则,不会因为上下文太长、任务太复杂、或者模型"没注意"而被跳过。
每个玩法都配了可直接复制的配置示例。
Claude 在等权限、等你输入、或者任务完成时,自动推一个桌面通知。对经常切去浏览器查资料的场景,不用一直盯着终端了。
{"hooks": {"Notification": [{"hooks": [{"type": "command","command": "osascript -e 'display notification "Claude need you" with title "Claude Code"'"}]}]}}
建议:只监听关键状态,所有操作都推的话十分钟响八次,你很快会关掉它。
Claude 一修改文件,就自动跑 prettier、ruff format、gofmt、eslint --fix 等工具。
能少改一次格式,就少一次上下文消耗——Claude 能改对,但"每次都记得改"就不一定了。
{"hooks": {"PostToolUse": [{"matcher": "Edit|Write|MultiEdit","hooks": [{"type": "command","command": "npx prettier --write $FILE_PATH"}]}]}}
matcher 用 | 分隔工具名,我在项目里跑过,没问题。
在 Claude 真正执行前拦下高风险操作。比如:
.env、lockfile、动 migrationsrm -rf、git push --force、curl | sh提示词是软的,hook 是硬的——规则会真的阻止执行,不是"建议" Claude 别这么做。
{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "bash -c 'if echo "$TOOL_INPUT" | grep -qE "(rm -rf|git push --force)"; then echo "已拦截危险命令"; exit 1; fi'"}]}]}}
hook 能拿到完整命令($TOOL_INPUT),检查后决定放行还是拦截。
对少量安全命令自动批准,减少反复点权限的打断。
白名单示例:git status、git diff --stat、npm test、pnpm lint。
{"hooks": {"PermissionRequest": [{"matcher": "Bash","hooks": [{"type": "command","command": "bash -c 'if echo "$TOOL_INPUT" | grep -qE "^(git status|git diff --stat|npm test|pnpm lint)"; then echo "{"hookSpecificOutput":{"permissionDecision":"allow"}}"; else echo "{"hookSpecificOutput":{"permissionDecision":"ask"}}"; fi'"}]}]}}
警告:白名单一定要窄,不能用太宽的正则。别写成 git .*,那等于把半个终端都交出去了。
适合 monorepo、多语言项目、direnv、Python venv 等场景。
作用:在 Claude 会话启动、上下文压缩前后,自动刷新环境变量和项目状态,避免"本地 shell 能跑,Claude Bash 跑不了"的问题。
{"hooks": {"SessionStart": [{"hooks": [{"type": "command","command": "source .env && echo "环境已加载: NODE_ENV=$NODE_ENV""}]}],"PreCompact": [{"hooks": [{"type": "command","command": "env > .claude/env-snapshot.txt"}]}]}}
在 Claude 宣布"任务完成"前,强制跑测试、lint、git diff --check 等检查。
不通过就不能标记 Done,能减少"看起来完成了,其实没验证"的情况。
{"hooks": {"Stop": [{"hooks": [{"type": "command","command": "bash -c 'npm test && git diff --check; exit $?'"}]}]}}
讲完单个 hook,说一个把它们串起来的真实场景。
我用的终端是 Ghostty,它对 macOS 原生通知的支持不太好。Claude Code 跑完任务或者等输入时,我看不到任何通知,切去浏览器查资料回来经常不知道进展。
解决方案是用一个脚本挂到四个 hook 事件上:
{"hooks": {"Stop": [{ "hooks": [{ "type": "command", "command": "/path/to/notifier.js" }] }],"SessionEnd": [{ "hooks": [{ "type": "command", "command": "/path/to/notifier.js" }] }],"Notification": [{ "hooks": [{ "type": "command", "command": "/path/to/notifier.js" }] }],"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "/path/to/notifier.js" }] }]}}
四个事件分别覆盖:
最终效果:
![[Claude_Code_Hooks_最被低估的能力-20260629112520608.jpeg]]
官方推荐用 SessionStart 的 compact matcher,在上下文压缩(compaction)后重新注入关键上下文 1。
Steve Kinney 还建议 2:在 PreCompact 先写一个小状态文件,保存:
这对长任务特别有用。因为 compaction 后最容易丢的不是代码,而是"为什么要这样改"。
lasso-security/claude-hooks 做了一个很实战的 PostToolUse 防护 3:Claude 读文件、抓网页、跑 Bash 后,扫描输出里有没有:
然后把警告写回 Claude 的上下文。
这个玩法很适合让 Claude 读外部网页——我每次让它去查 README 或 issue,第一反应就是扫一遍输出有没有注入指令。
官方的 hook 类型其实有 10 个 1,除了上面讲的 6+2 个,还有 3 个值得知道:
用户每次发 prompt 时,自动注入项目上下文或安全规则。比如自动挂上项目 README 摘要、检测危险关键词、附加 coding style 要求。
这就是一个 cat .claude/project_context.md 的事。
使用多袋里(subagent)时,验证子袋里是否真的完成了任务。
可以防止子袋里"假装完成"——多袋里工作流里这问题挺烦人。
会话结束时自动做清理和记录。
用法:
注意:配 async: true,避免拖慢退出。
官方文档明确写了,hooks 默认会阻塞 Claude 的执行。
长测试、外部 API、重活请考虑 async: true,否则你会明显感觉"越装越卡"。社区在 HN 上也有人专门提到:hook 多了、插件多了,性能会掉 4。
但 async: true 有副作用:执行顺序不确定。只在确实耗时的操作上使用它,别给所有 hook 都加上。
Check Point 今年就披露过基于 repo 配置文件的攻击面 5,Hooks / MCP / env 都可能成为入口。
Anthropic 官方也强调了 trust verification。
实践建议:只从可信来源复制 hooks 配置。别随便把网上看到的 hook 配置粘贴到你的 .claude/settings.json 里。
Steve Kinney 那句我很认同 2:
越小越容易测,越不容易误伤。一个 hook 里做 10 件事,出错了你不知道哪件有问题。
Hooks 不是什么新概念——CI/CD 里的 pre-commit hook、webhook、git hook,搞技术的都见过。但 Claude Code 把 hooks 提到了一个不一样的位置:它不是附赠功能,是你跟 AI 协作时最后一道确定性防线。
Prompt 会随着上下文变长而衰减,模型会在复杂任务中"走神"。但写进 .claude/settings.json 的 hook 不会——它每次都执行,每次都生效。
我花了一段时间才理解这个区别。以前总想着"把 prompt 写得更细更全",后来发现真正重要的那些事,靠的是 hook,不是 prompt。
你最想用 Hook 解决什么问题?欢迎在评论区告诉我。
#ClaudeCode #AI编程 #开发工具 #自动化
Anthropic. Claude Code Hooks 开发文档. anthropics/claude-code 仓库,plugins/plugin-dev/skills/hook-development/SKILL.md. 版本:Claude Code v2.1.195 (2026-06-26). 链接:github.com/anthropics/… ↩ ↩2 ↩3 ↩4
Steve Kinney. Claude Code Hooks 社区文章与最佳实践. 引用"PreCompact 状态保存"和"小 Hook 原则". ↩ ↩2
Lasso Security. lasso-security/claude-hooks — Prompt Injection 防护 hook 集合. 最后更新:2026-06-23. 链接:github.com/lasso-secur… ↩
Hacker News. Claude Code Hooks 性能讨论帖. 社区用户反馈 hook 增多后的性能影响. ↩
Check Point Research. 基于 AI 编码工具配置文件(Hooks/MCP)的攻击面研究报告. 2026. ↩