首页 › tutorials › Claude Code Hooks全链路开发实战

概述

本教程面向已有Claude Code基础使用经验的开发者,系统讲解Hooks机制——从理解事件模型、配置schema,到编写生产级钩子脚本、调试排错、团队共享。学完后你将具备用Hooks构建确定性工作流的能力,让Claude Code在每次工具调用、文件编辑、会话启停时自动执行你定义的逻辑,彻底告别重复提醒AI的窘境。

适用人群:已安装Claude Code并完成至少一个项目的开发者,熟悉JSON配置和基础Shell脚本。


前置条件

项目 要求
Claude Code v1.0.20+(Hooks在早期版本中引入,建议最新版)
Shell环境 Bash/Zsh,支持标准输入输出
编辑器 任意(VS Code推荐)
基础知识 JSON配置、Shell脚本、正则表达式

验证Claude Code版本:

claude --version

第一章:Hooks机制全景理解

1.1 什么是Hooks

Hooks是用户定义的Shell命令、LLM提示或子Agent,在Claude Code生命周期的特定节点自动执行。它们提供确定性控制——不依赖AI"记住"规则,而是通过系统级机制强制执行。

核心价值: - 自动格式化:每次文件编辑后自动运行Prettier/ESLint - 安全防护:拦截危险命令(rm -rf、修改.env) - 上下文注入:会话启动或压缩后自动注入项目规范 - 工作流自动化:编辑后自动运行测试、Git操作 - 通知集成:任务完成后发送Slack/邮件通知

1.2 Hooks事件模型

Claude Code定义了多种Hook事件类型,每种在不同的生命周期节点触发:

┌─────────────────────────────────────────────────────────────┐
│                    Claude Code 生命周期                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  会话开始 ──→ [SessionStart] ──→ 对话循环 ──→ 会话结束     │
│                ↑                              ↓             │
│          注入上下文/规范              [Stop] 通知用户        │
│                                                             │
│  ┌──────────── 对话循环内部 ────────────┐                   │
│  │                                      │                   │
│  │  AI生成工具调用                       │                   │
│  │       ↓                              │                   │
│  │  [PreToolUse] ──→ 执行工具 ──→ [PostToolUse]            │
│  │   拦截/验证         ↓          格式化/通知               │
│  │                (Write/Edit/Bash/...)                    │
│  │                                      │                   │
│  │  上下文压缩                           │                   │
│  │       ↓                              │                   │
│  │  [Compaction] ──→ 注入关键上下文      │                   │
│  └──────────────────────────────────────┘                   │
└─────────────────────────────────────────────────────────────┘
事件 触发时机 典型用途
PreToolUse 工具调用之前 拦截危险操作、验证输入
PostToolUse 工具调用之后 自动格式化、运行测试
Notification Claude停止生成时 发送通知、触发后续流程
Stop 会话结束 清理临时文件、汇总报告
SubagentStop 子Agent完成时 聚合子任务结果

1.3 配置层级

Hooks可在三个层级配置,优先级从高到低:

  1. 项目级(.claude/settings.json)—— 团队共享,进入版本控制
  2. 用户级(~/.claude/settings.json)—— 个人偏好
  3. 企业级(管理员配置)—— 全组织强制策略

第二章:配置Schema详解

2.1 基本结构

Hooks配置在settings.json的hooks字段中:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "your-script.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ]
  }
}

2.2 字段详解

顶层分组(Hook Group):

{
  "matcher": "工具名匹配模式",   // 正则表达式,匹配工具名
  "hooks": [                     // 该匹配下要执行的钩子列表
    { "type": "command", "command": "..." },
    { "type": "prompt", "prompt": "..." }
  ]
}

Matcher字段: - 精确匹配:"Bash" —— 只匹配Bash工具 - 正则匹配:"Write|Edit" —— 匹配Write或Edit - 通配所有:".*" 或省略matcher —— 匹配所有工具

Hook类型: - "command" —— 执行Shell命令 - "prompt" —— 向AI注入提示文本(不执行Shell) - "subagent" —— 启动子Agent执行任务

2.3 环境变量

Hooks执行时可访问关键环境变量:

变量 含义 示例
$CLAUDE_TOOL_NAME 当前工具名 Bash, Write, Edit
$CLAUDE_TOOL_INPUT 工具输入(JSON字符串) {"command":"ls"}
$CLAUDE_FILE_PATH 涉及的文件路径 /src/app.ts

对于PostToolUse,还可以通过stdin获取工具输出结果。

