19-多智能体协作和复杂推理

6 阅读21分钟

在现代软件开发中,复杂任务往往需要多个专家协同完成。同样,AI Agent也可以通过团队协作来解决更复杂的问题。本文将深入探讨如何构建多Agent系统,让AI"团队"高效协作。

时间:45分钟 | 难度:⭐⭐⭐⭐ | Week 3 Day 19


📋 学习目标

  • 理解多Agent系统的核心价值和应用场景
  • 掌握四种主流的Agent协作模式
  • 实现协调者模式和流水线模式
  • 设计Agent间通信和状态共享机制
  • 处理多Agent系统中的冲突和一致性问题
  • 构建生产级的多Agent代码审查系统

🚀 快速入门:为什么需要多Agent?

单Agent的局限性

单个Agent面临的挑战:

  1. 知识边界:一个Agent难以精通所有领域
  2. 上下文限制:Token限制导致无法处理超大规模任务
  3. 复杂度爆炸:单一系统提示词变得臃肿难以维护
  4. 推理深度:某些问题需要多角度分析和验证

多Agent的优势

专业分工:每个Agent专注于特定领域 并行处理:多个Agent同时工作提升效率 质量保障:多重验证机制减少错误 可扩展性:轻松添加新的专家Agent

典型架构

         用户请求
            ↓
      ┌─────────────┐
      │  协调Agent   │
      └─────────────┘
            ↓
    ┌───────┴───────┐
    ↓       ↓       ↓
  分析    研究    编码
  Agent   Agent   Agent
    ↓       ↓       ↓
    └───────┬───────┘
            ↓
      汇总并返回结果

🎯 深度讲解

1️⃣ 四种协作模式

模式一:协调者模式(Coordinator Pattern)

核心思想:一个领导Agent将任务分配给多个专家Agent

      用户
       ↓
   [协调Agent]
       ↓
  ┌────┼────┐
  ↓    ↓    ↓
[专家A][专家B][专家C]
  ↓    ↓    ↓
  └────┼────┘
       ↓
   [协调Agent]
       ↓
     结果

适用场景:任务可以明确拆分,需要集中决策

模式二:流水线模式(Pipeline Pattern)

核心思想:任务按顺序经过多个Agent处理

用户 → [Agent1][Agent2][Agent3] → 结果
      需求分析   架构设计   代码实现

适用场景:任务有明确的处理步骤,前后依赖

模式三:辩论模式(Debate Pattern)

核心思想:多个Agent从不同角度分析,通过辩论达成共识

        主题
         ↓
    ┌────┴────┐
    ↓         ↓
 [正方Agent] [反方Agent]
    ↓         ↓
    └────┬────┘
         ↓
    [裁判Agent]
         ↓
      最终结论

适用场景:需要多角度验证的决策问题

模式四:群聊模式(Group Chat Pattern)

核心思想:多个Agent自由交流,共同解决问题

    [Agent A] ←→ [Agent B]
         ↕           ↕
    [Agent C] ←→ [Agent D]

    所有Agent共享消息历史

适用场景:开放性问题,需要头脑风暴

🔍 四种模式全维度对比

[!tip] 对比视角 四种模式没有绝对优劣,关键在于任务特征质量要求。下面从 10 个维度进行深度对比。

核心对比表
维度协调者模式流水线模式辩论模式群聊模式
通信拓扑星型(中心→放射)链式(线性串联)对抗型(正反→裁判)全连接(网状)
决策方式集中决策(协调者拍板)逐级决策(每步独立)对抗决策(辩论后裁定)涌现决策(共识浮现)
任务拆分协调者主动拆分预先定义好步骤不拆分,同一问题多角度动态涌现,无预设
并行能力⭐⭐⭐ 子任务可并行⭐ 严格串行⭐⭐ 正反方可并行⭐⭐⭐ 高度并行
Token 成本中等(协调 + N个子任务)低(线性累加)高(多轮辩论)最高(全员共享历史)
结果可控性⭐⭐⭐ 协调者把关⭐⭐⭐ 流程固定⭐⭐ 依赖裁判质量⭐ 结果不可预测
容错能力⭐⭐⭐ 某专家失败可重试⭐ 一步失败全链断⭐⭐ 一方弱不影响裁定⭐⭐ 其他Agent可补位
实现复杂度中等中等
Agent 数量1协调 + N专家N个串联2+对手 + 1裁判N个平等参与者
消息流向双向(协调者↔专家)单向(前→后)交叉(正↔反→裁判)广播(全员可见)
典型场景客服路由、项目管理、智能问诊ETL数据处理、代码生成→Review→部署、文档翻译→校对→排版方案评审、投资决策、论文审稿、代码方案PK产品头脑风暴、创意策划、需求讨论
类比项目经理分活给工程师工厂流水线法庭辩论 + 法官裁决微信群聊讨论
通信模式对比图
协调者模式(星型)          流水线模式(链式)

    专家A                  AB → C → D → 结果
      ↑
协调者 ← → 专家B           每一步的输出 = 下一步的输入
      ↓
    专家C

辩论模式(对抗型)          群聊模式(网状)

  正方 ←→ 反方              A ←→ B
    ↓       ↓               ↕     ↕
    └→ 裁判 ←┘              C ←→ D
        ↓
      结论                 所有消息广播给所有Agent
Token 成本分析
假设每个Agent单次调用 = 1000 tokens

