本教程深入讲解 Claude Code 的三大自动化核心能力:Headless 模式(-p 标志)、Hooks 生命周期钩子系统、以及批量任务与多Agent并行。学完本教程,你将掌握如何在 CI/CD 管道中集成 Claude Code、用 Hooks 实现全自动化的编码工作流、以及编写可复用的自动化脚本处理多仓库任务。
适用人群:已具备 Claude Code 基础使用经验,希望将其从交互式工具升级为自动化引擎的开发者。
npm install -g @anthropic-ai/claude-code)Claude Code 的 Headless 模式通过 -p(或 --print)标志启用,它会跳过交互式 TUI 界面,直接执行提示词并将结果输出到 stdout。这使 Claude Code 可以嵌入到 Shell 脚本、CI/CD 管道、cron 任务等任何非交互式场景。

图表 1
最简单的 Headless 调用:
# 直接传入提示词
claude -p "解释当前项目的目录结构"
# 通过管道传入内容
cat error.log | claude -p "分析这个错误日志,找出根本原因"
# 结合 heredoc 传入多行提示词
claude -p "$(cat <<'EOF'
检查 src/ 目录下所有 TypeScript 文件,
找出潜在的 TypeScript strict 模式兼容性问题,
列出每个文件的问题和修复建议。
EOF
)"
Headless 模式下有几个至关重要的标志参数:
# --output-format: 控制输出格式
claude -p "列出所有TODO注释" --output-format json
# --max-turns: 限制Agent循环次数,防止失控
claude -p "修复所有lint错误" --max-turns 20
# --allowedTools: 限制可用工具集(安全关键)
claude -p "分析代码质量" --allowedTools "Read,Grep,Glob"
# --continue / -c: 继续上一次对话
claude -c -p "继续刚才的工作"
# --resume: 恢复指定session
claude --resume session-abc123 -p "继续之前的任务"
# --dangerously-skip-permissions: 完全跳过权限确认(仅CI/CD环境)
claude -p "运行测试并修复失败用例" --dangerously-skip-permissions
--output-format 支持三种格式,各有适用场景:
| 格式 | 适用场景 | 特点 |
|---|---|---|
text(默认) |
人类阅读、日志记录 | 纯文本输出,包含Markdown格式 |
json |
脚本解析、管道串联 | 结构化JSON,含session ID、cost等信息 |
stream-json |
实时处理、UI集成 | 逐事件流式输出,可实时捕获中间状态 |
JSON 输出示例:
claude -p "检查package.json中的依赖版本是否过时" --output-format json
输出结构:
{
"session_id": "sess_abc123",
"result": "以下依赖需要更新:\n1. react: 18.2.0 → 19.0.0\n...",
"cost_usd": 0.023,
"duration_ms": 4521,
"num_turns": 3,
"tool_usage": {
"Read": 2,
"Bash": 1
}
}
问题1:Headless模式下Agent循环次数过多导致超时
# 错误:没有限制turns,可能无限循环
claude -p "修复所有bug"
# 正确:设置合理的max-turns
claude -p "修复所有bug" --max-turns 15
问题2:权限确认导致Headless模式阻塞
# CI/CD环境中使用(注意安全风险)
claude -p "运行npm test" --dangerously-skip-permissions
# 更安全的替代:限制工具集
claude -p "运行npm test" \
--allowedTools "Bash(npm test:*)" \
--max-turns 5
Claude Code Hooks 是一套事件驱动的自动化系统,允许你在 Agent 生命周期的特定节点注入自定义逻辑。每个 Hook 可以是 Shell 命令、HTTP 端点或 LLM 提示词。

