让 AI 自己协作 —— 多智能体(Swarm)系统的设计与实现

3 阅读5分钟

让 AI 自己协作 —— 多智能体(Swarm)系统的设计与实现

Claude Code 源码泄露技术解析系列 · 第 5 篇
深入解析多智能体协作系统的架构设计与实现模式


引言

当你给 Claude Code 一个复杂任务时,它可能会说:

"我会先分析项目结构,然后查看相关文件,最后给出完整的解决方案。"

这背后是一个多智能体协作系统在运作。Claude Code 会将复杂任务分解为多个子任务,分配给不同的"虚拟智能体"并行执行,最后聚合结果。

本文将深入解析多智能体系统的设计模式,并实现一个可运行的 Agent Swarm 框架。

本文你将学到

  • 单智能体 vs 多智能体架构对比
  • 任务分解策略(Decomposition)
  • 智能体间通信模式(消息总线)
  • 上下文隔离与权限控制
  • 结果聚合与冲突解决
  • 实战:实现一个简单的 Agent Swarm

一、单智能体 vs 多智能体架构

1.1 单智能体架构

// 传统单智能体模式
class SingleAgent {
  async execute(task: Task): Promise<Result> {
    // 顺序执行所有步骤
    const analysis = await this.analyze(task);
    const plan = await this.plan(analysis);
    const execution = await this.executePlan(plan);
    const validation = await this.validate(execution);
    
    return { analysis, plan, execution, validation };
  }
}

局限性

  • ❌ 串行执行,耗时长
  • ❌ 上下文窗口限制
  • ❌ 单一视角,容易遗漏
  • ❌ 无法并行处理独立子任务

1.2 多智能体架构

// 多智能体协作模式
class SwarmSystem {
  async execute(task: Task): Promise<Result> {
    // 1. 任务分解
    const subtasks = await this.decompose(task);
    
    // 2. 并行分配给不同智能体
    const agents = subtasks.map(subtask => 
      this.spawnAgent(subtask)
    );
    
    // 3. 并行执行
    const results = await Promise.all(
      agents.map(agent => agent.execute())
    );
    
    // 4. 结果聚合
    return this.aggregate(results);
  }
}

优势

  • ✅ 并行执行,效率高
  • ✅ 每个智能体专注特定领域
  • ✅ 上下文隔离,减少干扰
  • ✅ 可水平扩展

1.3 Claude Code 中的 Swarm 模式

// Claude Code 的多智能体场景
const swarmScenarios = {
  // 代码审查场景
  codeReview: {
    agents: ['Reader', 'Analyzer', 'SecurityChecker', 'StyleChecker'],
    workflow: 'parallel-then-merge'
  },
  
  // 功能开发场景
  featureDev: {
    agents: ['Planner', 'Coder', 'Tester', 'Documenter'],
    workflow: 'sequential-pipeline'
  },
  
  // 问题排查场景
  debugging: {
    agents: ['Investigator', 'Hypothesizer', 'Tester', 'Fixer'],
    workflow: 'iterative-loop'
  }
};

二、任务分解策略

2.1 基于依赖图的分解

interface SubTask {
  id: string;
  description: string;
  agent: string;
  dependencies: string[]; // 依赖的子任务 ID
  input: any;
  status: 'pending' | 'running' | 'completed' | 'failed';
  result?: any;
}

class TaskDecomposer {
  async decompose(task: Task): Promise<SubTask[]> {
    // 使用 LLM 进行任务分解
    const prompt = `
将以下任务分解为可并行执行的子任务:

任务:${task.description}

要求:
1. 识别独立的子任务
2. 明确子任务之间的依赖关系
3. 为每个子任务分配合适的角色

请返回 JSON 格式的子任务列表。
    `;
    
    const decomposition = await this.llm.generate(prompt);
    return this.parseSubTasks(decomposition);
  }
  
  // 构建执行顺序
  buildExecutionOrder(subtasks: SubTask[]): SubTask[][] {
    const levels: SubTask[][] = [];
    const completed = new Set<string>();
    const remaining = [...subtasks];
    
    while (remaining.length > 0) {
      // 找出当前可执行的子任务(依赖已满足)
      const ready = remaining.filter(st =>
        st.dependencies.every(dep => completed.has(dep))
      );
      
      if (ready.length === 0) {
        throw new Error('检测到循环依赖');
      }
      
      levels.push(ready);
      ready.forEach(st => {
        completed.add(st.id);
        remaining.splice(remaining.indexOf(st), 1);
      });
    }
    
    return levels;
  }
}

2.2 基于角色的分解

