首页 › tutorials › Claude Agent SDK:用TypeScript构建生产级AI Agent

概述

本教程聚焦 Anthropic 在 2025 年底发布、2026 年持续迭代的 Claude Agent SDK(原 Claude Code SDK),手把手教你用 TypeScript 从零构建一个具备自定义工具、生命周期钩子、MCP 集成和子 Agent 编排能力的生产级 AI Agent。学完即可将 Agent 嵌入 CI/CD 管道、批量任务系统或任何需要自主决策的自动化场景。

适用人群:有 TypeScript 基础、想超越 claude -p 命令行模式、在代码层面完全控制 Agent 行为的中高级开发者。


前置条件

项目 要求
Node.js >= 18.0
TypeScript >= 5.3(项目内安装即可)
Claude 账户 Pro / Max / Team / Enterprise 均可
API Key ANTHROPIC_API_KEY 环境变量
基础知识 熟悉 async/await、事件流、npm 包管理

环境准备

# 创建项目目录
mkdir my-claude-agent && cd my-claude-agent

# 初始化 TypeScript 项目
npm init -y
npm install typescript @types/node --save-dev
npx tsc --init

# 安装 Claude Agent SDK
npm install @anthropic-ai/claude-agent-sdk

# 设置 API Key(写入 .bashrc 或 .zshrc 持久化)
export ANTHROPIC_API_KEY="sk-ant-xxxxx"

一、理解 Agent SDK 架构

Claude Agent SDK 不是对 /v1/messages API 的简单封装。它直接暴露了 Claude Code 内部使用的 Agent Loop——包括工具调用、上下文管理、流式输出、权限控制等完整能力链。

graph TB
    subgraph "Your Application"
        A[Entry Point<br/>index.ts]
        A --> B[createSession]
    end

    subgraph "Agent SDK Core"
        B --> C[Agent Loop<br/>思考→决策→工具调用→观察]
        C --> D[Built-in Tools<br/>Read/Write/Bash/Glob/Grep]
        C --> E[Custom Tools<br/>你定义的工具]
        C --> F[MCP Servers<br/>外部工具协议]
        C --> G[Hooks<br/>PreToolUse/PostToolUse]
    end

    subgraph "Anthropic API"
        C -->|Messages API| H[Claude Model]
    end

    C -->|subscribe| I[Event Stream<br/>Message/ToolCall/Result]

    style B fill:#7c3aed,color:#fff
    style C fill:#2563eb,color:#fff
    style E fill:#059669,color:#fff
    style G fill:#dc2626,color:#fff

核心概念速览

概念 说明
Session 一次 Agent 运行实例,包含上下文、工具集和配置
Agent Loop 模型自动循环执行:思考 → 调用工具 → 观察结果 → 继续思考
Custom Tools 你定义的 TypeScript 函数,Agent 可自主决定调用
Hooks 生命周期回调,在工具调用前后拦截、校验、记录
Subagents 从主 Agent 派生的子 Agent,可并行执行独立任务
MCP Integration 通过 Model Context Protocol 连接外部服务

二、第一个 Agent:30 秒跑起来

创建 src/01-hello.ts:

import { createSession } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  const session = createSession({
    model: "claude-sonnet-4-6",
    workingDirectory: process.cwd(),
    systemPrompt: "你是一个代码分析助手,用中文回答问题。",
  });

  const result = await session.run("请分析当前目录结构,告诉我这是什么项目");

  console.log("=== Agent 回复 ===");
  console.log(result.finalMessage);
}

main().catch(console.error);

运行:

npx tsx src/01-hello.ts

预期输出:Agent 会自主调用 Glob 工具扫描目录,调用 Read 工具读取 package.json,然后返回项目分析结果。

事件流模式:实时追踪 Agent 行为

上面的 session.run() 是简化写法。生产环境中你需要订阅事件流,实时了解 Agent 在做什么:

