本教程面向希望将Claude Code从"人机对话工具"升级为"无人值守自动化引擎"的开发者。你将掌握三大核心能力:Headless -p模式(非交互式单次执行)、Hooks生命周期钩子(工具调用前后拦截)、批量并行任务(/batch与shell并行模式)。学完后,你能构建从代码审查、批量迁移到CI/CD门禁的完整自动化流水线。
适合人群:已使用Claude Code 2周以上的开发者,熟悉基本命令和项目配置。
前置条件:
- Claude Code CLI已安装并登录(claude 命令可用)
- 了解Shell脚本基础(变量、循环、管道)
- 一个可供实验的Git仓库
- Claude Max订阅(部分功能需要)
正常使用Claude Code时,你面对的是一个全屏终端UI(TUI),可以打字交互、选择确认、查看进度。但在自动化场景中,你需要的是:输入一段指令,拿到一段结果,没有交互,没有等待确认。
这就是Headless模式——通过 -p(或 --print)标志激活的非交互式执行模式。
flowchart LR
A[Shell脚本 / CI管道] -->|"claude -p '指令'"| B[Claude Code Headless]
B -->|"JSON / Text / Stream"| C[标准输出stdout]
C --> D[管道处理 / jq解析 / 文件重定向]
style A fill:#4A90D9,color:#fff
style B fill:#7B68EE,color:#fff
style C fill:#50C878,color:#fff
style D fill:#FF8C00,color:#fff
# 最简用法:直接输出纯文本
claude -p "解释当前项目的架构"
# 管道输入:把文件内容喂给Claude
cat error.log | claude -p "总结日志中的关键错误"
# 重定向输出:结果保存到文件
claude -p "审查这个文件的安全漏洞" < app.py > security_report.txt
三种输出格式决定了你如何消费Claude的输出:
| 格式 | 标志 | 适用场景 | 关键特征 |
|---|---|---|---|
| text | --output-format text |
人类阅读、简单脚本 | 纯文本,无元数据 |
| json | --output-format json |
自动化处理、CI/CD | 结构化JSON含token/cost |
| stream-json | --output-format stream-json |
实时流式处理、进度监控 | NDJSON逐行输出事件 |
JSON输出格式详解——这是自动化的核心:
claude -p --output-format json "列出所有TODO注释"
返回结果结构:
{
"type": "result",
"subtype": "success",
"result": "实际响应文本,多行内容用\\n转义",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"total_cost_usd": 0.001234,
"duration_ms": 2500,
"usage": {
"input_tokens": 1024,
"output_tokens": 512,
"cache_read_input_tokens": 8192
},
"modelUsage": {
"claude-sonnet-4-6-20260515": {
"inputTokens": 1024,
"outputTokens": 512,
"costUSD": 0.001234
}
}
}
用jq提取关键字段:
# 只提取响应文本
claude -p --output-format json "项目的README说了什么" | jq -r '.result'
# 提取费用和token使用量
claude -p --output-format json "分析代码质量" | jq '{cost: .total_cost_usd, tokens: .usage}'
# 检查是否成功
claude -p --output-format json "运行测试" | jq -r '.subtype'
# 输出: success 或 error
当你给Claude一个需要几分钟才能完成的复杂任务时,stream-json 模式让你实时获取进度:
claude -p --output-format stream-json --verbose "重构整个auth模块" | while IFS= read -r line; do
echo "$line" | jq -r 'select(.type == "assistant") | .message.content[] | select(.type == "text") | .text' 2>/dev/null
done
Node.js中的流式消费更优雅:
import { spawn } from 'child_process';
async function* streamClaude(prompt) {
const proc = spawn('claude', [
'-p',
'--output-format', 'stream-json',
'--verbose',
prompt
]);
let buffer = '';
for await (const chunk of proc.stdout) {
buffer += chunk.toString();
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (!line.trim()) continue;
try {
const event = JSON.parse(line);
if (event.type === 'assistant') {
const text = event.message.content
.filter(c => c.type === 'text')
.map(c => c.text)
.join('');
yield text;
}
} catch (e) { /* 跳过不完整的JSON行 */ }
}
}
}
// 使用:实时打印Claude的输出
for await (const chunk of streamClaude('解释这个项目的测试策略')) {
process.stdout.write(chunk);
}
Headless模式下,Claude没有人类在场确认操作。你需要用 --allowedTools 精确控制它能做什么:
# 只读分析:不能修改任何东西
claude -p --allowedTools "Read,Grep,Glob" "分析项目的依赖关系"
# 只允许编辑文件
claude -p --allowedTools "Edit" "修复src/utils.ts中的类型错误"
# 允许编辑和git操作
claude -p --allowedTools "Edit,Write,Bash(git add *),Bash(git commit *)" "应用代码风格修复"
# 限制bash命令范围
claude -p --allowedTools "Edit,Bash(npm test),Bash(npm run lint)" "修复所有lint错误"
关键安全标志组合:
# 最大预算控制:防止意外超支
claude -p --max-budget-usd 0.50 "做一次快速的代码审查"
# 跳过所有权限确认(仅在受信任环境中使用!)
claude -p --dangerously-skip-permissions "执行自动化迁移"
# 自定义系统提示词
claude -p --system-prompt "你是一个专注于安全的代码审查专家" "审查这个认证模块"
默认情况下,每次 claude -p 都是独立的全新会话。如果你需要多轮对话,可以用 --resume 继续:
# 第一轮:创建会话
RESULT=$(claude -p --output-format json "分析项目的测试覆盖率")
SESSION_ID=$(echo "$RESULT" | jq -r '.session_id')
# 第二轮:在同一会话中继续
claude -p --output-format json --resume "$SESSION_ID" "根据上面的分析,生成改进建议"
这在CI场景中不太常用,但在长时间运行的自动化任务中很有价值。
Hooks是Claude Code的事件驱动扩展机制。你注册一个Shell命令,它会在特定生命周期事件发生时自动执行。不需要你手动触发——它由Claude Code运行时自动调用。
sequenceDiagram
participant U as 用户/Scheduler
participant C as Claude Code
participant H as Hook脚本
U->>C: 发起请求
Note over C: SessionStart事件触发
C->>H: Pre用户提示Hook
H-->>C: 修改/通过/拒绝
Note over C: Agent处理中...
loop 每次工具调用
C->>H: PreToolUse Hook
H-->>C: 允许/拒绝/修改参数
C->>C: 执行工具
C->>H: PostToolUse Hook
H-->>C: 记录/后处理
end
Note over C: 任务完成
C->>H: Stop Hook
H-->>C: 清理/通知
C-->>U: 返回结果
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
| PreToolUse | 工具执行之前 | 安全拦截、参数校验、权限控制 |
| PostToolUse | 工具执行之后 | 自动格式化、日志记录、通知 |
| Notification | Claude主动通知时 | 桌面通知、Slack/钉钉推送 |
| Stop | Agent完成任务时 | 清理临时文件、发送汇总报告 |
| UserPromptSubmit | 用户提交提示词时 | 注入上下文、模板渲染 |
Hooks在 .claude/settings.json 或 ~/.claude/settings.json 中配置:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "python3 .claude/hooks/pre_tool_use.py"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "bash .claude/hooks/on_complete.sh"
}
]
}
]
}
}
配置层级优先级(从高到低):
.claude/settings.json —— 团队共享的Hook规则~/.claude/settings.json —— 个人偏好/etc/claude/settings.json —— 组织强制策略Claude Code通过标准输入(stdin)向Hook脚本传递结构化JSON:
{
"session_id": "550e8400-e29b-41d4",
"tool_name": "Edit",
"tool_input": {
"file_path": "/home/user/project/src/auth.ts",
"old_string": "const token = 'hardcoded-secret'",
"new_string": "const token = process.env.AUTH_TOKEN"
},
"tool_output": "Successfully edited file",
"conversation_id": "conv-abc123"
}
Hook通过标准输出(stdout)返回结果,Claude Code根据返回内容决定后续行为:
#!/usr/bin/env python3
import sys, json
# 读取Claude传入的JSON载荷
data = json.loads(sys.stdin.read())
tool_input = data.get('tool_input', {})
file_path = tool_input.get('file_path', '')
# === 行为1:静默通过(不返回任何内容)===
# 直接退出即可,Claude继续执行
# === 行为2:拒绝操作 ===
if '.env' in file_path or 'secret' in file_path:
print(json.dumps({
"decision": "deny",
"reason": f"禁止修改敏感文件: {file_path}"
}))
sys.exit(0)
# === 行为3:修改参数 ===
# 拦截Bash命令中的危险操作
tool_name = data.get('tool_name', '')
if tool_name == 'Bash':
command = tool_input.get('command', '')
if 'rm -rf' in command or 'DROP TABLE' in command.upper():
print(json.dumps({
"decision": "deny",
"reason": f"检测到危险命令: {command}"
}))
sys.exit(0)
# === 行为4:添加额外信息 ===
print(json.dumps({
"decision": "approve",
"supplementary": "注意:该文件被3个模块引用,修改后请运行测试验证"
}))
案例1:自动格式化 —— PostToolUse
每次编辑文件后自动运行Prettier:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}]
}
]
}
}
案例2:安全拦截 —— PreToolUse
防止Claude修改敏感文件:
#!/usr/bin/env python3
# 文件: .claude/hooks/guard_sensitive.py
import sys, json, os
PROTECTED = ['.env', 'credentials', 'secret', '.pem', '.key']
data = json.loads(sys.stdin.read())
file_path = data.get('tool_input', {}).get('file_path', '')
for pattern in PROTECTED:
if pattern in file_path.lower():
print(json.dumps({
"decision": "deny",
"reason": f"安全策略:禁止修改包含'{pattern}'的文件"
}))
sys.exit(0)
案例3:Bash命令审计 —— PreToolUse
记录所有Bash命令到审计日志:
#!/bin/bash
# 文件: .claude/hooks/audit_bash.sh
read -r INPUT
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
TIMESTAMP=$(date -Iseconds)
SESSION=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
if [ -n "$COMMAND" ]; then
echo "[$TIMESTAMP] session=$SESSION command=$COMMAND" >> .claude/audit.log
fi
案例4:测试自动运行 —— PostToolUse
编辑测试文件后自动运行相关测试:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "FILE=\"$CLAUDE_FILE_PATH\"; if [[ \"$FILE\" == *.test.* ]] || [[ \"$FILE\" == *.spec.* ]]; then npx vitest run \"$FILE\" 2>&1 | tail -5; fi"
}]
}
]
}
}
案例5:完成通知 —— Stop Hook
任务完成后发送桌面通知:
#!/bin/bash
# 文件: .claude/hooks/notify_done.sh
read -r INPUT
COST=$(echo "$INPUT" | jq -r '.total_cost_usd // 0')
DURATION=$(echo "$INPUT" | jq -r '.duration_ms // 0')
# macOS通知
osascript -e "display notification \"费用: \$$COST | 耗时: ${DURATION}ms\" with title \"Claude Code任务完成\""
# Linux通知
# notify-send "Claude Code任务完成" "费用: \$$COST | 耗时: ${DURATION}ms"
案例6:SessionStart自动上下文注入
每次启动会话时自动加载项目状态:
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [{
"type": "command",
"command": "echo '当前分支: '$(git branch --show-current)' | 未提交更改: '$(git status --porcelain | wc -l)'个文件 | 最近3次提交:' $(git log --oneline -3 | tr '\\n' ', ')"
}]
}
]
}
}
Claude Code提供三种批量执行路径,各有适用场景:
flowchart TB
A[批量任务需求] --> B{任务类型?}
B -->|同一变换应用到多文件| C[/batch 命令]
B -->|不同指令对不同目标| D[Shell并行 -p]
B -->|需要精细控制流程| E[Agent SDK编排]
C --> C1[优势: 自动worktree隔离<br>自动PR创建]
D --> D1[优势: 灵活组合<br>并发可控]
E --> E1[优势: 完整编程控制<br>条件逻辑]
style A fill:#4A90D9,color:#fff
style C fill:#7B68EE,color:#fff
style D fill:#50C878,color:#fff
style E fill:#FF8C00,color:#fff
| 维度 | /batch |
Shell并行 -p |
Agent SDK |
|---|---|---|---|
| 触发方式 | 交互式斜杠命令 | 终端Shell脚本 | Node.js/Python程序 |
| 并行管理 | 自动(内部调度器) | 手动(& + wait) |
编程控制 |
| 文件隔离 | Git Worktree自动隔离 | 需手动创建worktree | 编程控制 |
| 结果输出 | 自动创建PR | stdout/stderr | 回调/Promise |
| 适用规模 | 5-30个独立单元 | 任意数量(受API限制) | 灵活 |
| 学习曲线 | 低 | 中 | 高 |
/batch 命令:代码库级迁移利器/batch 是v2.1.63引入的内置斜杠命令,专为"同一个变换规则应用到整个代码库"的场景设计。
使用方式——在Claude Code交互会话中输入:
/batch 把所有React class组件迁移到hooks
/batch 把lodash替换为原生JavaScript等价实现
/batch 给所有函数参数添加TypeScript类型注解
/batch 把数据库字段名从camelCase改为snake_case
三阶段内部执行流程:
阶段1: 研究与规划
├── 启动Explore子Agent扫描代码库
├── 识别目标文件、调用点、依赖关系
├── 拆分为5-30个独立工作单元
└── 确定验证方法(测试命令、现有测试套件)
阶段2: 并行执行
├── 每个单元启动一个后台Agent
├── 每个Agent在独立Git Worktree中工作
├── 实现 → 运行测试 → 代码审查(/simplify) → 提交
└── 推送并创建独立PR
阶段3: 进度追踪
├── 实时显示状态表格
└── 输出汇总:"22/24个单元已成功创建PR"
Git Worktree目录结构:
project/
├── .git/ # 共享Git数据库
├── .claude/
│ └── worktrees/
│ ├── batch-unit-1/ # 单元1的工作副本
│ │ └── src/...
│ ├── batch-unit-2/ # 单元2的工作副本
│ │ └── src/...
│ └── batch-unit-3/ # 单元3的工作副本
│ └── src/...
└── src/ # 主工作树(不受影响)
适用任务判断标准:
| 适合 /batch | 不适合 /batch |
|---|---|
| 框架迁移(React→Vue, Jest→Vitest) | 文件间有强依赖的变更 |
| API接口变更后更新所有调用点 | 目标不明确的探索性重构 |
| 命名规范统一化 | 单文件变更 |
| 库替换(axios→fetch封装) | 需要跨单元协调的工作 |
当你需要给不同文件发送不同指令,或需要更精细的并发控制时,用Shell脚本 + -p 模式:
基础并行模板:
#!/bin/bash
# batch_parallel.sh — 并行批量处理模板
MAX_PARALLEL=5 # 最大并发数
PROMPT_TEMPLATE="将 {} 从class组件迁移到hooks,保持功能不变"
FILES=$(cat files-to-migrate.txt)
count=0
for file in $FILES; do
prompt="${PROMPT_TEMPLATE/\{\}/$file}"
# 后台启动Claude实例
claude -p "$prompt" \
--allowedTools "Edit,Read,Grep,Glob" \
--output-format json \
> "results/$(basename $file).json" 2>&1 &
count=$((count + 1))
# 控制并发数
if [ $count -ge $MAX_PARALLEL ]; then
wait -n # 等待任意一个后台任务完成
count=$((count - 1))
fi
done
wait # 等待所有任务完成
echo "全部完成"
# 生成汇总报告
echo "=== 批量处理结果 ==="
for result in results/*.json; do
file=$(basename "$result" .json)
status=$(jq -r '.subtype' "$result" 2>/dev/null || echo "parse_error")
cost=$(jq -r '.total_cost_usd' "$result" 2>/dev/null || echo "0")
echo "$file: $status (\$$cost)"
done
用xargs实现更简洁的并行:
# 每个文件作为独立参数传入
cat files-to-migrate.txt | xargs -P 5 -I {} sh -c '
claude -p "给 {} 添加TypeScript类型注解" \
--allowedTools "Edit,Read" \
--output-format json \
> "results/$(basename {}).json"
'
# -P 5: 最多5个并行进程
# -I {}: 用文件路径替换占位符
带错误处理和重试的增强版:
#!/bin/bash
# batch_robust.sh — 带重试和错误处理的批量处理
MAX_PARALLEL=3
MAX_RETRIES=2
BUDGET_LIMIT=5.00 # 单任务最大费用(USD)
process_file() {
local file=$1
local attempt=1
local result_file="results/$(basename "$file").json"
while [ $attempt -le $MAX_RETRIES ]; do
echo "[尝试 $attempt] 处理: $file"
claude -p "修复 $file 中的所有lint错误,只修改必要的部分" \
--allowedTools "Edit,Read,Grep,Glob,Bash(npm run lint*)" \
--max-budget-usd $BUDGET_LIMIT \
--output-format json \
> "$result_file" 2>&1
# 检查结果
status=$(jq -r '.subtype' "$result_file" 2>/dev/null)
if [ "$status" = "success" ]; then
echo "[成功] $file"
return 0
fi
echo "[失败] $file (状态: $status)"
attempt=$((attempt + 1))
sleep 5 # 重试前等待
done
echo "[放弃] $file 达到最大重试次数"
return 1
}
# 导出函数供xargs使用
export -f process_file
export MAX_RETRIES BUDGET_LIMIT
# 并行执行
mkdir -p results
cat failed_files.txt | xargs -P $MAX_PARALLEL -I {} bash -c 'process_file "$@"' _ {}
# 统计结果
success=$(find results -name "*.json" -exec jq -r 'select(.subtype=="success") .subtype' {} \; | wc -l)
total=$(find results -name "*.json" | wc -l)
echo "结果: $success/$total 成功"
一个真实案例:50个React组件从class迁移到hooks。
| 方法 | 耗时 | 并发数 | API调用 |
|---|---|---|---|
| 顺序执行 | ~100分钟 | 1 | 50 |
| Shell并行(5) | ~20分钟 | 5 | 50 |
| Shell并行(10) | ~12分钟 | 10 | 50 |
| /batch命令 | ~15分钟 | 自动 | 50+ |
2026年4月Anthropic推出了Routines——为Claude Code配置定时、触发式、云端运行的自动化任务。它本质上是"cron for AI agents"。
flowchart TB
subgraph 触发方式
T1[定时调度<br>cron表达式]
T2[GitHub事件<br>PR/Issue/Push]
T3[API调用<br>Webhook触发]
end
subgraph Routine配置
R1[prompt: 执行指令]
R2[repo: 目标仓库]
R3[connectors: MCP连接]
R4[branch: 目标分支]
end
触发方式 --> Routine配置
Routine配置 --> E[云端Claude Code实例]
E --> F[创建PR / 更新Issue / 生成报告]
style T1 fill:#4A90D9,color:#fff
style T2 fill:#7B68EE,color:#fff
style T3 fill:#50C878,color:#fff
style E fill:#FF8C00,color:#fff
Claude Code的定时自动化分三层,从本地到云端:
| 层级 | 名称 | 运行位置 | 适合场景 |
|---|---|---|---|
| L1 | /loop 命令 |
本地终端 | 开发时的持续循环 |
| L2 | Desktop Scheduled Tasks | 本地cron/Task Scheduler | 个人定时任务 |
| L3 | Cloud Routines | Anthropic云端 | 团队级、跨仓库自动化 |
L1:/loop 命令——在当前会话中循环执行:
# 在Claude Code交互会话中
/loop 每5分钟检查一次测试是否通过,如果失败则尝试修复
L2:Desktop定时任务——用系统级调度器运行:
# crontab示例:每天凌晨2点运行代码审查
0 2 * * * cd /path/to/project && claude -p "检查最近的commit,审查代码质量" --output-format json > /tmp/review_$(date +\%Y\%m\%d).json
L3:Cloud Routines——通过Anthropic控制台或API配置:
{
"name": "每日依赖安全审查",
"prompt": "检查package.json中的所有依赖,对比已知漏洞数据库,生成安全报告。如果发现高危漏洞,创建一个修复PR。",
"repo": "my-org/my-project",
"branch": "main",
"schedule": "0 6 * * 1-5",
"connectors": ["npm-audit", "github-security"],
"on_complete": {
"create_pr": true,
"notify": ["slack:#security-alerts"]
}
}
Routines + Hooks = 完全无人值守的自动化闭环:
flowchart LR
A[Cloud Routine<br>每日凌晨触发] --> B[Claude Code<br>Headless模式]
B --> C{PreToolUse Hook<br>安全检查}
C -->|通过| D[执行任务<br>依赖更新/代码审查]
C -->|拒绝| E[终止并告警]
D --> F{PostToolUse Hook<br>自动测试}
F -->|通过| G[自动创建PR]
F -->|失败| H[回滚并通知]
G --> I[Stop Hook<br>发送汇总报告]
style A fill:#4A90D9,color:#fff
style C fill:#FF6B6B,color:#fff
style F fill:#50C878,color:#fff
style I fill:#FF8C00,color:#fff
让我们把所有知识组合起来,构建一个从代码提交到审查报告的全自动流水线。
project/
├── .claude/
│ ├── settings.json # Hook配置
│ ├── hooks/
│ │ ├── guard_dangerous.py # 安全拦截
│ │ ├── auto_format.sh # 自动格式化
│ │ └── notify.sh # 完成通知
│ └── scripts/
│ ├── batch_review.sh # 批量审查脚本
│ └── ci_review.sh # CI审查入口
├── .github/
│ └── workflows/
│ └── claude-review.yml # GitHub Actions配置
└── src/
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "python3 .claude/hooks/guard_dangerous.py"
}]
},
{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "python3 .claude/hooks/guard_dangerous.py"
}]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "bash .claude/hooks/auto_format.sh"
}]
}
],
"Stop": [
{
"hooks": [{
"type": "command",
"command": "bash .claude/hooks/notify.sh"
}]
}
]
}
}
#!/usr/bin/env python3
# .claude/hooks/guard_dangerous.py
import sys, json, os
# 受保护的文件和目录模式
PROTECTED_PATTERNS = [
'.env', '.env.local', '.env.production',
'credentials', 'secret', '.pem', '.key',
'id_rsa', '.ssh/',
'production.db', 'backup.sql'
]
# 危险的Bash命令模式
DANGEROUS_COMMANDS = [
'rm -rf /', 'rm -rf ~', 'rm -rf *',
'DROP TABLE', 'DROP DATABASE',
'curl.*|.*sh', 'wget.*|.*bash',
'chmod 777', 'chown root'
]
def check_file_access(file_path):
"""检查文件是否在保护列表中"""
if not file_path:
return None
for pattern in PROTECTED_PATTERNS:
if pattern in file_path:
return f"安全策略:禁止修改包含'{pattern}'的文件: {file_path}"
return None
def check_bash_command(command):
"""检查Bash命令是否包含危险操作"""
if not command:
return None
import re
for pattern in DANGEROUS_COMMANDS:
if re.search(pattern, command, re.IGNORECASE):
return f"安全策略:检测到危险命令模式: {pattern}"
return None
# 读取Claude传入的JSON载荷
try:
data = json.loads(sys.stdin.read())
except:
sys.exit(0) # 解析失败时静默通过
tool_name = data.get('tool_name', '')
tool_input = data.get('tool_input', {})
# 检查文件操作
if tool_name in ('Write', 'Edit'):
file_path = tool_input.get('file_path', '')
reason = check_file_access(file_path)
if reason:
print(json.dumps({"decision": "deny", "reason": reason}))
sys.exit(0)
# 检查Bash命令
if tool_name == 'Bash':
command = tool_input.get('command', '')
reason = check_bash_command(command)
if reason:
print(json.dumps({"decision": "deny", "reason": reason}))
sys.exit(0)
# 静默通过
sys.exit(0)
#!/bin/bash
# .claude/hooks/auto_format.sh
# 从环境变量获取文件路径
FILE_PATH="${CLAUDE_FILE_PATH:-}"
if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
exit 0
fi
# 根据文件类型选择格式化工具
case "$FILE_PATH" in
*.ts|*.tsx|*.js|*.jsx|*.json|*.css|*.md)
npx prettier --write "$FILE_PATH" 2>/dev/null
;;
*.py)
python3 -m black "$FILE_PATH" 2>/dev/null
python3 -m isort "$FILE_PATH" 2>/dev/null
;;
*.go)
gofmt -w "$FILE_PATH" 2>/dev/null
;;
esac
exit 0
#!/bin/bash
# .claude/scripts/batch_review.sh
# 用法: ./batch_review.sh [commit_range]
# 示例: ./batch_review.sh main..feature-branch
set -euo pipefail
COMMIT_RANGE="${1:-HEAD~5..HEAD}"
OUTPUT_DIR="reviews/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"
echo "=== 代码审查开始 ==="
echo "审查范围: $COMMIT_RANGE"
echo "结果目录: $OUTPUT_DIR"
# 获取变更的文件列表
CHANGED_FILES=$(git diff --name-only "$COMMIT_RANGE" | grep -E '\.(ts|tsx|js|jsx|py|go|rs)$' || true)
if [ -z "$CHANGED_FILES" ]; then
echo "没有需要审查的代码文件"
exit 0
fi
echo "待审查文件: $(echo "$CHANGED_FILES" | wc -l) 个"
# 并行审查每个文件
MAX_PARALLEL=3
count=0
for file in $CHANGED_FILES; do
[ ! -f "$file" ] && continue
base_name=$(basename "$file" | sed 's/\.[^.]*$//')
result_file="$OUTPUT_DIR/${base_name}.json"
claude -p \
"你是资深代码审查专家。审查文件 $file 的最近变更。
关注以下维度:
1. 安全漏洞(注入、XSS、敏感信息泄露)
2. 性能问题(不必要的循环、内存泄漏风险)
3. 代码质量(命名、结构、可维护性)
4. 错误处理(边界条件、异常捕获)
输出格式:
- 严重程度: HIGH/MEDIUM/LOW
- 问题描述
- 修复建议
- 涉及行号(如有)" \
--allowedTools "Read,Grep,Glob" \
--output-format json \
> "$result_file" 2>&1 &
count=$((count + 1))
if [ $count -ge $MAX_PARALLEL ]; then
wait -n
count=$((count - 1))
fi
done
wait
echo ""
echo "=== 审查完成,生成报告 ==="
# 合并所有审查结果
echo "# 代码审查报告" > "$OUTPUT_DIR/report.md"
echo "**审查范围**: $COMMIT_RANGE" >> "$OUTPUT_DIR/report.md"
echo "**审查时间**: $(date '+%Y-%m-%d %H:%M:%S')" >> "$OUTPUT_DIR/report.md"
echo "" >> "$OUTPUT_DIR/report.md"
total_cost=0
total_high=0
total_medium=0
total_low=0
for result in "$OUTPUT_DIR"/*.json; do
[ ! -f "$result" ] && continue
file_name=$(jq -r '.result' "$result" 2>/dev/null | head -1)
review=$(jq -r '.result' "$result" 2>/dev/null || echo "解析失败")
cost=$(jq -r '.total_cost_usd' "$result" 2>/dev/null || echo "0")
total_cost=$(echo "$total_cost + $cost" | bc)
# 简单统计严重程度
high=$(echo "$review" | grep -c "HIGH" || true)
medium=$(echo "$review" | grep -c "MEDIUM" || true)
low=$(echo "$review" | grep -c "LOW" || true)
total_high=$((total_high + high))
total_medium=$((total_medium + medium))
total_low=$((total_low + low))
base=$(basename "$result" .json)
echo "## $base" >> "$OUTPUT_DIR/report.md"
echo "$review" >> "$OUTPUT_DIR/report.md"
echo "" >> "$OUTPUT_DIR/report.md"
done
echo "" >> "$OUTPUT_DIR/report.md"
echo "---" >> "$OUTPUT_DIR/report.md"
echo "**统计**: HIGH=$total_high | MEDIUM=$total_medium | LOW=$total_low" >> "$OUTPUT_DIR/report.md"
echo "**总费用**: \$$total_cost" >> "$OUTPUT_DIR/report.md"
cat "$OUTPUT_DIR/report.md"
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 安装Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: 获取变更文件
id: files
run: |
FILES=$(git diff --name-only origin/main...HEAD | grep -E '\.(ts|tsx|js|py)$' | head -20)
echo "files=$FILES" >> $GITHUB_OUTPUT
- name: 运行Claude代码审查
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
mkdir -p review_results
for file in ${{ steps.files.outputs.files }}; do
[ ! -f "$file" ] && continue
claude -p \
"审查这个文件的变更,关注安全漏洞、性能问题和代码质量。
用中文输出审查意见,格式为GitHub PR评论。" \
--allowedTools "Read,Grep,Glob" \
--output-format json \
> "review_results/$(basename $file).json" || true
done
- name: 发布审查评论
run: |
for result in review_results/*.json; do
[ ! -f "$result" ] && continue
review=$(jq -r '.result' "$result" 2>/dev/null || echo "审查失败")
file=$(basename "$result" .json)
# 使用gh CLI发布PR评论
gh pr comment ${{ github.event.pull_request.number }} \
--body "## 📋 代码审查: $file
$review" || true
done
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
flowchart TB
subgraph 触发层
T1[开发者Push代码]
T2[定时调度<br>cron]
T3[手动触发<br>batch_review.sh]
end
subgraph Hook层
H1[PreToolUse<br>安全拦截]
H2[PostToolUse<br>自动格式化]
H3[Stop<br>完成通知]
end
subgraph 执行层
E1[Claude -p<br>Headless模式]
E2[/batch<br>并行迁移]
E3[Cloud Routine<br>云端定时]
end
subgraph 输出层
O1[审查报告<br>Markdown]
O2[自动PR<br>修复建议]
O3[Slack通知<br>汇总信息]
end
T1 --> E1
T2 --> E3
T3 --> E1
E1 --> H1
H1 --> H2
H2 --> O1
E2 --> O2
E3 --> H3
H3 --> O3
style 触发层 fill:#4A90D9,color:#fff
style Hook层 fill:#FF6B6B,color:#fff
style 执行层 fill:#7B68EE,color:#fff
style 输出层 fill:#50C878,color:#fff
自动化场景中,成本失控是最大风险:
# 单任务预算上限
claude -p --max-budget-usd 0.50 "快速代码审查"
# 用Haiku模型降低成本(简单任务)
claude -p --model haiku "给这个函数添加类型注解"
# 批量任务的总预算控制
TOTAL_BUDGET=10.00
SPENT=0
for file in $(cat files.txt); do
remaining=$(echo "$TOTAL_BUDGET - $SPENT" | bc)
if (( $(echo "$remaining <= 0" | bc -l) )); then
echo "预算已耗尽,停止处理"
break
fi
result=$(claude -p --output-format json --max-budget-usd 1.00 "处理 $file")
cost=$(echo "$result" | jq -r '.total_cost_usd')
SPENT=$(echo "$SPENT + $cost" | bc)
echo "已花费: \$$SPENT / \$$TOTAL_BUDGET"
done
#!/bin/bash
# 带检查点的批量处理
CHECKPOINT_FILE=".claude/checkpoint.txt"
touch "$CHECKPOINT_FILE"
for file in $(cat tasks.txt); do
# 跳过已完成的任务
if grep -q "^$file$" "$CHECKPOINT_FILE" 2>/dev/null; then
echo "[跳过] $file (已完成)"
continue
fi
# 执行任务
if claude -p "处理 $file" --allowedTools "Edit,Read" --output-format json > "results/$file.json"; then
echo "$file" >> "$CHECKPOINT_FILE"
echo "[完成] $file"
else
echo "[失败] $file — 将在下次运行时重试"
fi
done
自动化场景中必须遵守的安全规则:
| 规则 | 说明 | 实现方式 |
|---|---|---|
| 永远不要自动推送main | 自动PR只能推送到feature分支 | --allowedTools "Bash(git push origin feature-*)" |
| 限制文件修改范围 | 禁止修改配置文件、CI文件 | PreToolUse Hook拦截 |
| 费用上限 | 每个任务都有max-budget | --max-budget-usd |
| 审计日志 | 记录所有自动化操作 | PostToolUse Hook写日志 |
| 人工审批门禁 | 关键变更必须人工确认 | PR review required设置 |
| 训练营类型 | 适用性 | 建议教学时长 | 说明 |
|---|---|---|---|
| Claude Code中级班 | 高 | 3小时 | 重点关注Hooks和-p模式 |
| DevOps自动化营 | 高 | 4小时 | 重点CI/CD集成和Routines |
| 团队工程效率营 | 中 | 2.5小时 | 重点/batch和批量审查 |
| AI编程入门营 | 低 | 1小时 | 仅演示概念,实操要求高 |
实验环境要求:每个学员需要独立Git仓库、Claude Max订阅、终端环境(macOS/Linux优先)。
[!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 等场景全覆盖。
