概述:本教程系统讲解Claude Code的三大自动化能力——Headless模式(-p标志)、Hooks生命周期钩子、以及Agent SDK编程式调用。学完本教程,你将能把Claude Code嵌入CI/CD流水线、构建批量代码审查工具、实现自动格式化和安全检查。适合有半年以上Claude Code使用经验的开发者,以及需要将AI编码能力产品化的工程团队。
前置条件:
- Claude Code CLI已安装并完成认证(claude --version ≥ 1.0.36)
- 熟悉命令行操作和shell脚本
- 了解JSON格式和基本的Node.js/Python知识
- 一个可用的项目目录作为实验环境
Headless模式是Claude Code的非交互式运行方式。通过添加-p(或--print)标志,Claude Code不再启动交互式TUI界面,而是直接在标准输出中打印结果。这使得它可以在脚本、CI管道、定时任务中无人值守地运行。

图表 1
最简单的headless调用只需要一个提示词:
# 单次问答,直接输出到终端
claude -p "解释一下这个项目的目录结构"
# 管道输入——将文件内容作为上下文
cat src/main.ts | claude -p "这段代码有什么问题?请用JSON格式返回问题列表"
# 指定工作目录
claude -p --cwd /path/to/project "运行所有测试并报告失败原因"
--output-format标志决定了Claude Code如何返回结果,这在编程集成中至关重要:
# 纯文本输出(默认)
claude -p "列出所有TODO注释" --output-format text
# JSON输出——适合程序解析
claude -p "分析代码质量" --output-format json
# 流式JSON——逐条输出,适合实时处理
claude -p "重构这个模块" --output-format stream-json
# 获取JSON格式的完整对话记录
claude -p "解释架构设计" --output-format json --verbose
JSON输出格式的典型结构:
{
"type": "result",
"subtype": "success",
"cost_usd": 0.042,
"duration_ms": 12340,
"duration_api_ms": 8920,
"is_error": false,
"num_turns": 3,
"result": "项目采用分层架构...",
"session_id": "abc123"
}
在自动化场景中,安全是第一要务。--allowedTools标志控制Claude Code可以使用哪些工具:
# 只允许读取——最安全的只读模式
claude -p "审查代码风格" \
--allowedTools "Read,Glob,Grep"
# 允许读取和编辑——用于代码修改
claude -p "修复所有lint错误" \
--allowedTools "Read,Edit,Glob,Grep"
# 允许执行bash命令——用于测试运行
claude -p "运行测试套件并修复失败用例" \
--allowedTools "Read,Edit,Bash,Glob,Grep"
# 禁用网络访问工具——防止信息泄露
claude -p "分析代码逻辑" \
--disallowedTools "WebSearch,WebFetch"
--max-turns防止Agent陷入无限循环,这在批量任务中尤其重要:
# 最多执行5轮工具调用
claude -p "修复所有TypeScript类型错误" \
--max-turns 5 \
--allowedTools "Read,Edit,Bash"
下面是一个完整的shell脚本,用headless模式批量审查Git仓库中的变更文件:
#!/bin/bash
# batch-review.sh — 批量代码审查脚本
set -euo pipefail
# 获取main分支到当前HEAD之间变更的文件列表
CHANGED_FILES=$(git diff --name-only main...HEAD -- '*.ts' '*.tsx' '*.py')
if [ -z "$CHANGED_FILES" ]; then
echo "没有发现变更文件"
exit 0
fi
echo "=== 批量代码审查开始 ==="
echo "待审查文件:"
echo "$CHANGED_FILES"
echo ""
# 逐文件审查
while IFS= read -r file; do
echo "--- 审查: $file ---"
# 使用-p模式进行非交互式审查
claude -p "$(cat <<'PROMPT'
请审查以下文件的最新git diff,重点关注:
1. 潜在的安全漏洞
2. 性能问题
3. 代码可维护性
请用简洁的中文输出审查结果,如果没有问题就说"无问题"。
PROMPT
)" \
--allowedTools "Read,Bash" \
--max-turns 3 \
--cwd "$(git rev-parse --show-toplevel)"
echo ""
done <<< "$CHANGED_FILES"
echo "=== 批量代码审查完成 ==="
运行方式:
chmod +x batch-review.sh
./batch-review.sh
| 问题 | 原因 | 解决方案 |
|---|---|---|
Error: No API key |
未设置认证 | 运行 claude login 或设置 ANTHROPIC_API_KEY |
| 输出包含ANSI转义码 | 终端检测到TTY | 设置 NO_COLOR=1 环境变量 |
| 脚本卡住不返回 | Agent轮次过多 | 添加 --max-turns 限制 |
| 权限被拒绝 | 工具不在白名单 | 检查 --allowedTools 配置 |
| JSON解析失败 | 混合了文本和JSON | 使用 --output-format json |
Hooks是Claude Code中一个强大的自动化层,允许你在Agent执行的关键节点注入自定义逻辑。每个Hook本质上是一个shell命令,在特定事件触发时自动执行。

