首页 › tutorials › Claude Code自动化全栈:-p模式到Hooks到Agent SDK

概述

本教程系统讲解 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 无头模式 — 从终端到管道

1.1 核心概念

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 消费者]

1.2 基础用法

# 最简形式 — 输出纯文本
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

1.3 三种输出格式详解

text 模式(默认)

claude -p "统计项目中 TODO 注释的数量"
# 输出:项目中存在 47 个 TODO 注释...

适合人类阅读和简单日志记录。

json 模式

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'

stream-json 模式

这是最强大的输出格式——实时逐行发出 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'

1.4 高级标志组合

# 裸模式 — 跳过 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"

1.5 常见问题

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 控制预算上限。


第二部分:Hooks 系统 — 确定性事件驱动

2.1 Hooks 与 CLAUDE.md 的本质区别

CLAUDE.md = 建议性指令(LLM 可能忽略)
Hooks   = 强制性规则(Shell 命令,确定性执行)

Hooks 是用户定义的 Shell 命令,在 Claude Code 生命周期特定时刻自动触发。关键特性:

2.2 全部 Hook 事件类型

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

2.3 配置层级

文件 范围 Git 提交 典型用途
~/.claude/settings.json 全局所有项目 否 个人偏好、桌面通知
.claude/settings.json 项目级 是 团队共享规则
.claude/settings.local.json 项目本地 否(gitignore) 个人本地覆盖

2.4 三种 Hook 类型

类型 执行方式 适用场景
command 执行 Shell 脚本 格式化、lint、安全检查、日志
prompt 发送给 LLM 判断 yes/no 复杂语义验证
agent 启动多轮子 Agent(最多 50 轮) 深度验证(需读文件+执行命令)

2.5 配置结构

在 .claude/settings.json 中添加 hooks 字段:

{
  "hooks": {
    "EventName": [
      {
        "matcher": "正则匹配工具名",
        "hooks": [
          {
            "type": "command",
            "command": "脚本路径或内联命令",
            "timeout": 60,
            "async": false
          }
        ]
      }
    ]
  }
}

2.6 七大实战配置

配置 1:自动 Prettier 格式化

{
  "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 确保不阻断流程。

配置 2:阻止危险 Bash 命令

#!/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 决定也无法绕过。

配置 3:保护敏感文件

#!/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

配置 4:桌面通知

{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code 需要你的输入\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

配置 5:压缩后重新注入上下文

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "compact",
        "hooks": [
          {
            "type": "command",
            "command": "echo '提醒:使用 Bun 而非 npm。当前 Sprint:auth 重构。所有 PR 必须通过 CI。'"
          }
        ]
      }
    ]
  }
}

效果:每次上下文压缩后自动注入关键项目约束,防止长时间对话后遗忘。

配置 6:完成时自动运行测试

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "验证工作是否完成:1) 运行测试套件 2) 检查 TypeScript 编译错误 3) 确认没有 console.log 遗留。报告结果。",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

注意:Stop hook 中的 Agent 类型会启动一个独立子 Agent(最多 50 轮工具调用),非常适合深度验证。

配置 7:自动批准特定权限

{
  "hooks": {
    "PermissionRequest": [
      {
        "matcher": "Read|Glob|Grep",
        "hooks": [
          {
            "type": "command",
            "command": "echo '{\"hookSpecificOutput\": {\"hookEventName\": \"PermissionRequest\", \"decision\": {\"behavior\": \"allow\"}}}'"
          }
        ]
      }
    ]
  }
}

2.7 Hook 输入输出规范

stdin JSON 输入(PreToolUse)

{
  "session_id": "sess_abc123",
  "cwd": "/home/dev/myproject",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": {
    "command": "npm test"
  },
  "permission_mode": "default"
}

stdout JSON 输出(权限决策)

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "allow",
    "permissionDecisionReason": "项目策略自动批准只读操作"
  }
}

退出码含义

退出码 含义 行为
0 成功 操作继续。stdout 作为上下文添加
2 阻断 操作被阻止。stderr 显示给 Claude
其他 非阻断错误 操作继续。stderr 在 verbose 模式可见

2.8 环境变量

变量 含义
$CLAUDE_PROJECT_DIR 项目根目录
$CLAUDE_ENV_FILE 持久化环境变量文件路径
$CLAUDE_TOOL_NAME 当前工具名称
$CLAUDE_FILE_PATH 当前文件路径
$CLAUDE_CODE_REMOTE 远程环境标记

2.9 调试技巧

# 在 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

第三部分:Agent SDK — 编程式 AI 代理

3.1 SDK 选择指南

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

3.2 Claude Code SDK 基础用法

安装:

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)}...]`);
  }
}

3.3 Agent SDK — query 函数

安装:

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);

3.4 自定义安全回调

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);
}

3.5 进程内 MCP 服务器

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);
}

第四部分:批量任务与多 Agent 编排

4.1 Shell 批量脚本

#!/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/"

4.2 Node.js 批量处理器(带限流)

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);

4.3 多 Agent 顺序协作

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)}`);

4.4 Agent SDK 子 Agent 编排

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 保证质量)。


第五部分:CI/CD 集成实战

5.1 GitHub Actions 自动 PR 审查

# .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)\`*"

5.2 Git Pre-commit Hook 自动检查

#!/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

5.3 定时巡检 Cron Job

#!/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 结合,构建一个完整的代码质量守卫系统。

6.1 项目结构

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/                   # 报告输出目录

6.2 完整 Hook 配置

{
  "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"
          }
        ]
      }
    ]
  }
}

6.3 批量审查脚本

// 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

6.4 健康巡检脚本

// 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);

6.5 工作流全景

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)

参考来源

  1. Run Claude Code programmatically - Claude Code Docs — Anthropic 官方 Headless/Print 模式文档,涵盖所有 CLI 标志和输出格式
  2. Hooks reference - Claude Code Docs — Anthropic 官方 Hooks 事件参考,包含完整 JSON Schema 和退出码定义
  3. Claude Agent SDK - GitHub — Anthropic 官方 Agent SDK TypeScript 源码仓库,含安装和基础示例
  4. Claude Code Hooks: Complete Guide with 20+ Examples — 社区整理的 20+ 个可复制 Hook 配置实例
  5. Claude Code stream-json 详解 — 深度解析 stream-json 输出格式的事件类型和消费者实现

[!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 等场景全覆盖。

51学通信知识星球海报-扫码加入