AI API 中转站导航 提交中转站
教程 2026-05-26 浏览 2 次

Claude Code 从零到精通:多Agent协作开发完全教程-第七章:Hooks 事件钩子

第七章:Hooks 事件钩子

Hooks 让你在 Claude Code 的特定事件发生时自动执行操作。

7.1 Hook 的作用

Plaintext

┌──────────────────────────────────────────────┐

│ Hooks 工作原理 │

├──────────────────────────────────────────────┤

│ │

│ Claude Code 事件 → 触发 Hook → 执行 │

│ │

│ 例如: │

│ - 会话开始时 → 读取配置文件 │

│ - 工具调用前 → 检查权限 │

│ - 工具调用后 → 记录日志 │

│ - 提交代码前 → 运行 lint 检查 │

│ - 发送通知 → 同步到 Slack │

│ │

└──────────────────────────────────────────────┘

7.2 Hook 的四种类型

类型 说明 适用场景

command 执行 shell 命令 运行 lint、格式化、通知

http 发送 HTTP 请求 通知外部服务、记录日志

prompt 注入提示词到上下文 动态添加规范、提醒

agent 触发子agent 自动代码审查

7.3 配置 Hooks

在 .claude/settings.json 中配置(支持三个层级:用户全局、项目共享、项目本地):

JSON

{

"hooks": {

"SessionStart": [

{

"type": "command",

"command": "cat .claude/welcome.md",

"description": "显示欢迎信息和项目概览"

}

],

"PreToolUse": [

{

"tool": "Bash",

"type": "command",

"command": "echo '准备执行命令...'",

"description": "命令执行前的提示"

}

],

"PostToolUse": [

{

"tool": "Edit",

"type": "command",

"command": "npx eslint --fix $FILE",

"description": "编辑文件后自动 lint"

}

],

"PreCompact": [

{

"type": "prompt",

"prompt": "压缩时请务必保留:1.所有修改过的文件列表 2.测试命令 3.当前进度",

"description": "压缩前注入保留指令(减少信息丢失30%)"

}

]

}

}

💡 PreToolUse hook 的特殊能力:可以返回 allow(允许)、deny(拒绝)、ask(询问用户)来控制工具执行,非常适合做安全防护。

7.4 常见 Hook 场景

Hook 事件 用途 示例

SessionStart 会话开始时注入上下文 读取项目配置、显示最近变更

PreToolUse 工具调用前检查/拦截 权限检查、危险操作拦截

PostToolUse 工具调用后处理 自动格式化、运行测试

PreCompact 压缩上下文前 指定必须保留的信息

Stop Agent 停止时 保存进度、发送通知

Notification 通知事件 推送到 Slack/微信

7.5 Hook 执行生命周期与数据流

理解 Hook 的完整执行流程,是掌握"怎么生效"的关键:

Plaintext

┌─────────────────────────────────────────────────────────────┐

│ Hook 执行生命周期 │

├─────────────────────────────────────────────────────────────┤

│ │

│ ① 事件触发(如 SessionStart / PreToolUse) │

│ │ │

│ ▼ │

│ ② 查找匹配的 Hook 配置 │

│ - 按配置层级合并(managed > local > project > user) │

│ - 检查 matcher 是否匹配(正则匹配工具名等) │

│ │ │

│ ▼ │

│ ③ 构建 stdin JSON 输入 │

│ { │

│ "session_id": "abc-123", │

│ "cwd": "/path/to/project", │

│ "hook_event_name": "PreToolUse", │

│ "tool_name": "Bash", ← 仅工具相关事件 │

│ "tool_input": { "command": "..." } │

│ } │

│ │ │

│ ▼ │

│ ④ 执行 Hook(command / http / prompt / agent) │

│ │ │

│ ▼ │

│ ⑤ 处理输出 │

│ - command 类型:stdout 作为反馈/上下文 │

│ - command 类型:exit code 控制流程(0=继续, 2=阻止) │

│ - prompt 类型:注入文本到 Claude 对话上下文 │

│ │

└─────────────────────────────────────────────────────────────┘

关键点:Hook 的 stdin 会自动注入事件的上下文信息(JSON 格式),你的脚本可以读取并据此做出决策。

7.6 上下文注入机制详解

这是 Hooks 最强大的能力之一——在对话中动态注入信息,让 Claude 自动获取额外上下文。

方式一:prompt 类型 Hook(直接注入)

prompt 类型 Hook 会将指定文本直接注入到 Claude 的对话上下文中:

JSON

{

"hooks": {

"PreCompact": [

{

"type": "prompt",

"prompt": "压缩时请保留所有修改过的文件路径和测试命令",

"description": "压缩前注入保留指令"

}

],

"SessionStart": [

{

"type": "prompt",

"prompt": "当前项目使用 TypeScript + React,测试框架为 Vitest",

"description": "会话开始注入技术栈信息"

}

]

}

}

