在现代软件开发中,复杂任务往往需要多个专家协同完成。同样,AI Agent也可以通过团队协作来解决更复杂的问题。本文将深入探讨如何构建多Agent系统,让AI"团队"高效协作。
时间:45分钟 | 难度:⭐⭐⭐⭐ | Week 3 Day 19
📋 学习目标
- 理解多Agent系统的核心价值和应用场景
- 掌握四种主流的Agent协作模式
- 实现协调者模式和流水线模式
- 设计Agent间通信和状态共享机制
- 处理多Agent系统中的冲突和一致性问题
- 构建生产级的多Agent代码审查系统
🚀 快速入门:为什么需要多Agent?
单Agent的局限性
单个Agent面临的挑战:
- 知识边界:一个Agent难以精通所有领域
- 上下文限制:Token限制导致无法处理超大规模任务
- 复杂度爆炸:单一系统提示词变得臃肿难以维护
- 推理深度:某些问题需要多角度分析和验证
多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 A → B → 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 ←┘
(辩论模式)
↓
最终代码
组合原则:
- 顶层用协调者 — 统一入口和调度
- 有序步骤用流水线 — 代码生成的设计→编码→优化
- 质量把关用辩论 — Code Review 阶段
- 创意探索用群聊 — 早期需求讨论(可选)
选型决策树
你的任务是什么?
│
├─ 能拆分成独立子任务?
│ ├─ 是 → 子任务之间有顺序依赖?
│ │ ├─ 是 → 📋 流水线模式
│ │ └─ 否 → 🎯 协调者模式
│ └─ 否 → 需要提高决策质量/准确性?
│ ├─ 是 → ⚖️ 辩论模式
│ └─ 否 → 问题是否开放/探索性?
│ ├─ 是 → 💬 群聊模式
│ └─ 否 → 🎯 协调者模式(默认)
│
└─ 性能/成本敏感?
├─ 是 → 📋 流水线 或 🎯 协调者
└─ 否 → ⚖️ 辩论 或 💬 群聊
[!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: 部署和运维最佳实践
📚 扩展阅读
-
LangChain4J官方文档
-
多Agent系统论文
- "Communicative Agents for Software Development" (ChatDev)
- "AutoGen: Enabling Next-Gen LLM Applications"
-
开源项目
-
设计模式
- 《设计模式:可复用面向对象软件的基础》
- 分布式系统的协调模式
✅ 检查清单
完成今天的学习后,你应该能够:
- 解释多Agent系统相比单Agent的优势
- 实现协调者模式的多Agent系统
- 实现流水线模式的Agent编排
- 设计Agent间的通信机制(消息、共享上下文、事件)
- 处理Agent意见冲突(投票、优先级、仲裁)
- 构建生产级的代码审查团队系统
- 实现异常处理、超时控制和降级策略
下一步:进入Week 4,我们将把所学知识应用到真实的生产场景!
💡 思考题:如果让你设计一个AI驱动的软件开发团队,你会包含哪些Agent?它们如何协作?
🎯 挑战:尝试实现一个"AI代码重构团队",包含分析、重构、测试、文档4个Agent,完成一次完整的代码重构流程。
学习进度: Week 3 Day 19 ✅ | 总进度: 19/30 (63%)