2.4 退出码语义

退出码 含义 对Claude的影响
0 成功 正常继续
2 阻止+反馈 阻止工具执行,将stdout作为反馈返回Claude
其他非零 错误 记录错误但继续执行(取决于配置)

退出码2是实现安全防护的核心——它阻止操作并给Claude一个理由。


第三章:第一个Hook——5分钟实战

3.1 目标:自动格式化

最经典的Hook用例:每次Claude编辑文件后自动运行Prettier。

步骤1:在项目根目录创建.claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

步骤2:验证配置生效:

# 启动Claude Code,让AI编辑任意文件
claude
# > 请帮我修改 src/app.ts,把标题改成 "Hello Hooks"

预期结果:Claude编辑文件后,你会看到Prettier自动运行,文件被格式化。Claude的输出中会显示Hook执行信息。

3.2 常见问题

问题 原因 解决方案
Hook未触发 matcher写错 检查工具名大小写(Write不是write)
命令报错 文件路径含空格 用双引号包裹$CLAUDE_FILE_PATH
格式化卡住 Prettier缺少配置 确保项目有.prettierrc
所有文件都格式化 缺少忽略规则 添加.prettierignore

第四章:安全防护——拦截危险操作

4.1 阻止rm -rf

这是PreToolUse最强大的能力——在执行前拦截。

创建脚本.claude/hooks/block-dangerous.sh:

#!/bin/bash
# 从stdin读取工具输入JSON
INPUT=$(cat)

# 检查是否包含危险命令模式
COMMAND=$(echo "$INPUT" | jq -r '.command // empty')

DANGEROUS_PATTERNS=(
  "rm -rf /"
  "rm -rf ~"
  "DROP TABLE"
  "DROP DATABASE"
  "git push --force"
  "git reset --hard"
  "dd if="
  ":(){:|:&};:"
  "chmod -R 777 /"
  "mkfs"
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qi "$pattern"; then
    echo "⛔ 安全防护:检测到危险命令模式 '$pattern'。此操作已被阻止。如果确需执行,请手动在终端操作。"
    exit 2
  fi
done

exit 0

在settings.json中配置:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ]
  }
}

赋予执行权限:

chmod +x .claude/hooks/block-dangerous.sh

4.2 保护敏感文件

阻止Claude修改关键配置文件:

#!/bin/bash
# .claude/hooks/protect-files.sh
INPUT=$(cat)

# 提取文件路径
FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // .filePath // empty')

PROTECTED_FILES=(
  ".env"
  ".env.production"
  "credentials.json"
  "service-account-key.json"
  "deploy-keys.pem"
)

PROTECTED_PATTERNS=(
  "\.env$"
  "\.env\."
  "secret"
  "credential"
  "private.?key"
)

for protected in "${PROTECTED_FILES[@]}"; do
  if [[ "$FILE_PATH" == *"$protected"* ]]; then
    echo "🔒 文件保护:'$FILE_PATH' 是受保护文件,禁止修改。如需编辑,请手动操作。"
    exit 2
  fi
done

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if echo "$FILE_PATH" | grep -qiE "$pattern"; then
    echo "🔒 文件保护:'$FILE_PATH' 匹配敏感文件模式,禁止修改。"
    exit 2
  fi
done

exit 0

配置:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}

4.3 合并安全防护配置

将所有安全规则整合为一个完整的settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

第五章:上下文注入——让AI始终了解项目

5.1 SessionStart注入

会话启动时自动注入项目规范,无需写入CLAUDE.md:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ]
  }
}

SessionStart的prompt类型Hook:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "项目使用 React 18 + TypeScript + Vite。路由使用 react-router v6。状态管理用 Zustand。CSS 使用 Tailwind。测试框架 Vitest + Testing Library。所有组件使用函数式组件和 Hooks。"
          }
        ]
      }
    ]
  }
}

注意:SessionStart作为特殊事件,推荐使用prompt类型注入上下文。实际配置中,prompt类型hooks直接向Claude的上下文窗口追加文本,不执行Shell命令。

5.2 Compaction后注入

当对话上下文被压缩(compaction)时,关键信息可能丢失。通过Compaction Hook重新注入:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "[上下文恢复] 当前项目架构:前端 React 18 + Vite,后端 Node.js + Express,数据库 PostgreSQL。API遵循RESTful规范,使用JWT认证。请继续保持这一技术栈的编码风格。"
          }
        ]
      }
    ]
  }
}

5.3 动态上下文——基于Git分支注入