协调者模式(1 + 3个专家,各调用1次):
  协调者分配: 1000
  专家A/B/C:  3 × 1000 = 3000
  协调者汇总: 2000(包含3个结果)
  总计:  6000 tokens

流水线模式(3步串联):
  Step1: 1000
  Step2: 1500(包含Step1结果)
  Step3: 2000(包含Step1+2结果)
  总计:  4500 tokens   最省

辩论模式(3轮辩论 + 裁判):
  Round1 正方: 1000, 反方: 1500
  Round2 正方: 2500, 反方: 3000
  Round3 正方: 4000, 反方: 4500
  裁判汇总: 5000
  总计:  21500 tokens   贵!

群聊模式(4个Agent,每人发言3次):
  消息历史不断增长,每人都看到全部历史
  总计:  30000+ tokens   最贵!

[!warning] 成本陷阱 辩论和群聊模式的成本随轮次二次增长(每轮都要带上之前所有历史)。设置 maxRounds 限制是必须的。

错误处理对比
协调者模式:
  专家B失败 → 协调者感知 → 重新分配给专家D → 继续
  ✅ 最优雅的错误恢复

流水线模式:
  Step2失败 → 整条链断裂 → 从Step2重试或全部重来
  ❌ 单点故障风险最高

辩论模式:
  反方Agent失败 → 裁判只听到正方 → 结论偏颇
  ⚠️ 需要fallback机制(如默认反对意见)

群聊模式:
  AgentC掉线 → 其他Agent继续讨论 → 可能缺少某个视角
  ⚠️ 降级运行,质量下降但不中断
适用任务类型对比
任务特征最佳模式为什么
可拆分为独立子任务🏆 协调者子任务并行,协调者汇总
有明确的处理步骤🏆 流水线自然映射为A→B→C
需要提高准确性/避免偏见🏆 辩论对抗性思考减少盲区
探索性/开放性问题🏆 群聊自由碰撞产生创意
代码生成 + Review流水线 or 辩论流水线=生成→Review→修复;辩论=两种方案PK
客户服务路由协调者路由Agent判断意图→分发给对应专家
学术论文评审辩论多个Reviewer独立评审→编辑决策
产品头脑风暴群聊产品/技术/设计/运营Agent自由讨论
ETL数据处理流水线提取→清洗→转换→加载
复杂项目管理协调者PM分配任务→追踪进度→汇总报告
模式组合:实际项目中的混合架构

[!info] 现实中的多Agent系统往往不是单一模式 复杂系统通常组合使用多种模式,形成层级结构。

真实案例:AI 代码助手

[协调者Agent] ← 顶层用协调者模式
      ↓
  ┌───┼───────────┐
  ↓   ↓           ↓
需求  代码生成      测试
分析  (流水线模式)   验证
  ↓   ↓           ↓
  │  设计→编码→优化  │
  ↓                ↓
  └──→ Code Review ←┘
       (辩论模式)
       ↓
     最终代码

组合原则

  1. 顶层用协调者 — 统一入口和调度
  2. 有序步骤用流水线 — 代码生成的设计→编码→优化
  3. 质量把关用辩论 — Code Review 阶段
  4. 创意探索用群聊 — 早期需求讨论(可选)
选型决策树
你的任务是什么?
│
├─ 能拆分成独立子任务?
│   ├─ 是 → 子任务之间有顺序依赖?
│   │       ├─ 是 → 📋 流水线模式
│   │       └─ 否 → 🎯 协调者模式
│   └─ 否 → 需要提高决策质量/准确性?
│           ├─ 是 → ⚖️ 辩论模式
│           └─ 否 → 问题是否开放/探索性?
│                   ├─ 是 → 💬 群聊模式
│                   └─ 否 → 🎯 协调者模式(默认)
│
└─ 性能/成本敏感?
    ├─ 是 → 📋 流水线 或 🎯 协调者
    └─ 否 → ⚖️ 辩论 或 💬 群聊

[!tip] 经验法则

  • 不确定用什么 → 先用协调者模式(最通用、最可控)
  • 追求质量 → 加上辩论模式做验证
  • 追求效率 → 流水线模式最省 token
  • 追求创意 → 群聊模式最发散

2️⃣ 协调者模式实现

定义协调者Agent

import dev.langchain4j.service.SystemMessage;
import dev.langchain4j.service.UserMessage;

interface CoordinatorAgent {

    @SystemMessage("""
        你是一个项目经理Agent,负责协调多个专家Agent完成任务。

        你的职责:
        1. 分析用户需求,拆解为子任务
        2. 决定调用哪些专家Agent
        3. 整合各专家的结果
        4. 确保最终输出的一致性和完整性

        可用的专家Agent:
        - AnalysisAgent: 代码分析专家
        - SecurityAgent: 安全审查专家
        - PerformanceAgent: 性能优化专家

        请以JSON格式返回任务分配方案:
        {
          "tasks": [
            {"agent": "AnalysisAgent", "instruction": "..."},
            {"agent": "SecurityAgent", "instruction": "..."}
          ]
        }
    """)
    String planTasks(String userRequest);

    @SystemMessage("整合以下专家意见,给出综合结论:")
    String synthesize(@UserMessage String expertOpinions);
}

定义专家Agents

interface AnalysisAgent {

