Files
claude-code/docs/extensibility/hooks.mdx
claude-code-best d9174fa230 docs: 重写 Hooks,从源码解剖改为扩展机制设计分析
移除 TypeScript 代码、源码路径和完整的 JSON schema,
聚焦四种 Hook 能力的递进设计、异步 Hook 的非阻塞考量、
工作区信任的纵深防御和 Session Hook 的生命周期隔离。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-20 10:59:41 +08:00

149 lines
4.6 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Hooks"
description: "Hooks 是 Claude Code 的扩展机制——在工具调用前后注入自定义逻辑。理解四种 Hook 能力、匹配机制和安全防护。"
keywords: ["Hooks", "生命周期钩子", "拦截器", "PreToolUse", "Hook 协议"]
---
## 核心问题
Claude Code 提供了强大的内置功能但每个团队和工作流都不同。Hooks 让你可以在关键节点注入自定义逻辑——不需要修改 Claude Code 本身。
## Hook 事件
Hooks 覆盖 Agent 生命周期的所有关键节点:
| 阶段 | 典型事件 |
|------|---------|
| **会话** | 启动、结束、初始化 |
| **用户交互** | 提交消息、停止响应 |
| **工具执行** | 工具调用前、工具调用后(成功/失败) |
| **权限** | 权限请求、权限被拒 |
| **子 Agent** | 启动、停止 |
| **压缩** | 压缩前、压缩后 |
| **协作** | Teammate 空闲、任务创建/完成 |
## 四种 Hook 能力
Hook 不仅是"执行一个脚本"——它有四种不同的能力:
### 1. 拦截操作PreToolUse
在工具执行前拦截,可以阻止危险操作:
```json
{
"hookSpecificOutput": {
"permissionDecision": "deny",
"permissionDecisionReason": "不允许在生产分支上强制推送"
}
}
```
### 2. 修改行为
修改工具的输入或输出:
```json
{
"hookSpecificOutput": {
"updatedInput": { "command": "npm test -- --bail" }
}
}
```
PostToolUse 的 `updatedMCPToolOutput` 可以替换 MCP 工具的返回值——用于过滤敏感数据。
### 3. 注入上下文
向 AI 的对话中注入额外信息:
- `additionalContext` — 注入为用户消息AI 可以参考
- `systemMessage` — 显示为系统警告
### 4. 控制流程
阻止 Agent 继续执行:
```json
{
"continue": false,
"stopReason": "构建失败,停止执行"
}
```
**设计洞察**:四种能力从"被动观察"到"主动干预"递进。最简单的 Hook 只是记录日志,最强大的 Hook 可以阻止操作、修改输入、控制流程。
## 六种 Hook 类型
| 类型 | 执行方式 | 适用场景 |
|------|---------|---------|
| `command` | Shell 命令 | 通用脚本、CI 检查 |
| `prompt` | 注入到 AI 上下文 | 代码规范提醒 |
| `agent` | 启动子 Agent | 复杂分析任务 |
| `http` | HTTP 请求 | 远程服务、Webhook |
| `callback` | 内部 JS 函数 | 系统内置 Hook |
| `function` | 运行时函数 | Agent/Skill 内部使用 |
### 异步 Hook
Hook 进程的 stdout 第一行如果是 `{"async":true}`,系统将其转为后台任务。异步 Hook 完成后通过通知机制汇报结果。
**设计考量**:有些 Hook 需要长时间运行(如"等待 CI 结果"),不应该阻塞 Agent 的执行。异步 Hook 让这些操作在后台运行,完成后再通知 Agent。
## 匹配机制
### Matcher 模式
```
"Write" → 精确匹配
"Write|Edit" → 多值匹配
"^Bash(git.*)" → 正则匹配
"*" 或 "" → 通配所有
```
### if 条件
Hook 可以指定 `if` 条件,只在特定输入时触发:
```json
{
"command": "check-branch.sh",
"if": "Bash(git push*)"
}
```
条件使用与权限规则相同的语法——工具名 + 参数模式。Bash 工具还会进行 AST 级别的命令解析。
### 多来源合并
Hook 从多个来源汇聚:
- settings.json 中的配置user/project/local
- SDK 注册的回调
- Agent/Skill 的 frontmatter
- 运行时动态注册
同一命令可能在不同层级重复出现。系统按复合键去重,保留最后合并的层级。
## 安全防护
### 工作区信任
**所有 Hook 都要求工作区信任**。这是纵深防御——防止恶意仓库的 `.claude/settings.json` 在未信任的情况下执行任意命令。
**设计哲学**Hook 有执行任意命令的能力,这个能力不应该被不可信的来源获取。项目级配置是团队共享的,任何人都可以修改——信任检查确保只有用户明确信任的项目才能运行 Hook。
### 超时控制
Hook 有默认 10 分钟的超时限制,可以通过配置调整。超时后 Hook 进程被终止Agent 继续执行。
## Session Hook 的生命周期
Agent 和 Skill 可以注册 session Hook绑定到特定的 session ID。Agent 结束时自动清理——Agent A 的 Hook 不会泄漏到 Agent B 的执行中。
**设计考量**如果不自动清理Agent A 的 PreToolUse Hook 可能意外拦截 Agent B 的工具调用,导致难以调试的问题。
## 接下来
- **Skills** — 理解基于 Hook 的技能系统
- **MCP 配置** — 理解外部工具的注册
- **权限模型** — 理解 PreToolUse Hook 与权限系统的协作