更高级的用法:根据当前Git分支动态注入不同规范:

#!/bin/bash
# .claude/hooks/dynamic-context.sh

BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")

case "$BRANCH" in
  "main"|"master")
    echo "⚠️ 当前在主分支。所有修改必须:1) 先创建feature分支 2) 通过PR合并 3) 通过CI检查。禁止直接push到main。"
    ;;
  "develop"*)
    echo "📌 当前在开发分支。请确保:1) 编写单元测试 2) 遵循Conventional Commits规范 3) 代码覆盖率不低于80%。"
    ;;
  "feature/"*)
    echo "🔧 功能开发中。完成后请:1) 运行完整测试套件 2) 更新相关文档 3) 创建PR到develop分支。"
    ;;
  "hotfix/"*)
    echo "🚨 紧急修复!请:1) 最小化改动范围 2) 添加回归测试 3) 同时修复main和develop。"
    ;;
esac

第六章:通知与工作流集成

6.1 任务完成通知

Claude完成任务后自动发送通知(通过Notification事件):

#!/bin/bash
# .claude/hooks/notify.sh

# 获取通知内容
MESSAGE=$(cat)

# macOS通知
if [[ "$OSTYPE" == "darwin"* ]]; then
  osascript -e "display notification \"Claude Code任务完成\" with title \"Claude Code\" sound name \"Glass\""
fi

# Linux通知
if command -v notify-send &>/dev/null; then
  notify-send "Claude Code" "任务完成" --icon=utilities-terminal
fi

# 可选:发送到Slack
# curl -X POST -H 'Content-type: application/json' \
#   --data "{\"text\":\"✅ Claude Code任务完成: $(date)\"}" \
#   "$SLACK_WEBHOOK_URL"

6.2 自动Git工作流

编辑后自动暂存和提交:

#!/bin/bash
# .claude/hooks/auto-git.sh
# PostToolUse - 在文件编辑后自动git add

FILE_PATH="$CLAUDE_FILE_PATH"

if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
  exit 0
fi

# 排除不需要自动暂存的文件
IGNORE_PATTERNS=("*.lock" "*.log" ".env*" "dist/" "node_modules/")

for pattern in "${IGNORE_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == $pattern ]]; then
    exit 0
  fi
done

git add "$FILE_PATH" 2>/dev/null
exit 0

6.3 编辑后自动运行测试

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=\"$CLAUDE_FILE_PATH\"; if [[ \"$FILE\" == *.test.* ]] || [[ \"$FILE\" == *.spec.* ]]; then npx vitest run \"$FILE\" 2>&1 | tail -5; elif [[ \"$FILE\" == src/**/*.ts ]] && [[ \"$FILE\" != *.d.ts ]]; then CORRESPONDING_TEST=\"${FILE%.ts}.test.ts\"; if [[ -f \"$CORRESPONDING_TEST\" ]]; then npx vitest run \"$CORRESPONDING_TEST\" 2>&1 | tail -5; fi; fi"
          }
        ]
      }
    ]
  }
}

第七章:高级模式——Prompt Hook与子Agent

7.1 Prompt类型Hook

Prompt类型Hook不执行Shell命令,而是直接向Claude注入文本指令。适合注入编码规范、项目上下文:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "编码规范检查提醒:请确保新代码遵循以下规则——1) 使用const而非let,除非需要重新赋值 2) 优先使用可选链(?.)和空值合并(??) 3) 函数不超过30行 4) 组件文件不超过200行。"
          }
        ]
      },
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "执行Shell命令前请注意:本项目使用pnpm作为包管理器,不要使用npm或yarn。Docker命令需要加--user参数。"
          }
        ]
      }
    ]
  }
}

7.2 多Hook链式执行

同一个matcher下可配置多个hooks,它们按顺序执行:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          },
          {
            "type": "command",
            "command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          },
          {
            "type": "command",
            "command": "echo \"[$(date)] Formatted: $CLAUDE_FILE_PATH\" >> .claude/format-log.txt"
          }
        ]
      }
    ]
  }
}

执行顺序:Prettier格式化 → ESLint修复 → 记录日志。如果其中任何一个返回退出码2,后续hooks不再执行。

7.3 条件式Hook——基于文件类型

#!/bin/bash
# .claude/hooks/smart-format.sh
# 根据文件扩展名选择格式化工具

FILE_PATH="$CLAUDE_FILE_PATH"

if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
  exit 0
fi

EXT="${FILE_PATH##*.}"

