Claude Code Harness 09:Hooks 自动化治理
前面立住了 Plan、TDD、Verify 三层工作流。流程有了,但只要还在靠人记得执行,就一定会退化。Hooks 解决的就是这件事:把高频、机械、容易遗漏的动作从"人记得"变成"系统保证"。
但这里要先划一条线:大多数 Claude Code 工作台不是毁在 hook 太少,而是毁在 hook 太乱。一开始只想补一点自动化,结果越玩越上头,所有事件都挂上脚本,每次 Claude 一动就触发一串东西,最后系统变成一个过度热心的保安------看起来很高级,实际很吵,出了问题分不清是业务逻辑错了还是某个 hook 在多管闲事。
一、Hook 的角色定位:治理层,不是工作流
工作流是"怎么做事"的路径:/plan、/tdd、/verify。Hook 是穿在这些路径侧边的治理带:做事前提醒一下、做事后检查一下、进入某个节点时保存一下状态、要越线时先拦一下。
text
User Task
↓
Command / Workflow Entry
↓
Claude starts working
↓
┌─────────────────────────────┐
│ Hook Layer │
│ - remind │
│ - audit │
│ - auto-fix small things │
│ - block obvious violations │
└─────────────────────────────┘
↓
Core execution (read / write / edit / bash / mcp)
↓
Verification / Summary / Memory update
Hook 不是系统中心。如果你把什么都往 hook 里塞,后面一定会出问题。但如果把它放在治理带的位置,它会非常有价值。
二、判断标准:什么适合做 Hook
三个条件同时满足时,一个动作就适合变成 hook:
高频。 不是一个月才碰一次,而是每天、每周都会碰到。
机械。 不需要复杂推理,不需要长上下文,不需要高自由度。
容易漏。 如果不做自动化,人类和 Claude 都很容易"这次先算了"。
典型适合的例子:改完 .ts/.tsx 后做局部 typecheck(Claude 改完组件后容易觉得"逻辑通了",但类型约束在别的文件里炸了);检查 console.log(调试阶段顺手留下的打印语句特别容易忘删);长命令提醒后台化(npm run dev 堵住主会话是前端开发常见问题)。
三、什么不该做 Hook
需要复杂推理的事。 "帮我分析这个设计该不该重构"、"帮我判断这个 PR 的风险级别"------这些需要大量上下文和灵活判断,硬塞到 hook 里要么效果差要么系统很脆。这类事更适合 command、skill 或 review workflow。
低频动作。 一个季度才碰一次的事不值得优先放进 hook。hook 的代价不只是写出来,还包括未来维护、测试、知道它什么时候在触发。
会改变核心任务路径的事。 强行在 hook 里塞完整 review 流程、希望 hook 自动决定任务拆分------这是把本该显式发生的工作流偷偷藏进了隐式自动化。系统虽然看起来很自动,实际却很难理解。开发工作系统最怕的不是自动化不够,而是自动化过深导致你自己都不知道系统什么时候做了什么。
四、Hook 的四类职责
提醒。 最轻的一层,不阻断只提醒。长命令提醒后台化、提醒看 git diff、提醒当前会话上下文可能已经太脏。
审计。 不改变主流程,但在关键节点检查质量问题。console.log 检查、临时调试代码检查、敏感文件读写提醒。
自动补动作。 比提醒更进一步。自动格式化、局部 typecheck、记录状态、补充 session summary。
阻断。 最重的一层,应该非常克制。只做最明确、最不可容忍的越线行为:破坏性命令、明确不允许的敏感路径操作。
起步时先做提醒 + 审计 + 少量自动补动作。阻断只覆盖最明确的越线。一旦阻断太多,系统迅速变成过度热心的保安。
五、Node/Next.js 项目最值得先落的 5 条 Hook
Hook 1:编辑 .ts/.tsx 后局部 typecheck。 前端项目里最常见的 Claude 偏差就是组件逻辑看起来没问题但类型约束在别的文件里炸了。只在 .ts/.tsx 编辑后触发,优先跑局部 typecheck,不要一上来全量 tsc --noEmit 卡死主流程。
Hook 2:编辑后查 console.log。 Claude 在调试阶段特别容易留下 console.log,调试时不觉得有什么,提交前特别容易漏。作为 stop 审计非常合适。
Hook 3:长命令提醒后台化。 npm run dev、npm run test -- --watch、长时间 E2E。这些命令不该堵在主会话里,提醒放进 tmux 或独立终端。
Hook 4:PreCompact 保存当前状态。 长任务场景特别值钱。刚讨论完几轮正准备切阶段,compact 一下把关键状态压没了。在 PreCompact 先保存当前目标、已完成、未完成、当前风险。
Hook 5:SessionEnd 自动生成 session summary。 Node/Next.js 项目经常是前端调一半、后端接口还没补完、明天继续这种模式。没有 session summary,第二天只能靠自己重新回忆上下文。
六、最小 Hook 配置
先只做三件事:改代码后发现最容易漏的低级问题、长会话切阶段前保状态、结束时留下可恢复信息。
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/scripts/post-edit-typecheck.js"
},
{
"type": "command",
"command": "node .claude/hooks/scripts/check-console-log.js"
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/scripts/pre-compact-save.js"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "node .claude/hooks/scripts/session-summary.js"
}
]
}
]
}
}
先把骨架立住再一点点补逻辑。不要等到"想好了所有高级玩法"才开始。
七、Hook 选择表
| Hook 场景 | 首批落地 | 原因 |
|---|---|---|
.ts/.tsx 编辑后 typecheck |
是 | 高频、机械、容易漏 |
console.log 审计 |
是 | 高频、低成本、收益高 |
| 长命令提醒后台化 | 是 | 减少主会话堵塞 |
| PreCompact 保存状态 | 是 | 长任务稳定性提升明显 |
| SessionEnd summary | 是 | 跨会话恢复收益很高 |
| 自动做完整 code review | 否 | 推理太重 |
| 自动决定任务拆分 | 否 | 属于 workflow / planning 层 |
| 接入大量阻断规则 | 暂缓 | 起步阶段体验容易变差 |
| 所有文件编辑后全量 build | 否 | 太重,开发体验差 |
社区参考:everything-claude-code 适合看完整生命周期 hook 设计(pre-compact、session-start、session-end、post-edit-typecheck);claude-code-best-practice 适合看更轻量的项目内 hook 组织方式。
八、小结
Hook 的价值不在于"多自动",而在于把高频、机械、容易漏的动作系统化。它不是 workflow 本身,不是复杂推理层,不是系统中心------是工作系统的治理带。
到这里工作系统已经从"有流程"进入了"有自动托底能力"。下一章进入另一个长期被低估的问题:上下文管理与长会话恢复。一旦工作系统开始稳定运转,最先撞上的通常不是功能问题,而是上下文质量开始掉。