// 预定义的角色模板
const ROLE_TEMPLATES = {
  RESEARCHER: {
    name: '研究员',
    description: '负责收集信息、阅读文档、分析代码',
    tools: ['read_file', 'search_code', 'web_search'],
    outputType: 'analysis'
  },
  
  ARCHITECT: {
    name: '架构师',
    description: '负责设计解决方案、制定计划',
    tools: ['read_file', 'write_file'],
    outputType: 'plan'
  },
  
  DEVELOPER: {
    name: '开发者',
    description: '负责编写代码、实现功能',
    tools: ['read_file', 'write_file', 'run_command'],
    outputType: 'code'
  },
  
  REVIEWER: {
    name: '审查员',
    description: '负责代码审查、质量检查',
    tools: ['read_file', 'search_code'],
    outputType: 'feedback'
  },
  
  TESTER: {
    name: '测试员',
    description: '负责编写测试、验证功能',
    tools: ['read_file', 'write_file', 'run_command'],
    outputType: 'test_result'
  }
};

class RoleBasedDecomposer {
  decomposeByRole(task: Task): SubTask[] {
    const roles = this.identifyRequiredRoles(task);
    
    return roles.map((role, index) => ({
      id: `task-${index}`,
      description: this.generateRoleTask(role, task),
      agent: role,
      dependencies: index === 0 ? [] : [`task-${index - 1}`],
      input: task,
      status: 'pending'
    }));
  }
  
  identifyRequiredRoles(task: Task): string[] {
    // 根据任务类型决定需要的角色
    if (task.type === 'bug_fix') {
      return ['RESEARCHER', 'DEVELOPER', 'TESTER'];
    }
    if (task.type === 'feature') {
      return ['ARCHITECT', 'DEVELOPER', 'REVIEWER', 'TESTER'];
    }
    if (task.type === 'review') {
      return ['RESEARCHER', 'REVIEWER'];
    }
    return ['DEVELOPER'];
  }
}

2.3 动态任务分解

class DynamicDecomposer {
  async decompose(task: Task, context: Context): Promise<SubTask[]> {
    // 迭代式分解:根据执行结果动态调整
    const subtasks: SubTask[] = [];
    const pendingTasks = [task];
    
    while (pendingTasks.length > 0) {
      const current = pendingTasks.shift()!;
      
      // 判断是否需要进一步分解
      const shouldDecompose = await this.shouldDecomposeFurther(current, context);
      
      if (shouldDecompose) {
        const children = await this.decomposeTask(current);
        pendingTasks.push(...children);
      } else {
        // 原子任务,直接执行
        subtasks.push({
          id: generateId(),
          description: current.description,
          agent: this.selectAgent(current),
          dependencies: [],
          input: current,
          status: 'pending'
        });
      }
    }
    
    return this.resolveDependencies(subtasks);
  }
  
  async shouldDecomposeFurther(task: Task, context: Context): Promise<boolean> {
    // 判断标准:
    // 1. 任务复杂度(token 数)
    // 2. 涉及的文件数量
    // 3. 需要的工具类型数量
    
    const complexity = await this.estimateComplexity(task);
    return complexity > context.threshold;
  }
}

三、智能体间通信模式

3.1 消息总线架构

interface Message {
  id: string;
  from: string;
  to: string | '*'; // '*' 表示广播
  type: 'request' | 'response' | 'event' | 'broadcast';
  payload: any;
  timestamp: number;
  correlationId?: string; // 关联请求 ID
}

class MessageBus {
  private subscribers: Map<string, Set<(msg: Message) => void>> = new Map();
  private messageQueue: Message[] = [];
  
  // 订阅主题
  subscribe(topic: string, handler: (msg: Message) => void): () => void {
    if (!this.subscribers.has(topic)) {
      this.subscribers.set(topic, new Set());
    }
    this.subscribers.get(topic)!.add(handler);
    
    // 返回取消订阅函数
    return () => this.subscribers.get(topic)!.delete(handler);
  }
  
  // 发布消息
  async publish(message: Message): Promise<void> {
    this.messageQueue.push(message);
    
    // 广播消息
    if (message.to === '*') {
      for (const [topic, handlers] of this.subscribers) {
        for (const handler of handlers) {
          handler(message);
        }
      }
    } else {
      // 定向发送
      const handlers = this.subscribers.get(message.to);
      if (handlers) {
        for (const handler of handlers) {
          handler(message);
        }
      }
    }
  }
  
  // 请求 - 响应模式
  async request<T>(message: Message, timeout = 5000): Promise<T> {
    const correlationId = generateId();
    message.correlationId = correlationId;
    
    return new Promise((resolve, reject) => {
      const timer = setTimeout(() => {
        unsubscribe();
        reject(new Error('请求超时'));
      }, timeout);
      
      const unsubscribe = this.subscribe(message.from, (response) => {
        if (response.correlationId === correlationId) {
          clearTimeout(timer);
          unsubscribe();
          resolve(response.payload);
        }
      });
      
      this.publish(message);
    });
  }
}

3.2 共享状态管理

interface SharedState {
  variables: Map<string, any>;
  files: Map<string, string>;
  context: Map<string, any>;
  version: number;
}

class SharedStateManager {
  private state: SharedState = {
    variables: new Map(),
    files: new Map(),
    context: new Map(),
    version: 0
  };
  
  private listeners: Set<() => void> = new Set();
  