import { createSession } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  const session = createSession({
    model: "claude-sonnet-4-6",
    workingDirectory: process.cwd(),
  });

  // 订阅事件流
  session.subscribe((event) => {
    switch (event.type) {
      case "assistant_message":
        // Agent 的文本输出
        process.stdout.write(event.content);
        break;
      case "tool_call":
        console.log(`\n🔧 调用工具: ${event.toolName}`);
        console.log(`   参数: ${JSON.stringify(event.input).slice(0, 200)}`);
        break;
      case "tool_result":
        console.log(`   结果: ${String(event.output).slice(0, 100)}...`);
        break;
      case "error":
        console.error(`\n❌ 错误: ${event.message}`);
        break;
    }
  });

  await session.run("统计 src 目录下所有 .ts 文件的代码行数");
}

main().catch(console.error);

常见问题:

问题 原因 解决方案
ANTHROPIC_API_KEY not set 环境变量未配置 export ANTHROPIC_API_KEY=sk-ant-...
Model not found 模型名称错误 确认使用 claude-sonnet-4-6 或 claude-opus-4-6
ECONNREFUSED 网络代理问题 设置 HTTPS_PROXY 或检查防火墙
超时 复杂任务轮次过多 设置 maxTurns 限制

三、自定义工具:让 Agent 拥有你的能力

Agent 的强大来自于工具。内置工具让 Agent 能读写文件、执行命令,但自定义工具让 Agent 能操作你的业务系统。

3.1 定义工具的基本模式

import { createSession, tool } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";

// 定义工具 schema
const SearchDatabaseSchema = z.object({
  query: z.string().describe("SQL 查询语句"),
  database: z.string().default("main").describe("数据库名称"),
});

// 创建会话并注册工具
const session = createSession({
  model: "claude-sonnet-4-6",
  workingDirectory: process.cwd(),
  tools: [
    {
      name: "search_database",
      description: "查询业务数据库,执行 SQL 并返回结果。仅支持 SELECT 语句。",
      inputSchema: SearchDatabaseSchema,
      execute: async (input) => {
        // 安全检查:只允许 SELECT
        if (!input.query.trim().toUpperCase().startsWith("SELECT")) {
          return { error: "只允许 SELECT 查询" };
        }

        // 模拟数据库查询
        console.log(`[DB] 执行查询: ${input.query}`);
        const mockResults = [
          { id: 1, name: "产品A", sales: 15000 },
          { id: 2, name: "产品B", sales: 28000 },
          { id: 3, name: "产品C", sales: 9500 },
        ];
        return { rows: mockResults, rowCount: mockResults.length };
      },
    },
    {
      name: "send_notification",
      description: "向团队发送通知消息,用于报告异常或关键指标",
      inputSchema: z.object({
        channel: z.enum(["slack", "email", "webhook"]).describe("通知渠道"),
        message: z.string().describe("通知内容"),
        priority: z.enum(["low", "medium", "high"]).default("medium"),
      }),
      execute: async (input) => {
        console.log(
          `[NOTIFY] ${input.priority.toUpperCase()} -> ${input.channel}: ${input.message}`
        );
        return { status: "sent", timestamp: new Date().toISOString() };
      },
    },
  ],
});

3.2 工具设计的五个原则

graph LR
    A[单一职责] --> B[描述精确]
    B --> C[Schema 严格]
    C --> D[安全边界]
    D --> E[幂等设计]

    style A fill:#10b981,color:#fff
    style B fill:#3b82f6,color:#fff
    style C fill:#8b5cf6,color:#fff
    style D fill:#ef4444,color:#fff
    style E fill:#f59e0b,color:#fff

原则一:描述精确——描述即 Prompt

工具的 description 是 Agent 决定是否调用该工具的关键依据。模糊描述 = 错误调用。

// ❌ 糟糕的描述
{ description: "查询数据" }

// ✅ 精确的描述
{ description: "查询业务数据库中的销售数据。支持按日期范围、产品类别、地区筛选。仅返回聚合统计结果,不返回原始明细行。" }

原则二:Schema 严格——用 Zod 约束输入

// ❌ 松散定义
inputSchema: z.object({ path: z.string() })

// ✅ 严格定义,带描述和约束
inputSchema: z.object({
  path: z.string()
    .min(1)
    .describe("目标文件或目录的绝对路径"),
  recursive: z.boolean()
    .default(false)
    .describe("是否递归处理子目录"),
  maxDepth: z.number()
    .min(1).max(10)
    .default(3)
    .describe("递归最大深度,1-10"),
})