    @SystemMessage("""
        你是代码分析专家,专注于:
        - 代码结构和设计模式
        - 可读性和可维护性
        - 最佳实践遵循情况

        请给出详细的分析报告。
    """)
    String analyze(String code);
}

interface SecurityAgent {

    @SystemMessage("""
        你是安全审查专家,检查:
        - SQL注入、XSS等常见漏洞
        - 敏感数据处理
        - 权限控制
        - 依赖项安全

        列出所有安全隐患,按严重程度排序。
    """)
    String reviewSecurity(String code);
}

interface PerformanceAgent {

    @SystemMessage("""
        你是性能优化专家,关注:
        - 算法复杂度
        - 内存使用
        - 数据库查询优化
        - 并发处理

        提供性能评估和优化建议。
    """)
    String analyzePerformance(String code);
}

协调者编排逻辑

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;

public class MultiAgentCoordinator {

    private final CoordinatorAgent coordinator;
    private final AnalysisAgent analysisAgent;
    private final SecurityAgent securityAgent;
    private final PerformanceAgent performanceAgent;
    private final Gson gson = new Gson();

    public MultiAgentCoordinator(ChatLanguageModel model) {
        this.coordinator = AiServices.create(CoordinatorAgent.class, model);
        this.analysisAgent = AiServices.create(AnalysisAgent.class, model);
        this.securityAgent = AiServices.create(SecurityAgent.class, model);
        this.performanceAgent = AiServices.create(PerformanceAgent.class, model);
    }

    public String reviewCode(String code, String userRequest) {
        // 第一步:协调者规划任务
        String planJson = coordinator.planTasks(userRequest);
        JsonObject plan = gson.fromJson(planJson, JsonObject.class);
        JsonArray tasks = plan.getAsJsonArray("tasks");

        // 第二步:并行执行各专家任务
        StringBuilder expertOpinions = new StringBuilder();

        for (int i = 0; i < tasks.size(); i++) {
            JsonObject task = tasks.get(i).getAsJsonObject();
            String agentName = task.get("agent").getAsString();
            String instruction = task.get("instruction").getAsString();

            // 根据Agent名称调用对应的专家
            String result = executeExpertTask(agentName, code, instruction);
            expertOpinions.append(String.format(
                "=== %s 的意见 ===\n%s\n\n",
                agentName, result
            ));
        }

        // 第三步:协调者整合结果
        String finalReport = coordinator.synthesize(expertOpinions.toString());

        return finalReport;
    }

    private String executeExpertTask(String agentName, String code, String instruction) {
        return switch (agentName) {
            case "AnalysisAgent" -> analysisAgent.analyze(code + "\n\n" + instruction);
            case "SecurityAgent" -> securityAgent.reviewSecurity(code + "\n\n" + instruction);
            case "PerformanceAgent" -> performanceAgent.analyzePerformance(code + "\n\n" + instruction);
            default -> "未知的Agent: " + agentName;
        };
    }
}

使用示例

public class CoordinatorExample {

    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .temperature(0.7)
            .build();

        MultiAgentCoordinator coordinator = new MultiAgentCoordinator(model);

        String code = """
            public class UserService {
                public User getUser(String id) {
                    String sql = "SELECT * FROM users WHERE id = " + id;
                    return database.query(sql);
                }
            }
        """;

        String request = "全面审查这段代码,找出所有问题";

        String report = coordinator.reviewCode(code, request);
        System.out.println(report);
    }
}

3️⃣ 流水线模式实现

定义流水线各阶段Agent

interface RequirementAgent {
    @SystemMessage("你是需求分析专家,将用户描述转换为明确的技术需求")
    String analyzeRequirement(String userDescription);
}

interface ArchitectAgent {
    @SystemMessage("你是架构师,根据需求设计系统架构,输出组件图和接口定义")
    String designArchitecture(String requirement);
}

interface ImplementationAgent {
    @SystemMessage("你是高级开发工程师,根据架构设计编写Java代码实现")
    String implement(String architecture);
}

interface TestAgent {
    @SystemMessage("你是测试工程师,为给定的代码编写JUnit测试用例")
    String writeTests(String code);
}

流水线编排器

public class PipelineOrchestrator {

    private final RequirementAgent requirementAgent;
    private final ArchitectAgent architectAgent;
    private final ImplementationAgent implementationAgent;
    private final TestAgent testAgent;

    public PipelineOrchestrator(ChatLanguageModel model) {
        this.requirementAgent = AiServices.create(RequirementAgent.class, model);
        this.architectAgent = AiServices.create(ArchitectAgent.class, model);
        this.implementationAgent = AiServices.create(ImplementationAgent.class, model);
        this.testAgent = AiServices.create(TestAgent.class, model);
    }

    public DevelopmentResult develop(String userDescription) {
        // 阶段1:需求分析
        System.out.println("📋 阶段1: 需求分析中...");
        String requirement = requirementAgent.analyzeRequirement(userDescription);

        // 阶段2:架构设计
        System.out.println("🏗️ 阶段2: 架构设计中...");
        String architecture = architectAgent.designArchitecture(requirement);

        // 阶段3:代码实现
        System.out.println("💻 阶段3: 代码实现中...");
        String code = implementationAgent.implement(architecture);

        // 阶段4:测试编写
        System.out.println("🧪 阶段4: 测试用例生成中...");
        String tests = testAgent.writeTests(code);

        return new DevelopmentResult(requirement, architecture, code, tests);
    }
}