  // 获取变量
  get<T>(key: string): T | undefined {
    return this.state.variables.get(key);
  }
  
  // 设置变量(带版本控制)
  set<T>(key: string, value: T): void {
    this.state.variables.set(key, value);
    this.state.version++;
    this.notifyListeners();
  }
  
  // 原子更新
  update<T>(key: string, updater: (value: T | undefined) => T): void {
    const current = this.get<T>(key);
    const updated = updater(current);
    this.set(key, updated);
  }
  
  // 监听变化
  onChange(listener: () => void): () => void {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }
  
  private notifyListeners(): void {
    for (const listener of this.listeners) {
      listener();
    }
  }
  
  // 快照与恢复
  snapshot(): SharedState {
    return JSON.parse(JSON.stringify({
      variables: Object.fromEntries(this.state.variables),
      files: Object.fromEntries(this.state.files),
      context: Object.fromEntries(this.state.context),
      version: this.state.version
    }));
  }
  
  restore(snapshot: SharedState): void {
    this.state.variables = new Map(Object.entries(snapshot.variables));
    this.state.files = new Map(Object.entries(snapshot.files));
    this.state.context = new Map(Object.entries(snapshot.context));
    this.state.version = snapshot.version;
    this.notifyListeners();
  }
}

3.3 事件驱动通信

type EventType = 
  | 'task_started'
  | 'task_completed'
  | 'task_failed'
  | 'result_available'
  | 'error_occurred'
  | 'context_updated';

interface SwarmEvent {
  type: EventType;
  source: string;
  data: any;
  timestamp: number;
}

class EventEmitter {
  private handlers: Map<EventType, Set<(event: SwarmEvent) => void>> = new Map();
  
  on(event: EventType, handler: (event: SwarmEvent) => void): void {
    if (!this.handlers.has(event)) {
      this.handlers.set(event, new Set());
    }
    this.handlers.get(event)!.add(handler);
  }
  
  emit(event: SwarmEvent): void {
    const handlers = this.handlers.get(event.type);
    if (handlers) {
      for (const handler of handlers) {
        handler(event);
      }
    }
  }
}

// 使用示例
class Agent {
  constructor(private events: EventEmitter) {
    this.events.on('task_completed', (event) => {
      if (event.data.nextAgent === this.name) {
        this.startTask(event.data.result);
      }
    });
  }
  
  completeTask(result: any): void {
    this.events.emit({
      type: 'task_completed',
      source: this.name,
      data: { result, nextAgent: 'REVIEWER' },
      timestamp: Date.now()
    });
  }
}

四、上下文隔离与权限控制

4.1 上下文隔离

interface AgentContext {
  agentId: string;
  role: string;
  permissions: Permission[];
  variables: Map<string, any>;
  files: Set<string>; // 可访问的文件
  tools: Set<string>; // 可使用的工具
  maxTokens: number;
  timeout: number;
}

class ContextIsolator {
  createContext(agentId: string, role: string, task: SubTask): AgentContext {
    const roleConfig = ROLE_TEMPLATES[role as keyof typeof ROLE_TEMPLATES];
    
    return {
      agentId,
      role,
      permissions: this.derivePermissions(roleConfig),
      variables: new Map([
        ['TASK_ID', task.id],
        ['TASK_DESCRIPTION', task.description],
        ['AGENT_ROLE', role]
      ]),
      files: new Set(task.input.allowedFiles || []),
      tools: new Set(roleConfig.tools),
      maxTokens: 4000,
      timeout: 60000
    };
  }
  
  derivePermissions(roleConfig: any): Permission[] {
    const permissions: Permission[] = [];
    
    if (roleConfig.tools.includes('read_file')) {
      permissions.push({ type: 'fs:read' });
    }
    if (roleConfig.tools.includes('write_file')) {
      permissions.push({ type: 'fs:write' });
    }
    if (roleConfig.tools.includes('run_command')) {
      permissions.push({ type: 'process' });
    }
    
    return permissions;
  }
  
  // 验证操作是否允许
  canPerform(context: AgentContext, action: string, resource?: string): boolean {
    // 检查工具权限
    if (action.startsWith('tool:')) {
      const toolName = action.replace('tool:', '');
      return context.tools.has(toolName);
    }
    
    // 检查文件权限
    if (action.startsWith('file:') && resource) {
      return context.files.has(resource);
    }
    
    return false;
  }
}

4.2 权限委托

class PermissionDelegator {
  // 临时权限提升
  async elevatePermission(
    context: AgentContext,
    permission: Permission,
    duration: number,
    reason: string
  ): Promise<AgentContext> {
    // 记录权限提升日志
    await this.logPermissionElevation(context.agentId, permission, reason);
    
    // 创建临时上下文
    const elevated = { ...context };
    elevated.permissions = [...context.permissions, permission];
    
    // 设置自动撤销
    setTimeout(() => {
      this.revokeElevation(context.agentId, permission);
    }, duration);
    
    return elevated;