Claude Code 从入门到精通(四):Hooks从原理到实践
1. 引言
在使用 Claude Code 进行开发时,你是否经常需要重复执行格式化代码、运行测试、拦截危险命令等操作?Hooks 作为 Claude Code 的事件驱动自动化系统,能将这些"重复但关键"的动作从"手动记忆执行"转化为"系统自动触发",同时支持安全校验、质量门禁等核心场景,实现"该阻断则阻断、该自动化则自动化"的高效开发流程。
此前我们已讲解 Claude Code 的安装集成、命令体系与数据流动,本文将结合实战场景,全面解析 Hooks 的核心原理、配置方式、实战案例与最佳实践,帮助你落地自动化与安全防护方案。
2. Hooks 核心概念
2.1 定义与价值
Hooks 是 Claude Code 的事件驱动拦截与自动化机制,可在特定事件触发时自动执行预设逻辑(脚本或提示),核心价值体现在四大场景:
-
安全防护 :拦截危险命令(如
rm -rf /)、保护敏感文件(如.env)、预防数据泄露; -
质量保证:强制代码格式化、验证测试覆盖率、检查编码规范;
-
合规审计:记录所有操作日志、生成审计报告、满足团队合规要求;
-
工作流自动化:会话初始化、工具执行后自动处理、集成外部工具。
2.2 核心特性
-
事件驱动:绑定 Claude Code 关键生命周期事件(如会话启动、工具执行);
-
双形态支持:命令型(运行 Shell 脚本,适合自动化)与提示型(LLM 智能判断,适合质量门禁);
-
分层配置:支持用户级(跨项目)与项目级(团队共享)配置,灵活适配不同场景;
-
决策可控:支持"允许/阻断/修改"操作,兼顾安全性与灵活性。
2.3 数据流动
Bash
用户请求
↓
Claude 决策
↓
[PreToolUse Hook] ← 在这里拦截和验证
↓
[批准/修改/拒绝]
↓
执行工具
↓
[PostToolUse Hook] ← 在这里记录和审计
↓
返回结果
2.4 核心价值
Bash
┌────────────────────────────────────────┐
│ 1. 安全防护 (Security) │
│ - 阻止危险命令 │
│ - 保护敏感文件 │
│ - 预防安全事故 │
└─────────────────┬──────────────────────┘
↓
┌────────────────────────────────────────┐
│ 2. 质量保证 (Quality Assurance) │
│ - 强制代码审查 │
│ - 验证测试覆盖率 │
│ - 检查代码规范 │
└─────────────────┬──────────────────────┘
↓
┌────────────────────────────────────────┐
│ 3. 合规审计 (Compliance & Audit) │
│ - 记录所有操作 │
│ - 生成审计日志 │
│ - 满足合规要求 │
└─────────────────┬──────────────────────┘
↓
┌────────────────────────────────────────┐
│ 4. 工作流自动化 (Workflow Automation) │
│ - 负载上下文 │
│ - 自动化任务 │
│ - 集成外部工具 │
└────────────────────────────────────────┘
2.3 与其他机制的区别
| 机制 | 触发方式 | 执行模型 | 适用场景 |
|---|---|---|---|
| Hooks | 事件驱动 | 拦截器 | 安全校验、自动化、审计 |
| Commands | / 手动触发 |
同步工具链 | 自定义工作流 |
| Agents | 任务驱动 | 自主循环 | 复杂多步骤任务 |
| Skills | 关键词触发 | 上下文注入 | 知识增强 |
3. 配置方式与层级
Claude Code 支持分层配置 Hooks,按"优先级从低到高"分为以下层级,高优先级配置会覆盖低优先级:
3.1 配置层级详情
| 配置层级 | 文件路径 | 适用场景 | 是否提交 Git |
|---|---|---|---|
| 用户级(全局) | ~/.claude/settings.json |
个人通用逻辑(如全局危险命令拦截、通知方式) | 否 |
| 项目级(共享) | {project}/.claude/settings.json |
团队统一规范(如格式化规则、测试要求) | 是 |
| 项目级(本地) | {project}/.claude/settings.local.json |
个人私有逻辑(如本地路径脚本) | 否(需加入 .gitignore) |
| 插件级 | plugin-directory/hooks/hooks.json |
插件内置 Hooks | 是(插件发布时) |
3.2 配置格式规范
-
项目级/用户级:直接定义事件与 Hook 逻辑,无需包装器:
JSON{ "PreToolUse": [ { "matcher": "Bash", "hooks": [{"type": "command", "command": "./.claude/hooks/guard-bash.sh", "blocking": true}] } ] } -
插件级 :需用
{"hooks": {...}}包装:JSON{ "description": "安全防护 Hooks", "hooks": { "PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "guard-bash.sh"}]}] } }
4. 事件类型全解析
Hooks 支持 8 种核心事件,覆盖 Claude Code 完整生命周期,不同事件对应不同使用场景:
| 事件 | 触发时机 | 支持 Hook 类型 | 核心用途 |
|---|---|---|---|
| SessionStart | 会话启动时 | 命令型 | 初始化环境、检查依赖、打印提示 |
| SessionEnd | 会话结束时 | 命令型 | 清理临时文件、记录统计数据 |
| UserPromptSubmit | 用户提交输入前 | 命令型 | 输入验证、关键词拦截、注入上下文 |
| PreToolUse | 工具执行前(Write/Edit/Bash 等) | 命令型 | 危险命令拦截、参数校验、敏感信息检测 |
| PostToolUse | 工具执行后 | 命令型 | 自动格式化、运行测试、生成变更摘要 |
| Stop | Claude 决定停止前 | 提示型 | 质量门禁(如检查测试是否通过) |
| SubagentStop | 子代理停止前 | 提示型 | 子任务验收(如检查代码审查是否完成) |
| Notification | Claude 发送通知时 | 命令型 | 转发通知(系统通知/Slack/飞书) |
关键事件说明
-
PreToolUse :安全防护核心事件,可拦截危险操作(如
rm -rf /、写入敏感信息); -
PostToolUse:自动化核心事件,工具执行后自动处理(如格式化代码、运行测试);
-
Stop:质量管控核心事件,通过 LLM 智能判断是否满足停止条件(如是否完成测试)。
5. Hook 实现方式
Hooks 支持两种实现方式,分别适配不同场景,可根据需求灵活选择:
5.1 命令型 Hooks(Command Hooks)
运行 Shell 脚本/命令,适合自动化、校验、审计等确定性逻辑,是最常用的实现方式。
核心特性
-
优势:执行快速(毫秒级)、逻辑确定、无额外成本、支持复杂自动化;
-
劣势:不支持智能推理、无上下文理解能力;
-
适用场景:路径验证、格式检查、危险命令拦截、自动化测试。
基础语法
JSON
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit", // 匹配工具(支持正则/模式串)
"hooks": [
{
"type": "command",
"command": "./.claude/hooks/format.sh", // 脚本路径
"blocking": false // 是否阻断主流程(true=阻断,false=后台执行)
}
]
}
]
}
}
上下文与退出码
- 上下文获取 :通过环境变量或
stdin(JSON 格式)获取上下文,常用变量:
| 变量名 | 说明 | 适用事件 |
|---|---|---|
TOOL_NAME |
工具名称(如 Write/Bash) | PreToolUse/PostToolUse |
TOOL_INPUT |
工具输入(JSON 字符串) | PreToolUse/PostToolUse |
TOOL_INPUT_FILE_PATH |
文件路径 | Write/Edit 相关事件 |
CLAUDE_WORKING_DIR |
当前工作目录 | 所有事件 |
-
退出码约定(控制流程):
-
exit 0:成功,继续主流程; -
exit 2:阻断(仅blocking=true时生效),拦截当前操作; -
exit 1:非阻断错误,记录日志但不中断流程。
-
5.2 提示型 Hooks(Prompt Hooks)
仅支持 Stop/SubagentStop 事件,通过 LLM 智能判断是否满足停止条件,适合质量门禁场景。
核心特性
-
优势:支持智能推理、理解上下文、灵活判断、易于维护;
-
劣势:执行较慢(秒级)、有 Token 成本、结果可能不一致;
-
适用场景:复杂质量校验、代码审查、智能决策。
基础语法
JSON
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "检查是否满足停止条件:1. 代码已格式化;2. 测试全部通过;3. 无未提交变更。返回 JSON:{\"decision\":\"stop\"|\"continue\",\"feedback\":\"说明\"}"
}
]
}
]
}
}
响应格式要求
必须返回 JSON 格式决策,示例:
JSON
{
"decision": "continue",
"feedback": "请先运行 `npm test` 并修复所有测试失败问题"
}
6. 实战案例模板
以下案例覆盖安全防护、自动化、质量管控核心场景,兼顾通用性与可复用性,需提前安装 jq(JSON 解析工具):brew install jq(macOS)或 apt install jq(Linux)。
6.1 安全防护:PreToolUse 拦截危险 Bash 命令
场景 :拦截 rm -rf /、git push --force 等高危命令,避免误操作。
配置(项目级 settings.json)
JSON
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "./.claude/hooks/guard-bash.sh", "blocking": true }
]
}
]
}
}
脚本(guard-bash.sh)
Bash
#!/bin/bash
set -euo pipefail
# 获取上下文(环境变量或 stdin)
input_json="${TOOL_INPUT:-$(cat || true)}"
cmd="$(echo "${input_json}" | jq -r '.command // empty' 2>/dev/null || true)"
# 允许显式跳过(加 [claude-allow-danger] 标记)
if [[ "${cmd}" == *"[claude-allow-danger]"* ]]; then
exit 0
fi
# 高危命令模式(可按需扩展)
deny_patterns=(
'(^|[[:space:]])rm[[:space:]]+-rf[[:space:]]+(/|~|\\$HOME)' # rm -rf 根目录/家目录
'(^|[[:space:]])git[[:space:]]+push([[:space:]].*)?--force' # git push --force
'(^|[[:space:]])chmod[[:space:]]+-R[[:space:]]+777' # 全局 777 权限
)
# 匹配高危命令则阻断
for pattern in "${deny_patterns[@]}"; do
if echo "${cmd}" | grep -Eq "${pattern}"; then
echo "❌ 已阻断高危命令:${cmd}" >&2
echo "提示:如确认执行,在命令末尾添加 [claude-allow-danger] 显式确认" >&2
exit 2
fi
done
exit 0
6.2 安全防护:PreToolUse 检测敏感信息
场景:写入文件前检测 API Key、密码等敏感信息,防止泄露。
配置
JSON
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "./.claude/hooks/check-secrets.sh", "blocking": true }
]
}
]
}
}
脚本(check-secrets.sh)
Bash
#!/bin/bash
set -euo pipefail
input_json="${TOOL_INPUT:-$(cat || true)}"
content="$(echo "${input_json}" | jq -r '.new_string // .content // ""' 2>/dev/null || true)"
# 敏感信息匹配模式(可扩展)
secret_patterns=(
'AKIA[0-9A-Z]{16}' # AWS Access Key
'ghp_[a-zA-Z0-9]{36}' # GitHub PAT
'sk-[a-zA-Z0-9]{32,}' # 通用 API Key
'(?i)password\\s*[:=]\\s*["\x27][^"\x27]+["\x27]' # 明文密码
'(?i)api[_-]?key\\s*[:=]\\s*["\x27][^"\x27]+["\x27]' # API Key
)
for pattern in "${secret_patterns[@]}"; do
if echo "${content}" | grep -Pq "${pattern}" 2>/dev/null; then
echo "❌ 检测到潜在敏感信息,已阻断写入" >&2
echo "建议:改用环境变量或密钥管理服务,不要直接写入文件" >&2
exit 2
fi
done
exit 0
6.3 自动化:PostToolUse 自动格式化 + 运行测试
场景:文件写入/编辑后自动格式化代码,并运行相关测试,保证代码质量。
配置
JSON
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "./.claude/hooks/format.sh", "blocking": false },
{ "type": "command", "command": "./.claude/hooks/auto-test.sh", "blocking": false }
]
}
]
}
}
格式化脚本(format.sh)
Bash
#!/bin/bash
set -euo pipefail
file="${TOOL_INPUT_FILE_PATH:-}"
[[ -n "${file}" && -f "${file}" ]] || exit 0
# 按文件后缀选择格式化工具
case "${file}" in
*.ts|*.tsx|*.js|*.jsx|*.json)
command -v prettier >/dev/null 2>&1 && prettier --write "${file}" >/dev/null 2>&1 || true
command -v eslint >/dev/null 2>&1 && eslint --fix "${file}" >/dev/null 2>&1 || true
;;
*.py)
command -v black >/dev/null 2>&1 && black "${file}" >/dev/null 2>&1 || true
command -v isort >/dev/null 2>&1 && isort "${file}" >/dev/null 2>&1 || true
;;
*.go)
command -v gofmt >/dev/null 2>&1 && gofmt -w "${file}" >/dev/null 2>&1 || true
;;
esac
exit 0
自动测试脚本(auto-test.sh)
Bash
#!/bin/bash
set -euo pipefail
file="${TOOL_INPUT_FILE_PATH:-}"
[[ -n "${file}" && -f "${file}" ]] || exit 0
# 跳过测试文件本身(避免循环测试)
if echo "${file}" | grep -Eq '(\\.test\\.|\\.spec\\.|/tests?/)'; then
exit 0
fi
# Node.js 项目测试
if [[ -f package.json && command -v npm >/dev/null 2>&1 ]]; then
if echo "${file}" | grep -Eq '\\.(ts|tsx|js|jsx)$'; then
echo "🧪 运行 JavaScript/TypeScript 测试"
npm test --silent 2>/dev/null || true
fi
fi
# Python 项目测试
if [[ -f pyproject.toml && command -v pytest >/dev/null 2>&1 ]]; then
if echo "${file}" | grep -Eq '\\.py$'; then
echo "🧪 运行 Python 测试"
pytest -q 2>/dev/null || true
fi
fi
exit 0
6.4 自动化:SessionStart 环境体检
场景:会话启动时自动检查依赖、Git 状态等,提前发现环境问题。
配置
JSON
{
"hooks": {
"SessionStart": [
{
"hooks": [
{ "type": "command", "command": "./.claude/hooks/session-init.sh", "blocking": false }
]
}
]
}
}
脚本(session-init.sh)
Bash
#!/bin/bash
set -euo pipefail
echo "🚀 Claude Code 会话初始化 - 环境体检"
echo "工作目录:${CLAUDE_WORKING_DIR:-$(pwd)}"
# Git 状态检查
if command -v git >/dev/null 2>&1 && git rev-parse --git-dir >/dev/null 2>&1; then
echo "Git 分支:$(git branch --show-current)"
changes="$(git status --porcelain | wc -l | tr -d ' ')"
[[ "${changes}" != "0" ]] && echo "⚠️ 存在未提交变更:${changes} 项"
fi
# Node.js 环境检查
if [[ -f package.json ]]; then
command -v node >/dev/null 2>&1 && echo "Node 版本:$(node --version)"
[[ -d node_modules ]] || echo "📦 提示:请运行 npm install 安装依赖"
fi
# Python 环境检查
if [[ -f requirements.txt ]]; then
command -v python >/dev/null 2>&1 && echo "Python 版本:$(python --version 2>&1 | head -n 1)"
[[ -n "${VIRTUAL_ENV:-}" ]] || echo "🐍 提示:请激活虚拟环境"
fi
exit 0
6.5 质量门禁:Stop 提示型 Hook 自检
场景:Claude 决定停止前,自动检查是否满足质量要求(如测试通过、无未提交变更)。
配置
JSON
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "作为质量门禁,检查以下条件是否全部满足:1. 代码已格式化;2. 所有测试通过;3. 无未提交的代码变更;4. 无敏感信息泄露。请返回 JSON 决策:{\"decision\":\"stop\"|\"continue\",\"feedback\":\"详细说明\"}"
}
]
}
]
}
}
6.6 通知自动化:Notification 转发系统通知
场景:将 Claude Code 通知转发为系统通知(macOS),及时获取操作结果。
配置
JSON
{
"hooks": {
"Notification": [
{
"hooks": [
{ "type": "command", "command": "./.claude/hooks/notify.sh", "blocking": false }
]
}
]
}
}
脚本(notify.sh)
Bash
#!/bin/bash
set -euo pipefail
msg_json="${NOTIFICATION_MESSAGE:-$(cat || true)}"
title="$(echo "${msg_json}" | jq -r '.title // "Claude Code"' 2>/dev/null || true)"
message="$(echo "${msg_json}" | jq -r '.message // empty' 2>/dev/null || true)"
[[ -n "${message}" ]] || exit 0
# 优先使用 terminal-notifier,无则使用系统默认通知
if command -v terminal-notifier >/dev/null 2>&1; then
terminal-notifier -title "${title}" -message "${message}" -group "claude-code" >/dev/null 2>&1 || true
else
osascript -e "display notification \"${message}\" with title \"${title}\"" >/dev/null 2>&1 || true
fi
exit 0
7. 高级特性:Hookify 插件
Hookify 是简化 Hooks 创建的插件,支持用 YAML + Markdown 配置规则,自动生成脚本,无需编写复杂 JSON 和 Shell 代码,适合快速落地简单规则。
7.1 核心价值
-
简化配置:无需编写脚本,用自然语言描述规则;
-
快速迭代:支持交互式创建、启用/禁用规则;
-
易维护:规则文件结构化,便于团队共享。
7.2 基础配置格式
创建文件 .claude/hookify.{规则名}.local.md,格式如下:
Markdown
---
name: block-dangerous-rm
enabled: true
event: bash
pattern: rm\s+-rf
action: block
---
⚠️ **危险命令拦截**
已阻断 `rm -rf` 命令,避免误删重要文件。
如需执行,请确认路径后添加 [claude-allow-danger] 标记。
7.3 常用命令
-
创建规则:
/hookify Block rm -rf commands(自然语言描述); -
列出规则:
/hookify:list(查看所有启用的规则); -
配置规则:
/hookify:configure(交互式启用/禁用规则); -
帮助:
/hookify:help(查看使用说明)。
8. 最佳实践
8.1 安全设计原则
-
最小权限:仅监听必要事件、匹配相关工具,避免过度拦截;
-
多层防护 :结合
permissions.deny配置与 Hooks 拦截,双重保障; -
明确提示:阻断操作时输出清晰原因和解决方案,提升体验;
-
优雅降级:Hook 脚本失败时不阻断主流程,仅记录日志。
8.2 性能优化技巧
-
并行执行:多个 Hooks 配置在同一事件下,默认并行执行,减少耗时;
-
缓存结果:重复检查逻辑(如依赖审计)可缓存结果,避免重复计算;
-
短路求值:重要检查放前面,命中后直接退出,减少无效执行;
-
区分阻塞性 :耗时操作(如全量测试)设为
blocking=false,不影响开发流程。
8.3 团队协作规范
-
项目级 Hooks 与代码一起提交 Git,确保团队环境一致;
-
敏感逻辑(如 API Key)放在
settings.local.json,避免泄露; -
统一退出码和日志格式,便于问题排查;
-
定期审计 Hooks 配置,清理过期规则。
9. 故障排查
9.1 常见问题与解决方案
| 问题现象 | 可能原因 | 排查步骤 |
|---|---|---|
| Hook 不执行 | 脚本无执行权限、配置格式错误、事件/工具匹配失败 | 1. 给脚本加权限:chmod +x *.sh;2. 验证 JSON 格式:jq . settings.json;3. 启用调试:claude --debug="hooks" |
| 无故被阻断 | blocking=true 且脚本 exit 2 |
1. 查看脚本日志:bash hook.sh;2. 检查退出码:echo $?;3. 确认是否误匹配规则 |
| 执行变慢 | 脚本耗时过长、全量测试/扫描 | 1. 设为 blocking=false;2. 优化脚本(增量执行);3. 增加超时控制 |
| 环境变量取不到 | 环境差异、变量名错误 | 1. 同时支持 stdin 和环境变量;2. 打印上下文调试:echo $TOOL_INPUT |
9.2 调试技巧
-
启用详细日志 :
claude --debug="hooks" 2>&1 | grep -E "(Hook|PreToolUse|PostToolUse)"; -
手动测试脚本 :
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | bash guard-bash.sh; -
检查 Hook 加载 :在 Claude Code 中执行
/hooks,查看已加载的配置; -
验证匹配规则 :
echo "Write" | grep -E "Write|Edit"(检查 matcher 是否匹配工具名)。
10. 总结
Claude Code Hooks 是事件驱动的自动化与安全防护核心机制,通过命令型与提示型双形态、分层配置、灵活的事件绑定,可覆盖安全防护、质量保证、自动化等全场景需求。
落地建议:先从核心安全场景(危险命令拦截、敏感信息检测)入手,再逐步扩展到自动化(格式化、测试)和质量管控(Stop 门禁),结合 Hookify 插件快速落地简单规则,复杂场景用 Shell 脚本实现定制逻辑。
通过合理配置 Hooks,可将人为约束转化为流程自动化,减少重复工作,提升代码质量与开发效率。