record DevelopmentResult(
    String requirement,
    String architecture,
    String code,
    String tests
) {
    public void print() {
        System.out.println("\n=== 需求文档 ===\n" + requirement);
        System.out.println("\n=== 架构设计 ===\n" + architecture);
        System.out.println("\n=== 代码实现 ===\n" + code);
        System.out.println("\n=== 测试用例 ===\n" + tests);
    }
}

带反馈的流水线

public class FeedbackPipeline {

    private final ImplementationAgent implementationAgent;
    private final TestAgent testAgent;

    public String developWithFeedback(String architecture, int maxIterations) {
        String code = implementationAgent.implement(architecture);

        for (int i = 0; i < maxIterations; i++) {
            // 测试Agent审查代码
            String testFeedback = testAgent.writeTests(code);

            // 检查是否有测试失败(简化示例)
            if (testFeedback.contains("PASS") && !testFeedback.contains("FAIL")) {
                System.out.println("✅ 测试通过,开发完成!");
                return code;
            }

            // 如果有问题,让实现Agent根据反馈改进
            System.out.println("⚠️ 第" + (i+1) + "轮迭代,根据测试反馈改进代码...");
            code = implementationAgent.implement(
                "原始架构:\n" + architecture +
                "\n\n当前代码:\n" + code +
                "\n\n测试反馈:\n" + testFeedback +
                "\n\n请改进代码以通过所有测试"
            );
        }

        return code;
    }
}

4️⃣ Agent间通信机制

方案一:共享上下文(Shared Context)

import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

public class SharedContextSystem {

    // 线程安全的共享状态
    private final Map<String, Object> sharedContext = new ConcurrentHashMap<>();

    public void executeWithSharedContext(String code) {
        // Agent 1: 分析代码并存储结果
        AnalysisAgent analysisAgent = createAgent(AnalysisAgent.class);
        String analysisResult = analysisAgent.analyze(code);
        sharedContext.put("analysis", analysisResult);

        // Agent 2: 读取分析结果,进行安全审查
        SecurityAgent securityAgent = createAgent(SecurityAgent.class);
        String previousAnalysis = (String) sharedContext.get("analysis");
        String securityResult = securityAgent.reviewSecurity(
            code + "\n\n参考之前的分析:\n" + previousAnalysis
        );
        sharedContext.put("security", securityResult);

        // Agent 3: 综合所有结果生成报告
        String analysis = (String) sharedContext.get("analysis");
        String security = (String) sharedContext.get("security");

        String finalReport = String.format("""
            综合审查报告:

            一、代码分析
            %s

            二、安全审查
            %s
            """, analysis, security);

        sharedContext.put("finalReport", finalReport);
    }

    private <T> T createAgent(Class<T> agentClass) {
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .build();
        return AiServices.create(agentClass, model);
    }
}

方案二:消息传递(Message Passing)

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

record AgentMessage(
    String fromAgent,
    String toAgent,
    String content,
    long timestamp
) {}

public class MessageBus {

    private final Queue<AgentMessage> messageQueue = new ConcurrentLinkedQueue<>();

    public void send(String from, String to, String content) {
        AgentMessage message = new AgentMessage(
            from, to, content, System.currentTimeMillis()
        );
        messageQueue.offer(message);
        System.out.println("📨 " + from + " -> " + to + ": " + content.substring(0, 50) + "...");
    }

    public AgentMessage receive(String agentName) {
        return messageQueue.stream()
            .filter(msg -> msg.toAgent().equals(agentName))
            .findFirst()
            .orElse(null);
    }

    public void broadcastMessage(String from, String content) {
        // 广播给所有Agent
        String[] allAgents = {"AnalysisAgent", "SecurityAgent", "PerformanceAgent"};
        for (String agent : allAgents) {
            if (!agent.equals(from)) {
                send(from, agent, content);
            }
        }
    }
}

public class MessageBasedSystem {

    private final MessageBus messageBus = new MessageBus();

    public void executeWithMessages(String code) {
        // 协调者发送任务
        messageBus.send("Coordinator", "AnalysisAgent",
            "请分析以下代码:\n" + code);

        // AnalysisAgent处理并回复
        AgentMessage task = messageBus.receive("AnalysisAgent");
        if (task != null) {
            String result = performAnalysis(code);
            messageBus.send("AnalysisAgent", "Coordinator", result);
        }

        // 协调者收集结果
        AgentMessage response = messageBus.receive("Coordinator");
        System.out.println("收到分析结果:" + response.content());
    }

    private String performAnalysis(String code) {
        // 实际分析逻辑
        return "分析完成";
    }
}

方案三:事件驱动(Event-Driven)

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

interface AgentEventListener {
    void onEvent(AgentEvent event);
}

record AgentEvent(
    String type,        // "TASK_COMPLETED", "ERROR", "REQUEST_HELP"
    String sourceAgent,
    Object data
) {}

public class EventDrivenSystem {

    private final List<AgentEventListener> listeners = new ArrayList<>();

    public void addEventListener(AgentEventListener listener) {
        listeners.add(listener);
    }

    public void fireEvent(AgentEvent event) {
        System.out.println("🔔 事件触发: " + event.type() + " from " + event.sourceAgent());
        for (AgentEventListener listener : listeners) {
            listener.onEvent(event);
        }
    }