原则三:安全边界——永远不要信任模型输入

execute: async (input) => {
  // 白名单校验
  const ALLOWED_TABLES = ["products", "orders", "users"];
  const tableName = extractTableName(input.query);
  if (!ALLOWED_TABLES.includes(tableName)) {
    return { error: `表 ${tableName} 不在允许列表中` };
  }

  // 路径遍历防护
  const resolved = path.resolve(input.path);
  if (!resolved.startsWith(ALLOWED_BASE_DIR)) {
    return { error: "路径超出允许范围" };
  }

  // 执行实际操作...
}

原则四:幂等设计——Agent 可能重复调用

// 使用幂等键确保重复调用安全
execute: async (input) => {
  const idempotencyKey = `${input.action}:${input.target}:${input checksum}`;
  if (await cache.has(idempotencyKey)) {
    return { status: "already_applied", skipped: true };
  }
  const result = await performAction(input);
  await cache.set(idempotencyKey, result);
  return result;
}

原则五:返回结构化数据

// ❌ 返回纯文本
return "找到 3 个文件,总共 500 行";

// ✅ 返回结构化数据,Agent 可以进一步处理
return {
  files: [
    { path: "src/index.ts", lines: 120, functions: 5 },
    { path: "src/utils.ts", lines: 230, functions: 12 },
    { path: "src/config.ts", lines: 150, functions: 4 },
  ],
  summary: { totalFiles: 3, totalLines: 500, totalFunctions: 21 },
};

四、生命周期钩子:精细控制 Agent 行为

Hooks 是 Agent SDK 的核心治理机制。你可以在不修改工具代码的前提下,拦截、记录、审批甚至阻止 Agent 的操作。

4.1 四类钩子

import { createSession, HookPoint } from "@anthropic-ai/claude-agent-sdk";

const session = createSession({
  model: "claude-sonnet-4-6",
  workingDirectory: process.cwd(),

  hooks: {
    // 1. 工具调用前——审批与拦截
    onPreToolUse: async (context) => {
      const { toolName, input } = context;

      // 阻止危险操作
      if (toolName === "Bash" && typeof input.command === "string") {
        const dangerous = ["rm -rf", "DROP TABLE", "format", ":(){:|:&};:"];
        if (dangerous.some((d) => input.command.includes(d))) {
          return {
            decision: "block" as const,
            reason: `阻止危险命令: ${input.command}`,
          };
        }
      }

      // 保护敏感文件
      if (toolName === "Write" || toolName === "Edit") {
        const sensitive = [".env", "credentials", "secret", "private_key"];
        if (
          typeof input.file_path === "string" &&
          sensitive.some((s) => input.file_path.includes(s))
        ) {
          return {
            decision: "block" as const,
            reason: `禁止修改敏感文件: ${input.file_path}`,
          };
        }
      }

      // 记录审计日志
      auditLog.record({
        timestamp: new Date(),
        tool: toolName,
        input: JSON.stringify(input).slice(0, 500),
        decision: "allow",
      });

      return { decision: "allow" as const };
    },

    // 2. 工具调用后——结果处理
    onPostToolUse: async (context) => {
      const { toolName, input, output } = context;

      // 自动格式化修改过的文件
      if (toolName === "Write" && input.file_path?.endsWith(".ts")) {
        // 可触发 prettier/eslint
        console.log(`[POST] ${input.file_path} 已修改,建议运行 lint`);
      }

      // 敏感输出脱敏
      if (toolName === "Read" && typeof output === "string") {
        const sanitized = output.replace(
          /password["\s:=]+["']?[^"'\s,}]+/gi,
          'password: "***REDACTED***"'
        );
        return { modifiedOutput: sanitized };
      }
    },

    // 3. 通知——Agent 状态变化
    onNotification: async (notification) => {
      console.log(`[NOTIFY] ${notification.type}: ${notification.message}`);
      // 可发送到监控系统
      metrics.increment(`agent.notification.${notification.type}`);
    },

    // 4. 会话开始/结束
    onSessionStart: async () => {
      console.log("[SESSION] Agent 会话开始");
      await loadProjectContext();
    },
    onSessionEnd: async (summary) => {
      console.log(
        `[SESSION] 会话结束,共 ${summary.toolCallCount} 次工具调用,${summary.tokenUsage} tokens`
      );
      await reportUsage(summary);
    },
  },
});