图表 2
Claude Code 支持以下核心生命周期事件:
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse |
工具执行前 | 权限检查、输入验证、安全审计 |
PostToolUse |
工具执行后 | 自动格式化、日志记录、通知推送 |
Notification |
Agent发出通知时 | Slack/邮件通知、仪表盘更新 |
Stop |
Agent完成/停止时 | 任务完成通知、结果汇总、清理工作 |
Hooks 在 .claude/settings.json 中配置(项目级)或 ~/.claude/settings.json(全局级):
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "python3 scripts/pre-edit-check.py"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash scripts/on-task-complete.sh"
}
]
}
]
}
}
matcher 字段控制 Hook 何时触发:
// 匹配特定工具
"matcher": "Edit"
// 匹配工具+参数(Bash命令匹配)
"matcher": "Bash(git push:*)"
// 匹配所有工具
"matcher": ""
// 匹配多个工具(用逗号分隔)
"matcher": "Edit,Write"
Claude Code 通过 stdin 向 Hook 传入 JSON 格式的事件数据,Hook 通过 stdout 返回结果:
输入(stdin JSON)示例:
{
"session_id": "sess_abc123",
"tool_name": "Edit",
"tool_input": {
"file_path": "/project/src/index.ts",
"old_string": "const x = 1",
"new_string": "const x = 2"
}
}
输出(stdout JSON)选项:
// 选项1:批准执行
{"decision": "approve"}
// 选项2:拒绝执行(带原因)
{"decision": "block", "reason": "不允许修改config文件"}
// 选项3:修改工具输入
{
"decision": "approve",
"patch": {
"tool_input": {
"new_string": "const x = 3"
}
}
}
退出码语义:
| 退出码 | 含义 | 效果 |
|---|---|---|
| 0 | 通过 | 继续执行 |
| 2 | 阻止 | 阻止当前工具调用 |
| 其他 | 错误 | 忽略Hook,继续执行 |
每次编辑文件后自动运行 Prettier:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit,Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
}
]
}
]
}
}
#!/usr/bin/env bash
# scripts/protect-sensitive-files.sh
# 读取stdin中的JSON
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# 定义受保护文件列表
PROTECTED_FILES=(
".env"
".env.production"
"config/secrets.json"
"credentials.json"
)
for protected in "${PROTECTED_FILES[@]}"; do
if [[ "$FILE_PATH" == *"$protected"* ]]; then
echo "{\"decision\": \"block\", \"reason\": \"安全策略:禁止修改敏感文件 $protected\"}"
exit 0
fi
done
echo "{\"decision\": \"approve\"}"
配置:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit,Write",
"hooks": [
{
"type": "command",
"command": "bash scripts/protect-sensitive-files.sh"
}
]
}
]
}
}
#!/usr/bin/env bash
# scripts/slack-notify.sh
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id')
COST=$(echo "$INPUT" | jq -r '.cost_usd // 0')
curl -s -X POST "$SLACK_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{
\"text\": \"✅ Claude Code 任务完成\",
\"blocks\": [
{
\"type\": \"section\",
\"text\": {
\"type\": \"mrkdwn\",
\"text\": \"*Session:* $SESSION_ID\\n*Cost:* \\\$$COST\"
}
}
]
}" > /dev/null 2>&1
{
"hooks": {
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash scripts/slack-notify.sh"
}
]
}
]
}
}
将 Headless 模式与 Shell 脚本结合,可以构建强大的批量任务系统。