case "$EXT" in
  ts|tsx|js|jsx|json|css|md)
    npx prettier --write "$FILE_PATH" 2>/dev/null
    ;;
  py)
    python -m black "$FILE_PATH" 2>/dev/null
    python -m isort "$FILE_PATH" 2>/dev/null
    ;;
  go)
    gofmt -w "$FILE_PATH" 2>/dev/null
    ;;
  rs)
    rustfmt "$FILE_PATH" 2>/dev/null
    ;;
  java)
    google-java-format -i "$FILE_PATH" 2>/dev/null
    ;;
  *)
    # 未知文件类型,不做格式化
    ;;
esac

exit 0

第八章:调试与排错

8.1 调试模式

启用Hooks调试日志:

# 在Shell中设置环境变量
export CLAUDE_HOOK_DEBUG=1

# 或在.claude/settings.json中
{
  "env": {
    "CLAUDE_HOOK_DEBUG": "1"
  }
}

8.2 常见错误排查

问题1:Hook未触发

# 检查配置文件是否正确
cat .claude/settings.json | jq '.hooks'

# 验证JSON格式
jq . .claude/settings.json

检查清单: - [ ] 文件路径正确(.claude/settings.json) - [ ] JSON格式有效 - [ ] matcher拼写正确(区分大小写) - [ ] hooks数组格式正确 - [ ] Shell脚本有执行权限

问题2:Hook执行报错

# 手动测试Hook脚本
echo '{"command":"ls -la"}' | bash .claude/hooks/block-dangerous.sh
echo $?
# 应输出 0 或 2

# 检查脚本的Shell兼容性
shellcheck .claude/hooks/block-dangerous.sh

问题3:格式化循环

如果Prettier或ESLint的修改触发了新的Write/Edit事件,可能导致循环。解决方案:

#!/bin/bash
# .claude/hooks/safe-format.sh
FILE="$CLAUDE_FILE_PATH"

# 防重复标记
MARKER=".claude/.formatting-$(echo "$FILE" | md5sum | cut -d' ' -f1)"

if [[ -f "$MARKER" ]]; then
  rm "$MARKER"
  exit 0
fi

touch "$MARKER"
npx prettier --write "$FILE" 2>/dev/null || true

8.3 日志系统

为所有Hooks建立统一日志:

#!/bin/bash
# .claude/hooks/logger.sh —— 在每个Hook脚本中source此文件

LOG_FILE=".claude/hooks.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

log_hook() {
  local level="$1"
  local message="$2"
  echo "[$TIMESTAMP] [$level] $message" >> "$LOG_FILE"
}

log_hook "INFO" "Hook executed: $0, Tool: $CLAUDE_TOOL_NAME, File: $CLAUDE_FILE_PATH"

在各个Hook脚本中使用:

#!/bin/bash
source .claude/hooks/logger.sh
log_hook "INFO" "Starting format check for $CLAUDE_FILE_PATH"
# ... 实际逻辑 ...
log_hook "INFO" "Format check completed"

第九章:团队协作——Hooks工程化

9.1 项目Hooks目录结构

project-root/
├── .claude/
│   ├── settings.json          # Hooks配置入口
│   ├── hooks/
│   │   ├── README.md          # Hooks说明文档
│   │   ├── block-dangerous.sh
│   │   ├── protect-files.sh
│   │   ├── smart-format.sh
│   │   ├── auto-test.sh
│   │   ├── notify.sh
│   │   └── logger.sh          # 共享日志模块
│   └── hooks.log              # 运行日志(gitignore)
├── .gitignore
└── ...

.gitignore中添加:

.claude/hooks.log
.claude/.formatting-*

9.2 团队共享配置

将项目Hooks纳入版本控制,确保团队一致性:

# 初始化
git add .claude/settings.json .claude/hooks/
git commit -m "feat: add Claude Code hooks for project safety and automation"

团队成员拉取后自动生效,无需额外配置。

9.3 Hooks测试框架

为Hooks编写测试,确保可靠性:

#!/bin/bash
# .claude/hooks/test-hooks.sh

set -e

PASS=0
FAIL=0

assert_exit_code() {
  local test_name="$1"
  local expected="$2"
  local actual="$3"
  if [[ "$actual" == "$expected" ]]; then
    echo "✅ PASS: $test_name"
    ((PASS++))
  else
    echo "❌ FAIL: $test_name (expected=$expected, actual=$actual)"
    ((FAIL++))
  fi
}

