主题
3.2 Hooks — 自动化工作流
学习目标
学完这节课,你将能够:
- 理解 Hooks 的三种类型及其触发时机
- 配置 PreToolUse / PostToolUse / Stop 钩子
- 实现自动格式化、安全检查、桌面通知等实用场景
- 在
settings.json中正确编写 Hook 配置
什么是 Hooks
想象你雇了一个助手帮你写代码。Hooks 就是你给这个助手立的"规矩":
- 写文件之前,先检查有没有写死的密钥(PreToolUse)
- 写完文件之后,自动跑一遍代码格式化(PostToolUse)
- 整个任务结束时,发一条桌面通知告诉你(Stop)
这些"规矩"一旦设定,每次都会自动执行,不需要你反复提醒。它们是真正的自动化——不是 AI "记住了要做",而是系统层面强制执行的脚本。
你说话 → [PreToolUse 钩子] → AI 执行工具 → [PostToolUse 钩子] → 继续对话
...
任务结束 → [Stop 钩子]三种 Hook 类型
PreToolUse — 工具执行前
在 Claude Code 调用工具(写文件、执行命令等)之前触发。适合做拦截和校验。
典型用途:
- 检查即将写入的文件是否包含硬编码密钥
- 阻止对特定目录的修改(比如保护
production/目录) - 在写文件前先备份原文件
PostToolUse — 工具执行后
在工具执行完成后触发。适合做自动修正和通知。
典型用途:
- 写完文件后自动运行
prettier/black格式化 - 执行命令后检查退出码,记录日志
- 修改代码后自动运行相关测试
Stop — 会话结束时
在 Claude Code 认为任务已完成、准备停下来时触发。适合做收尾检查。
典型用途:
- 发送桌面通知:"任务已完成"
- 运行完整的测试套件做最终验证
- 生成本次改动的摘要报告
实用案例
案例 1:自动格式化代码
每次 Claude Code 写完文件后,自动运行格式化工具,保证代码风格一致。
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}
]
}
}效果:AI 写完任何文件后,prettier 会自动格式化它。2>/dev/null || true 确保即使格式化失败也不会中断工作流。
[截图: 终端中显示 PostToolUse hook 自动格式化了刚写入的文件]
案例 2:安全检查 — 拦截硬编码密钥
在写文件之前,扫描内容是否包含可能的密钥或密码。
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"command": "~/.claude/hooks/check-secrets.sh"
}
]
}
}check-secrets.sh 脚本示例:
bash
#!/bin/bash
# 检查即将写入的内容是否包含疑似密钥
if echo "$CLAUDE_TOOL_INPUT" | grep -qiE '(api_key|secret|password|token)\s*[:=]\s*["\x27][A-Za-z0-9+/=]{16,}'; then
echo "BLOCKED: 检测到可能的硬编码密钥,请使用环境变量替代"
exit 1
fi
exit 0效果:如果 AI 试图写入包含硬编码密钥的代码,Hook 会阻止并给出提示。AI 会自动修正为使用环境变量的方式。
[截图: PreToolUse hook 拦截了一个包含 API_KEY 的文件写入,并显示了 BLOCKED 提示]
案例 3:桌面通知 — 任务完成提醒
长时间运行的任务完成后,发送系统通知,这样你可以去做别的事情。
json
{
"hooks": {
"Stop": [
{
"matcher": "",
"command": "osascript -e 'display notification \"Claude Code 任务已完成\" with title \"Claude Code\"'"
}
]
}
}macOS 用 osascript,Linux 用 notify-send:
json
{
"command": "notify-send 'Claude Code' '任务已完成'"
}[截图: macOS 右上角弹出的系统通知 "Claude Code 任务已完成"]
案例 4:自动运行测试
每次修改代码文件后,自动运行相关的测试文件。
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "~/.claude/hooks/auto-test.sh"
}
]
}
}bash
#!/bin/bash
# 只对源代码文件触发测试(排除测试文件本身和配置文件)
FILE="$CLAUDE_FILE_PATH"
if [[ "$FILE" == *.test.* ]] || [[ "$FILE" == *.spec.* ]] || [[ "$FILE" == *.config.* ]]; then
exit 0
fi
# 尝试查找对应的测试文件并运行
TEST_FILE="${FILE%.*}.test.${FILE##*.}"
if [ -f "$TEST_FILE" ]; then
npx jest "$TEST_FILE" --silent 2>/dev/null || true
fi配置教程
Hook 配置在 ~/.claude/settings.json 文件中。
第一步:打开配置文件
bash
# 如果文件不存在会自动创建
vim ~/.claude/settings.json或者直接让 Claude Code 帮你配:
你:帮我在 settings.json 中配置一个 PostToolUse hook,
每次写文件后自动运行 prettier 格式化[截图: settings.json 文件的完整 hooks 配置段落]
第二步:理解配置结构
json
{
"hooks": {
"PreToolUse": [
{
"matcher": "匹配的工具名,支持正则",
"command": "要执行的 shell 命令"
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "你的命令"
}
],
"Stop": [
{
"matcher": "",
"command": "你的命令"
}
]
}
}第三步:可用的环境变量
Hook 脚本中可以使用以下环境变量获取上下文:
| 环境变量 | 说明 | 可用阶段 |
|---|---|---|
$CLAUDE_FILE_PATH | 被操作的文件路径 | PreToolUse / PostToolUse |
$CLAUDE_TOOL_INPUT | 工具的输入内容 | PreToolUse |
$CLAUDE_TOOL_NAME | 当前工具名称 | PreToolUse / PostToolUse |
第四步:测试你的 Hook
配置保存后,下一次 Claude Code 执行对应操作时,Hook 会自动触发。建议先用简单的 echo 命令测试:
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"command": "echo 'Hook triggered for: $CLAUDE_FILE_PATH' >> /tmp/claude-hooks.log"
}
]
}
}然后让 Claude Code 创建一个测试文件,检查 /tmp/claude-hooks.log 是否有记录。
小结
- Hooks 是系统层面的自动化,不依赖 AI 的"记忆",每次都会强制执行
- 三种类型:PreToolUse(执行前拦截)、PostToolUse(执行后处理)、Stop(任务结束时收尾)
- 实用组合:格式化 + 安全检查 + 通知,三件套覆盖日常 90% 的自动化需求
- 配置在
~/.claude/settings.json的hooks字段中 - Hook 脚本返回非零退出码可以阻止操作(仅 PreToolUse)
安全提示:Hook 脚本以你的用户权限运行,拥有你系统上的全部权限。务必审查脚本内容,不要从不可信来源复制 Hook 配置。特别是
command字段——恶意命令可以删除文件、窃取数据。只使用你自己编写或完全理解的脚本。