# 自动化 · Hooks 让它按规矩来 · Claude Code · 终端里的编排台

**作者** Aklman · **章节** 07 / 11 · **首发** 2026.07 · **语言** 中文为主, 中英双语
**原文** https://library.aklman.com/books/claude-code/07-hooks
**全书 markdown** https://library.aklman.com/books/claude-code/llms.md
**上一章** https://library.aklman.com/books/claude-code/06-mcp/llms.md
**下一章** https://library.aklman.com/books/claude-code/08-headless/llms.md

> 本章来自 Aklman · Library, 完整免费阅读。允许 AI 摘读、引用、问答; 转载请保留作者署名与原文链接 (CC BY-NC-ND 4.0, https://library.aklman.com/license)。

---

> 有些事你不想靠「希望模型记得」：每次改完自动跑 formatter、提交前必须过 lint、绝不允许它碰生产库、每次收尾发个通知。这些不能是建议，得是规矩。Hooks 就是规矩：它们是你在特定时机（工具调用前后、会话结束时）自动执行的脚本 —— 由 harness 执行，不由模型自觉，所以它跳不过。这一章讲 hooks 能钉住哪些行为、几个真正值得设的（安全闸、质量门、通知），以及它和 CLAUDE.md「叮嘱」的根本区别：一个是请求，一个是硬约束。

有些事你不想靠「希望模型记得」:每次改完文件跑格式化,提交前必须过 lint,生产配置绝对不许碰,收工时给你发条通知。写进 CLAUDE.md,它十次里九次照做 —— 而这四件事你要的是十次里十次。差的那一次,不能靠更大的字体解决。这一章讲 hooks:不求模型自觉、由 harness 到点必然执行的规矩。

### I · 请求与规矩的分界线

这本书已经两次踩到这条线:第 3 章说记忆是「上下文,不是强制配置」[^3],第 4 章说 skill 由模型理解执行、结果可能有出入。hooks 站在线的另一侧 —— 定义原话:「用户定义的 shell 命令、HTTP 端点或 LLM 提示,在 Claude Code 生命周期的特定时点**自动执行**」。[^2]关键词是自动:hook 由 harness 在事件上触发,不经过模型的判断,它想跳也跳不过。官方把分工说得很干脆:必须每次发生、零例外的动作,用 hooks;CLAUDE.md 是建议,hooks 是确定。[^4]

---

### II · 装第一条:通知 + 格式化

hooks 住在 settings 文件里(`~/.claude/settings.json` 归你,`.claude/settings.json` 随仓库),结构三层:事件名 → matcher 筛工具 → 要跑的命令。下面这份配置装了两条最常用的:改完文件自动 prettier,Claude 等你输入时发桌面通知 —— 后者治好的病叫「盯终端」:

_两条入门 hook:PostToolUse 格式化、Notification 桌面提醒(macOS)_
```text title=".claude/settings.json"

```json
{
 "hooks": {
 "PostToolUse": [
 {
 "matcher": "Edit|Write",
 "hooks": [
 {
 "type": "command",
 "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
 }
 ]
 }
 ],
 "Notification": [
 {
 "matcher": "",
 "hooks": [
 {
 "type": "command",
 "command": "osascript -e 'display notification \"Claude 在等你\" with title \"Claude Code\"'"
 }
 ]
 }
 ]
 }
}
```

```

读法:`PostToolUse` 是「工具跑完之后」这个时点;matcher `Edit|Write` 表示只在编辑或写文件后触发;命令从 stdin 收到这次事件的 JSON,用 `jq` 取出文件路径喂给 prettier。[^1]不想手写 JSON 也行,这活可以派:直接说「写一个每次编辑后跑 eslint 的 hook」,让 Claude 自己给自己立规矩。[^4]装好后用 `/hooks` 面板核对 —— 它是只读的浏览器,改动仍走 settings 文件。[^1]

---

### III · 时点地图与否决权

生命周期上有约三十个可挂的事件,不用全记 —— 先认四个:`PreToolUse`,动手之前,唯一能**拦下**动作的时点;`PostToolUse`,动完之后,放质量动作;`Stop`,它想收工时,放验收闸;`SessionEnd`,会话结束,放通知和清理。[^2]hook 和 harness 的对话协议是退出码:exit 0 放行;**exit 2 否决** —— 动作被拦下,你写进 stderr 的理由会交还给 Claude,它读了会调整做法。[^1]要更细的裁决(允许、询问、改写输入),exit 0 加一段 stdout JSON。[^1]

PreToolUse 有一个值得单独记住的性质:它跑在权限模式检查**之前** —— 一条返回 deny 的 hook,连 `bypassPermissions` 模式也拦得住。[^1]这意味着 hooks 是比权限模式更硬的一层:模式管的是「问不问你」,hook 管的是「许不许做」。第 2 章那句「信不过的点用规矩钉死」,钉子就是它。

---

### IV · 真值得设的三类:安全闸、质量门、通知

别一口气挂三十个事件。多数人长期真正在用的是三类:

| 类型 | 挂在 | 典型规矩 |
|---|---|---|
| 安全闸 | `PreToolUse` | 碰 .env、migrations、生产配置 → exit 2 拦下 |
| 质量门 | `PostToolUse` / `Stop` | 改完跑 lint;检查不过不许收工 |
| 通知 | `Notification` / `SessionEnd` | 等输入、收工时提醒你,人离开终端 |

安全闸的写法在文档里就有现成样:一个脚本核对目标路径,命中保护清单就 exit 2 并在 stderr 里说明为什么 —— Claude 收到理由,换路走。[^1]质量门的顶配是 Stop hook,第 9 章已经预告过:收工前跑你的检查,不过不放行;也记得它的边界 —— 连续拦 8 次后 harness 会放行,它是门,不是牢,兜底仍在测试和 CI。[^4]

> 反向纪律:别把该是判断的事塞进硬规矩。「代码要优雅」做不成 exit 2;需要裁量的检查,用 prompt 型 hook(让一个模型按你的标准评估)或干脆交给第 9 章的 reviewer。hook 擅长的是黑白分明的事 —— 路径、命令、退出码。灰色地带塞进闸门,得到的不是纪律,是误拦。

动手 · 一晚上装齐三类:

- 装上面的通知 hook,从此让终端叫你,而不是你守终端。

- 把你仓库里最不可碰的路径(.env、migrations)写成 PreToolUse 安全闸,亲手触发一次确认它真拦。

- 把第 9 章那条验收检查升级成 Stop hook —— 从「你记得看」变成「不过不收工」。

> 叮嘱是请求,
> hook 是规矩

## 引用与参考

01 · Claude Code Docs · Hooks guide —— hooks 提供确定性控制,「保证某些动作必然发生,而不是依赖 LLM 选择去做」。配置放 settings 文件的 hooks 块:事件名 → matcher(如 Edit|Write)→ type: command 的命令;/hooks 面板只读浏览,增改要编辑 settings 或让 Claude 代写。协议:事件数据以 JSON 进 stdin;exit 0 放行,exit 2 拦下且 stderr 作为反馈交还给 Claude 让它调整;更复杂的决定用 exit 0 + stdout JSON(如 PreToolUse 的 permissionDecision: deny)。PreToolUse 在权限模式检查之前执行 —— 返回 deny 的 hook 连 bypassPermissions 也拦得住。示例即文档所载:PostToolUse 用 jq 取 file_path 交给 prettier;PreToolUse 脚本对 .env、.git/ 等保护路径 exit 2。截至 2026-07-17。  (Claude Code Docs · Hooks guide)
02 · Claude Code Docs · Hooks reference —— 定义原话:「hooks 是用户定义的 shell 命令、HTTP 端点或 LLM 提示,在 Claude Code 生命周期的特定时点自动执行」;事件约三十个,含 PreToolUse、PostToolUse、Stop、SessionStart、SessionEnd、Notification、UserPromptSubmit、SubagentStop 等;能力包括拦下工具调用、改写工具输入输出、注入上下文、发通知。截至 2026-07-17。  (Claude Code Docs · Hooks reference)
03 · Claude Code Docs · Memory —— CLAUDE.md 与 auto memory 是「上下文,不是强制配置」;要不论模型怎么决定都拦住某个动作,用 PreToolUse hook。截至 2026-07-17。  (Claude Code Docs · Memory)
04 · Claude Code Docs · Best practices —— 「hooks 用于必须每次发生、零例外的动作」,CLAUDE.md 的指令是建议性的,hooks 才是确定性的;可以直接让 Claude 替你写 hook;Stop hook 把检查设为收工硬门,连续拦 8 次后放行。截至 2026-07-17。  (Claude Code Docs · Best practices)

---

*自动化 · Hooks 让它按规矩来 · Claude Code · 终端里的编排台 · Aklman 著 · CC BY-NC-ND 4.0 · https://library.aklman.com/books/claude-code/07-hooks*