4.2 钩子执行流程

sequenceDiagram
    participant U as 用户代码
    participant SDK as Agent SDK
    participant H as Hook 系统
    participant T as 工具执行器

    U->>SDK: session.run(prompt)
    SDK->>SDK: Agent 思考:决定调用工具X

    rect rgb(254, 243, 199)
        Note over SDK,H: PreToolUse 钩子链
        SDK->>H: onPreToolUse(toolX, input)
        H-->>SDK: decision: allow / block
    end

    alt decision = block
        SDK-->>SDK: 跳过执行,返回拒绝原因
    else decision = allow
        SDK->>T: execute(toolX, input)
        T-->>SDK: output

        rect rgb(220, 252, 231)
            Note over SDK,H: PostToolUse 钩子链
            SDK->>H: onPostToolUse(toolX, input, output)
            H-->>SDK: modifiedOutput(可选)
        end

        SDK->>SDK: Agent 继续思考...
    end

    SDK-->>U: 最终结果

五、MCP 集成:连接外部工具生态

Agent SDK 通过 Model Context Protocol(MCP)连接第三方服务,无需自己实现每个工具的通信协议。

5.1 连接 MCP Server

import { createSession } from "@anthropic-ai/claude-agent-sdk";

const session = createSession({
  model: "claude-sonnet-4-6",
  workingDirectory: process.cwd(),

  mcpServers: {
    // 方式一:本地进程(stdio 传输)
    github: {
      transport: "stdio",
      command: "npx",
      args: ["-y", "@modelcontextprotocol/server-github"],
      env: {
        GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_TOKEN!,
      },
    },

    // 方式二:HTTP 传输
    database: {
      transport: "http",
      url: "http://localhost:3001/mcp",
      headers: {
        Authorization: `Bearer ${process.env.DB_API_KEY}`,
      },
    },

    // 方式三:内联 MCP Server(直接在代码中定义)
    customAnalytics: {
      transport: "inline",
      tools: [
        {
          name: "get_analytics",
          description: "获取网站分析数据",
          inputSchema: {
            type: "object",
            properties: {
              metric: {
                type: "string",
                enum: ["pageviews", "unique_visitors", "bounce_rate"],
              },
              dateRange: { type: "string", description: "如: 7d, 30d, 90d" },
            },
            required: ["metric"],
          },
          handler: async (input: any) => {
            // 直接调用你的分析 API
            const resp = await fetch(
              `https://analytics.example.com/api/${input.metric}?range=${input.dateRange || "7d"}`
            );
            return resp.json();
          },
        },
      ],
    },
  },
});

// Agent 现在可以自主使用 GitHub、数据库、分析工具
const result = await session.run(
  "查看 myorg/myrepo 最近 7 天的 PR,分析合并率,然后查询对应时间段的产品页面访问量变化"
);

5.2 MCP 连接模式对比

graph TB
    subgraph "Agent Session"
        A[Agent Loop]
    end

    subgraph "stdio 模式"
        B1[子进程] --> B2[MCP Server<br/>如 GitHub/文件系统]
    end

    subgraph "HTTP 模式"
        C1[HTTP Client] --> C2[远程 MCP Server<br/>如数据库/API 网关]
    end

    subgraph "inline 模式"
        D1[进程内函数调用] --> D2[自定义工具<br/>无需额外进程]
    end

    A -->|stdin/stdout| B1
    A -->|HTTP POST| C1
    A -->|直接调用| D1

    style B2 fill:#3b82f6,color:#fff
    style C2 fill:#8b5cf6,color:#fff
    style D2 fill:#10b981,color:#fff
模式 适用场景 启动开销 调试难度
stdio 本地工具(文件、Git) 需启动子进程 中等
HTTP 远程服务(数据库、API) 无(直连) 低
inline 自定义逻辑、快速原型 零 最低

