Claude Code | | 约 28 分钟 | 11,030 字

Claude Code Sub-Agent 模式实战

理解和运用 Sub-Agent 分而治之处理复杂任务

什么是 Sub-Agent

当我们给 Claude Code 一个复杂任务时,它有时候会”分身”——创建一个或多个 Sub-Agent(子代理)来并行处理不同的子任务。

比如你说:

帮我重构 src/components/ 下的所有组件,统一使用新的设计系统

Claude Code 可能会:

  1. 主 Agent 分析任务,拆分为多个子任务
  2. 创建 Sub-Agent A 处理 Header 组件
  3. 创建 Sub-Agent B 处理 Footer 组件
  4. 创建 Sub-Agent C 处理 Sidebar 组件
  5. 主 Agent 汇总结果,确保一致性

这就是 Sub-Agent 模式——分而治之。


Sub-Agent 的触发条件

Claude Code 不是每次都会使用 Sub-Agent。它会根据任务的特征来决定:

条件是否触发 Sub-Agent原因
修改单个文件任务简单,不需要拆分
修改多个独立文件可能文件之间无依赖,可以并行
跨目录的大规模重构任务复杂,需要分工
需要多种专业知识不同子任务需要不同”专家”
简单问答不涉及工具调用

观察 Sub-Agent 的创建

在 Claude Code 的输出中,你会看到类似这样的提示:

正在分析任务...
创建子任务 1: 重构 Header 组件
创建子任务 2: 重构 Footer 组件
创建子任务 3: 重构 Sidebar 组件
并行执行中...

Sub-Agent 的工作原理

架构概览

┌─────────────────────────────────────────┐
│              主 Agent (Orchestrator)      │
│                                          │
│  1. 接收用户任务                          │
│  2. 分析和拆分任务                        │
│  3. 分配给 Sub-Agent                     │
│  4. 收集和整合结果                        │
│  5. 返回最终结果                          │
└──────────┬──────────┬──────────┬────────┘
           │          │          │
     ┌─────▼─────┐ ┌──▼──────┐ ┌▼─────────┐
     │ Sub-Agent │ │Sub-Agent│ │Sub-Agent │
     │     A     │ │    B    │ │    C     │
     │           │ │         │ │          │
     │ 处理任务1 │ │处理任务2│ │ 处理任务3│
     └───────────┘ └─────────┘ └──────────┘

上下文隔离

每个 Sub-Agent 有自己独立的上下文:

  • 独立的对话历史
  • 独立的工具调用
  • 独立的文件操作

这意味着 Sub-Agent A 修改的文件不会影响 Sub-Agent B 的读取——除非主 Agent 协调它们。

结果汇总

Sub-Agent 完成后,主 Agent 会:

  1. 收集所有 Sub-Agent 的输出
  2. 检查是否有冲突(比如两个 Sub-Agent 修改了同一个文件)
  3. 解决冲突
  4. 整合结果
  5. 做最终验证

任务分解模式

模式 1:按文件分解

最常见的模式——每个 Sub-Agent 处理一个或一组文件:

重构 src/components/ 下的所有组件

分解为:

  • Sub-Agent 1: Header.astro, Navigation.astro
  • Sub-Agent 2: Footer.astro, SocialLinks.astro
  • Sub-Agent 3: Sidebar.astro, TableOfContents.astro

模式 2:按职责分解

不同 Sub-Agent 负责不同的职责:

给项目添加完整的测试覆盖

分解为:

  • Sub-Agent 1: 单元测试(工具函数)
  • Sub-Agent 2: 组件测试(React/Astro 组件)
  • Sub-Agent 3: 集成测试(API 端点)

模式 3:按阶段分解

虽然不是并行的,但可以按阶段分工:

将项目从 JavaScript 迁移到 TypeScript

分解为:

  • 阶段 1 Sub-Agent: 添加 TypeScript 配置
  • 阶段 2 Sub-Agent: 转换工具函数
  • 阶段 3 Sub-Agent: 转换组件
  • 阶段 4 Sub-Agent: 修复类型错误