    // 示例:Agent完成任务时触发事件
    public void agentCompletesTask(String agentName, String result) {
        AgentEvent event = new AgentEvent("TASK_COMPLETED", agentName, result);
        fireEvent(event);
    }
}

public class EventListenerExample {

    public static void main(String[] args) {
        EventDrivenSystem eventSystem = new EventDrivenSystem();

        // 协调者监听所有Agent的完成事件
        eventSystem.addEventListener(event -> {
            if (event.type().equals("TASK_COMPLETED")) {
                System.out.println("协调者收到:" + event.sourceAgent() + " 完成任务");
                // 触发下一个Agent的任务
            }
        });

        // 模拟Agent完成任务
        eventSystem.agentCompletesTask("AnalysisAgent", "分析报告...");
    }
}

5️⃣ 冲突解决机制

策略一:投票机制

import java.util.*;

public class VotingSystem {

    public String resolveByVoting(String question, List<String> agentOpinions) {
        // 统计每个观点的支持度
        Map<String, Integer> votes = new HashMap<>();

        for (String opinion : agentOpinions) {
            // 简化:提取关键结论(实际应用中需要更复杂的相似度计算)
            String conclusion = extractConclusion(opinion);
            votes.put(conclusion, votes.getOrDefault(conclusion, 0) + 1);
        }

        // 找出最多票数的观点
        return votes.entrySet().stream()
            .max(Map.Entry.comparingByValue())
            .map(Map.Entry::getKey)
            .orElse("无法达成一致");
    }

    private String extractConclusion(String opinion) {
        // 简化示例:提取最后一句话作为结论
        String[] sentences = opinion.split("\\.");
        return sentences[sentences.length - 1].trim();
    }
}

策略二:优先级机制

public class PrioritySystem {

    enum AgentPriority {
        HIGH(3),
        MEDIUM(2),
        LOW(1);

        final int value;
        AgentPriority(int value) { this.value = value; }
    }

    record AgentOpinion(
        String agentName,
        AgentPriority priority,
        String content
    ) {}

    public String resolveByPriority(List<AgentOpinion> opinions) {
        return opinions.stream()
            .max(Comparator.comparing(op -> op.priority().value))
            .map(AgentOpinion::content)
            .orElse("无意见");
    }

    // 示例:安全问题优先级最高
    public static void main(String[] args) {
        List<AgentOpinion> opinions = List.of(
            new AgentOpinion("SecurityAgent", AgentPriority.HIGH, "发现SQL注入漏洞!"),
            new AgentOpinion("PerformanceAgent", AgentPriority.MEDIUM, "性能可接受"),
            new AgentOpinion("StyleAgent", AgentPriority.LOW, "命名规范需改进")
        );

        PrioritySystem system = new PrioritySystem();
        String decision = system.resolveByPriority(opinions);
        System.out.println("最终决策:" + decision); // 输出安全Agent的意见
    }
}

策略三:协调者仲裁

interface ArbitratorAgent {

    @SystemMessage("""
        你是仲裁者,当多个Agent意见不一致时,你需要:
        1. 分析各方观点的合理性
        2. 考虑问题的严重程度和优先级
        3. 给出最终决策并说明理由

        返回JSON格式:
        {
          "decision": "采纳的意见",
          "reasoning": "决策理由"
        }
    """)
    String arbitrate(String conflictDescription);
}

public class ArbitrationSystem {

    private final ArbitratorAgent arbitrator;

    public ArbitrationSystem(ChatLanguageModel model) {
        this.arbitrator = AiServices.create(ArbitratorAgent.class, model);
    }

    public String resolveConflict(Map<String, String> agentOpinions) {
        StringBuilder conflict = new StringBuilder("各Agent意见如下:\n\n");

        agentOpinions.forEach((agent, opinion) ->
            conflict.append(agent).append(":\n").append(opinion).append("\n\n")
        );

        return arbitrator.arbitrate(conflict.toString());
    }
}

💼 实战:代码审查团队系统

完整的多Agent代码审查系统

import dev.langchain4j.model.chat.ChatLanguageModel;
import dev.langchain4j.model.openai.OpenAiChatModel;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.SystemMessage;
import java.util.*;
import java.util.concurrent.*;

// 安全审查Agent
interface SecurityReviewAgent {
    @SystemMessage("""
        你是资深安全工程师,专注发现:
        - SQL注入、XSS、CSRF等Web漏洞
        - 硬编码的密码和密钥
        - 不安全的加密算法
        - 权限控制缺陷

        输出格式:
        严重级别 | 问题描述 | 代码位置 | 修复建议
    """)
    String review(String code);
}

// 性能审查Agent
interface PerformanceReviewAgent {
    @SystemMessage("""
        你是性能优化专家,检查:
        - O(n²)及以上的算法复杂度
        - N+1查询问题
        - 不必要的对象创建
        - 缺少索引的数据库查询

        给出性能评分(0-100)和优化建议。
    """)
    String review(String code);
}

// 代码风格Agent
interface StyleReviewAgent {
    @SystemMessage("""
        你是代码规范专家,检查:
        - 命名规范(驼峰、常量大写等)
        - 代码格式和缩进
        - 注释质量
        - 遵循Java最佳实践

        列出所有不符合规范的地方。
    """)
    String review(String code);
}

// 架构审查Agent
interface ArchitectureReviewAgent {
    @SystemMessage("""
        你是架构师,评估:
        - 单一职责原则
        - 依赖倒置
        - 接口隔离
        - 设计模式使用

        评估架构健康度并提出改进建议。
    """)
    String review(String code);
}