六、子 Agent 编排:并行处理复杂任务

当单个 Agent 难以高效处理复杂任务时,子 Agent(Subagent)模式允许你派生多个专注的 Agent 并行工作。

6.1 定义和调用子 Agent

import { createSession, subagent } from "@anthropic-ai/claude-agent-sdk";

// 定义子 Agent 配置
const codeReviewer = subagent({
  name: "code-reviewer",
  description: "专注代码质量审查,检查安全漏洞、性能问题和代码风格",
  systemPrompt: `你是一个严格的代码审查员。检查以下内容:
1. 安全漏洞(SQL 注入、XSS、路径遍历)
2. 性能问题(N+1 查询、内存泄漏、不必要的同步操作)
3. 代码风格(命名规范、函数长度、注释质量)
输出格式:按严重程度分级(Critical/Warning/Info)的审查报告。`,
  allowedTools: ["Read", "Glob", "Grep"], // 只给读权限
  maxTurns: 10,
});

const testWriter = subagent({
  name: "test-writer",
  description: "根据代码自动生成单元测试和集成测试",
  systemPrompt: `你是一个测试工程师。为给定代码编写:
1. 单元测试覆盖正常路径和边界条件
2. 使用项目现有的测试框架
3. Mock 外部依赖
4. 确保测试可独立运行`,
  allowedTools: ["Read", "Write", "Glob", "Grep", "Bash"],
  maxTurns: 15,
});

const docWriter = subagent({
  name: "doc-writer",
  description: "根据代码生成 API 文档和使用说明",
  systemPrompt: "根据代码生成 Markdown 格式的 API 文档,包含参数说明、返回值、使用示例。",
  allowedTools: ["Read", "Write", "Glob"],
  maxTurns: 8,
});

// 主 Agent 会话
const session = createSession({
  model: "claude-sonnet-4-6",
  workingDirectory: process.cwd(),
  subagents: [codeReviewer, testWriter, docWriter],
});

6.2 并行编排实战

// 主 Agent 接收到任务后,会自动决定何时调用子 Agent
// 也可以通过 prompt 显式引导并行执行
const result = await session.run(`
请对 src/api/ 目录下的所有接口文件执行以下任务(并行):
1. 用 code-reviewer 审查代码质量
2. 用 test-writer 为每个接口编写测试
3. 用 doc-writer 生成 API 文档

最后汇总三方面结果,给出综合评分和改进建议。
`);

console.log(result.finalMessage);

6.3 编排模式对比

graph TB
    subgraph "模式一:串行子 Agent"
        S1[主 Agent] --> SA1[子 Agent A]
        SA1 --> SA2[子 Agent B]
        SA2 --> SA3[子 Agent C]
        SA3 --> S1
    end

    subgraph "模式二:并行子 Agent"
        P1[主 Agent] --> PA1[子 Agent A]
        P1 --> PA2[子 Agent B]
        P1 --> PA3[子 Agent C]
        PA1 --> P1
        PA2 --> P1
        PA3 --> P1
    end

    subgraph "模式三:嵌套子 Agent"
        N1[主 Agent] --> NA1[编排 Agent]
        NA1 --> NB1[子 Agent 1]
        NA1 --> NB2[子 Agent 2]
        NB1 --> NA1
        NB2 --> NA1
        NA1 --> N1
    end

    style S1 fill:#2563eb,color:#fff
    style P1 fill:#059669,color:#fff
    style N1 fill:#dc2626,color:#fff
模式 适用场景 Token 消耗 延迟
串行 后一步依赖前一步结果 最低 最高
并行 独立任务可同时执行 较高 最低
嵌套 复杂任务需要层次化分解 最高 中等

七、完整实战项目:智能代码质量巡检 Agent

将前面学到的所有能力整合为一个可部署的代码质量巡检系统。

7.1 项目结构