模式 4:按专业领域分解

优化应用的整体性能

分解为:

  • Sub-Agent 1(前端专家): 优化渲染性能、减少 bundle 大小
  • Sub-Agent 2(后端专家): 优化 API 响应时间、数据库查询
  • Sub-Agent 3(基础设施专家): 优化缓存策略、CDN 配置

实战示例

示例 1:多文件重构

把 src/utils/ 下所有的 CommonJS 模块转换为 ES Modules

Claude Code 的执行过程:

主 Agent: 扫描 src/utils/ 目录,发现 8 个 CommonJS 文件

Sub-Agent 1: 转换 format.js, date.js
  - require() → import
  - module.exports → export
  - 更新文件扩展名

Sub-Agent 2: 转换 api.js, http.js
  - 同上
  - 处理动态 require

Sub-Agent 3: 转换 config.js, env.js, logger.js, helpers.js
  - 同上

主 Agent: 汇总结果
  - 检查所有 import 路径是否正确
  - 运行 npm run build 验证
  - 运行 npm test 确认功能正常

示例 2:全栈功能开发

添加用户搜索功能,包括前端搜索框、后端 API 和数据库查询
主 Agent: 分析需求,设计接口

Sub-Agent 1 (后端):
  - 创建 src/api/routes/search.ts
  - 实现全文搜索查询
  - 添加分页支持

Sub-Agent 2 (前端):
  - 创建 src/components/SearchBar.tsx
  - 实现实时搜索(debounce)
  - 添加搜索结果展示

Sub-Agent 3 (测试):
  - 编写 API 测试
  - 编写组件测试
  - 编写 E2E 测试

主 Agent: 整合
  - 确保前后端接口一致
  - 运行所有测试
  - 输出功能摘要

示例 3:代码审查

审查 PR #42 的所有变更
主 Agent: 获取 PR diff,分析变更范围

Sub-Agent 1 (安全审查):
  - 检查是否有安全漏洞
  - 检查敏感信息泄露
  - 检查权限控制

Sub-Agent 2 (质量审查):
  - 检查代码风格
  - 检查类型安全
  - 检查错误处理

Sub-Agent 3 (性能审查):
  - 检查算法复杂度
  - 检查内存使用
  - 检查数据库查询效率

主 Agent: 汇总审查报告
  - 合并所有发现
  - 按严重程度排序
  - 生成统一的审查报告

使用 SDK 编排 Sub-Agent

通过 Claude Code SDK,我们可以手动编排 Sub-Agent 模式:

基础编排

import { claude } from "@anthropic-ai/claude-code";

async function parallelRefactor(files: string[]) {
  // 将文件分组
  const chunkSize = 3;
  const chunks: string[][] = [];
  for (let i = 0; i < files.length; i += chunkSize) {
    chunks.push(files.slice(i, i + chunkSize));
  }

  // 并行处理每组文件
  const results = await Promise.all(
    chunks.map((chunk, index) =>
      claude(
        `重构以下文件,使用新的设计系统:
        ${chunk.join(", ")}

        规则:
        - 使用 Tailwind CSS 替换内联样式
        - 使用新的 Button, Card, Input 组件
        - 保持功能不变`,
        {
          cwd: process.cwd(),
          allowedTools: ["Read", "Write", "Edit"],
          timeout: 60000,
        }
      )
    )
  );

  // 汇总结果
  console.log(`完成 ${files.length} 个文件的重构`);
  results.forEach((r, i) => {
    console.log(`组 ${i + 1}: ${r.text.substring(0, 100)}...`);
  });
}

// 使用
await parallelRefactor([
  "src/components/Header.tsx",
  "src/components/Footer.tsx",
  "src/components/Sidebar.tsx",
  "src/components/Card.tsx",
  "src/components/Button.tsx",
  "src/components/Modal.tsx",
]);