// 总协调Agent
interface CoordinatorReviewAgent {
    @SystemMessage("""
        你是技术负责人,综合各专家意见生成最终审查报告。

        报告结构:
        1. 总体评价(通过/需改进/拒绝)
        2. 关键问题汇总
        3. 优先级排序的改进建议
        4. 代码质量评分
    """)
    String synthesizeReport(String allReviews);
}

// 审查结果
record ReviewResult(
    String securityReview,
    String performanceReview,
    String styleReview,
    String architectureReview,
    String finalReport,
    long executionTimeMs
) {
    public void print() {
        System.out.println("\n" + "=".repeat(80));
        System.out.println("📊 代码审查报告");
        System.out.println("=".repeat(80));

        System.out.println("\n🔒 安全审查");
        System.out.println("-".repeat(80));
        System.out.println(securityReview);

        System.out.println("\n⚡ 性能审查");
        System.out.println("-".repeat(80));
        System.out.println(performanceReview);

        System.out.println("\n✨ 代码风格");
        System.out.println("-".repeat(80));
        System.out.println(styleReview);

        System.out.println("\n🏗️ 架构审查");
        System.out.println("-".repeat(80));
        System.out.println(architectureReview);

        System.out.println("\n📋 综合报告");
        System.out.println("=".repeat(80));
        System.out.println(finalReport);

        System.out.println("\n⏱️ 执行时间: " + executionTimeMs + "ms");
    }
}

// 多Agent代码审查系统
public class CodeReviewTeam {

    private final SecurityReviewAgent securityAgent;
    private final PerformanceReviewAgent performanceAgent;
    private final StyleReviewAgent styleAgent;
    private final ArchitectureReviewAgent architectureAgent;
    private final CoordinatorReviewAgent coordinator;
    private final ExecutorService executor;

    public CodeReviewTeam(ChatLanguageModel model) {
        this.securityAgent = AiServices.create(SecurityReviewAgent.class, model);
        this.performanceAgent = AiServices.create(PerformanceReviewAgent.class, model);
        this.styleAgent = AiServices.create(StyleReviewAgent.class, model);
        this.architectureAgent = AiServices.create(ArchitectureReviewAgent.class, model);
        this.coordinator = AiServices.create(CoordinatorReviewAgent.class, model);
        this.executor = Executors.newFixedThreadPool(4);
    }

    public ReviewResult reviewCode(String code) {
        long startTime = System.currentTimeMillis();

        try {
            // 并行执行各专家审查
            CompletableFuture<String> securityFuture = CompletableFuture.supplyAsync(
                () -> {
                    System.out.println("🔒 安全审查进行中...");
                    return securityAgent.review(code);
                }, executor
            );

            CompletableFuture<String> performanceFuture = CompletableFuture.supplyAsync(
                () -> {
                    System.out.println("⚡ 性能审查进行中...");
                    return performanceAgent.review(code);
                }, executor
            );

            CompletableFuture<String> styleFuture = CompletableFuture.supplyAsync(
                () -> {
                    System.out.println("✨ 风格审查进行中...");
                    return styleAgent.review(code);
                }, executor
            );

            CompletableFuture<String> architectureFuture = CompletableFuture.supplyAsync(
                () -> {
                    System.out.println("🏗️ 架构审查进行中...");
                    return architectureAgent.review(code);
                }, executor
            );

            // 等待所有审查完成
            CompletableFuture.allOf(
                securityFuture, performanceFuture, styleFuture, architectureFuture
            ).join();

            String securityReview = securityFuture.get();
            String performanceReview = performanceFuture.get();
            String styleReview = styleFuture.get();
            String architectureReview = architectureFuture.get();

            // 协调者综合所有意见
            System.out.println("📊 生成综合报告...");
            String allReviews = String.format("""
                === 安全审查 ===
                %s

                === 性能审查 ===
                %s

                === 风格审查 ===
                %s

                === 架构审查 ===
                %s
                """, securityReview, performanceReview, styleReview, architectureReview);

            String finalReport = coordinator.synthesizeReport(allReviews);

            long executionTime = System.currentTimeMillis() - startTime;

            return new ReviewResult(
                securityReview,
                performanceReview,
                styleReview,
                architectureReview,
                finalReport,
                executionTime
            );

        } catch (Exception e) {
            throw new RuntimeException("代码审查失败", e);
        }
    }

    public void shutdown() {
        executor.shutdown();
    }

    // 使用示例
    public static void main(String[] args) {
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .temperature(0.3)
            .build();

        CodeReviewTeam team = new CodeReviewTeam(model);

        String code = """
            public class UserController {

                private Connection conn;

                public User getUser(String id) {
                    // 直接拼接SQL,存在注入风险
                    String sql = "SELECT * FROM users WHERE id = '" + id + "'";

                    try {
                        Statement stmt = conn.createStatement();
                        ResultSet rs = stmt.executeQuery(sql);

                        // N+1查询问题
                        List<User> users = new ArrayList<>();
                        while (rs.next()) {
                            User user = new User();
                            user.setId(rs.getString("id"));
                            user.setName(rs.getString("name"));

                            // 每个用户都查询一次订单
                            String orderSql = "SELECT * FROM orders WHERE user_id = '" + user.getId() + "'";
                            ResultSet orderRs = stmt.executeQuery(orderSql);
                            // ... 处理订单
                        }

                        return users.get(0);
                    } catch (SQLException e) {
                        e.printStackTrace(); // 不应该打印堆栈,应该记录日志
                        return null;
                    }
                }
            }
        """;

        ReviewResult result = team.reviewCode(code);
        result.print();

        team.shutdown();
    }
}