prompt 字段支持 $ARGUMENTS 占位符,会被替换为事件的实际参数。

方式二:command 类型 Hook 的 stdout 注入

对于 SessionStart 和 UserPromptSubmit 事件,command 类型 Hook 的标准输出(stdout)会被直接添加到 Claude 的上下文中:

JSON

{

"hooks": {

"SessionStart": [

{

"type": "command",

"command": "echo '## 项目状态' && git log --oneline -5 && echo '## 待修复问题' && cat .claude/todo.md",

"description": "注入项目状态和待办事项"

}

],

"UserPromptSubmit": [

{

"type": "command",

"command": "echo '当前分支: '$(git branch --show-current) && echo '未提交变更: '$(git status --short | wc -l)' 个文件'",

"description": "每次对话时注入 git 状态"

}

]

}

}

Plaintext

┌──────────────────────────────────────────────────────────┐

│ 上下文注入方式对比 │

├──────────────┬───────────────────────────────────────────┤

│ │ prompt 类型 command 类型 │

├──────────────┼───────────────────────────────────────────┤

│ 注入内容 │ 固定文本 脚本 stdout 输出 │

│ 是否动态 │ 静态(或用 $ARGUMENTS)完全动态 │

│ 适用场景 │ 固定规范、提醒 实时状态、环境信息 │

│ 注入时机 │ 事件触发时 事件触发时 │

│ 执行开销 │ 无 有(执行脚本) │

└──────────────┴───────────────────────────────────────────┘

💡 实用技巧:SessionStart 的 stdout 注入非常适合做"项目上下文预加载"——Claude 一启动就知道项目状态、最近改动、待办事项等。

7.7 PreToolUse 权限控制详解

PreToolUse 是最强大的 Hook 事件,可以在工具执行前拦截、允许或询问用户:

控制方式:Exit Code + JSON 输出

Plaintext

┌──────────────────────────────────────────────────────────┐

│ PreToolUse 控制流程 │

├──────────────────────────────────────────────────────────┤

│ │

│ 工具调用请求 (如: Bash "rm -rf /") │

│ │ │

│ ▼ │

│ PreToolUse Hook 执行 │

│ │ │

│ ├── exit 0 → ✅ 允许执行(默认) │

│ │ │

│ ├── exit 2 → 🚫 阻止执行(静默拦截) │

│ │ │

│ └── stdout JSON → 精细控制 │

│ { │

│ "hookSpecificOutput": { │

│ "permissionDecision": "allow" | "deny" | "ask"

│ } │

│ } │

│ - "allow": 允许执行,跳过用户确认 │

│ - "deny": 阻止执行,告知 Claude │

│ - "ask": 弹出确认框,让用户决定 │

│ │

└──────────────────────────────────────────────────────────┘

实战示例:危险命令拦截器

Bash

#!/bin/bash

.claude/hooks/safety-guard.sh

读取 stdin 中的工具调用信息

INPUT=$(cat)

TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')

COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

拦截危险命令

if [[ "$TOOL_NAME" == "Bash" ]]; then

if echo "$COMMAND" | grep -qE 'rm\s+-rf|drop\s+table|--force|reset\s+--hard'; then

echo '{"hookSpecificOutput":{"permissionDecision":"deny"}}'

exit 0

fi

fi

其他情况允许

exit 0

JSON

{

"hooks": {

"PreToolUse": [

{

"matcher": { "tool": "Bash" },

"type": "command",

"command": "bash .claude/hooks/safety-guard.sh",

"description": "拦截危险 shell 命令"

}

]

}

}

7.8 Matcher 匹配器

Matcher 用于精确控制 Hook 在哪些条件下触发,避免不必要的执行:

JSON

{

"hooks": {

"PreToolUse": [

{

"matcher": {

"tool": "Bash"

},

"type": "command",

"command": "bash .claude/hooks/check-bash.sh",

"description": "仅匹配 Bash 工具调用"

}

],

"PostToolUse": [

{

"matcher": {

"tool": "Edit|Write"

},

"type": "command",

"command": "npx prettier --write $FILE",

"description": "匹配 Edit 或 Write 工具(正则语法)"

}

]

}

}

匹配字段 说明 示例

tool 匹配工具名(支持正则) "Bash", "Edit|Write", ".*"

没有设置 matcher 的 Hook 会在每次对应事件触发时执行。建议总是设置 matcher 以避免性能损耗。

7.9 Hook 可用的环境变量

Hook 脚本可以通过 stdin JSON 获取丰富的上下文信息:

字段 说明 示例值

session_id 当前会话 ID "abc-123-def"

cwd Claude Code 工作目录 "/Users/dev/myproject"

hook_event_name 触发的事件名 "PreToolUse"

tool_name 工具名(仅工具事件) "Bash", "Edit"

tool_input 工具输入参数(仅工具事件) {"command": "npm test"}

transcript_path 对话记录文件路径 "/path/to/transcript.jsonl"

读取方式示例(Bash):

Bash

#!/bin/bash

INPUT=$(cat) # 从 stdin 读取 JSON

TOOL=$(echo "$INPUT" | jq -r '.tool_name')

CWD=$(echo "$INPUT" | jq -r '.cwd')

echo "工具: $TOOL, 目录: $CWD"

7.10 配置层级与优先级

Hook 可以在四个层级配置,高优先级的层级覆盖低优先级:

Plaintext

┌─────────────────────────────────────────────────┐

│ 配置层级(优先级从高到低) │

├─────────────────────────────────────────────────┤

│ │

│ ① managed (企业管理) 最高优先级 │

│ ~/.claude/settings.managed.json │

│ → 企业 IT 统一下发,用户无法覆盖 │

│ │

│ ② local (项目本地) │

│ .claude/settings.local.json │

│ → 个人本地配置,不提交到 Git │

│ │

│ ③ project (项目共享) │

│ .claude/settings.json │

│ → 团队共享规范,提交到 Git │

│ │

│ ④ user (用户全局) 最低优先级 │

│ ~/.claude/settings.json │

│ → 个人全局默认配置 │

│ │

├─────────────────────────────────────────────────┤

│ 合并规则:同一事件的 Hook 数组跨层级合并 │

│ (不是覆盖,而是拼接执行) │

└─────────────────────────────────────────────────┘

⚠️ 注意:不同层级的同一事件 Hook 会合并执行(数组拼接),而不是高优先级覆盖低优先级。优先级主要影响的是权限设置等其他配置项。

7.11 完整 Hook 配置示例

一个综合了多种 Hook 能力的实际项目配置:

JSON

{

"hooks": {

"SessionStart": [

{

"type": "command",

"command": "echo '📋 最近 5 条提交:' && git log --oneline -5 && echo '📌 当前分支:' $(git branch --show-current)",

"description": "会话启动时注入项目上下文"

}

],

"UserPromptSubmit": [

{

"type": "command",

"command": "echo '⚡ 未暂存变更:' $(git diff --stat --shortstat 2>/dev/null || echo '无')",

"description": "每次用户发送消息时注入 git 状态"

}

],

"PreToolUse": [

{

"matcher": { "tool": "Bash" },

"type": "command",

"command": "bash .claude/hooks/safety-guard.sh",

"description": "拦截危险 shell 命令"

}

],

"PostToolUse": [

{

"matcher": { "tool": "Edit|Write" },

"type": "command",

"command": "npx prettier --write $FILE 2>/dev/null; exit 0",

"description": "文件编辑后自动格式化"

}

],

"PreCompact": [

{

"type": "prompt",

"prompt": "压缩时务必保留:1.所有修改过的文件完整路径 2.测试运行命令 3.当前任务进度 4.已知问题",

"description": "压缩前注入保留指令"

}

],

"Notification": [

{

"type": "command",

"command": "osascript -e 'display notification \"Claude Code 有新消息\" with title \"CC 通知\"'",

"description": "macOS 系统通知"

}

]

}

}

返回列表
相关推荐

继续阅读

教程

Claude Code 从零到精通教程-多Agent协作开发完全教程目录及第一章

目录 •[第一章:认识AI开发的演进之路](https://liaohezuo.com/article/1) •[第二章:Claude Code 安装与入门](https://liaohezuo.co

教程

Claude Code 从零到精通:多Agent协作开发完全教程-第二章:Claude Code 安装与入门

第二章:Claude Code 安装与入门 2.1 安装 Claude Code 📖 官方安装文档:https://docs.anthropic.com/en/docs/claude-code/qu

教程

Claude Code 从零到精通:多Agent协作开发完全教程-第三章:CLAUDE.md — 你的开发规范圣经

第三章:CLAUDE.md — 你的开发规范圣经 CLAUDE.md 是 Claude Code 最核心的配置文件,它决定了 AI 的行为边界和开发质量。规范先行是多 Agent 开发的第一原则。 3

教程

Claude Code 从零到精通:多Agent协作开发完全教程-第四章:Skills 技能系统

第四章:Skills 技能系统 Skills 是 Claude Code 的工作流定义,用自然语言描述一系列操作步骤。可以理解为"给 AI 的标准操作流程(SOP)"。 4.1 Skills 是什么?