带协调的编排

import { claude, Conversation } from "@anthropic-ai/claude-code";

async function coordinatedRefactor() {
  // 第一步:分析和规划(主 Agent)
  const plan = await claude(
    `分析 src/components/ 目录,列出所有需要重构的组件,
    以 JSON 格式返回:
    {
      "groups": [
        { "name": "导航组件", "files": ["Header.tsx", "Nav.tsx"] },
        ...
      ],
      "sharedChanges": ["需要统一修改的内容"]
    }`,
    {
      cwd: process.cwd(),
      allowedTools: ["Read", "Glob", "Grep"],
    }
  );

  const { groups, sharedChanges } = JSON.parse(plan.text);

  // 第二步:并行重构(Sub-Agents)
  const results = await Promise.all(
    groups.map((group: { name: string; files: string[] }) =>
      claude(
        `重构 ${group.name}:${group.files.join(", ")}

        统一变更要求:
        ${sharedChanges.join("\n")}

        完成后列出所有修改的文件和变更摘要。`,
        {
          cwd: process.cwd(),
          allowedTools: ["Read", "Write", "Edit"],
          timeout: 120000,
        }
      )
    )
  );

  // 第三步:验证和整合(主 Agent)
  const validation = await claude(
    `刚刚完成了以下组件的重构:
    ${groups.map((g: { name: string }) => g.name).join(", ")}

    请执行以下验证:
    1. 运行 npx tsc --noEmit 检查类型
    2. 运行 npm run lint 检查代码风格
    3. 运行 npm test 确认功能正常
    4. 检查组件之间的接口是否一致

    报告验证结果。`,
    {
      cwd: process.cwd(),
      allowedTools: ["Read", "Bash", "Glob", "Grep"],
      timeout: 60000,
    }
  );

  console.log("验证结果:", validation.text);
}

专家模式编排

import { claude } from "@anthropic-ai/claude-code";

interface ExpertReview {
  expert: string;
  systemPrompt: string;
  focus: string;
}

async function expertReview(targetPath: string) {
  const experts: ExpertReview[] = [
    {
      expert: "安全专家",
      systemPrompt: "你是一个应用安全专家,专注于发现安全漏洞",
      focus: "安全漏洞、注入攻击、认证问题、敏感信息泄露",
    },
    {
      expert: "性能专家",
      systemPrompt: "你是一个性能优化专家,专注于代码效率",
      focus: "算法复杂度、内存泄漏、不必要的计算、缓存策略",
    },
    {
      expert: "架构专家",
      systemPrompt: "你是一个软件架构师,专注于代码结构和设计模式",
      focus: "设计模式、模块耦合、代码复用、可扩展性",
    },
  ];

  // 并行执行专家审查
  const reviews = await Promise.all(
    experts.map((expert) =>
      claude(
        `审查 ${targetPath},重点关注:${expert.focus}

        以 JSON 格式返回:
        {
          "expert": "${expert.expert}",
          "findings": [
            {
              "severity": "high|medium|low",
              "file": "文件路径",
              "line": 行号,
              "issue": "问题描述",
              "suggestion": "改进建议"
            }
          ],
          "score": 1-10
        }`,
        {
          cwd: process.cwd(),
          systemPrompt: expert.systemPrompt,
          allowedTools: ["Read", "Glob", "Grep"],
          timeout: 60000,
        }
      )
    )
  );

  // 汇总报告
  const allFindings = reviews.flatMap((r) => {
    try {
      return JSON.parse(r.text).findings;
    } catch {
      return [];
    }
  });

  // 按严重程度排序
  allFindings.sort((a: any, b: any) => {
    const order = { high: 0, medium: 1, low: 2 };
    return (order[a.severity as keyof typeof order] || 2) -
           (order[b.severity as keyof typeof order] || 2);
  });

  console.log(`\n审查完成,共发现 ${allFindings.length} 个问题:`);
  console.log(`- 高严重度: ${allFindings.filter((f: any) => f.severity === "high").length}`);
  console.log(`- 中严重度: ${allFindings.filter((f: any) => f.severity === "medium").length}`);
  console.log(`- 低严重度: ${allFindings.filter((f: any) => f.severity === "low").length}`);

  return allFindings;
}