🚀 生产级多Agent系统

异常处理和重试

import java.time.Duration;
import java.util.function.Supplier;

public class RobustMultiAgentSystem {

    // 带重试的Agent调用
    public <T> T executeWithRetry(
        Supplier<T> agentCall,
        int maxRetries,
        Duration retryDelay
    ) {
        int attempt = 0;
        Exception lastException = null;

        while (attempt < maxRetries) {
            try {
                return agentCall.get();
            } catch (Exception e) {
                lastException = e;
                attempt++;
                System.err.println("Agent调用失败,第" + attempt + "次重试: " + e.getMessage());

                if (attempt < maxRetries) {
                    try {
                        Thread.sleep(retryDelay.toMillis());
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new RuntimeException("重试被中断", ie);
                    }
                }
            }
        }

        throw new RuntimeException("Agent调用失败,已重试" + maxRetries + "次", lastException);
    }

    // 示例使用
    public String reviewWithRetry(String code) {
        SecurityReviewAgent agent = createSecurityAgent();

        return executeWithRetry(
            () -> agent.review(code),
            3,  // 最多重试3次
            Duration.ofSeconds(2)  // 每次间隔2秒
        );
    }

    private SecurityReviewAgent createSecurityAgent() {
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .timeout(Duration.ofSeconds(60))
            .build();
        return AiServices.create(SecurityReviewAgent.class, model);
    }
}

超时控制

import java.util.concurrent.*;

public class TimeoutControlledSystem {

    private final ExecutorService executor = Executors.newCachedThreadPool();

    public String executeWithTimeout(
        Callable<String> agentTask,
        long timeoutSeconds
    ) throws TimeoutException {
        Future<String> future = executor.submit(agentTask);

        try {
            return future.get(timeoutSeconds, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            future.cancel(true);
            throw new TimeoutException("Agent执行超时 (" + timeoutSeconds + "秒)");
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("Agent执行异常", e);
        }
    }

    // 示例:设置30秒超时
    public String reviewWithTimeout(String code) throws TimeoutException {
        SecurityReviewAgent agent = createSecurityAgent();

        return executeWithTimeout(
            () -> agent.review(code),
            30  // 30秒超时
        );
    }

    private SecurityReviewAgent createSecurityAgent() {
        ChatLanguageModel model = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .build();
        return AiServices.create(SecurityReviewAgent.class, model);
    }
}

降级和回退策略

public class FallbackSystem {

    private final SecurityReviewAgent primaryAgent;
    private final SecurityReviewAgent fallbackAgent;

    public FallbackSystem() {
        // 主Agent:使用GPT-4
        ChatLanguageModel primaryModel = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-4")
            .build();
        this.primaryAgent = AiServices.create(SecurityReviewAgent.class, primaryModel);

        // 备用Agent:使用GPT-3.5(更快更便宜)
        ChatLanguageModel fallbackModel = OpenAiChatModel.builder()
            .apiKey(System.getenv("OPENAI_API_KEY"))
            .modelName("gpt-3.5-turbo")
            .build();
        this.fallbackAgent = AiServices.create(SecurityReviewAgent.class, fallbackModel);
    }

    public String reviewWithFallback(String code) {
        try {
            System.out.println("使用主Agent(GPT-4)审查...");
            return primaryAgent.review(code);
        } catch (Exception e) {
            System.err.println("主Agent失败,切换到备用Agent(GPT-3.5): " + e.getMessage());
            return fallbackAgent.review(code);
        }
    }
}

监控和日志

import java.time.Instant;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

record AgentMetrics(
    String agentName,
    int callCount,
    int successCount,
    int failureCount,
    long totalExecutionMs,
    long lastCallTimestamp
) {
    public double successRate() {
        return callCount == 0 ? 0 : (double) successCount / callCount * 100;
    }

    public double avgExecutionMs() {
        return callCount == 0 ? 0 : (double) totalExecutionMs / callCount;
    }
}

public class MonitoringSystem {

    private final Map<String, AgentMetrics> metricsMap = new ConcurrentHashMap<>();

    public <T> T monitoredCall(String agentName, Supplier<T> agentCall) {
        long startTime = System.currentTimeMillis();

        try {
            T result = agentCall.get();
            recordSuccess(agentName, System.currentTimeMillis() - startTime);
            return result;
        } catch (Exception e) {
            recordFailure(agentName, System.currentTimeMillis() - startTime);
            throw e;
        }
    }

    private void recordSuccess(String agentName, long executionMs) {
        metricsMap.compute(agentName, (name, metrics) -> {
            if (metrics == null) {
                return new AgentMetrics(name, 1, 1, 0, executionMs, Instant.now().toEpochMilli());
            } else {
                return new AgentMetrics(
                    name,
                    metrics.callCount() + 1,
                    metrics.successCount() + 1,
                    metrics.failureCount(),
                    metrics.totalExecutionMs() + executionMs,
                    Instant.now().toEpochMilli()
                );
            }
        });
    }