code-patrol/
├── src/
│   ├── index.ts          # 入口,CLI 参数解析
│   ├── agent.ts          # Agent 配置,工具和钩子
│   ├── tools/
│   │   ├── metrics.ts    # 代码度量工具
│   │   ├── git-tools.ts  # Git 操作工具
│   │   └── report.ts     # 报告生成工具
│   └── hooks/
│       ├── audit.ts      # 审计钩子
│       └── guard.ts      # 安全防护钩子
├── package.json
└── tsconfig.json

7.2 核心代码:agent.ts

import { createSession, subagent } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";

// ===== 自定义工具 =====
const codeMetricsTool = {
  name: "analyze_complexity",
  description:
    "分析指定目录下 TypeScript 文件的圈复杂度、函数行数、依赖深度。返回按复杂度排序的报告。",
  inputSchema: z.object({
    directory: z.string().describe("要分析的目录路径"),
    threshold: z.number().default(10).describe("复杂度告警阈值"),
  }),
  execute: async (input: { directory: string; threshold: number }) => {
    // 实际项目中可调用 sonarqube API 或自定义分析器
    const mockMetrics = [
      { file: `${input.directory}/auth.ts`, complexity: 18, functions: 6, lines: 340 },
      { file: `${input.directory}/api.ts`, complexity: 12, functions: 8, lines: 280 },
      { file: `${input.directory}/utils.ts`, complexity: 4, functions: 12, lines: 180 },
    ];

    const violations = mockMetrics.filter(
      (m) => m.complexity > input.threshold
    );

    return {
      totalFiles: mockMetrics.length,
      violations,
      summary: {
        avgComplexity:
          mockMetrics.reduce((s, m) => s + m.complexity, 0) / mockMetrics.length,
        maxComplexity: Math.max(...mockMetrics.map((m) => m.complexity)),
      },
    };
  },
};

const gitAnalysisTool = {
  name: "git_hotspots",
  description: "分析 Git 历史中的变更热点文件(被频繁修改的文件通常需要关注)",
  inputSchema: z.object({
    since: z.string().default("2 weeks ago").describe("时间范围"),
    topN: z.number().default(10).describe("返回排名前 N 的热点文件"),
  }),
  execute: async (input: { since: string; topN: number }) => {
    // 模拟 git log --format="%H" --name-only 分析
    return {
      hotspots: [
        { file: "src/api/auth.ts", changes: 23, authors: 4, risk: "high" },
        { file: "src/api/payments.ts", changes: 18, authors: 3, risk: "high" },
        { file: "src/utils/validator.ts", changes: 15, authors: 2, risk: "medium" },
      ],
      period: input.since,
    };
  },
};

// ===== 子 Agent 定义 =====
const securityScanner = subagent({
  name: "security-scanner",
  description: "扫描代码中的安全漏洞,包括 OWASP Top 10 风险",
  systemPrompt: `你是一个安全扫描专家。检查以下安全问题:
- SQL 注入、XSS、CSRF
- 硬编码密钥和凭证
- 不安全的反序列化
- 路径遍历漏洞
- 不安全的随机数生成
按 CVSS 评分标准给出严重程度。`,
  allowedTools: ["Read", "Glob", "Grep"],
  maxTurns: 12,
});

const archAnalyzer = subagent({
  name: "arch-analyzer",
  description: "分析项目架构模式、模块耦合度和循环依赖",
  systemPrompt: `你是一个架构分析专家。评估:
1. 模块划分是否合理
2. 是否存在循环依赖
3. 分层是否清晰(controller/service/dao)
4. 公共组件复用率
输出架构健康度评分(0-100)。`,
  allowedTools: ["Read", "Glob", "Grep"],
  maxTurns: 10,
});

// ===== 安全钩子 =====
const guardHook = {
  onPreToolUse: async (context: any) => {
    // 禁止写操作——巡检 Agent 只读不写
    const writeTools = ["Write", "Edit"];
    if (writeTools.includes(context.toolName)) {
      return {
        decision: "block" as const,
        reason: "巡检模式下禁止文件修改操作",
      };
    }
    return { decision: "allow" as const };
  },

  onSessionEnd: async (summary: any) => {
    console.log(`\n📊 巡检统计:`);
    console.log(`   工具调用: ${summary.toolCallCount} 次`);
    console.log(`   Token 消耗: ${summary.tokenUsage}`);
    console.log(`   执行时间: ${summary.duration}ms`);
  },
};