# 测试1:安全命令应通过
echo '{"command":"ls -la src/"}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "Safe command passes" "0" "$?"

# 测试2:rm -rf应被阻止
echo '{"command":"rm -rf /"}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "rm -rf blocked" "2" "$?"

# 测试3:DROP TABLE应被阻止
echo '{"command":"echo \"DROP TABLE users;\""}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "DROP TABLE blocked" "2" "$?"

# 测试4:保护.env文件
echo '{"file_path":"./.env"}' | bash .claude/hooks/protect-files.sh
assert_exit_code ".env protected" "2" "$?"

# 测试5:普通文件可编辑
echo '{"file_path":"./src/app.ts"}' | bash .claude/hooks/protect-files.sh
assert_exit_code "Normal file allowed" "0" "$?"

echo ""
echo "═══════════════════════════"
echo "  Results: $PASS passed, $FAIL failed"
echo "═══════════════════════════"

[[ $FAIL -eq 0 ]] || exit 1

运行测试:

bash .claude/hooks/test-hooks.sh

预期输出:

✅ PASS: Safe command passes
✅ PASS: rm -rf blocked
✅ PASS: DROP TABLE blocked
✅ PASS: .env protected
✅ PASS: Normal file allowed

═══════════════════════════
  Results: 5 passed, 0 failed
═══════════════════════════

第十章:完整实战项目——全栈项目Hooks套件

10.1 项目场景

一个React + Node.js + PostgreSQL全栈项目,需要: 1. 自动格式化(Prettier + ESLint) 2. 安全防护(阻止危险命令、保护敏感文件) 3. 编辑后自动测试 4. Git分支规范注入 5. 任务完成通知

10.2 完整配置

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          },
          {
            "type": "prompt",
            "prompt": "本项目使用pnpm,不要使用npm或yarn。Docker命令需加--user $(id -u):$(id -g)。"
          }
        ]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          },
          {
            "type": "prompt",
            "prompt": "编码规范:TypeScript严格模式,React函数式组件,Zustand状态管理,Tailwind CSS。每个组件不超过200行,函数不超过30行。"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/smart-format.sh"
          },
          {
            "type": "command",
            "command": "bash .claude/hooks/auto-test.sh"
          },
          {
            "type": "command",
            "command": "bash .claude/hooks/auto-git.sh"
          }
        ]
      }
    ],
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/notify.sh"
          }
        ]
      }
    ]
  }
}

10.3 工作流全览

flowchart TB
    A[Claude Code 会话启动] --> B{工具调用?}

    B -->|Bash命令| C[PreToolUse: Bash]
    C --> C1[安全检查脚本]
    C --> C2[pnpm规范提示]
    C1 -->|exit 0| D[执行Bash命令]
    C1 -->|exit 2 阻止| E[返回错误给Claude]

    B -->|Write/Edit文件| F[PreToolUse: Write/Edit]
    F --> F1[敏感文件保护检查]
    F --> F2[编码规范注入]
    F1 -->|exit 0| G[执行文件编辑]
    F1 -->|exit 2 阻止| E

    D --> H[PostToolUse]
    G --> H

    H --> H1[智能格式化]
    H1 --> H2[自动运行测试]
    H2 --> H3[自动Git暂存]

    H3 --> I[Claude继续响应]

    I --> J{会话结束?}
    J -->|是| K[Notification Hook]
    K --> K1[发送桌面通知]
    K --> L[会话结束]

    J -->|否| B

    style C1 fill:#ff6b6b,color:#fff
    style F1 fill:#ff6b6b,color:#fff
    style E fill:#ffd93d,color:#333
    style K1 fill:#6bcb77,color:#fff

10.4 配置验证清单

部署前逐项验证:

# 1. JSON格式检查
jq . .claude/settings.json && echo "✅ JSON valid"