    private void recordFailure(String agentName, long executionMs) {
        metricsMap.compute(agentName, (name, metrics) -> {
            if (metrics == null) {
                return new AgentMetrics(name, 1, 0, 1, executionMs, Instant.now().toEpochMilli());
            } else {
                return new AgentMetrics(
                    name,
                    metrics.callCount() + 1,
                    metrics.successCount(),
                    metrics.failureCount() + 1,
                    metrics.totalExecutionMs() + executionMs,
                    Instant.now().toEpochMilli()
                );
            }
        });
    }

    public void printMetrics() {
        System.out.println("\n=== Agent性能指标 ===");
        metricsMap.forEach((name, metrics) -> {
            System.out.printf("""
                Agent: %s
                  调用次数: %d
                  成功率: %.2f%%
                  平均耗时: %.2fms
                  失败次数: %d
                """,
                name,
                metrics.callCount(),
                metrics.successRate(),
                metrics.avgExecutionMs(),
                metrics.failureCount()
            );
        });
    }
}

📝 练习题

练习1:实现辩论模式Agent

创建一个技术方案评审系统,包含:

  • 正方Agent:论证方案的优势
  • 反方Agent:指出方案的风险和问题
  • 裁判Agent:综合双方观点给出最终决策
// 你的实现
interface ProponentAgent {
    // TODO: 实现正方Agent
}

interface OpponentAgent {
    // TODO: 实现反方Agent
}

interface JudgeAgent {
    // TODO: 实现裁判Agent
}

public class DebateSystem {
    // TODO: 实现辩论流程
    public String evaluateProposal(String proposal) {
        // 1. 正方提出论点
        // 2. 反方提出反驳
        // 3. 正方进行辩护(可选)
        // 4. 裁判做出决策
        return null;
    }
}

练习2:实现带缓存的多Agent系统

为了避免重复调用相同的Agent任务,实现一个缓存机制:

public class CachedMultiAgentSystem {

    private final Map<String, String> cache = new ConcurrentHashMap<>();

    public String reviewWithCache(String code, String agentName) {
        // TODO:
        // 1. 生成缓存key(code的hash + agentName)
        // 2. 检查缓存是否存在
        // 3. 存在则返回缓存结果
        // 4. 不存在则调用Agent并缓存结果
        return null;
    }
}

练习3:实现异步多Agent系统

使用CompletableFuture实现一个完全异步的代码审查系统,要求:

  • 所有Agent调用异步执行
  • 支持流式返回结果(一个Agent完成就立即返回,不等其他)
  • 实现超时和异常处理
public class AsyncReviewSystem {

    public CompletableFuture<ReviewResult> reviewAsync(String code) {
        // TODO: 实现异步审查
        return null;
    }

    public void streamResults(String code, Consumer<String> resultConsumer) {
        // TODO: 每个Agent完成后立即回调resultConsumer
    }
}

🎓 Week 3 总结

恭喜完成第三周的学习!本周我们深入探讨了AI Agent的高级应用:

本周回顾

Day 15: Function Calling

  • 让AI调用真实的Java方法
  • 实现工具的动态选择和组合

Day 16: RAG系统

  • 向量数据库和语义检索
  • 构建知识库问答系统

Day 17: Agent规划和执行

  • ReAct模式的推理和行动
  • 多轮对话的状态管理

Day 18: Agent工具和记忆

  • 工具注册和调用
  • 短期和长期记忆设计

Day 19: 多Agent协作(今天)

  • 四种协作模式
  • Agent间通信机制
  • 生产级系统设计

技术栈总览

Week 1: 基础能力
├── Prompt Engineering
├── 结构化输出
└── 流式处理

Week 2: 高级特性
├── 图像和音频
├── Embedding向量
└── 对话上下文

Week 3: Agent系统 
├── Function Calling
├── RAG检索增强
├── 规划和执行
├── 工具和记忆
└── 多Agent协作

下周预告:Week 4 - 生产实战

  • Day 20: 构建完整的客服Agent系统
  • Day 21: 性能优化和成本控制
  • Day 22: 安全和隐私保护
  • Day 23: 监控、日志和可观测性
  • Day 24: 部署和运维最佳实践

📚 扩展阅读

  1. LangChain4J官方文档

  2. 多Agent系统论文

    • "Communicative Agents for Software Development" (ChatDev)
    • "AutoGen: Enabling Next-Gen LLM Applications"
  3. 开源项目

  4. 设计模式

    • 《设计模式:可复用面向对象软件的基础》
    • 分布式系统的协调模式

✅ 检查清单

完成今天的学习后,你应该能够:

  • 解释多Agent系统相比单Agent的优势
  • 实现协调者模式的多Agent系统
  • 实现流水线模式的Agent编排
  • 设计Agent间的通信机制(消息、共享上下文、事件)
  • 处理Agent意见冲突(投票、优先级、仲裁)
  • 构建生产级的代码审查团队系统
  • 实现异常处理、超时控制和降级策略

下一步:进入Week 4,我们将把所学知识应用到真实的生产场景!


💡 思考题:如果让你设计一个AI驱动的软件开发团队,你会包含哪些Agent?它们如何协作?

🎯 挑战:尝试实现一个"AI代码重构团队",包含分析、重构、测试、文档4个Agent,完成一次完整的代码重构流程。


学习进度: Week 3 Day 19 ✅ | 总进度: 19/30 (63%)

下一篇: 035 - 实战:完整的客服Agent系统