// ===== 创建 Agent =====
export function createPatrolAgent(targetDir: string) {
  return createSession({
    model: "claude-sonnet-4-6",
    workingDirectory: targetDir,
    systemPrompt: `你是代码质量巡检 Agent。你的任务是全面评估项目代码质量并生成结构化报告。

巡检流程:
1. 先用 analyze_complexity 获取复杂度概况
2. 用 git_hotspots 识别高频变更文件
3. 用 security-scanner 并行扫描安全漏洞
4. 用 arch-analyzer 并行分析架构健康度
5. 汇总所有结果,生成最终报告

报告格式:
- 总体评分(A/B/C/D)
- 各维度评分和详细发现
- 优先修复建议(按影响排序)`,

    tools: [codeMetricsTool, gitAnalysisTool],
    subagents: [securityScanner, archAnalyzer],
    hooks: guardHook,
    maxTurns: 30,
  });
}

7.3 入口文件:index.ts

import { createPatrolAgent } from "./agent";

async function main() {
  const targetDir = process.argv[2] || process.cwd();

  console.log(`🔍 启动代码质量巡检: ${targetDir}\n`);

  const agent = createPatrolAgent(targetDir);

  // 订阅事件,实时展示进度
  agent.subscribe((event) => {
    switch (event.type) {
      case "tool_call":
        console.log(`  ⚙️  ${event.toolName}(${JSON.stringify(event.input).slice(0, 80)}...)`);
        break;
      case "subagent_start":
        console.log(`  🤖 启动子 Agent: ${event.subagentName}`);
        break;
      case "subagent_complete":
        console.log(`  ✅ 子 Agent 完成: ${event.subagentName}`);
        break;
    }
  });

  const result = await agent.run(
    `对 ${targetDir} 执行全面代码质量巡检,生成评估报告。`
  );

  // 输出最终报告
  console.log("\n" + "=".repeat(60));
  console.log(result.finalMessage);
  console.log("=".repeat(60));
}

main().catch((err) => {
  console.error("巡检失败:", err);
  process.exit(1);
});

7.4 运行与输出

# 巡检指定项目
npx tsx src/index.ts /path/to/your/project

# 预期输出示例:
# 🔍 启动代码质量巡检: /path/to/your/project
#
#   ⚙️  analyze_complexity({"directory":"src","threshold":10})...
#   ⚙️  git_hotspots({"since":"2 weeks ago","topN":10})...
#   🤖 启动子 Agent: security-scanner
#   🤖 启动子 Agent: arch-analyzer
#   ✅ 子 Agent 完成: security-scanner
#   ✅ 子 Agent 完成: arch-analyzer
#
# ============================================================
# 📋 代码质量巡检报告
#
# 总体评分: B+
#
# | 维度 | 评分 | 状态 |
# |------|------|------|
# | 复杂度 | 7/10 | ⚠️  auth.ts 超阈值 |
# | 安全性 | 8/10 | ✅  无高危漏洞 |
# | 架构 | 7.5/10 | ⚠️  api 层耦合较重 |
# | 变更热点 | 6/10 | ⚠️  auth.ts 变更过于频繁 |
# ...

八、Token 优化与成本控制

Agent SDK 的灵活性意味着 token 消耗可能快速累积。以下是生产环境中的关键优化策略。

8.1 限制工具权限

// 只给 Agent 必要的工具,减少无意义的工具探索
const session = createSession({
  // ...
  allowedTools: ["Read", "Glob", "Grep"], // 移除 Bash、Write、Edit
  // 或者使用 deniedTools 排除特定工具
  deniedTools: ["Bash"], // 明确禁止
});

8.2 控制轮次

const session = createSession({
  // ...
  maxTurns: 15, // 最多 15 轮工具调用循环
  // 每轮 = 一次模型调用 + 可能的工具调用
  // 建议:简单任务 5-10 轮,复杂任务 15-30 轮
});

8.3 压缩系统提示

