-
Notifications
You must be signed in to change notification settings - Fork 2
Hooks System
wangliang edited this page Jul 25, 2026
·
2 revisions
Claude Code hooks 如何在机械层面强制执行 PDCA 循环——防御体系的第四和第五层。
AGENTS.md 中的文字指令说"编码前必须读取记忆"。但在长会话、大量工具调用下,AI 可能跳过文字指令。Hooks 是机械约束——它们在特定生命周期事件中运行 shell 命令,可以通过非零退出码阻断会话。
graph TD
START[会话开始] --> SSH[SessionStart Hook]
SSH --> PROMPT[用户输入提示]
PROMPT --> UPSH[UserPromptSubmit Hook]
UPSH --> TOOL[AI 调用工具]
TOOL --> PTUH[PreToolUse Hook]
PTUH --> RESP[AI 生成响应]
RESP --> STOP[会话结束]
STOP --> STOPH[Stop Hook]
STOPH -->|exit 0| END[会话正常结束]
STOPH -->|exit 2| WAKE[唤醒 AI:完成 Act 阶段]
WAKE --> RESP
触发: Claude Code 会话开始。
用途: 验证项目环境就绪,提醒 PDCA。
检查内容:
-
CLAUDE.md和AGENTS.md是否存在 -
.github/agent/memory/目录是否存在 -
.claude/settings.local.json是否存在且有效
触发: 用户提交提示。
用途: 检测是否为编码任务,提醒 Plan 阶段。
匹配模式: 只对看起来像编码任务的提示触发——对话性问题不触发。
触发: AI 即将使用工具(Write、Edit、Bash 等)。
用途: 阻断危险操作,除非明确授权。
阻断内容:
- 未经用户明确请求的
git push - 未知主机的 SSH 连接
- 修改生产环境的
docker compose命令 - 项目目录外的文件删除
触发: Claude Code 会话即将结束。
用途: 验证 Act 阶段已完成——记忆文件已更新。
检查: task-history.md 在本会话中是否被修改。
- 未修改 → exit 2(阻断会话结束)
-
asyncRewake: true→ 唤醒 AI 并提示执行 Act
| 退出码 | 含义 |
|---|---|
| 0 | 记忆已更新——会话可结束 |
| 2 | 记忆未更新——会话被阻断,AI 被唤醒完成 Act |
Hooks 在 .claude/settings.local.json 中配置:
为避免 hooks 在每次文件变更时触发(README.md、package.json 等),hooks 限定在源码目录:
用户说:"src/ tests/"
→ 变为:^src/\\|^tests/
这个正则嵌入在 hook 脚本中。只有匹配此模式的文件变更才触发 hook 逻辑。
| 文件 | 用途 | 提交到 git? |
|---|---|---|
settings.json |
项目级设置 | ✅ 是 |
settings.local.json |
本地覆盖(hooks、个人偏好) | ❌ 否(gitignored) |
如果两个文件都有 hooks,settings.local.json 优先。如果两个都存在,安装程序警告:
⚠️ settings.json 和 settings.local.json 同时存在。
建议:将 hooks 只合并到 settings.local.json 中。
| Hook | Claude Code | Copilot | Cursor |
|---|---|---|---|
| SessionStart | ✅ | ❌ | ❌ |
| UserPromptSubmit | ✅ | ❌ | ❌ |
| PreToolUse | ✅ | ❌ | ❌ |
| Stop | ✅ | ❌ | ❌ |
Hooks 是 Claude Code 专属(第 4-5 层)。Copilot 和 Cursor 依赖第 1-3 层进行 PDCA 强制执行。
🧠 ai-coding-ok — AI 编程的 PDCA 记忆闭环。
GitHub · Issues · MIT License
{ "hooks": { "SessionStart": [{ /* 验证脚本 */ }], "UserPromptSubmit": [{ /* 检测编码任务,提醒 Plan */ }], "PreToolUse": [{ /* 安全阻断 */ }], "Stop": [{ /* 检查 task-history.md 是否更新 */ }] } }