本教程面向已经掌握Claude Code基础操作的开发者,系统讲解三大自动化核心能力:-p无头模式的参数与输出控制、Hooks生命周期事件的配置与实战、以及多任务并行编排的工程化方案。你将学会如何把Claude Code从"交互式聊天工具"转变为"可编程的自动化引擎",构建CI/CD流水线、批量代码审查、夜间自动重构等生产级工作流。
适用人群:有3个月以上Claude Code使用经验的开发者、DevOps工程师、技术团队负责人
学习目标:
- 掌握-p模式的6种输出格式与4类管道组合
- 理解Hooks的6大生命周期事件并编写实用Hook
- 构建完整的批量任务编排系统
- 实现生产级安全门禁与成本控制
| 条件 | 说明 |
|---|---|
| Claude Code | 版本 ≥ 1.0.70(支持--output-format stream-json) |
| Node.js | ≥ 18.0(Agent SDK依赖) |
| Shell | Bash 4+ 或 Zsh |
| API密钥 | ANTHROPIC_API_KEY已配置,或Max订阅已激活 |
| Git | 任何版本(批量任务需要worktree支持) |
验证环境:
# 检查Claude Code版本
claude --version
# 检查API连通性
claude -p "Reply with OK" --output-format json | jq '.result'
# 预期输出: "OK"
# 检查Agent SDK
npm list @anthropic-ai/claude-code 2>/dev/null || echo "SDK未安装,后续章节会引导安装"
-p无头模式深度解析Claude Code默认运行在交互式TUI(Terminal User Interface)模式下。当加上-p(即--print)标志后,它切换到无头模式——没有TUI、没有颜色、没有交互提示,直接将结果输出到stdout。
# 交互模式:进入REPL
claude
# 无头模式:单次执行,输出到stdout
claude -p "解释src/auth.py的认证流程"
这个看似简单的切换,背后是两种完全不同的工作范式:
flowchart LR
subgraph 交互模式
A[用户输入] --> B[TUI渲染]
B --> C[Agent思考]
C --> D[请求权限]
D --> E[用户批准]
E --> F[工具执行]
F --> G[结果展示]
G --> A
end
subgraph 无头模式
H[CLI参数/prompt] --> I[Agent思考]
I --> J[自动/预授权执行]
J --> K[stdout输出]
K --> L[退出码]
end
交互模式 -.->|'-p'标志| 无头模式
无头模式的关键参数分为三类:输入控制、输出控制、执行约束。
# ═══ 输入控制 ═══
claude -p "直接传入prompt"
echo "文件内容" | claude -p "分析这段代码" # 管道输入
claude -p "比较实现差异" < <(cat a.ts b.ts) # 进程替换
# ═══ 输出控制 ═══
claude -p "说明" --output-format text # 纯文本(默认)
claude -p "说明" --output-format json # 结构化JSON
claude -p "说明" --output-format stream-json # 流式JSON事件
# ═══ 执行约束 ═══
claude -p "重构auth模块" --max-turns 10 # 限制Agent轮次
claude -p "快速检查" --model haiku # 指定模型
claude -p "生成文档" --max-tokens 4096 # 限制输出token
JSON输出格式详解——这是生产自动化的基石:
{
"type": "result",
"subtype": "success",
"result": "重构已完成,修改了3个文件...",
"session_id": "sess_abc123",
"total_cost_usd": 0.0482,
"usage": {
"input_tokens": 3842,
"output_tokens": 1203,
"cache_read_input_tokens": 25000
}
}
关键字段解析:
- session_id:可用于--resume恢复会话
- total_cost_usd:单次调用成本,用于成本监控
- usage.cache_read_input_tokens:缓存命中的token数,反映prompt工程质量
#!/bin/bash
# analyze-file.sh — 分析单个文件
FILE="$1"
claude -p --output-format json \
"审查以下文件的代码质量,关注安全性、性能和可维护性:
返回JSON格式:{issues: [{severity, line, description}]}" \
< "$FILE"
#!/bin/bash
# review-diff.sh — 审查最近的代码变更
DIFF=$(git diff HEAD~1 --unified=5)
claude -p --output-format json \
"你是一位高级代码审查员。审查以下git diff:
$DIFF
对每个问题返回JSON:
{findings: [{severity: 'critical'|'warning'|'info',
file, line, message, suggestion}]}"
#!/bin/bash
# batch-scan.sh — 批量扫描目录下的所有文件
DIR="$1"
PATTERN="${2:-*.ts}"
find "$DIR" -name "$PATTERN" -type f | while read -r file; do
echo "=== 扫描: $file ==="
claude -p --quiet --output-format json \
"列出此文件中的所有TODO、FIXME和HACK注释。返回JSON数组。" \
< "$file" | jq -r '.result' 2>/dev/null
done
无头模式的真正威力在于与Unix管道的组合:
# 范式1:Claude → 文件
claude -p "生成User模型的CRUD API文档" > docs/user-api.md
# 范式2:文件 → Claude → 处理
cat error.log | claude -p "分析错误日志的根因" | tee analysis.md
# 范式3:Claude → Claude(链式处理)
claude -p "生成pytest测试用例" < src/calculator.py | \
claude -p "审查这些测试用例的覆盖率,补充边界测试"
# 范式4:Git → Claude → 决策
git log --oneline -20 | claude -p --output-format json \
"分析这20条commit,判断是否有破坏性变更" | \
jq -r '.result'
Claude Code的Agent循环中,你可以在prompt里写"请每次编辑后运行测试"。但AI可能会忘记、可能会跳过、可能会在"不必要"时跳过。Hooks把这个"建议"变成了"保证"。
Hooks是在Claude Code生命周期的特定时刻自动执行的shell命令。它们是确定性的——不受AI记忆或注意力影响,每次都会触发。
sequenceDiagram
participant U as 用户
participant CC as Claude Code
participant H as Hooks系统
Note over U,CC: 会话开始
U->>CC: 启动claude
CC->>H: SessionStart触发
H-->>CC: 加载项目上下文
Note over U,CC: 用户提交prompt
U->>CC: 输入指令
CC->>H: UserPromptSubmit触发
H-->>CC: 注入额外上下文/校验
Note over U,CC: Agent准备使用工具
CC->>H: PreToolUse触发
H-->>CC: 放行/阻止/修改
Note over U,CC: 工具执行完毕
CC->>H: PostToolUse触发
H-->>CC: 自动格式化/测试/日志
Note over U,CC: 需要用户注意
CC->>H: Notification触发
H-->>U: 发送Slack/桌面通知
Note over U,CC: Agent完成响应
CC->>H: Stop触发
H-->>CC: 生成总结/推送通知
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
SessionStart |
新会话创建时 | 加载项目上下文、同步外部数据 |
UserPromptSubmit |
用户提交prompt后、AI处理前 | 注入上下文、校验指令合法性 |
PreToolUse |
Agent调用工具前 | 安全审计、阻止危险操作 |
PostToolUse |
工具执行完成后 | 自动格式化、运行测试、记录日志 |
Notification |
Agent需要用户注意时 | 转发到Slack/桌面通知 |
Stop |
Agent完成响应后 | 生成总结、推送结果、触发下游 |
Hooks配置在.claude/settings.json中(项目级)或~/.claude/settings.json中(全局级):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/path/to/pre-bash-check.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "prettier --write $CLAUDE_FILE_PATH 2>/dev/null"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' '任务完成'"
}
]
}
]
}
}
关键字段解析:
- matcher:正则匹配工具名称。"Bash"只匹配Bash工具,"Write|Edit"匹配文件写入类工具
- type:目前仅支持"command"
- command:要执行的shell命令
- Hook脚本通过环境变量获取上下文(如$CLAUDE_FILE_PATH)
每个Hook执行时可以访问以下环境变量:
| 变量 | 说明 | 可用事件 |
|---|---|---|
CLAUDE_TOOL_NAME |
正在调用的工具名 | PreToolUse, PostToolUse |
CLAUDE_TOOL_INPUT |
工具输入参数(JSON) | PreToolUse, PostToolUse |
CLAUDE_FILE_PATH |
涉及的文件路径 | PostToolUse (Write/Edit) |
CLAUDE_SESSION_ID |
当前会话ID | 所有事件 |
CLAUDE_EXIT_CODE |
工具执行退出码 | PostToolUse |
#!/bin/bash
# .claude/hooks/session-start.sh
# 功能:在每次会话开始时,自动加载最近的git变更和TODO列表
echo "=== 项目状态快照 ==="
echo ""
echo "最近5条提交:"
git log --oneline -5 2>/dev/null
echo ""
echo "未完成的TODO(前20条):"
grep -rn "TODO\|FIXME\|HACK" src/ --include="*.ts" --include="*.py" 2>/dev/null | head -20
echo ""
echo "当前分支:$(git branch --show-current 2>/dev/null)"
echo "未提交变更:$(git status --short 2>/dev/null | wc -l)个文件"
配置:
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "bash .claude/hooks/session-start.sh"
}]
}]
}
}
#!/bin/bash
# .claude/hooks/pre-bash-guard.sh
# 功能:在执行Bash命令前,检查是否包含危险操作
INPUT="$CLAUDE_TOOL_INPUT"
COMMAND=$(echo "$INPUT" | jq -r '.command // empty')
# 阻止rm -rf /
if echo "$COMMAND" | grep -qE 'rm\s+-rf\s+(/\s|$)'; then
echo "BLOCK: 拒绝删除根目录操作"
exit 1
fi
# 阻止force push
if echo "$COMMAND" | grep -qE 'git\s+push.*--force'; then
echo "BLOCK: 拒绝force push到远程仓库"
exit 1
fi
# 阻止删除远程分支
if echo "$COMMAND" | grep -qE 'git\s+push.*:.*--delete|\-\-delete.*origin'; then
echo "BLOCK: 拒绝删除远程分支"
exit 1
fi
# 阻止在生产环境执行未验证的curl
if echo "$COMMAND" | grep -qE 'curl.*\|\s*sh|curl.*\|\s*bash'; then
echo "BLOCK: 拒绝通过管道执行远程脚本"
exit 1
fi
# 放行
exit 0
关键机制:Hook脚本以退出码
1退出时,会阻止该工具调用。退出码0则放行。这是构建安全门禁的核心机制。
#!/bin/bash
# .claude/hooks/post-format.sh
# 功能:在文件被编辑后,自动运行对应的格式化工具
FILE_PATH="$CLAUDE_FILE_PATH"
if [ -z "$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
;;
esac
#!/bin/bash
# .claude/hooks/post-test.sh
# 功能:当测试文件被修改时,自动运行对应的测试
FILE_PATH="$CLAUDE_FILE_PATH"
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# 只在测试文件变更时触发
if echo "$FILE_PATH" | grep -qE '(test|spec|_test)'; then
echo "检测到测试文件变更,运行测试..."
if [ -f "package.json" ]; then
npx jest --no-coverage "$FILE_PATH" 2>&1 | tail -5
elif [ -f "pytest.ini" ] || [ -f "pyproject.toml" ]; then
python -m pytest "$FILE_PATH" -v --tb=short 2>&1 | tail -10
fi
fi
#!/bin/bash
# .claude/hooks/notify-slack.sh
# 功能:将Claude Code的通知转发到Slack频道
SLACK_WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
MESSAGE="$1"
curl -s -X POST "$SLACK_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"text\": \"🤖 Claude Code: $MESSAGE\"}" \
> /dev/null 2>&1
#!/bin/bash
# .claude/hooks/stop-summary.sh
# 功能:在Agent完成响应后,生成变更摘要
# 收集本次会话的文件变更
CHANGED=$(git diff --name-only 2>/dev/null)
if [ -n "$CHANGED" ]; then
echo ""
echo "📋 本次会话变更摘要:"
echo "$CHANGED" | while read -r f; do
LINES=$(git diff --stat "$f" 2>/dev/null | tail -1)
echo " - $f $LINES"
done
# 检查是否有未运行的测试
if [ -f "package.json" ]; then
echo ""
echo "⏳ 提醒:运行 'npm test' 验证变更"
fi
fi
# 发送桌面通知(macOS)
if command -v osascript &>/dev/null; then
osascript -e 'display notification "Claude Code任务完成" with title "Claude Code"'
fi
flowchart TB
subgraph 模式A:串行批处理
A1[文件1] --> C1[Claude处理]
A2[文件2] --> C2[Claude处理]
A3[文件3] --> C3[Claude处理]
C1 --> R[汇总结果]
C2 --> R
C3 --> R
end
subgraph 模式B:并行Fan-out
B1[任务分发器] --> P1[Worker 1]
B1 --> P2[Worker 2]
B1 --> P3[Worker 3]
B1 --> P4[Worker N]
P1 --> AG[聚合器]
P2 --> AG
P3 --> AG
P4 --> AG
end
subgraph 模式C:MapReduce
M1[输入分割] --> MAP[Map阶段]
MAP --> SHUFFLE[Shuffle]
SHUFFLE --> REDUCE[Reduce阶段]
REDUCE --> OUT[最终输出]
end
适合:文件数量少(<20)、需要严格顺序、结果需要人工确认的场景。
#!/bin/bash
# batch-serial-review.sh
# 功能:串行审查所有变更文件
set -euo pipefail
# 获取本次PR的所有变更文件
FILES=$(git diff --name-only origin/main...HEAD -- '*.ts' '*.tsx' '*.py')
RESULTS_DIR="reviews/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$RESULTS_DIR"
TOTAL=$(echo "$FILES" | wc -l)
CURRENT=0
echo "$FILES" | while read -r file; do
CURRENT=$((CURRENT + 1))
echo "[$CURRENT/$TOTAL] 审查: $file"
# 使用-p模式进行无头审查
claude -p --output-format json --quiet \
"你是代码审查专家。审查以下文件的最近git diff。
关注:安全漏洞、性能问题、逻辑错误、可维护性。
输出JSON格式:{score: 1-10, issues: [{severity, line, message}]}" \
< "$file" > "$RESULTS_DIR/$(basename "$file").json"
# 提取评分
SCORE=$(jq -r '.result' "$RESULTS_DIR/$(basename "$file").json" 2>/dev/null | jq -r '.score' 2>/dev/null || echo "N/A")
echo " 评分: $SCORE/10"
# 成本追踪
COST=$(jq -r '.total_cost_usd // 0' "$RESULTS_DIR/$(basename "$file").json" 2>/dev/null)
echo " 成本: \$$COST"
done
echo ""
echo "✅ 审查完成。结果保存在 $RESULTS_DIR/"
echo "总成本统计:"
jq -s '[.[].total_cost_usd // 0] | add' "$RESULTS_DIR"/*.json 2>/dev/null | \
awk '{printf " $%.4f\n", $1}'
适合:文件数量多(20-100)、任务相互独立、需要快速完成的场景。
#!/bin/bash
# batch-parallel-scan.sh
# 功能:并行扫描项目中的安全漏洞
set -uo pipefail
MAX_PARALLEL=4 # 根据API限制调整
DIR="${1:-src}"
RESULTS_DIR="security-scan-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$RESULTS_DIR"
# 收集目标文件
mapfile -t FILES < <(find "$DIR" -type f \( -name "*.ts" -o -name "*.py" -o -name "*.go" \))
echo "🔍 扫描 ${#FILES[@]} 个文件,并行度 $MAX_PARALLEL"
# 使用GNU parallel或xargs进行并行处理
printf '%s\n' "${FILES[@]}" | xargs -P "$MAX_PARALLEL" -I {} bash -c '
FILE="{}"
BASENAME=$(basename "$FILE" .$(echo "$FILE" | sed "s/.*\.//"))
OUTFILE="$RESULTS_DIR/${BASENAME}_$(echo "$FILE" | md5sum | cut -c1-8).json"
claude -p --output-format json --model haiku --quiet \
"安全扫描此文件。查找:SQL注入、XSS、硬编码密钥、不安全的反序列化。
返回JSON:{vulnerabilities: [{type, severity, line, description}]}" \
< "$FILE" > "$OUTFILE" 2>/dev/null
# 统计发现
COUNT=$(jq -r ".result | .vulnerabilities | length" "$OUTFILE" 2>/dev/null || echo "0")
echo " $FILE: $COUNT 个发现"
' _
echo ""
echo "📊 汇总报告:"
# 聚合所有结果
jq -s '[.[] | .result.vulnerabilities // []] | flatten | group_by(.type) |
map({type: .[0].type, count: length, critical: map(select(.severity=="critical")) | length})' \
"$RESULTS_DIR"/*.json 2>/dev/null
适合:超大代码库、需要先分析再汇总的复杂任务。
#!/bin/bash
# batch-mapreduce.sh
# 功能:MapReduce式的代码库文档生成
set -uo pipefail
PROJECT_DIR="${1:-.}"
OUTPUT_DIR="docs-auto"
mkdir -p "$OUTPUT_DIR"
echo "🗺️ Map阶段:提取每个模块的API签名"
echo "========================================"
# MAP阶段:并行提取API
find "$PROJECT_DIR/src" -type f -name "*.ts" ! -path "*/node_modules/*" | \
xargs -P 4 -I {} bash -c '
FILE="{}"
MODULE=$(echo "$FILE" | sed "s|$PROJECT_DIR/src/||" | sed "s|/|_|g" | sed "s|\.ts$||")
claude -p --model haiku --quiet \
"提取此TypeScript文件中所有export的函数、类、接口的签名。
格式:{module, exports: [{name, type, signature, description}]}" \
< "$FILE" > "$OUTPUT_DIR/map_$MODULE.json" 2>/dev/null
'
echo ""
echo "🔄 Reduce阶段:生成模块文档"
echo "========================================"
# REDUCE阶段:汇总生成文档
cat "$OUTPUT_DIR"/map_*.json | \
claude -p --output-format text \
"根据以下各模块的API签名JSON数据,生成一份完整的API参考文档。
按模块分组,包含函数签名、参数说明、返回值。
使用Markdown格式。" > "$OUTPUT_DIR/API_REFERENCE.md"
echo "✅ 文档已生成: $OUTPUT_DIR/API_REFERENCE.md"
构建一个完整的PR自动化审查流水线,集成-p模式、Hooks和批量处理:
flowchart LR
A[PR创建] --> B[Git Hook触发]
B --> C[提取变更文件]
C --> D[并行Claude审查]
D --> E[结果聚合]
E --> F{质量门禁}
F -->|通过| G[自动Approve]
F -->|未通过| H[生成审查报告]
H --> I[发布PR评论]
J[PostToolUse Hook] -.->|自动格式化| D
K[PreToolUse Hook] -.->|安全检查| D
mkdir -p auto-review/{scripts,hooks,config}
cd auto-review
#!/bin/bash
# scripts/review-pr.sh
# 用法: ./scripts/review-pr.sh <base-branch> <head-branch>
set -euo pipefail
BASE="${1:-origin/main}"
HEAD="${2:-HEAD}"
REPORT_DIR="review-reports/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$REPORT_DIR"
echo "🔍 自动代码审查流水线"
echo " Base: $BASE"
echo " Head: $HEAD"
echo ""
# ═══ 第一阶段:提取变更 ═══
echo "📋 第一阶段:提取变更..."
CHANGED_FILES=$(git diff --name-only "$BASE"..."$HEAD" -- '*.ts' '*.tsx' '*.py' '*.go')
TOTAL=$(echo "$CHANGED_FILES" | grep -c . || echo "0")
if [ "$TOTAL" -eq 0 ]; then
echo "✅ 没有需要审查的代码文件"
exit 0
fi
echo " 发现 $TOTAL 个变更文件"
# ═══ 第二阶段:并行审查 ═══
echo ""
echo "🤖 第二阶段:AI并行审查..."
MAX_PARALLEL=3
SEVERITY_THRESHOLD=7 # 1-10分制,低于此分数需要人工审查
echo "$CHANGED_FILES" | xargs -P "$MAX_PARALLEL" -I {} bash -c '
FILE="{}"
SAFE_NAME=$(echo "$FILE" | tr "/" "_")
# 获取该文件的diff
DIFF=$(git diff "$BASE"..."$HEAD" -- "$FILE" 2>/dev/null)
if [ -z "$DIFF" ]; then
exit 0
fi
# 调用Claude进行审查
RESULT=$(claude -p --output-format json --model sonnet --quiet \
"你是资深代码审查专家。审查以下git diff。
文件: $FILE
Diff:
$DIFF
审查维度:
1. 正确性:逻辑错误、边界情况
2. 安全性:注入、权限、数据泄露
3. 性能:N+1查询、内存泄漏、不必要的计算
4. 可维护性:命名、复杂度、重复代码
返回JSON:
{
\"score\": <1-10>,
\"summary\": \"一句话总结\",
\"issues\": [{\"severity\": \"critical\"|\"warning\"|\"info\",
\"line\": <行号>,
\"category\": \"正确性\"|\"安全性\"|\"性能\"|\"可维护性\",
\"message\": \"问题描述\",
\"suggestion\": \"修复建议\"}]
}" 2>/dev/null)
# 保存结果
echo "$RESULT" > "$REPORT_DIR/${SAFE_NAME}.json"
# 提取评分
SCORE=$(echo "$RESULT" | jq -r ".result.score // 0" 2>/dev/null)
ISSUES=$(echo "$RESULT" | jq -r ".result.issues | length" 2>/dev/null)
echo " [$FILE] 评分: $SCORE/10, 问题: $ISSUES 个"
' _
# ═══ 第三阶段:质量门禁 ═══
echo ""
echo "🚪 第三阶段:质量门禁..."
# 聚合评分
AVG_SCORE=$(jq -s '[.[].result.score // 0] | add / length' \
"$REPORT_DIR"/*.json 2>/dev/null || echo "0")
TOTAL_ISSUES=$(jq -s '[.[].result.issues // [] | .[]] | length' \
"$REPORT_DIR"/*.json 2>/dev/null || echo "0")
CRITICAL=$(jq -s '[.[].result.issues // [] | .[] | select(.severity=="critical")] | length' \
"$REPORT_DIR"/*.json 2>/dev/null || echo "0")
echo " 平均评分: $AVG_SCORE/10"
echo " 总问题数: $TOTAL_ISSUES"
echo " 严重问题: $CRITICAL"
# ═══ 第四阶段:决策 ═══
echo ""
if (( $(echo "$AVG_SCORE >= $SEVERITY_THRESHOLD" | bc -l) )) && [ "$CRITICAL" -eq 0 ]; then
echo "✅ 审查通过!代码质量达标。"
EXIT_CODE=0
else
echo "❌ 审查未通过。需要人工审查。"
# 生成详细报告
jq -s '{
summary: {
total_files: length,
average_score: ([.[].result.score // 0] | add / length),
total_issues: ([.[].result.issues // [] | .[]] | length),
critical_issues: ([.[].result.issues // [] | .[] | select(.severity=="critical")] | length)
},
files: [.[] | {
file: .result.file,
score: .result.score,
issues: .result.issues
}]
}' "$REPORT_DIR"/*.json > "$REPORT_DIR/summary.json" 2>/dev/null
echo " 详细报告: $REPORT_DIR/summary.json"
EXIT_CODE=1
fi
# ═══ 成本统计 ═══
echo ""
TOTAL_COST=$(jq -s '[.[].total_cost_usd // 0] | add' "$REPORT_DIR"/*.json 2>/dev/null || echo "0")
echo "💰 本次审查成本: \$$TOTAL_COST"
exit $EXIT_CODE
// .claude/settings.json
{
"hooks": {
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "echo '📋 审查模式已激活 | 分支: '$(git branch --show-current)"
}]
}],
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "bash .claude/hooks/pre-bash-guard.sh"
}]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH 2>/dev/null || true"
},
{
"type": "command",
"command": "bash .claude/hooks/post-test.sh"
}
]
}],
"Stop": [{
"hooks": [{
"type": "command",
"command": "bash .claude/hooks/stop-summary.sh"
}]
}]
}
}
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整历史用于diff
- name: Setup Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
chmod +x scripts/review-pr.sh
bash scripts/review-pr.sh origin/main HEAD
# 如果生成了报告,发布为PR评论
if [ -f "review-reports/"*/summary.json ]; then
REPORT=$(find review-reports -name summary.json | head -1)
BODY=$(jq -r '
"## 🤖 AI代码审查报告\n\n" +
"| 指标 | 值 |\n|------|----|\n" +
"| 文件数 | " + (.summary.total_files | tostring) + " |\n" +
"| 平均评分 | " + (.summary.average_score | tostring) + "/10 |\n" +
"| 问题总数 | " + (.summary.total_issues | tostring) + " |\n" +
"| 严重问题 | " + (.summary.critical_issues | tostring) + " |\n\n" +
"### 问题详情\n\n" +
(.files[] |
"#### " + .file + " (评分: " + (.score | tostring) + ")\n" +
(.issues[] | "- **[" + .severity + "]** " + .message + "\n")
)
' "$REPORT")
# 使用gh CLI发布评论
echo "$BODY" | gh pr comment ${{ github.event.pull_request.number }} --body-file -
fi
- name: Upload Report
if: always()
uses: actions/upload-artifact@v4
with:
name: review-report
path: review-reports/
# 本地运行审查
./scripts/review-pr.sh origin/main HEAD
# 预期输出:
# 🔍 自动代码审查流水线
# Base: origin/main
# Head: HEAD
#
# 📋 第一阶段:提取变更...
# 发现 5 个变更文件
#
# 🤖 第二阶段:AI并行审查...
# [src/auth.ts] 评分: 8/10, 问题: 2 个
# [src/user.ts] 评分: 6/10, 问题: 4 个
# [src/api.ts] 评分: 9/10, 问题: 1 个
# [src/db.ts] 评分: 7/10, 问题: 3 个
# [src/utils.ts] 评分: 9/10, 问题: 0 个
#
# 🚪 第三阶段:质量门禁...
# 平均评分: 7.8/10
# 总问题数: 10
# 严重问题: 0
#
# ✅ 审查通过!代码质量达标。
#
# 💰 本次审查成本: $0.1247
| 场景 | 推荐模型 | 预估单次成本 | 月度预估 |
|---|---|---|---|
| 单文件审查 | sonnet |
$0.01-0.05 | $5-20 |
| PR全量审查 | sonnet |
$0.05-0.20 | $20-80 |
| 批量文档生成 | haiku |
$0.002-0.01 | $2-10 |
| 复杂重构 | opus |
$0.10-0.50 | $50-200 |
| 安全扫描 | sonnet |
$0.02-0.08 | $10-40 |
成本优化策略:
# 策略1:使用缓存友好的prompt结构
# 在CLAUDE.md中放置不变的系统级指令,利用prompt caching
# 缓存命中的token成本仅为正常输入的1/10
# 策略2:批量任务的模型分级
# 快速过滤用haiku,深度分析用sonnet,最终决策用opus
cat files.txt | xargs -P 4 -I {} bash -c '
# 第一轮:haiku快速分类
CATEGORY=$(claude -p --model haiku --quiet \
"此文件属于哪个类别:critical/normal/trivial?只返回一个词" < "{}")
# 第二轮:按类别分配模型
MODEL="haiku"
[ "$CATEGORY" = "critical" ] && MODEL="sonnet"
claude -p --model "$MODEL" "详细分析此文件" < "{}"
'
# 策略3:设置token上限防止失控
claude -p "大规模重构" --max-tokens 8192 --max-turns 15
#!/bin/bash
# robust-automation.sh — 带重试和降级的自动化脚本
set -uo pipefail
MAX_RETRIES=3
TIMEOUT=300 # 5分钟超时
run_claude_with_retry() {
local prompt="$1"
local output_format="${2:-json}"
local model="${3:-sonnet}"
local attempt=1
while [ $attempt -le $MAX_RETRIES ]; do
echo " 尝试 $attempt/$MAX_RETRIES..."
# 使用timeout防止挂起
RESULT=$(timeout "$TIMEOUT" claude -p --output-format "$output_format" \
--model "$model" --quiet "$prompt" 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "$RESULT"
return 0
elif [ $EXIT_CODE -eq 124 ]; then
echo " ⏰ 超时,重试中..."
else
echo " ❌ 错误 (exit: $EXIT_CODE),重试中..."
fi
# 指数退避
sleep $((2 ** attempt))
attempt=$((attempt + 1))
done
# 降级到更小的模型
echo " 📉 降级到haiku模型..."
timeout "$TIMEOUT" claude -p --output-format "$output_format" \
--model haiku --quiet "$prompt" 2>&1
}
# 使用示例
run_claude_with_retry "审查这个文件的安全性" json sonnet
批量任务最常见的事故是"重跑导致重复操作"。遵循以下原则:
# ❌ 危险:每次都创建新PR
claude -p "创建一个PR,将这些修改合并到main"
# ✅ 安全:先检查是否已存在
claude -p "检查是否已有标题为'refactor-auth'的PR。
如果有,返回其URL。
如果没有,创建一个新的PR。
返回JSON: {action: 'found'|'created', url: '...'}"
# ❌ 危险:无条件覆盖文件
claude -p "将优化后的代码写入src/app.ts"
# ✅ 安全:先备份再写入
claude -p "先检查src/app.ts是否已在本次会话中被修改。
如果已修改,跳过。
如果未修改,创建备份后写入。
返回JSON: {action: 'skipped'|'backed_up_and_written'}"
#!/bin/bash
# monitor-batch.sh — 批量任务的实时监控
LOG_FILE="batch-run-$(date +%Y%m%d_%H%M%S).jsonl"
run_and_log() {
local task_id="$1"
local prompt="$2"
local start_time=$(date +%s)
RESULT=$(claude -p --output-format json "$prompt" 2>/dev/null)
local end_time=$(date +%s)
local duration=$((end_time - start_time))
# 写入结构化日志(JSONL格式,每行一个JSON对象)
jq -n \
--arg task_id "$task_id" \
--arg duration "$duration" \
--arg timestamp "$(date -Iseconds)" \
--argjson result "$RESULT" \
'{task_id: $task_id, timestamp: $timestamp, duration_s: $duration} + $result' \
>> "$LOG_FILE"
echo "$RESULT"
}
# 实时成本追踪
watch_costs() {
echo "📊 实时成本监控(每10秒刷新)"
while true; do
TOTAL=$(jq -s '[.[].total_cost_usd // 0] | add' "$LOG_FILE" 2>/dev/null || echo "0")
COUNT=$(jq -s 'length' "$LOG_FILE" 2>/dev/null || echo "0")
echo -ne "\r 任务: $COUNT | 总成本: \$$TOTAL "
sleep 10
done
}
# 启动后台监控
watch_costs &
MONITOR_PID=$!
# ... 运行批量任务 ...
# 清理
kill $MONITOR_PID 2>/dev/null
#!/bin/bash
# parallel-branches.sh — 在独立分支上并行处理多个特性
FEATURES=(
"feature/auth-refactor:重构认证模块,使用JWT替代Session"
"feature/api-versioning:为所有API端点添加版本号前缀"
"feature/error-handling:统一错误处理中间件"
)
BASE_BRANCH="develop"
for FEATURE_SPEC in "${FEATURES[@]}"; do
BRANCH="${FEATURE_SPEC%%:*}"
PROMPT="${FEATURE_SPEC##*:}"
echo "🌿 创建分支: $BRANCH"
# 为每个特性创建独立worktree
git worktree add ".worktrees/$BRANCH" -b "$BRANCH" "$BASE_BRANCH" 2>/dev/null || true
# 在worktree中异步运行Claude
(
cd ".worktrees/$BRANCH"
claude -p --dangerously-skip-permissions --max-turns 20 "$PROMPT" \
> "../reports/$BRANCH.log" 2>&1
# 如果有变更,自动提交
if [ -n "$(git status --porcelain)" ]; then
git add -A
git commit -m "feat($BRANCH): $PROMPT" --no-verify
echo "✅ $BRANCH 完成" >> "../reports/$BRANCH.log"
fi
) &
echo " 🚀 已启动 (PID: $!)"
done
# 等待所有任务完成
echo ""
echo "⏳ 等待所有特性分支完成..."
wait
echo ""
echo "📊 完成状态:"
for FEATURE_SPEC in "${FEATURES[@]}"; do
BRANCH="${FEATURE_SPEC%%:*}"
if grep -q "✅" "reports/$BRANCH.log" 2>/dev/null; then
echo " ✅ $BRANCH"
else
echo " ❌ $BRANCH"
fi
done
#!/bin/bash
# nightly-tasks.sh — 夜间自动化任务套件
# 配合cron使用:0 2 * * * /path/to/nightly-tasks.sh
set -uo pipefail
PROJECT_DIR="/path/to/project"
LOG_DIR="$PROJECT_DIR/nightly-logs/$(date +%Y%m%d)"
mkdir -p "$LOG_DIR"
cd "$PROJECT_DIR"
echo "🌙 夜间任务开始: $(date)" | tee "$LOG_DIR/main.log"
# ═══ 任务1:依赖安全审计 ═══
echo "[1/4] 依赖安全审计..." | tee -a "$LOG_DIR/main.log"
claude -p --output-format json --model sonnet \
"分析package.json中的所有依赖,检查已知的安全漏洞。
对比npm audit的输出(如果可用)。
返回JSON: {vulnerable: [{package, severity, version, recommendation}]}" \
< package.json > "$LOG_DIR/security-audit.json" 2>/dev/null
# ═══ 任务2:死代码检测 ═══
echo "[2/4] 死代码检测..." | tee -a "$LOG_DIR/main.log"
claude -p --output-format json --model haiku \
"扫描src/目录下的所有TypeScript文件,找出未被引用的export函数和类。
返回JSON: {dead_code: [{file, export_name, last_used_in_git_commit}]}" \
> "$LOG_DIR/dead-code.json" 2>/dev/null
# ═══ 任务3:测试覆盖率趋势 ═══
echo "[3/4] 测试覆盖率分析..." | tee -a "$LOG_DIR/main.log"
claude -p --output-format json --model haiku \
"分析最近的测试运行结果(如果存在coverage/目录),
识别覆盖率低于80%的模块。
返回JSON: {low_coverage: [{file, coverage_pct, missing_tests}]}" \
> "$LOG_DIR/coverage-analysis.json" 2>/dev/null
# ═══ 任务4:文档新鲜度检查 ═══
echo "[4/4] 文档新鲜度检查..." | tee -a "$LOG_DIR/main.log"
claude -p --output-format json --model haiku \
"对比README.md和CLAUDE.md的内容与当前代码结构。
识别过时的描述、缺失的新功能说明。
返回JSON: {outdated: [{doc_file, section, issue}]}" \
> "$LOG_DIR/doc-freshness.json" 2>/dev/null
# ═══ 汇总报告 ═══
echo "" | tee -a "$LOG_DIR/main.log"
echo "📊 夜间任务汇总:" | tee -a "$LOG_DIR/main.log"
TOTAL_COST=$(jq -s '[.[].total_cost_usd // 0] | add' "$LOG_DIR"/*.json 2>/dev/null)
echo " 总成本: \$$TOTAL_COST" | tee -a "$LOG_DIR/main.log"
# 如果有严重发现,发送通知
SECURITY_CRITICAL=$(jq -r '.result.vulnerable | map(select(.severity=="critical")) | length' \
"$LOG_DIR/security-audit.json" 2>/dev/null || echo "0")
if [ "$SECURITY_CRITICAL" -gt 0 ]; then
echo " ⚠️ 发现 $SECURITY_CRITICAL 个严重安全漏洞!" | tee -a "$LOG_DIR/main.log"
# 这里可以集成Slack/邮件通知
fi
echo "🌙 夜间任务完成: $(date)" | tee -a "$LOG_DIR/main.log"
配置cron定时执行:
# 每天凌晨2点运行
# crontab -e
0 2 * * * /path/to/nightly-tasks.sh >> /path/to/nightly-cron.log 2>&1
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | 企业级DevOps训练营、AI工程化训练营、高级开发训练营 |
| 前置知识要求 | Shell脚本基础、Git操作、JSON处理(jq) |
| 预计教学时长 | 4-6小时(含实操) |
| 实操占比 | 70%(大量动手练习) |
| 难度等级 | ⭐⭐⭐⭐(中高级) |
| 硬件要求 | 无特殊要求,需稳定网络访问Claude API |
| 分组建议 | 2-3人一组,每人负责一个Hook + 一个批量脚本 |
| 考核方式 | 完成一个包含3个Hook和1个批量脚本的完整自动化方案 |
[!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 等场景全覆盖。