图表 2
Claude Code支持以下生命周期事件:
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse |
工具调用之前 | 权限检查、参数验证、安全审计 |
PostToolUse |
工具调用之后 | 自动格式化、通知推送、日志记录 |
Notification |
Agent发送通知时 | Slack/邮件通知、状态同步 |
Stop |
Agent停止时 | 清理临时文件、汇总报告 |
SessionStart |
会话开始时 | 加载环境变量、初始化上下文 |
Hooks在settings.json中配置。配置文件位于:
~/.claude/settings.json.claude/settings.json{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/path/to/pre-bash-guard.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_FILE_PATH"
}
]
}
],
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' '$CLAUDE_NOTIFICATION'"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/path/to/session-summary.sh"
}
]
}
]
}
}
每个Hook通过标准输入接收JSON格式的上下文信息,通过退出码控制Claude Code的行为。
输入JSON结构(PreToolUse):
{
"session_id": "sess_abc123",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf node_modules"
}
}
退出码含义:
| 退出码 | 含义 | 效果 |
|---|---|---|
0 |
通过 | 继续执行工具调用 |
2 |
阻止 | 取消本次工具调用,向Agent反馈阻止原因 |
| 其他 | 错误 | Hook执行出错,工具调用被取消 |
通过stdout返回阻止原因:
#!/bin/bash
# pre-bash-guard.sh — 阻止危险的bash命令
read -r INPUT
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
# 检查危险命令模式
DANGEROUS_PATTERNS=("rm -rf /" "rm -rf ~" "DROP TABLE" "format c:" "> /dev/sda")
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if [[ "$COMMAND" == *"$pattern"* ]]; then
echo "已阻止危险命令:检测到 '$pattern' 模式。如果确认需要执行,请手动操作。"
exit 2
fi
done
exit 0
以下是一套生产级别的Hooks配置,覆盖代码质量、安全防护、通知和日志四大维度:
第一层:PreToolUse — 安全守卫
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/guard-bash.sh"
}
]
},
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/guard-edit.sh"
}
]
}
]
}
}
guard-bash.sh:
#!/bin/bash
# guard-bash.sh — Bash命令安全守卫
set -euo pipefail
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command')
# 规则1:阻止强制推送
if echo "$CMD" | grep -qE 'git\s+push\s+.*--force|git\s+push\s+.*-f\b'; then
echo "已阻止:禁止使用 --force 推送。如需覆盖远程历史,请使用 --force-with-lease。"
exit 2
fi
# 规则2:阻止删除受保护分支
if echo "$CMD" | grep -qE 'git\s+branch\s+-[dD]\s+(main|master|release|develop)'; then
echo "已阻止:禁止删除受保护分支 (main/master/release/develop)。"
exit 2
fi
# 规则3:阻止操作生产环境文件
if echo "$CMD" | grep -qE '/etc/|/var/www/production|/usr/local/bin/deploy'; then
echo "已阻止:检测到生产环境路径,请确认后再手动执行。"
exit 2
fi
exit 0
guard-edit.sh:
#!/bin/bash
# guard-edit.sh — 文件编辑守卫
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# 阻止编辑敏感文件
PROTECTED_FILES=(".env" ".env.production" "credentials.json" "secrets.yaml" ".ssh/config")
for protected in "${PROTECTED_FILES[@]}"; do
if [[ "$FILE_PATH" == *"$protected"* ]]; then
echo "已阻止:禁止编辑敏感文件 $FILE_PATH。如需修改,请手动操作。"
exit 2
fi
done
exit 0
第二层:PostToolUse — 自动格式化
{
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/auto-format.sh"
}
]
}
]
}
auto-format.sh:
#!/bin/bash
# auto-format.sh — 编辑后自动格式化
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.file_path')
# 根据文件扩展名选择格式化工具
case "$FILE_PATH" in
*.ts|*.tsx|*.js|*.jsx)
npx prettier --write "$FILE_PATH" 2>/dev/null || true
npx eslint --fix "$FILE_PATH" 2>/dev/null || true
;;
*.py)
python -m black "$FILE_PATH" 2>/dev/null || true
python -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
第三层:PostToolUse — 测试自动运行
{
"PostToolUse": [
{
"matcher": "Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/auto-test.sh"
}
]
}
]
}
auto-test.sh:
#!/bin/bash
# auto-test.sh — 编辑后自动运行相关测试
set -euo pipefail
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
# 查找对应的测试文件
TEST_FILE=""
case "$FILE_PATH" in
src/**/*.ts)
# src/utils/helper.ts → src/utils/helper.test.ts
TEST_FILE="${FILE_PATH%.ts}.test.ts"
;;
**/*.py)
# app/models/user.py → tests/test_user.py
BASENAME=$(basename "${FILE_PATH%.py}")
TEST_FILE="tests/test_${BASENAME}.py"
;;
esac
# 如果测试文件存在,运行测试
if [ -n "$TEST_FILE" ] && [ -f "$TEST_FILE" ]; then
echo "检测到变更:$FILE_PATH"
echo "运行关联测试:$TEST_FILE"
case "$TEST_FILE" in
*.test.ts) npx vitest run "$TEST_FILE" --reporter=verbose ;;
*.test.py) python -m pytest "$TEST_FILE" -v ;;
esac
fi
第四层:Notification — 即时通知
{
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/notify.sh"
}
]
}
]
}
notify.sh:
#!/bin/bash
# notify.sh — 多渠道通知
set -euo pipefail
INPUT=$(cat)
MESSAGE=$(echo "$INPUT" | jq -r '.message // .notification // empty')
# macOS系统通知
if [[ "$(uname)" == "Darwin" ]]; then
osascript -e "display notification \"$MESSAGE\" with title \"Claude Code\""
fi
# Linux桌面通知
if [[ "$(uname)" == "Linux" ]]; then
notify-send "Claude Code" "$MESSAGE" 2>/dev/null || true
fi
# 可选:Slack通知
# curl -s -X POST "$SLACK_WEBHOOK_URL" \
# -H 'Content-Type: application/json' \
# -d "{\"text\": \"🤖 Claude Code: $MESSAGE\"}"
第五层:Stop — 会话日志
{
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "bash ~/.claude/hooks/log-session.sh"
}
]
}
]
}
log-session.sh:
#!/bin/bash
# log-session.sh — 记录会话摘要
set -euo pipefail
INPUT=$(cat)
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // "unknown"')
TIMESTAMP=$(date '+%Y-%m-%d_%H%M%S')
LOG_DIR="$HOME/.claude/logs"
mkdir -p "$LOG_DIR"
# 将会话信息追加到日志文件
echo "$INPUT" | jq '.' >> "$LOG_DIR/session_${TIMESTAMP}.jsonl"
# 输出摘要
echo "会话日志已保存到 $LOG_DIR/session_${TIMESTAMP}.jsonl"
matcher字段支持精确匹配和正则表达式两种模式:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{"type": "command", "command": "echo 'Bash工具将被调用'"}]
},
{
"matcher": "Edit|Write",
"hooks": [{"type": "command", "command": "echo '文件将被修改'"}]
},
{
"matcher": "",
"hooks": [{"type": "command", "command": "echo '任意工具将被调用'"}]
}
]
}
}
如果说-p模式是"远程遥控",那么Agent SDK就是"嵌入式控制"。Agent SDK允许你在TypeScript或Python代码中直接调用Claude Code的全部能力——包括工具调用、上下文管理、Agent循环。
# TypeScript SDK
npm install @anthropic-ai/claude-code-sdk
# Python SDK
pip install claude-code-sdk
import { claude } from '@anthropic-ai/claude-code-sdk';
async function main() {
// 基础调用
const result = await claude({
prompt: '分析这个项目的依赖关系,找出过时的包',
options: {
maxTurns: 5,
allowedTools: ['Read', 'Glob', 'Grep', 'Bash'],
cwd: '/path/to/project',
},
});
console.log('结果:', result.result);
console.log('成本:', result.cost_usd, 'USD');
console.log('耗时:', result.duration_ms, 'ms');
}
main();
import { claude } from '@anthropic-ai/claude-code-sdk';
async function streamExample() {
const stream = claude({
prompt: '重构认证模块',
options: {
maxTurns: 10,
allowedTools: ['Read', 'Edit', 'Bash'],
},
});
for await (const event of stream) {
switch (event.type) {
case 'assistant':
// Agent的文本输出
process.stdout.write(event.content);
break;
case 'tool_use':
// 工具调用事件
console.log(`\n[工具调用] ${event.tool_name}`);
break;
case 'tool_result':
// 工具返回结果
console.log(`[工具结果] ${event.tool_name} 完成`);
break;
case 'result':
// 最终结果
console.log('\n=== 完成 ===');
console.log(`成本: $${event.cost_usd.toFixed(4)}`);
console.log(`轮次: ${event.num_turns}`);
break;
}
}
}
streamExample();
Subagent是Agent SDK中最重要的模式之一。它允许你同时启动多个Agent实例,各自独立完成任务,最终汇总结果。

图表 3
TypeScript实现并行Subagent:
import { claude } from '@anthropic-ai/claude-code-sdk';
interface ReviewResult {
category: string;
issues: string[];
score: number;
}
async function parallelCodeReview(projectPath: string): Promise<void> {
const reviewTasks = [
{
category: '代码质量',
prompt: `审查 ${projectPath} 中的所有TypeScript源文件,找出代码质量问题:命名不规范、重复代码、过长函数。返回JSON格式的结果。`,
allowedTools: ['Read', 'Glob', 'Grep'],
},
{
category: '安全审计',
prompt: `检查 ${projectPath} 中的安全漏洞:SQL注入、XSS、硬编码密钥、不安全的依赖。返回JSON格式的结果。`,
allowedTools: ['Read', 'Glob', 'Grep', 'Bash'],
},
{
category: '性能瓶颈',
prompt: `分析 ${projectPath} 中的性能问题:N+1查询、内存泄漏风险、不必要的同步操作。返回JSON格式的结果。`,
allowedTools: ['Read', 'Glob', 'Grep'],
},
{
category: '依赖健康',
prompt: `检查 ${projectPath} 的 package.json 和 package-lock.json,找出过时的、有已知漏洞的、不再维护的依赖。返回JSON格式的结果。`,
allowedTools: ['Read', 'Bash'],
},
];
// 并行启动所有审查任务
const results = await Promise.all(
reviewTasks.map(async (task) => {
const result = await claude({
prompt: task.prompt,
options: {
maxTurns: 5,
allowedTools: task.allowedTools,
cwd: projectPath,
},
});
return {
category: task.category,
content: result.result,
cost: result.cost_usd,
};
})
);
// 汇总结果
console.log('\n========================================');
console.log(' 并行代码审查综合报告');
console.log('========================================\n');
let totalCost = 0;
for (const r of results) {
totalCost += r.cost;
console.log(`## ${r.category}`);
console.log(r.content);
console.log(`(成本: $${r.cost.toFixed(4)})\n`);
}
console.log(`\n总成本: $${totalCost.toFixed(4)}`);
}
// 运行
parallelCodeReview(process.argv[2] || process.cwd());
import asyncio
from claude_code_sdk import claude
async def batch_analyze(repos: list[str]):
"""并行分析多个仓库"""
tasks = [
claude(
prompt=f"分析 {repo} 的架构,输出技术栈和模块依赖关系",
options={
"max_turns": 3,
"allowed_tools": ["Read", "Glob", "Grep"],
"cwd": repo,
},
)
for repo in repos
]
results = await asyncio.gather(*tasks)
for repo, result in zip(repos, results):
print(f"\n{'='*50}")
print(f"仓库: {repo}")
print(f"{'='*50}")
print(result.result)
if __name__ == "__main__":
repos = [
"/projects/frontend",
"/projects/backend",
"/projects/shared-libs",
]
asyncio.run(batch_analyze(repos))
/loop是Claude Code内置的循环执行命令(v2.1.71+引入),用于在会话中周期性地执行任务:
# 在Claude Code交互界面中使用
> /loop 每30秒检查一次测试状态,如果全部通过则停止
# 典型场景:监控部署状态
> /loop 每60秒检查一次 kubectl get pods 的状态,当所有pod都为Running时通知我
通过/schedule命令可以创建持久化的定时任务,即使关闭Claude Code终端也会按计划执行:
# 每天早上9点执行
> /schedule "每天早上9点总结昨天的git commits,生成日报" --cron "0 9 * * *"
# 每周一运行
> /schedule "运行完整的测试套件并报告覆盖率变化" --cron "0 10 * * 1"
┌──────── 分钟 (0-59)
│ ┌────── 小时 (0-23)
│ │ ┌──── 日 (1-31)
│ │ │ ┌── 月 (1-12)
│ │ │ │ ┌ 星期 (0-7, 0和7都是周日)
│ │ │ │ │
* * * * *
常用表达式:
| 表达式 | 含义 |
|---|---|
*/5 * * * * |
每5分钟 |
0 * * * * |
每小时整点 |
0 9 * * * |
每天上午9点 |
0 9 * * 1-5 |
工作日上午9点 |
0 0 1 * * |
每月1号零点 |
将前面学到的所有技术整合为一个完整的CI/CD代码审查机器人。
claude-review-bot/
├── package.json
├── tsconfig.json
├── src/
│ ├── index.ts # 主入口
│ ├── reviewer.ts # 代码审查逻辑
│ ├── hooks/
│ │ ├── guard-bash.sh # Bash命令守卫
│ │ ├── guard-edit.sh # 文件编辑守卫
│ │ └── auto-format.sh # 自动格式化
│ └── reporters/
│ ├── console.ts # 控制台报告
│ └── github.ts # GitHub PR评论
├── .claude/
│ └── settings.json # Hooks配置
└── config.json # 审查规则配置
{
"rules": {
"security": {
"enabled": true,
"severity": "critical",
"patterns": [
"硬编码API密钥",
"SQL拼接",
"未验证的用户输入",
"不安全的正则表达式"
]
},
"quality": {
"enabled": true,
"severity": "warning",
"patterns": [
"重复代码",
"过长函数(>50行)",
"过深嵌套(>4层)",
"魔法数字"
]
},
"performance": {
"enabled": true,
"severity": "info",
"patterns": [
"N+1查询",
"不必要的同步操作",
"大循环内的内存分配"
]
}
},
"parallel": true,
"max_turns": 5,
"output": {
"format": "markdown",
"post_to_github": true
}
}
// src/index.ts
import { claude } from '@anthropic-ai/claude-code-sdk';
import * as fs from 'fs';
import * as path from 'path';
interface ReviewConfig {
rules: Record<string, {
enabled: boolean;
severity: string;
patterns: string[];
}>;
parallel: boolean;
max_turns: number;
}
async function main() {
const config: ReviewConfig = JSON.parse(
fs.readFileSync('config.json', 'utf-8')
);
const projectPath = process.argv[2] || process.cwd();
const changedFiles = getChangedFiles();
if (changedFiles.length === 0) {
console.log('没有检测到变更文件,跳过审查。');
return;
}
console.log(`📋 检测到 ${changedFiles.length} 个变更文件,开始审查...\n`);
// 根据配置构建审查任务
const tasks = Object.entries(config.rules)
.filter(([_, rule]) => rule.enabled)
.map(([category, rule]) => ({
category,
severity: rule.severity,
prompt: buildPrompt(category, rule.patterns, changedFiles),
}));
// 并行执行
if (config.parallel) {
const results = await Promise.all(
tasks.map(task => claude({
prompt: task.prompt,
options: {
maxTurns: config.max_turns,
allowedTools: ['Read', 'Glob', 'Grep'],
cwd: projectPath,
},
}))
);
// 按严重级别排序输出
const severityOrder = { critical: 0, warning: 1, info: 2 };
const combined = tasks.map((t, i) => ({
...t,
result: results[i].result,
cost: results[i].cost_usd,
}));
combined.sort((a, b) =>
severityOrder[a.severity] - severityOrder[b.severity]
);
printReport(combined);
}
}
function getChangedFiles(): string[] {
// 在CI环境中从git获取变更文件
const { execSync } = require('child_process');
try {
const baseBranch = process.env.GITHUB_BASE_REF || 'main';
return execSync(
`git diff --name-only origin/${baseBranch}...HEAD`
).toString().trim().split('\n').filter(Boolean);
} catch {
return [];
}
}
function buildPrompt(
category: string,
patterns: string[],
files: string[]
): string {
return `你是代码审查专家。请审查以下变更文件中是否存在 ${category} 相关问题。
重点关注:${patterns.join('、')}
变更文件列表:
${files.map(f => `- ${f}`).join('\n')}
请用以下JSON格式返回结果:
{
"issues": [
{
"file": "文件路径",
"line": 行号,
"severity": "critical/warning/info",
"message": "问题描述",
"suggestion": "修复建议"
}
]
}`;
}
function printReport(results: any[]): void {
console.log('\n' + '='.repeat(60));
console.log(' 🔍 Claude Code 审查报告');
console.log('='.repeat(60));
let totalCost = 0;
let totalIssues = 0;
for (const r of results) {
totalCost += r.cost;
console.log(`\n### ${r.category} (${r.severity})`);
console.log(r.result);
totalIssues++;
}
console.log('\n' + '='.repeat(60));
console.log(`📊 审查维度: ${results.length} | 总成本: $${totalCost.toFixed(4)}`);
console.log('='.repeat(60) + '\n');
}
main().catch(console.error);
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm ci
- name: Run Claude Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_BASE_REF: ${{ github.base_ref }}
run: npx tsx src/index.ts ${{ github.workspace }}
- name: Post review comment
if: always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const report = fs.readFileSync('review-report.md', 'utf-8');
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: report
});

