5. Hooks and automation — 操作者忘记时系统记得的东西
Skills 的另一半。系统在事件时自动触发的流程,无需操作者调用。Hooks 覆盖的盲点时刻、晋升标准、实际轮转中的 hooks,以及要避免的陷阱。
这是 Alice Way 系列的第 5 篇。第 4 篇 Skills and slash commands 把反复出现的心智动作压缩成一行名称。本篇关于另一半——让流程即使在操作者没有调用名称时也能触发。
0. Hook 把可遗忘的心智外包给系统
操作者会忘记。昨天的决策、开始新会话前的状态、就在汇报前本该运行的验证——一天一次,轻而易举。
Skills 阻断了部分遗忘——调用名称,流程就运行。但如果调用本身被忘记,skill 就不会触发。有些时刻,即使是一个词的名称也不会浮现。
Hooks 覆盖那些时刻。无需依赖操作者的意识,系统在特定事件时自动触发流程。 这是把操作者心智的一部分外包给系统的行为。
什么值得外包是有约束的:「绝不能忘记但容易忘记」、「条件清晰到可以自动判断」、「触发时机可以绑定到一个事件上」。本篇是对那个外包标准和实际轮转中的 hooks 的记录。
Hook 机制本身借鉴自 Anthropic Claude Code 的 hooks 系统。本篇是如何使用那个机制的记录,而非对它的发明。
1. 有些时刻意识会一片空白
操作者最常忘记的,不是因为流程很难,而是因为流程必须打断注意力集中在其他事情上的时刻。
| 时刻 | 意识状态 | 容易被忘记的流程 |
|---|---|---|
| 会话开始后 | 回想"我做到哪了" | 检查记忆同步状态 |
| 代码修改后 | 如释重负——"完成了" | lint / 构建 / 测试验证 |
| 起草报告前 | 组织措辞——"怎么表达" | 检查工作区域外的变更 |
| 会话关闭前 | 收尾——"好,今天完了" | 工作日志、HANDOFF、推送 |
| 危险命令前 | 执行——"这就结束了" | 重新确认实际意图 |
在所有这些时刻,操作者的心智都在别处。「不要忘记」这样的原则无法阻止这一点,需要在系统层面触发。
Hooks 是触发装置。它们打断意识空白的时刻并强制执行流程。
2. Skill 和 hook 之间的边界
这两者经常被混淆。核心区别是一件事——谁调用它。
| 调用者 | 触发时机 | 操作者意识 | |
|---|---|---|---|
| Skill / slash command | 操作者明确 | 操作者决定 | 调用前知晓 |
| Hook | 系统自动 | 事件决定 | 只看到结果(或根本没注意到) |
Skill 需要操作者「做这个」的决定才能触发。Hook 无需它就触发。所以 hook 最大的价值是——即使在操作者没有决定的时刻,流程也得到保证。
同一套流程可以两种方式暴露。/verify 可以直接作为 slash command 调用,也可以在「完成」报告前自动触发。操作者有意识调用 = skill;系统自动触发 = hook——进入同一套流程的两个入口。
3. 晋升标准 — 哪些流程被做成 hook
并非每个流程都应该成为 hook。只有通过以下全部五条的才获得自动触发权限。
3.1 跳过代价大,且容易跳过
Hook 有认知成本——系统在操作者不知道的情况下做了某件事。要证明那个成本合理,跳过的代价必须足够大。未经验证的推送、没有新鲜记忆同步就开始的会话——这些损失立即显现。是 hook 领地。
便利级别的流程留作 skills,不是 hooks。
3.2 触发条件是明确的事件
Hook 绑定到特定事件。「会话开始」、「tool use 前」、「发送输出前」、「会话结束」——那类事情。如果事件是模糊的——「感觉对的时候」——它不是 hook。
3.3 决定是可自动判断的
Hook 触发后,做什么必须是可以自动判断的。「如果变更通过 lint,OK;否则阻断」——一个清晰的分支。需要额外操作者判断的流程通过 skill 调用,而不是 hook。
3.4 失败是安全的
如果 hook 失败,整个系统不能崩溃。因为 hooks 在操作者的意识之外运作,失败不会立即被注意到。所以失败必须被隔离影响。
3.5 输出是一个信号
Hook 的结果以一行到达操作者。清晰的信号如「OK」、「已阻断」、「警告」。长而模糊的输出把 hook 变成操作者视野中的噪声。
4. 实际轮转中的 hooks
我每天依赖的一部分 hooks。
4.1 SessionStart — 会话开始时
会话一启动,就打印一行记忆同步状态。"Memory sync: current"或"5 min old — refresh needed"。操作者读那一行,立即做出判断。
没有这个 hook——操作者每次都要有意识地检查「记忆是否是最新的」。注意力集中在别处的时刻,检查被忘记,工作就直接开始了。然后基于过时的状态做出决策。
4.2 PreToolUse — 危险命令前
在 rm -rf、force push、破坏性 SQL 等特定命令前触发。要么请求用户确认,要么基于策略阻断。
这个 hook 的价值是——系统强制一个「我真的想要这个吗」的停顿时刻。打断快速执行流程正是重点所在。
4.3 PreToolUse → 自动触发 /verify
在「完成」报告前自动运行 lint、构建、测试的 hook。就在操作者即将写下「完成」时,系统介入并强制验证。如果失败,报告被阻断。
操作者的如释重负时刻(「现在完了」)是最危险的。Hook 在那种释然中强制一次停顿。
4.4 Stop — 会话关闭时
会话即将结束的那一刻,检查工作日志是否已更新,以及 HANDOFF 是否包含下一次会话需要的信息。如果缺少什么,提醒操作者。
没有这个 hook——操作者就在「完成」状态下关闭了。下一次会话从丢失的上下文开始。
4.5 积累效果
这些本身都是小流程。但积累效果很大——系统填补了操作者每天意识空白的 5—6 个时刻。操作者的心智只需专注于决策;「绝不能跳过的流程」由系统持守。
5. 设计原则
我收敛出来的 hook 设计原则。
5.1 简短快速
Hook 打断操作者的流程。如果不够简短,流程就会中断。耗时超过一秒的 hooks 应该异步运行或显示清晰进度。如果操作者开始想「为什么停了」,hook 的价值就变负了。
5.2 输出是一行
Hook 结束时,操作者看到的是一行。详细日志进入单独的文件。"Memory sync: current"、"Verification passed: 3 tests OK"、"Blocked: 2 lint errors"——那种形式。
5.3 失败隔离
Hook 失败不能影响主工作。如果记忆同步失败,会话仍然开始(带警告)。如果验证 hook 失败,阻断报告,但保持工作活跃。
5.4 可绕过
有时操作者有意想绕过 hook——调试、临时工作。必须存在明确的绕过选项。绕过被记录,但不被阻断。
5.5 幂等
同一事件触发两次,应该产生相同结果,或者至少不破坏。Hooks 是自动触发的,所以无法避免重复事件投递。
6. 不应该做成 hook 的东西 — 陷阱
晋升标准的另一面。
6.1 替代操作者决策
「当代码看起来是这样时自动修复」的 hook 是危险的。自动修复往往朝着不同于意图的方向走。Hooks 应该止于通知和阻断;自动修复在操作者调用 skill 时发生。
6.2 触发太频繁
每次按键或每次文件保存都触发的 hooks 变成噪声。事件的自然频率至少应该在分钟量级。亚秒级触发会打断操作者的流程。
6.3 长输出
如果一个 hook 触发了 30 行日志,它会把主工作的输出淹没。长信息进文件;控制台只得到一行信号。
6.4 失败导致主工作崩溃
如果 hook 失败级联导致主工作崩溃,操作者就会关掉那个 hook。一旦关掉,就永远关掉了。所以失败隔离不容商量。
7. 组合 skills 和 hooks
来自第 4 篇——skills第 5 节的网络效应,在加入 hooks 后再扩展一步。
同一套流程以两种方式暴露:
| 流程 | Skill 调用 | Hook 触发 |
|---|---|---|
/verify | 操作者明确想要验证时 | "完成"报告前自动触发 |
/start <project> | 操作者进入项目时 | (无——操作者意图就是开始) |
/session-end | 操作者声明收尾时 | (Stop hook 只检查遗漏) |
| 记忆同步 | (无专用 skill) | SessionStart 自动 |
这样配对——操作者有意识时用 skill,意识空白时用 hook——同一套流程无论哪种方式都得到保证。决策权留在操作者手中;安全网由系统持守。
下载 — settings.json 示例
本文介绍的 hook 布局(SessionStart / UserPromptSubmit / PreToolUse / PostToolUse)加上权限允许/拒绝列表,打包成一个文件。拿去用,把 <project-root> 替换成你自己的项目路径。
shasum -a 256 settings.json
# expected: 60b5bf7fec33f92d9ddcc6ab4696747df6bb3dab14e8287b696d45fbd6c1abde8. 压缩成一条原则
Hook 设计的核心压缩成一句话:
「只有操作者很可能忘记的流程才由系统自动触发。其他一切留作操作者选择调用的 skill。」
这条成立时,hooks 成为减轻操作者心智负担的安全设备。它崩溃时,它们成为劫持操作者意图的噪声。
下一篇涵盖一个智能体不做所有事的结构——多智能体委托,即什么交给其他协作者,什么自己做。