// ❌ 冗长的系统提示
systemPrompt: `你是一个专业的代码审查员,你的职责是审查代码质量。你需要检查以下所有方面:
1. 代码是否有安全漏洞
2. 代码是否有性能问题
...(500字)`

// ✅ 精简但精确的系统提示
systemPrompt: `代码审查员。检查:安全漏洞、性能问题、可维护性。
输出:JSON 格式 {severity, file, line, issue, fix}`

8.4 流式输出 + 早停

agent.subscribe((event) => {
  if (event.type === "assistant_message") {
    // 检测到满意结果时提前终止
    if (event.content.includes("## 最终报告")) {
      // 可以选择停止后续不必要的工具调用
    }
  }
});

九、从开发到部署的完整流程

graph LR
    subgraph "开发阶段"
        A[npm install<br/>@anthropic-ai/claude-agent-sdk] --> B[定义工具<br/>和钩子]
        B --> C[配置子 Agent<br/>和 MCP]
        C --> D[本地测试<br/>tsx 运行]
    end

    subgraph "测试阶段"
        D --> E[单元测试<br/>mock Agent 响应]
        E --> F[集成测试<br/>真实 API 调用]
        F --> G[压力测试<br/>并发 + 长时间运行]
    end

    subgraph "部署阶段"
        G --> H[Docker 镜像]
        H --> I[CI/CD 集成]
        I --> J[定时任务 / Webhook 触发]
    end

    style A fill:#7c3aed,color:#fff
    style G fill:#059669,color:#fff
    style J fill:#2563eb,color:#fff

Dockerfile 示例

FROM node:20-slim

WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY dist/ ./dist/

# 安全:不硬编码 API Key
ENV ANTHROPIC_API_KEY=""
ENV NODE_ENV=production

CMD ["node", "dist/index.js"]

GitHub Actions 集成

name: Code Quality Patrol
on:
  schedule:
    - cron: "0 2 * * 1" # 每周一凌晨 2 点
  workflow_dispatch: # 手动触发

jobs:
  patrol:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"

      - run: npm ci

      - name: Run Code Patrol Agent
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
        run: npx tsx src/index.ts ${{ github.workspace }}

      - name: Upload Report
        uses: actions/upload-artifact@v4
        with:
          name: patrol-report
          path: patrol-report.md

十、常见问题与故障排除

问题 症状 解决方案
Agent 无限循环 同一工具反复调用 设置 maxTurns,在钩子中检测重复模式
Token 消耗过高 单次运行 > 100K tokens 缩小工具范围,精简系统提示,使用子 Agent 隔离上下文
子 Agent 超时 长时间无响应 为子 Agent 设置更短的 maxTurns,添加超时机制
MCP 连接失败 ECONNREFUSED 或超时 检查 MCP Server 是否运行,网络是否可达
工具 Schema 错误 Agent 无法正确传参 检查 Zod schema 是否与 execute 参数类型匹配
内存泄漏 长时间运行后 OOM 确保关闭完成的 session,避免在全局累积事件

延伸阅读


参考来源

  1. Agent SDK overview - Claude Code Docs — Anthropic 官方 Agent SDK 架构说明和核心概念
  2. GitHub - anthropics/claude-agent-sdk-typescript — TypeScript SDK 源码仓库,含安装指南和 API 参考
  3. Subagents in the SDK - Claude Code Docs — 子 Agent 定义、并行执行和编排模式官方文档
  4. Connect to external tools with MCP - Claude Code Docs — MCP Server 集成三种传输模式说明
  5. Controlling Claude Agent Execution With Hooks — 钩子系统的实践模式和配置示例

训练营适用性评估

维度 评估
适合训练营类型 AI Agent 开发营、DevOps 自动化营、企业代码治理营
预计教学时长 4-6 小时(含动手实验)
学员基础要求 TypeScript 中级、了解 async/await 和事件驱动
实验环境需求 Node.js 18+、Anthropic API Key、Git
难度评级 ⭐⭐⭐⭐(中高级)
可拆分模块 基础 Agent(1h)→ 自定义工具(1.5h)→ Hooks + MCP(1.5h)→ 子 Agent + 实战(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 等场景全覆盖。

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