本教程系统讲解 Claude Code 三大自动化能力:Print 无头模式(-p)、Hooks 事件驱动系统、Agent SDK 编程接口。学完后你将掌握从单条命令自动化到多 Agent 协作编排的完整技术栈,适用于 CI/CD 集成、批量代码操作、安全审计和生产级 Agent 构建场景。
适用人群:已熟悉 Claude Code 基本操作,希望将其集成到自动化流水线或构建生产级 AI Agent 的开发者。
前置条件:Claude Code v1.0.30+、Node.js 18+、ANTHROPIC_API_KEY 环境变量、基础 Shell 脚本能力。
Print 模式(-p 或 --print)将 Claude Code 从交互式终端工具转变为非交互式命令行工具。它不会启动 TUI 界面,直接将结果输出到 stdout,可以像任何 Unix 命令一样被管道串联。
flowchart LR
A[用户/脚本] -->|claude -p "指令"| B[Print 模式]
B --> C{--output-format}
C -->|text| D[纯文本输出]
C -->|json| E[结构化 JSON]
C -->|stream-json| F[实时 JSON 事件流]
D --> G[终端/文件]
E --> H[jq 解析/程序处理]
F --> I[Node.js/Python 消费者]
# 最简形式 — 输出纯文本
claude -p "解释 src/auth.ts 中的 JWT 验证逻辑"
# 等价的长写法
claude --print "解释 src/auth.ts 中的 JWT 验证逻辑"
# 管道输入 — 将 stdin 作为上下文
cat error.log | claude -p "分析这段错误日志,给出修复建议"
# 输出重定向到文件
claude -p "为 src/api/ 下所有路由生成 OpenAPI 文档" > docs/api.md
claude -p "统计项目中 TODO 注释的数量"
# 输出:项目中存在 47 个 TODO 注释...
适合人类阅读和简单日志记录。
claude -p "列出所有 TODO 注释及其位置" --output-format json
输出结构:
{
"result": "找到 47 个 TODO 注释...",
"session_id": "sess_abc123",
"is_error": false,
"cost_usd": 0.032,
"num_turns": 3,
"duration_ms": 4500,
"duration_api_ms": 3200,
"usage": {
"input_tokens": 12800,
"output_tokens": 2400,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"server_tool_use": null
}
}
结合 jq 提取关键字段:
# 提取纯文本结果
claude -p "代码审查" --output-format json | jq -r '.result'
# 提取成本信息
claude -p "重构模块" --output-format json | jq '{cost: .cost_usd, turns: .num_turns}'
# 提取 token 消耗
claude -p "生成文档" --output-format json | jq '.usage'
这是最强大的输出格式——实时逐行发出 JSON 事件,每个事件占一行(JSONL 格式):
claude -p "分析整个项目的测试覆盖率" \
--output-format stream-json \
--verbose \
--include-partial-messages
事件类型一览:
| 事件 | 触发时机 | 关键字段 |
|---|---|---|
system.init |
会话初始化 | session_id, tools |
stream_event |
token 生成 | event.delta.text |
tool_use |
工具调用 | name, input |
tool_result |
工具结果 | content |
system.api_retry |
API 重试 | attempt, error_status |
result |
最终结果 | result, cost_usd |
用 jq 实时提取文本流:
claude -p "编写一个排序算法" \
--output-format stream-json \
--verbose \
--include-partial-messages \
| jq -rj 'select(.type == "stream_event" and .event.delta.type? == "text_delta") | .event.delta.text'
# 裸模式 — 跳过 skill 加载、LSP 初始化,速度最快
claude --bare -p "快速查询" --output-format json
# 指定模型
claude -p "深度代码审查" --model opus --output-format json
# 限制可用工具(只读模式)
claude -p "分析代码结构" --allowedTools "Read,Grep,Glob"
# 权限模式控制
claude -p "修复所有 lint 错误" \
--permission-mode bypassPermissions \
--output-format json
# 多轮会话续接
SESSION_ID=$(claude -p "开始代码审查" --output-format json | jq -r '.session_id')
claude -p "重点关注安全问题" --resume "$SESSION_ID"
Q: -p 模式下权限请求会怎样?
A: 默认权限模式下遇到需要审批的操作会阻塞。在自动化场景中使用 --permission-mode bypassPermissions 自动批准,或用 --allowedTools 限制工具范围避免触发权限。
Q: --bare 和普通 -p 的区别?
A: --bare 跳过 skill 自动发现、hooks 注册、LSP 初始化、auto-memory 更新。启动速度更快,但会失去这些功能。必须通过环境变量提供 API Key。
Q: 如何限制执行时间和成本?
A: 使用 --max-turns 限制 Agent 轮次,在 SDK 中使用 maxBudgetUsd 控制预算上限。
CLAUDE.md = 建议性指令(LLM 可能忽略)
Hooks = 强制性规则(Shell 命令,确定性执行)
Hooks 是用户定义的 Shell 命令,在 Claude Code 生命周期特定时刻自动触发。关键特性:
flowchart TD
subgraph 会话生命周期
SS[SessionStart] --> PRC[PreCompact]
PRC --> POC[PostCompact]
POC --> SE[SessionEnd]
end
subgraph 工具生命周期
PTU[PreToolUse] --> EXEC[工具执行]
EXEC --> |成功| POTU[PostToolUse]
EXEC --> |失败| POTUF[PostToolUseFailure]
end
subgraph 权限控制
PR[PermissionRequest] --> PD[PermissionDenied]
end
subgraph Agent 生命周期
SAS[SubagentStart] --> SASTOP[SubagentStop]
STOP[Stop] --> SF[StopFailure]
end
subgraph 用户交互
UPS[UserPromptSubmit]
NOTIF[Notification]
end
| 文件 | 范围 | Git 提交 | 典型用途 |
|---|---|---|---|
~/.claude/settings.json |
全局所有项目 | 否 | 个人偏好、桌面通知 |
.claude/settings.json |
项目级 | 是 | 团队共享规则 |
.claude/settings.local.json |
项目本地 | 否(gitignore) | 个人本地覆盖 |
| 类型 | 执行方式 | 适用场景 |
|---|---|---|
command |
执行 Shell 脚本 | 格式化、lint、安全检查、日志 |
prompt |
发送给 LLM 判断 yes/no | 复杂语义验证 |
agent |
启动多轮子 Agent(最多 50 轮) | 深度验证(需读文件+执行命令) |
在 .claude/settings.json 中添加 hooks 字段:
{
"hooks": {
"EventName": [
{
"matcher": "正则匹配工具名",
"hooks": [
{
"type": "command",
"command": "脚本路径或内联命令",
"timeout": 60,
"async": false
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write 2>/dev/null; exit 0"
}
]
}
]
}
}
效果:每次 Claude 修改文件后自动格式化,退出码 0 确保不阻断流程。
#!/bin/bash
# .claude/hooks/protect-bash.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
BLOCKED=("rm -rf /" "DROP TABLE" "DROP DATABASE" "terraform destroy" "git push --force" "npm publish")
for b in "${BLOCKED[@]}"; do
if echo "$COMMAND" | grep -qi "$b"; then
echo "BLOCKED: 危险命令检测到 '$b'" >&2
exit 2
fi
done
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "$CLAUDE_PROJECT_DIR/.claude/hooks/protect-bash.sh"
}
]
}
]
}
}
关键:退出码 2 表示阻断操作,stderr 内容作为反馈显示给 Claude。即使使用 --dangerously-skip-permissions,PreToolUse hook 的 deny 决定也无法绕过。
#!/bin/bash
# .claude/hooks/protect-files.sh
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path')
PROTECTED=(".env" ".env.local" ".env.production" "credentials.json" "package-lock.json" ".git/")
for p in "${PROTECTED[@]}"; do
if echo "$FILE_PATH" | grep -q "$p"; then
echo "BLOCKED: 受保护文件 '$FILE_PATH' 不可修改" >&2
exit 2
fi
done
exit 0
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code 需要你的输入\" with title \"Claude Code\"'"
}
]
}
]
}
}
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo '提醒:使用 Bun 而非 npm。当前 Sprint:auth 重构。所有 PR 必须通过 CI。'"
}
]
}
]
}
}
效果:每次上下文压缩后自动注入关键项目约束,防止长时间对话后遗忘。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "验证工作是否完成:1) 运行测试套件 2) 检查 TypeScript 编译错误 3) 确认没有 console.log 遗留。报告结果。",
"timeout": 120
}
]
}
]
}
}
注意:Stop hook 中的 Agent 类型会启动一个独立子 Agent(最多 50 轮工具调用),非常适合深度验证。
{
"hooks": {
"PermissionRequest": [
{
"matcher": "Read|Glob|Grep",
"hooks": [
{
"type": "command",
"command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"behavior\": \"allow\"}}}'"
}
]
}
]
}
}
{
"session_id": "sess_abc123",
"cwd": "/home/dev/myproject",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
},
"permission_mode": "default"
}
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "项目策略自动批准只读操作"
}
}
| 退出码 | 含义 | 行为 |
|---|---|---|
| 0 | 成功 | 操作继续。stdout 作为上下文添加 |
| 2 | 阻断 | 操作被阻止。stderr 显示给 Claude |
| 其他 | 非阻断错误 | 操作继续。stderr 在 verbose 模式可见 |
| 变量 | 含义 |
|---|---|
$CLAUDE_PROJECT_DIR |
项目根目录 |
$CLAUDE_ENV_FILE |
持久化环境变量文件路径 |
$CLAUDE_TOOL_NAME |
当前工具名称 |
$CLAUDE_FILE_PATH |
当前文件路径 |
$CLAUDE_CODE_REMOTE |
远程环境标记 |
# 在 Claude Code 内部查看已注册 hooks
/hooks
# 开启详细模式查看 hook 执行日志
Ctrl+O # 切换 verbose 模式
# 手动测试 hook 脚本
echo '{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}' | bash .claude/hooks/protect-bash.sh
echo $? # 应返回 2
flowchart TD
A[自动化需求] --> B{需要什么能力?}
B -->|只需简单调用| C[Claude Code SDK<br/>@anthropic-ai/claude-code]
B -->|需要 MCP/子 Agent| D[Agent SDK<br/>@anthropic-ai/claude-agent-sdk]
B -->|只需 Shell 脚本| E[CLI -p 模式]
C --> F["claude() 函数<br/>简单直接"]
D --> G["query() 函数<br/>流式 + MCP + 子 Agent"]
E --> H["claude -p + jq<br/>零代码"]
| 特性 | CLI -p |
Claude Code SDK | Agent SDK |
|---|---|---|---|
| 安装 | 已内置 | npm i @anthropic-ai/claude-code |
npm i @anthropic-ai/claude-agent-sdk |
| 语言 | Shell | TypeScript/JS | TypeScript/JS |
| 流式输出 | stream-json |
claude.stream() |
query() 异步迭代 |
| 子 Agent | 不支持 | 不支持 | 内置 agents 配置 |
| MCP 服务器 | 配置文件 | 不支持 | 进程内创建 |
| 预算控制 | --max-turns |
maxTurns |
maxTurns + maxBudgetUsd |
安装:
npm install @anthropic-ai/claude-code
一次性任务:
import { claude } from "@anthropic-ai/claude-code";
const result = await claude({
prompt: "为 src/api/ 下所有端点添加错误处理中间件",
options: {
maxTurns: 30,
model: "claude-sonnet-4-6",
allowedTools: ["Read", "Edit", "Write", "Glob", "Grep", "Bash"],
},
});
console.log("完成:", result.text);
console.log("成本:", result.cost.totalCost, "USD");
console.log("轮次:", result.turns);
流式处理:
import { claude } from "@anthropic-ai/claude-code";
const stream = claude.stream({
prompt: "重构用户认证模块,提取为独立服务",
options: { maxTurns: 20 },
});
for await (const event of stream) {
if (event.type === "text") {
process.stdout.write(event.text);
} else if (event.type === "tool_use") {
console.log(`\n[使用工具: ${event.name}]`);
} else if (event.type === "tool_result") {
console.log(`[工具结果: ${event.content?.slice(0, 100)}...]`);
}
}
安装:
npm install @anthropic-ai/claude-agent-sdk
npm install -D typescript @types/node tsx
基础查询:
import { query } from "@anthropic-ai/claude-agent-sdk";
async function main() {
for await (const message of query({
prompt: "分析项目结构并列出主要模块",
options: {
allowedTools: ["Bash", "Glob", "Read"],
maxTurns: 10,
},
})) {
switch (message.type) {
case "assistant":
const text = message.message.content
.filter((b) => b.type === "text")
.map((b) => b.text)
.join("");
if (text) console.log("[Claude]", text);
break;
case "tool_use":
console.log(`[工具调用] ${message.name}`);
break;
case "result":
if (message.subtype === "success") {
console.log("\n完成:", message.result);
} else {
console.error("失败:", message.error);
}
break;
}
}
}
main().catch(console.error);
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const msg of query({
prompt: "清理并优化代码库",
options: {
allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
maxTurns: 30,
maxBudgetUsd: 2.0, // 成本上限 $2
canUseTool: async (toolName, input) => {
// 阻止危险 Bash 命令
if (toolName === "Bash") {
const cmd = (input as { command: string }).command;
const dangerous = ["rm -rf", "DROP TABLE", "git push --force"];
if (dangerous.some((d) => cmd.includes(d))) {
return { allowed: false, reason: "破坏性命令被禁止" };
}
}
// 保护敏感文件
if (toolName === "Write" || toolName === "Edit") {
const fp = (input as { file_path: string }).file_path;
const protected_files = [".env", "package-lock.json", "prisma/schema.prisma"];
if (protected_files.some((p) => fp.includes(p))) {
return { allowed: false, reason: `受保护文件: ${fp}` };
}
}
return { allowed: true };
},
},
})) {
if ("result" in msg) console.log(msg.result);
}
import { query } from "@anthropic-ai/claude-agent-sdk";
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk/mcp";
// 创建内嵌 MCP 服务器
const analyticsServer = createSdkMcpServer({
name: "analytics",
version: "1.0.0",
tools: [
tool(
"get_metrics",
"获取指定日期范围的项目指标",
{
type: "object",
properties: {
metric: { type: "string", description: "指标名称" },
startDate: { type: "string", description: "起始日期 YYYY-MM-DD" },
endDate: { type: "string", description: "结束日期 YYYY-MM-DD" },
},
required: ["metric", "startDate", "endDate"],
},
async ({ metric, startDate, endDate }) => {
const res = await fetch(
`https://api.example.com/metrics?type=${metric}&from=${startDate}&to=${endDate}`
);
return JSON.stringify(await res.json());
}
),
],
});
// Agent 可直接调用 MCP 工具
for await (const msg of query({
prompt: "分析本月代码提交频率和 bug 修复趋势",
options: {
mcpServers: { analytics: analyticsServer },
allowedTools: ["mcp__analytics__get_metrics", "Bash", "Read", "Glob"],
maxTurns: 15,
},
})) {
if ("result" in msg) console.log(msg.result);
}
#!/bin/bash
# batch-review.sh — 批量审查 Git 变更文件
set -euo pipefail
CHANGED_FILES=$(git diff --name-only main...HEAD -- "*.ts" "*.tsx")
RESULTS_DIR="reviews/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$RESULTS_DIR"
for file in $CHANGED_FILES; do
echo "审查: $file"
claude -p "对这个文件进行代码审查,重点关注:
1. 安全漏洞
2. 性能问题
3. 代码风格
4. 缺失的错误处理
文件: $file" \
--output-format json \
--allowedTools "Read,Grep,Glob" \
> "$RESULTS_DIR/$(basename $file .ts).json"
done
echo "审查完成。结果保存在 $RESULTS_DIR/"
import { claude } from "@anthropic-ai/claude-code";
import { readdir, readFile } from "fs/promises";
import pLimit from "p-limit";
const limit = pLimit(3); // 最多 3 个并发 Agent
async function batchAnalyze(directory: string) {
const files = await readdir(directory);
const tsFiles = files.filter((f) => f.endsWith(".ts"));
const tasks = tsFiles.map((file) =>
limit(async () => {
console.log(`处理: ${file}`);
const result = await claude({
prompt: `分析 ${directory}/${file} 的代码质量,给出 1-10 评分和改进建议`,
options: {
maxTurns: 5,
model: "claude-haiku-4-5", // 快速模型节省成本
allowedTools: ["Read"],
},
});
return {
file,
score: result.text.match(/(\d+)\/10/)?.[1] ?? "N/A",
cost: result.cost.totalCost,
summary: result.text.slice(0, 200),
};
})
);
const results = await Promise.all(tasks);
// 按评分排序
results
.sort((a, b) => Number(b.score) - Number(a.score))
.forEach((r) => {
console.log(`${r.score}/10 | $${r.cost.toFixed(4)} | ${r.file}`);
});
const totalCost = results.reduce((sum, r) => sum + r.cost, 0);
console.log(`\n总成本: $${totalCost.toFixed(4)}`);
}
batchAnalyze("./src").catch(console.error);
import { claude } from "@anthropic-ai/claude-code";
async function developFeature(requirement: string) {
console.log("=== 阶段 1: 制定计划 ===");
const plan = await claude({
prompt: `阅读代码库,为实现以下需求制定详细计划:${requirement}`,
options: {
maxTurns: 15,
allowedTools: ["Read", "Glob", "Grep"], // 只读阶段
},
});
console.log("计划:", plan.text.slice(0, 500));
console.log("\n=== 阶段 2: 执行实现 ===");
const implementation = await claude({
prompt: `按照以下计划实现代码修改:\n\n${plan.text}`,
options: {
maxTurns: 50,
model: "claude-sonnet-4-6",
permissionMode: "acceptEdits",
},
});
console.log("\n=== 阶段 3: 代码审查 ===");
const review = await claude({
prompt: `审查所有修改,检查 bug、边界情况和测试覆盖。发现问题直接修复。`,
options: { maxTurns: 20 },
});
const totalCost =
plan.cost.totalCost +
implementation.cost.totalCost +
review.cost.totalCost;
return {
plan: plan.text,
code: implementation.text,
review: review.text,
totalCost,
};
}
// 使用
const result = await developFeature(
"添加用户注册 API 端点,支持邮箱验证"
);
console.log(`\n总成本: $${result.totalCost.toFixed(4)}`);
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const msg of query({
prompt: "分析项目测试覆盖率,为未覆盖的函数编写测试",
options: {
allowedTools: ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "Task"],
agents: {
"coverage-analyzer": {
description: "分析测试覆盖率,识别未测试代码",
tools: ["Bash", "Read", "Glob", "Grep"],
prompt: "你是测试覆盖率分析师。运行覆盖率工具并识别未测试的函数。",
model: "haiku",
},
"test-writer": {
description: "为 TypeScript 函数编写全面的单元测试",
tools: ["Read", "Write", "Edit", "Glob"],
prompt: "你是测试工程师。使用 Vitest 编写全面的单元测试。",
model: "sonnet",
},
},
maxTurns: 30,
},
})) {
if ("result" in msg) console.log(msg.result);
}
工作原理:定义 agents 后,主 Agent 获得 Task 工具,可以按名称启动子 Agent。每个子 Agent 有独立上下文和工具集,可使用不同模型(分析用 Haiku 省钱,编写用 Sonnet 保证质量)。
# .github/workflows/claude-review.yml
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
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: |
curl -fsSL https://claude.ai/install.sh | bash
- name: Run Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
run: |
claude --bare -p "审查这个 PR 的所有变更。
重点关注:安全漏洞、性能退化、代码风格。
用中文输出审查结果。" \
--output-format json \
--permission-mode bypassPermissions \
--allowedTools "Read,Grep,Glob,Bash" \
> review_result.json
- name: Post Review Comment
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
REVIEW=$(jq -r '.result' review_result.json)
gh pr comment ${{ github.event.pull_request.number }} \
--body "## Claude Code 审查结果
$REVIEW
---
*成本: \`$(jq -r '.cost_usd' review_result.json)\` USD*
*轮次: \`$(jq -r '.num_turns' review_result.json)\`*"
#!/bin/bash
# .git/hooks/pre-commit
STAGED=$(git diff --cached --name-only -- "*.ts" "*.tsx" "*.js")
if [ -z "$STAGED" ]; then exit 0; fi
for file in $STAGED; do
echo "AI 检查: $file"
RESULT=$(claude --bare -p "检查此文件是否有明显的 bug 或安全问题。只需回答 PASS 或 FAIL + 原因。
文件: $file" \
--output-format text \
--allowedTools "Read" \
--max-turns 3 \
2>/dev/null)
if echo "$RESULT" | grep -q "FAIL"; then
echo "❌ $file 未通过检查:"
echo "$RESULT"
exit 1
fi
echo "✅ $file 通过"
done
#!/bin/bash
# daily-health-check.sh — 每日代码健康巡检
REPORT_FILE="reports/health-$(date +%Y%m%d).md"
mkdir -p reports
claude --bare -p "执行代码库健康检查:
1. 检查依赖是否有安全漏洞 (npm audit)
2. 统计 TODO/FIXME 数量
3. 检查测试覆盖率趋势
4. 识别最大的文件和函数
5. 检查是否有未使用的依赖
输出 Markdown 格式的报告。" \
--output-format text \
--permission-mode bypassPermissions \
> "$REPORT_FILE"
echo "报告已生成: $REPORT_FILE"
# 可选:发送到 Slack
curl -X POST "$SLACK_WEBHOOK" \
-H "Content-Type: application/json" \
-d "{\"text\": \"每日代码健康报告已生成。\n$(head -5 $REPORT_FILE | sed 's/"/\\"/g')\"}"
将 Hooks、Print 模式和 Agent SDK 结合,构建一个完整的代码质量守卫系统。
project/
├── .claude/
│ ├── settings.json # Hook 配置
│ └── hooks/
│ ├── protect-bash.sh # 危险命令拦截
│ ├── protect-files.sh # 敏感文件保护
│ └── auto-format.sh # 自动格式化
├── scripts/
│ ├── batch-review.ts # 批量审查脚本
│ └── health-check.ts # 健康巡检脚本
├── .github/workflows/
│ └── claude-review.yml # CI 审查
└── reports/ # 报告输出目录
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/protect-bash.sh",
"timeout": 5
}
]
},
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/protect-files.sh",
"timeout": 5
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "FILE=$(cat | jq -r '.tool_input.file_path'); case \"$FILE\" in *.ts|*.tsx) npx prettier --write \"$FILE\" 2>/dev/null;; *.py) black \"$FILE\" 2>/dev/null;; esac; exit 0"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "验证修改是否完整:运行 npm test,检查 TypeScript 编译(npx tsc --noEmit),报告结果。如果测试失败,说明失败原因。",
"timeout": 120
}
]
}
],
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo '项目规则:使用 pnpm 而非 npm。所有 API 必须有错误处理。提交前运行 pnpm test。'"
}
]
}
],
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code 需要输入\" with title \"Claude Code\"' 2>/dev/null; exit 0"
}
]
}
]
}
}
// scripts/batch-review.ts
import { claude } from "@anthropic-ai/claude-code";
import { readdir, writeFile, mkdir } from "fs/promises";
import pLimit from "p-limit";
const limit = pLimit(3);
async function main() {
const srcDir = "./src";
const files = (await readdir(srcDir, { recursive: true }))
.filter((f) => String(f).endsWith(".ts"))
.map((f) => `${srcDir}/${f}`);
console.log(`发现 ${files.length} 个 TypeScript 文件`);
const tasks = files.map((file) =>
limit(async () => {
const result = await claude({
prompt: `对 ${file} 进行代码审查。评分 1-10。输出格式:
## 文件: ${file}
### 评分: X/10
### 问题列表
- [严重] 问题描述
### 建议
- 改进建议`,
options: {
maxTurns: 5,
model: "claude-haiku-4-5",
allowedTools: ["Read"],
},
});
return { file, review: result.text, cost: result.cost.totalCost };
})
);
const results = await Promise.all(tasks);
await mkdir("./reports", { recursive: true });
const report = results
.map((r) => r.review)
.join("\n\n---\n\n");
await writeFile("./reports/code-review.md", report);
const totalCost = results.reduce((sum, r) => sum + r.cost, 0);
console.log(`审查完成。总成本: $${totalCost.toFixed(4)}`);
}
main().catch(console.error);
运行:
npx tsx scripts/batch-review.ts
// scripts/health-check.ts
import { claude } from "@anthropic-ai/claude-code";
import { writeFile } from "fs/promises";
async function main() {
const result = await claude({
prompt: `执行代码库健康检查,输出 Markdown 报告:
1. ## 依赖安全 (npm audit 结果摘要)
2. ## 代码标记 (TODO/FIXME/HACK 数量和分布)
3. ## 文件体积 (超过 300 行的文件列表)
4. ## 复杂度热点 (圈复杂度高的函数)
5. ## 测试健康 (测试文件/源文件比例)
6. ## 改进建议 (Top 5 优先级最高的改进项)`,
options: {
maxTurns: 25,
model: "claude-sonnet-4-6",
permissionMode: "acceptEdits",
},
});
const date = new Date().toISOString().split("T")[0];
await writeFile(`./reports/health-${date}.md`, result.text);
console.log(`报告已生成: reports/health-${date}.md`);
console.log(`成本: $${result.cost.totalCost.toFixed(4)}`);
}
main().catch(console.error);
flowchart TB
subgraph 开发阶段
DEV[开发者提交代码] --> PRE[Git Pre-commit Hook]
PRE --> |AI检查| PASS{通过?}
PASS --> |是| COMMIT[提交成功]
PASS --> |否| REJECT[拒绝提交]
end
subgraph CI阶段
PUSH[Push 到 PR] --> GHA[GitHub Actions]
GHA --> CLAUDE[Claude Print 模式审查]
CLAUDE --> COMMENT[评论到 PR]
end
subgraph 交互阶段
INTER[开发者使用 Claude Code] --> HOOKS[Hooks 触发]
HOOKS --> PRE_HOOK[PreToolUse: 安全检查]
HOOKS --> POST_HOOK[PostToolUse: 自动格式化]
HOOKS --> STOP_HOOK[Stop: 自动测试]
end
subgraph 巡检阶段
CRON[每日 Cron] --> HEALTH[健康巡检脚本]
HEALTH --> REPORT[生成报告]
REPORT --> SLACK[通知团队]
end
COMMIT --> PUSH
| 维度 | 评估 |
|---|---|
| 适合训练营类型 | 企业 AI 工程化培训、DevOps 自动化进阶、AI Agent 开发实战 |
| 学员基础要求 | TypeScript 基础、Shell 脚本能力、Claude Code 使用经验 |
| 预计教学时长 | 4-6 小时(含动手实验) |
| 实验环境要求 | 每人一台有 Node.js 18+ 和 Claude Code 的开发机,ANTHROPIC_API_KEY |
| 建议分节 | Part 1-2(2h)→ Part 3-4(2h)→ Part 5-6(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 等场景全覆盖。