图表 3
#!/usr/bin/env bash
# batch-agent-tasks.sh — 批量执行Claude Code任务
set -euo pipefail
# 配置
MAX_PARALLEL=3
OUTPUT_DIR="./agent-results/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"
# 定义任务数组
declare -a TASKS=(
"frontend-app|更新所有React组件使用新的Design System"
"backend-api|检查并修复所有API端点的错误处理"
"shared-libs|升级所有依赖到最新稳定版本"
"docs-site|检查所有文档链接是否有效"
)
# 任务执行函数
run_agent_task() {
local repo_task="$1"
local repo_name="${repo_task%%|*}"
local task_desc="${repo_task##*|}"
local log_file="$OUTPUT_DIR/${repo_name}.log"
local json_file="$OUTPUT_DIR/${repo_name}.json"
echo "[START] $repo_name: $task_desc"
# 执行Claude Code headless任务
cd "/projects/$repo_name"
claude -p "$task_desc" \
--output-format json \
--max-turns 20 \
--allowedTools "Read,Edit,Write,Bash(npm*:*,git*:*)" \
> "$json_file" 2> "$log_file"
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "[DONE] $repo_name — 成功"
else
echo "[FAIL] $repo_name — 退出码: $exit_code"
fi
return $exit_code
}
# 并行执行(使用GNU parallel或xargs)
export -f run_agent_task
export OUTPUT_DIR
printf '%s\n' "${TASKS[@]}" | xargs -P "$MAX_PARALLEL" -I {} bash -c 'run_agent_task "$@"' _ {}
# 汇总结果
echo "===== 任务执行汇总 ====="
for json_file in "$OUTPUT_DIR"/*.json; do
if [ -f "$json_file" ]; then
repo=$(basename "$json_file" .json)
cost=$(jq -r '.cost_usd // 0' "$json_file" 2>/dev/null || echo "N/A")
turns=$(jq -r '.num_turns // 0' "$json_file" 2>/dev/null || echo "N/A")
echo " $repo: turns=$turns, cost=\$$cost"
fi
done
利用 Git Worktree 隔离多个 Agent 的工作空间,实现真正的并行开发:
#!/usr/bin/env bash
# parallel-agents.sh — 多Agent并行开发
REPO_ROOT="/projects/my-project"
BRANCHES=("feature/auth" "feature/dashboard" "feature/api-v2")
TASKS=(
"实现JWT认证中间件,包含refresh token逻辑"
"构建管理后台Dashboard,包含数据图表组件"
"重构API为v2版本,添加分页和过滤功能"
)
# 创建worktrees
for i in "${!BRANCHES[@]}"; do
branch="${BRANCHES[$i]}"
worktree_path="$REPO_ROOT/.claude/worktrees/${branch//\//-}"
git -C "$REPO_ROOT" worktree add "$worktree_path" -b "$branch" HEAD 2>/dev/null || true
done
# 并行启动Agents
for i in "${!BRANCHES[@]}"; do
branch="${BRANCHES[$i]}"
task="${TASKS[$i]}"
worktree_path="$REPO_ROOT/.claude/worktrees/${branch//\//-}"
(
cd "$worktree_path"
claude -p "$task" \
--output-format json \
--max-turns 30 \
--allowedTools "Read,Edit,Write,Bash(npm*:*,git*:*,node*:*)" \
> "$worktree_path/agent-result.json" 2>&1
# 完成后自动提交
if [ $? -eq 0 ]; then
git add -A
git commit -m "feat: $task (AI-generated)"
fi
) &
# 控制并发数
if (( $(jobs -r | wc -l) >= 3 )); then
wait -n
fi
done
wait
echo "所有Agent任务已完成"
# .github/workflows/ai-code-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
ai-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run AI Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
# 获取PR变更的文件列表
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
# 使用Claude Code进行代码审查
claude -p "
你是一位高级代码审查员。请审查以下PR中变更的文件:
$CHANGED_FILES
重点检查:
1. 安全漏洞(注入、XSS等)
2. 性能问题
3. 代码风格和最佳实践
4. 潜在的bug
输出格式为JSON数组,每个问题包含:
- file: 文件路径
- line: 行号(如果适用)
- severity: critical/warning/info
- message: 问题描述
- suggestion: 修复建议
" \
--output-format text \
--allowedTools "Read,Bash(git diff*:*,git log*:*)" \
--max-turns 15 \
> review_output.md
- name: Post Review Comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh pr comment ${{ github.event.pull_request.number }} \
--body-file review_output.md
# .github/workflows/auto-fix-lint.yml
name: Auto Fix Lint
on:
push:
branches: [develop]
jobs:
auto-fix:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: npm ci
- name: Install Claude Code
run: npm install -g @anthropic-ai/claude-code
- name: Run Linter
id: lint
run: |
npx eslint src/ --format json > eslint-results.json 2>&1 || true
echo "error_count=$(jq '. | map(.errorCount) | add' eslint-results.json)" >> $GITHUB_OUTPUT
- name: AI Fix Lint Errors
if: steps.lint.outputs.error_count > 0
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude -p "
eslint报告了$(cat eslint-results.json | jq '. | map(.errorCount) | add')个错误。
请阅读eslint-results.json中的错误详情,然后逐个修复。
修复后重新运行eslint验证。
" \
--allowedTools "Read,Edit,Write,Bash(npm*:*)" \
--max-turns 25 \
--dangerously-skip-permissions
- name: Commit and Push Fixes
run: |
git config user.name "Claude Code Bot"
git config user.email "[email protected]"
git diff --quiet || (git add -A && git commit -m "fix: auto-fix lint errors" && git push)
Claude Code 提供了强大的 Session 管理能力,非常适合自动化场景中的上下文持续:
# 查看所有历史session
claude sessions list
# 继续最近的session
claude --continue -p "继续刚才的修复工作"
# 恢复特定session(通过session ID)
claude --resume "sess_abc123" -p "根据之前的分析结果,开始实施修复"
# 使用 --continue 的典型自动化流程
# 第一步:分析(产生session)
SESSION_ID=$(claude -p "分析项目架构,列出需要重构的模块" \
--output-format json | jq -r '.session_id')
# 第二步:基于分析结果执行
claude --resume "$SESSION_ID -p "开始重构你提到的第一个模块"
# 第三步:验证
claude --resume "$SESSION_ID" -p "运行测试验证重构结果"
下面是一个完整的实战项目,将 Headless 模式、Hooks、Session 管理组合起来,构建一个代码质量守护系统。
.claude/
├── settings.json # Hook配置
├── scripts/
│ ├── pre-edit-guard.sh # 编辑前安全检查
│ ├── post-edit-format.sh # 编辑后格式化
│ ├── on-stop-report.sh # 任务完成报告
│ └── quality-check.sh # 质量检查脚本
├── quality-guard.sh # 主入口脚本
└── README.md
// .claude/settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit,Write",
"hooks": [
{
"type": "command",
"command": "bash .claude/scripts/pre-edit-guard.sh"
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash .claude/scripts/pre-bash-guard.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit,Write",
"hooks": [
{
"type": "command",
"command": "bash .claude/scripts/post-edit-format.sh"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash .claude/scripts/on-stop-report.sh"
}
]
}
]
}
}
#!/usr/bin/env bash
# .claude/scripts/pre-edit-guard.sh
# 编辑前安全检查:阻止修改受保护文件
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# 受保护文件模式
PROTECTED_PATTERNS=(
".env"
"secrets"
"credentials"
"id_rsa"
"*.pem"
"*.key"
)
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
# 退出码2 = 阻止操作
echo "{\"decision\": \"block\", \"reason\": \"安全策略禁止修改: $FILE_PATH (匹配模式: $pattern)\"}" >&2
exit 2
fi
done
# 审计日志
echo "[$(date -Iseconds)] EDIT: $FILE_PATH" >> .claude/edit-audit.log
echo "{\"decision\": \"approve\"}"
#!/usr/bin/env bash
# .claude/scripts/post-edit-format.sh
# 编辑后自动格式化
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [ -z "$FILE_PATH" ] || [ ! -f "$FILE_PATH" ]; then
exit 0
fi
# 根据文件类型选择格式化工具
case "$FILE_PATH" in
*.ts|*.tsx|*.js|*.jsx)
npx prettier --write "$FILE_PATH" 2>/dev/null
npx eslint --fix "$FILE_PATH" 2>/dev/null || true
;;
*.py)
python3 -m black "$FILE_PATH" 2>/dev/null || true
python3 -m isort "$FILE_PATH" 2>/dev/null || true
;;
*.go)
gofmt -w "$FILE_PATH" 2>/dev/null || true
;;
*.rs)
rustfmt "$FILE_PATH" 2>/dev/null || true
;;
esac
#!/usr/bin/env bash
# .claude/scripts/on-stop-report.sh
# Agent停止时生成报告
INPUT=$(cat)
REPORT_FILE=".claude/reports/$(date +%Y%m%d_%H%M%S).md"
mkdir -p .claude/reports
cat > "$REPORT_FILE" << REPORT
# Claude Code 任务报告
- **时间**: $(date -Iseconds)
- **Session**: $(echo "$INPUT" | jq -r '.session_id // "unknown"')
## 执行摘要
$(echo "$INPUT" | jq -r '.result // "无结果"' | head -50)
## 资源消耗
- API Cost: \$(echo "$INPUT" | jq -r '.cost_usd // 0')
- Turn 数: $(echo "$INPUT" | jq -r '.num_turns // 0')
---
*自动生成 by Claude Code Quality Guard*
REPORT
echo "报告已保存到: $REPORT_FILE"
#!/usr/bin/env bash
# quality-guard.sh — 代码质量守护主脚本
set -euo pipefail
MODE="${1:-check}"
PROJECT_DIR="${2:-.}"
cd "$PROJECT_DIR"
case "$MODE" in
check)
echo "🔍 运行代码质量检查..."
claude -p "
对当前项目执行全面代码质量检查:
1. 检查所有源文件是否符合lint规则
2. 检查是否有未处理的TODO/FIXME
3. 检查依赖安全性(npm audit或等效)
4. 检查代码复杂度热点
输出结构化的质量报告。
" \
--output-format json \
--allowedTools "Read,Grep,Glob,Bash(npm*:*,npx*:*)" \
--max-turns 15
;;
fix)
echo "🔧 自动修复代码质量问题..."
claude -p "
检查并修复所有可以自动修复的代码质量问题:
1. 运行linter并自动修复
2. 格式化所有代码文件
3. 移除未使用的import
4. 修复简单的类型错误
修复后重新运行检查确认。
" \
--output-format json \
--max-turns 25 \
--dangerously-skip-permissions
;;
review)
BRANCH="${3:-main}"
echo "📝 审查代码变更 (对比 $BRANCH)..."
claude -p "
审查当前分支相对于 $BRANCH 的所有代码变更。
重点检查:
1. 安全漏洞
2. 性能退化
3. 架构一致性
4. 测试覆盖率
给出具体的改进建议。
" \
--output-format text \
--allowedTools "Read,Bash(git diff*:*,git log*:*,git show:*)" \
--max-turns 20
;;
*)
echo "用法: $0 {check|fix|review} [project_dir] [branch]"
exit 1
;;
esac
使用方式:
# 检查代码质量
./quality-guard.sh check ./my-project
# 自动修复
./quality-guard.sh fix ./my-project
# 审查变更
./quality-guard.sh review ./my-project main
在自动化场景中,API 成本是需要重点关注的:
# 使用 --max-turns 严格限制循环次数
claude -p "修复lint错误" --max-turns 10
# 使用 --model 选择更经济的模型
claude -p "简单格式化任务" --model claude-haiku-4-5-20251001
# 先用只读模式分析,再用完整模式执行
# 步骤1:分析(低成本)
claude -p "列出需要修改的文件和原因" \
--allowedTools "Read,Grep,Glob" \
--output-format json > analysis.json
# 步骤2:精确执行(按需)
FILES=$(jq -r '.result' analysis.json)
claude -p "根据以下分析结果执行修改:$FILES" \
--max-turns 10 \
--allowedTools "Read,Edit,Write"
#!/usr/bin/env bash
# robust-agent.sh — 带错误处理和重试的Agent任务
MAX_RETRIES=3
RETRY_DELAY=30
TIMEOUT=300 # 5分钟超时
run_with_retry() {
local attempt=1
while [ $attempt -le $MAX_RETRIES ]; do
echo "尝试 $attempt/$MAX_RETRIES..."
if timeout "$TIMEOUT" claude -p "$1" \
--output-format json \
--max-turns 20 \
2>/dev/null; then
echo "成功完成"
return 0
fi
echo "尝试 $attempt 失败,${RETRY_DELAY}秒后重试..."
sleep "$RETRY_DELAY"
attempt=$((attempt + 1))
done
echo "所有重试均失败"
return 1
}
run_with_retry "修复所有TypeScript编译错误"
除了 command 类型,Hook 还支持 prompt 类型(LLM提示词)和 HTTP 端点:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "检查即将执行的Bash命令是否安全。如果命令包含 rm -rf、drop table、或 > /dev/sda 等危险操作,请阻止。"
}
]
}
]
}
}
Headless 模式下常用的环境变量:
# API密钥(必需)
export ANTHROPIC_API_KEY="sk-ant-..."
# 模型选择
export CLAUDE_CODE_MODEL="claude-sonnet-4-6"
# 最大思考token数
export CLAUDE_CODE_MAX_THINKING_TOKENS=8000
# 禁用非必要的网络请求
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
# 自定义MCP服务器配置路径
export CLAUDE_CODE_MCP_CONFIG="./mcp-config.json"

图表 4
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | DevOps 自动化训练营、AI 工程师训练营(中高级班)、企业级 AI 编码实践 |
| 教学时长 | 4-6 小时(含动手实验) |
| 难度等级 | 中高级 — 需要 Shell 脚本和 CI/CD 基础 |
| 实验环境要求 | 每人需要 Anthropic API Key、GitHub 仓库、CI/CD 环境 |
| 推荐教学顺序 | 先讲 Headless 基础(1h)→ Hooks 系统(1.5h)→ CI/CD 集成(1.5h)→ 综合实战(1-2h) |
[!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 等场景全覆盖。