图表 4
在自动化场景中,建议采用分层权限策略:
# 第一级:纯只读(报告生成)
claude -p "生成项目架构文档" \
--allowedTools "Read,Glob,Grep"
# 第二级:读写+受限Bash(代码修复)
claude -p "修复lint错误" \
--allowedTools "Read,Edit,Glob,Grep" \
--max-turns 10
# 第三级:完全权限(仅限CI环境)
if [ "$CI" = "true" ]; then
claude -p "执行完整的代码质量检查流程" \
--allowedTools "Read,Edit,Bash,Glob,Grep"
fi
# 使用 --max-turns 控制单次成本上限
claude -p "快速检查" --max-turns 2
# 使用 --model 选择更经济的模型
claude -p "简单的文本总结" --model haiku
# 在SDK中实现成本预算
const result = await claude({
prompt: '分析代码',
options: {
maxTurns: 5,
maxCostUsd: 0.50, // 成本上限50美分
},
});
async function resilientClaudeCall(
prompt: string,
maxRetries = 3
): Promise<any> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const result = await claude({
prompt,
options: {
maxTurns: 5,
allowedTools: ['Read', 'Edit', 'Bash'],
},
});
if (result.is_error) {
throw new Error(`Agent返回错误: ${result.result}`);
}
return result;
} catch (error) {
console.error(`第${attempt}次尝试失败:`, error);
if (attempt === maxRetries) throw error;
// 指数退避
await new Promise(r =>
setTimeout(r, Math.pow(2, attempt) * 1000)
);
}
}
}
#!/bin/bash
# multi-repo-sync.sh — 多仓库批量同步操作
REPOS=(
"/projects/frontend"
"/projects/backend"
"/projects/mobile"
"/projects/shared-libs"
)
PROMPT="检查并升级所有过时的npm依赖到最新稳定版本,运行测试确保没有破坏性变更"
for repo in "${REPOS[@]}"; do
echo "=== 处理: $repo ==="
claude -p "$PROMPT" \
--cwd "$repo" \
--allowedTools "Read,Edit,Bash,Glob,Grep" \
--max-turns 8 \
--output-format json \
> "${repo##*/}-result.json" &
done
# 等待所有后台任务完成
wait
echo "=== 所有仓库处理完成 ==="
# 汇总结果
for repo in "${REPOS[@]}"; do
RESULT_FILE="${repo##*/}-result.json"
if [ -f "$RESULT_FILE" ]; then
COST=$(jq -r '.cost_usd // 0' "$RESULT_FILE")
echo "$repo: 成本 \$${COST}"
fi
done
# 环境变量方式
CLAUDE_CODE_DEBUG=1 claude -p "测试"
# 查看详细工具调用
claude -p "分析代码" --verbose --output-format stream-json 2>&1 | tee debug.log
| 症状 | 可能原因 | 排查步骤 |
|---|---|---|
| Hook未触发 | 配置路径错误 | 检查 ~/.claude/settings.json 中 hooks 字段JSON格式 |
| Hook脚本报错 | 权限不足 | chmod +x 添加执行权限 |
-p模式超时 |
max-turns太小或提示词太模糊 | 增大 --max-turns,优化提示词 |
| JSON输出损坏 | 混合了警告和JSON | 使用 --output-format json 并设置 NO_COLOR=1 |
| 成本异常高 | Agent陷入循环 | 检查 --max-turns 和提示词的明确性 |
| SDK连接失败 | API Key问题 | 检查 ANTHROPIC_API_KEY 环境变量 |
# 在每个Hook脚本中添加日志
exec >> ~/.claude/hooks.log 2>&1
echo "[$(date)] Hook executed: $0"
echo "[$(date)] Input: $(cat)"
-p标志和输出格式的完整参考/loop和cron调度完整指南训练营适用性评估:本教程适合中级训练营(第3-4天),学员需具备CLI和基本编程基础。预计教学时长4-5小时,其中Headless模式讲解1小时、Hands实战配置2小时、Agent SDK编程练习2小时。建议学员提前准备好一个真实的代码仓库作为实验环境。
[!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 等场景全覆盖。