# 2. 所有脚本可执行
for f in .claude/hooks/*.sh; do
  test -x "$f" && echo "✅ $f" || echo "❌ $f (chmod +x needed)"
done

# 3. 依赖检查
command -v jq >/dev/null && echo "✅ jq" || echo "❌ jq missing"
command -v npx >/dev/null && echo "✅ npx" || echo "❌ npx missing"

# 4. 运行Hooks测试
bash .claude/hooks/test-hooks.sh

# 5. 端到端验证
echo "启动Claude Code并执行以下测试:"
echo "  a) 让Claude编辑一个.ts文件 → 应自动格式化"
echo "  b) 让Claude运行'rm -rf /' → 应被阻止"
echo "  c) 让Claude编辑.env → 应被保护"

第十一章:性能优化与最佳实践

11.1 性能原则

原则 说明
快速执行 Hook应<500ms完成,避免阻塞Claude
异步非阻塞 耗时操作(测试、通知)考虑后台执行
失败优雅 用\|\| true确保Hook失败不中断主流程
条件判断前置 先检查文件类型再执行具体操作

11.2 异步Hook模式

对于耗时操作(运行完整测试套件、发送通知),使用后台执行:

#!/bin/bash
# .claude/hooks/async-test.sh

FILE="$CLAUDE_FILE_PATH"

# 快速检查是否有对应测试
if [[ "$FILE" != *.ts ]] && [[ "$FILE" != *.tsx ]]; then
  exit 0
fi

TEST_FILE="${FILE%.ts}.test.ts"
[[ ! -f "$TEST_FILE" ]] && TEST_FILE="${FILE%.ts}.spec.ts"
[[ ! -f "$TEST_FILE" ]] && exit 0

# 后台运行测试,结果写入日志
(
  RESULT=$(npx vitest run "$TEST_FILE" 2>&1)
  echo "[$(date)] Test $TEST_FILE: $RESULT" >> .claude/hooks/test-results.log
) &

# 立即返回,不阻塞Claude
exit 0

11.3 配置分层策略

┌──────────────────────────────────────┐
│     企业级(管理员配置)              │  ← 安全策略、合规要求
│     所有项目强制执行                  │
├──────────────────────────────────────┤
│     用户级(~/.claude/settings.json)│  ← 个人偏好(主题、通知)
│     跨项目统一                       │
├──────────────────────────────────────┤
│     项目级(.claude/settings.json)  │  ← 项目特定规则
│     团队共享,进入版本控制            │
└──────────────────────────────────────┘

建议分配: - 企业级:阻止危险命令、保护敏感文件(强制) - 用户级:个人通知偏好、个人格式化工具 - 项目级:项目特定格式化规则、测试策略、编码规范注入

11.4 避免的常见陷阱

  1. 不要在Hook中执行长时间阻塞命令——Claude会等待Hook完成才继续
  2. 不要在PreToolUse中执行修改操作——只做检查和阻止
  3. 不要在PostToolUse中返回exit 2——PostToolUse的阻止语义与PreToolUse不同
  4. 不要依赖AI行为来触发Hook——Hook是确定性的,但AI不一定每次都调用相同工具
  5. 不要忽略跨平台兼容性——团队成员可能使用不同操作系统

第十二章:Hook与CLAUDE.md的协作

Hooks和CLAUDE.md各有分工,理解它们的关系能更好地组织项目规范:

维度 CLAUDE.md Hooks
本质 AI读取的文本指令 系统执行的代码/脚本
确定性 AI可能忽略 100%执行
适用场景 编码风格、架构决策 安全防护、自动化流程
可维护性 Markdown,易读 Shell脚本,需测试
执行时机 会话启动时加载 每次工具调用时触发

最佳实践: - CLAUDE.md:记录"应该做什么"(编码规范、架构说明) - Hooks:执行"必须做什么"(安全检查、自动格式化) - 两者互补:CLAUDE.md告诉AI项目背景,Hooks确保AI不犯低级错误


延伸阅读


参考来源

  1. Hooks Reference - Claude Code Docs — Anthropic官方Hooks参考文档,涵盖schema、事件类型、环境变量、退出码
  2. Automate Actions with Hooks - Claude Code Docs — 官方Hooks快速上手指南,包含实战示例
  3. Claude Code Hooks: Complete Guide with 20+ Examples — 社区综合指南,20+即用配置模板
  4. disler/claude-code-hooks-mastery - GitHub — 开源Hooks示例仓库,3.7k stars
  5. Claude Code Hooks: A Practical Guide - DataCamp — DataCamp教程,适合系统学习

训练营适用性评估:

训练营类型 适用性 预计时长 说明
Claude Code初级营 ⭐⭐ 2小时 建议只讲第1-3章(概念+第一个Hook)
Claude Code进阶营 ⭐⭐⭐⭐⭐ 4-6小时 全部章节,重点第4-7章
企业AI工程化营 ⭐⭐⭐⭐⭐ 6-8小时 全部章节+团队协作+CI/CD集成
DevOps自动化营 ⭐⭐⭐⭐ 3-4小时 重点第6、8、9章
安全工程营 ⭐⭐⭐ 2-3小时 重点第4、8章(安全防护+测试框架)

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入