// 使用
await expertReview("src/");

监控 Sub-Agent

进度追踪

import { claude } from "@anthropic-ai/claude-code";

async function trackedParallelExecution(tasks: string[]) {
  const total = tasks.length;
  let completed = 0;

  const results = await Promise.all(
    tasks.map(async (task, index) => {
      console.log(`[${index + 1}/${total}] 开始: ${task}`);

      const result = await claude(task, {
        cwd: process.cwd(),
        onProgress: (event) => {
          if (event.type === "tool_use") {
            console.log(`  [${index + 1}] 使用工具: ${event.tool}`);
          }
        },
      });

      completed++;
      console.log(`[${completed}/${total}] 完成: ${task}`);

      return result;
    })
  );

  return results;
}

错误处理

async function resilientParallelExecution(tasks: string[]) {
  const results = await Promise.allSettled(
    tasks.map((task) =>
      claude(task, {
        cwd: process.cwd(),
        timeout: 60000,
      })
    )
  );

  const succeeded = results.filter((r) => r.status === "fulfilled");
  const failed = results.filter((r) => r.status === "rejected");

  console.log(`成功: ${succeeded.length}, 失败: ${failed.length}`);

  // 重试失败的任务
  if (failed.length > 0) {
    console.log("重试失败的任务...");
    const retryTasks = failed.map((_, i) => tasks[results.indexOf(failed[i])]);
    // 串行重试,避免并发问题
    for (const task of retryTasks) {
      try {
        await claude(task, { cwd: process.cwd(), timeout: 120000 });
        console.log(`重试成功: ${task.substring(0, 50)}...`);
      } catch (error) {
        console.error(`重试失败: ${task.substring(0, 50)}...`);
      }
    }
  }
}

最佳实践

1. 任务粒度要合适

太粗的任务拆分不够,太细的任务开销太大:

// 太粗:一个 Sub-Agent 处理太多文件
await claude("重构 src/ 下所有 200 个文件");

// 太细:每个文件一个 Sub-Agent,开销太大
files.forEach(f => claude(`重构 ${f}`));

// 合适:按逻辑分组,每组 3-5 个文件
const groups = chunkByModule(files, 5);
await Promise.all(groups.map(g => claude(`重构 ${g.join(", ")}`)));

2. 避免 Sub-Agent 之间的冲突

// 不好:两个 Sub-Agent 可能修改同一个文件
await Promise.all([
  claude("优化 src/utils/index.ts 的导出"),
  claude("给 src/utils/index.ts 添加新函数"),
]);

// 好:确保 Sub-Agent 操作不同的文件
await Promise.all([
  claude("优化 src/utils/format.ts"),
  claude("优化 src/utils/date.ts"),
]);

3. 共享上下文通过参数传递

// 先获取共享信息
const designSystem = await claude("读取 src/design-system/tokens.ts 的内容");

// 然后传递给每个 Sub-Agent
await Promise.all(
  components.map(comp =>
    claude(`使用以下设计系统 Token 重构 ${comp}:
    ${designSystem.text}`)
  )
);

4. 始终做最终验证

// 并行执行
await Promise.all(subTasks.map(t => claude(t)));

// 最终验证(串行)
await claude("运行 npm run build && npm test,确认所有修改没有破坏功能");

Sub-Agent 模式是 Claude Code 处理复杂任务的秘密武器。理解它的工作原理,学会手动编排,你就能把一个小时的串行工作压缩到几分钟的并行执行。分而治之,不仅是算法的智慧,也是 AI 协作的智慧。

评论

加载中...

相关文章

分享:

评论

加载中...