摘要: 随着大型语言模型(LLM)技术的快速发展,单一Agent的能力边界日益显现。多Agent系统通过多个Agent之间的协作与通信,能够解决更复杂的任务。本文系统介绍了多Agent系统的基础概念、协作模式、主流框架及代码实现,并结合软件开发、客服、研究助手等典型场景,帮助读者快速掌握多Agent系统的核心原理与工程实践。
关键词: 多Agent系统、大语言模型、LangGraph、CrewAI、AutoGen、MetaGPT、Agent协作
一、引言
在LLM应用开发的实践中,单一Agent通常只能完成相对独立的任务,如回答问题、生成文本或执行特定工具调用。然而,当面对复杂、跨领域、需要多步骤推理的任务时,单一Agent往往显得力不从心------它可能缺乏足够的专业知识储备,难以同时处理多个子任务,或者在长程任务中出现注意力分散、上下文遗忘等问题。
多Agent系统(Multi-Agent System)应运而生。它通过将任务分解到多个各司其职的Agent,让它们相互协作、信息共享、联合推理,从而突破单一Agent的能力天花板。本文将深入剖析多Agent系统的核心技术,为LLM应用开发者提供从理论到实践的完整指南。
二、多Agent基础
2.1 为什么需要多Agent
在实际业务场景中,复杂任务往往呈现出以下特征:
-
任务异构性:一个任务需要多种专业能力,如软件需求分析需要产品思维,技术方案设计需要架构知识,代码实现需要编程能力。没有任何一个Agent能同时精通所有领域。
-
**规模增长问题:随着任务规模扩大,单一Agent需要维护的上下文急剧膨胀,推理成本指数级上升,输出质量反而下降。
-
可靠性瓶颈:单一Agent一旦出错,整个任务失败。多Agent可以通过交叉验证、容错设计提升系统可靠性。
-
并行处理需求:多个相互独立的子任务可以同时执行,多Agent天然支持并行处理,提升整体效率。
举一个具体例子:用户希望开发一个完整的Web应用。单一Agent很难同时做好产品设计、技术选型、代码编写、测试验证等所有工作,但如果分别由专业的PM Agent、Architect Agent、Coder Agent、Tester Agent协作完成,效果会好得多。
2.2 单Agent vs 多Agent
| 对比维度 | 单Agent | 多Agent |
|---|---|---|
| 任务复杂度 | 简单独立任务 | 复杂多步骤任务 |
| 专业知识 | 依赖单一模型的综合能力 | 各Agent专注特定领域 |
| 容错性 | 单一失败点 | 可通过冗余设计容错 |
| 并行性 | 串行执行 | 支持并行处理 |
| 上下文需求 | 随任务复杂度线性增长 | 可通过Agent分工控制 |
| 系统复杂度 | 低 | 较高 |
| 适用场景 | 问答、摘要、翻译等 | 软件开发、复杂推理、多角色模拟 |
2.3 Agent间通信机制
多Agent系统的核心挑战之一是Agent之间的通信。常见的通信机制包括:
消息传递机制:Agent之间通过显式的消息传递进行通信。每个Agent有自己的收件箱和发件箱,消息可以是结构化的(如JSON)也可以是非结构化的文本。消息传递支持异步通信,Agent不需要同时在线。
共享状态机制:多个Agent访问和修改一个共享的状态存储(如共享内存、黑板系统)。Agent通过读写共享状态来协调行动。这种机制适合需要共享大量中间结果的场景。
广播机制:一个Agent向所有其他Agent广播消息,其他Agent根据自身角色和状态选择性接收。适用于通知类消息。
管道机制:将多个Agent串联成管道,前一个Agent的输出直接作为后一个Agent的输入。适合具有明确先后依赖的流水线任务。
在工程实现中,大多数框架会将上述机制组合使用,以适应不同场景的需求。
三、Agent协作模式
多Agent的协作模式决定了Agent之间如何组织、交互和完成任务。根据不同的业务需求和任务特征,主要有以下三种协作模式。
3.1 层级模式(Hierarchical Model)
层级模式是最常见的协作模式之一。在这种模式中,存在一个协调者(Coordinator) Agent负责统筹全局,其他执行者(Executor) Agent负责具体执行子任务。
工作流程:
-
协调者接收用户请求,进行任务分解
-
协调者将子任务分配给相应的执行者Agent
-
执行者并行或串行执行子任务
-
执行者将结果汇报给协调者
-
协调者汇总结果,形成最终答案
优点 :结构清晰,职责分明,适合大多数有明确任务边界的场景。 缺点:协调者可能成为性能瓶颈,对协调者的规划能力要求较高。
典型应用:软件开发团队、复杂文档处理流水线。
3.2 并行模式(Parallel Model)
并行模式中,多个Agent独立工作,各自处理分配给自己的任务,最后将结果汇总。Agent之间不需要直接通信,独立性很高。
工作流程:
-
主控单元将任务分解为多个独立的子任务
-
多个Agent同时接收任务,同时开始处理
-
各Agent独立完成任务
-
主控单元收集各Agent的结果,进行最终汇总
优点 :天然支持并行执行,效率高,扩展性好。 缺点:适合可分解为独立子任务的场景,Agent间缺乏深度协作。
典型应用:大规模信息检索、多角度内容生成、并行测试验证。
3.3 协作模式(Collaborative Model)
协作模式中,Agent之间通过协商、讨论、甚至投票来共同完成决策。这种模式适合没有唯一正确答案、需要多方权衡的复杂决策场景。
工作流程:
-
任务被提出后,多个相关Agent参与讨论
-
各Agent基于自己的专业视角发表意见
-
Agent之间可能进行多轮讨论和辩论
-
通过某种机制(如投票、共识达成、权威裁定)形成最终决策
优点 :能综合多方观点,决策质量高。 缺点:通信开销大,可能产生分歧难以收敛。
典型应用:战略决策、多角度分析、复杂问题诊断。
四、主流多Agent框架
4.1 LangGraph------状态机工作流
LangGraph是LangChain生态中的核心组件,它将多Agent交互建模为一张有向图(Graph),图中的节点(Node)代表Agent或工具调用,边(Edge)代表状态转换。
核心概念:
-
State:整个图的共享状态,是一个字典结构
-
Node:图中的节点,可以是Agent、工具或任何可调用对象
-
Edge:连接节点的边,定义了状态如何从一个节点流向另一个节点
-
Conditional Edge:条件边,根据当前状态动态决定下一步走向
LangGraph的优势在于其表达能力强,能够清晰地建模复杂的条件分支和循环逻辑。
4.2 CrewAI------角色驱动
CrewAI专注于多Agent的角色协作。它设计了Role(角色) 、Goal(目标) 、**Backstory(背景故事)**等概念,让每个Agent具有鲜明的角色特征。
核心概念:
-
Agent:具有特定角色和目标的智能体
-
Task:具体的任务描述,指定期望的输出格式
-
Crew:一组Agent的集合,以及它们共同执行任务的流程定义
-
Process:Agent之间的协作流程(顺序、并行等)
CrewAI特别适合需要多个专业角色协作的场景,如软件开发团队模拟、商业案例分析等。
4.3 AutoGen------微软开源
AutoGen是微软研究院开源的多Agent框架,核心理念是Agent之间的对话协作。AutoGen支持灵活的Agent定义,允许开发者自定义Agent的角色、能力和交互方式。
核心概念:
-
ConversableAgent:可对话的Agent基类,支持发送和接收消息
-
GroupChat:群聊模式,多个Agent在一个共享空间中讨论
-
Manager:管理器模式,类似层级模式中的协调者
AutoGen的优势在于其对话驱动的设计,特别适合需要Agent之间深度讨论和协商的场景。
4.4 MetaGPT------软件工程场景
MetaGPT是另一个开源的多Agent框架,特别针对软件工程场景进行了优化。它模拟了一个完整的软件开发团队,包括Product Manager、Architect、Developer、Reviewer等多种角色。
核心创新 :MetaGPT引入了**SOP(Standard Operating Procedure,标准操作流程)**的概念,每个角色都遵循预定义的工作流程,确保输出的质量和一致性。
五、协作机制详解
5.1 信息共享
在多Agent系统中,信息共享是协作的基础。常见的信息共享策略包括:
共享内存:所有Agent访问同一个共享存储区域。这种方式简单直接,但需要处理好并发读写的问题。
消息广播:一个Agent产出的信息主动推送给所有相关Agent。推送机制确保了信息的及时性,但需要避免信息过载。
按需获取:Agent只在需要时才向其他Agent请求信息。这种方式节省了带宽,但增加了请求延迟。
上下文注入:将相关信息注入到Agent的上下文中,让Agent"自然而然"地获得必要信息。这种方式对Agent是透明的,但上下文膨胀是需要注意的问题。
5.2 任务分配
任务分配决定了哪个Agent负责哪个子任务。常见的分配策略包括:
静态分配:在系统设计时预先确定任务分配关系。优点是简单确定,缺点是缺乏灵活性。
动态分配:根据当前任务特征和Agent状态动态决定任务分配。需要一个任务分配器或协调者来执行分配逻辑。
能力匹配:根据Agent的专业能力匹配任务。如专门处理数学问题的Math Agent、处理代码的Coder Agent等。
负载均衡:考虑各Agent当前的工作负载,优先分配给负载较轻的Agent,避免部分Agent过载。
5.3 结果汇总
结果汇总将多个Agent的输出整合为最终结果。汇总策略包括:
直接拼接:最简单的策略,将各Agent的输出按顺序拼接。适用于结果之间相互独立的情况。
结构化整合:将各Agent的输出按照预定义的结构模板整合。适合需要形成标准化报告的场景。
交叉验证:当多个Agent处理同一任务时,通过比对结果识别可能的错误,提升可靠性。
智能融合:利用LLM的理解能力,将多个Agent的输出进行语义层面的融合,生成更全面、更准确的综合结果。
5.4 冲突解决
当多个Agent对同一问题给出不同甚至矛盾的结果时,需要冲突解决机制:
权威裁定:预设Agent之间的优先级,高优先级Agent的意见优先。
投票决定:多数Agent的意见作为最终决定。
重新讨论:将有分歧的问题提交给相关Agent重新讨论,直到达成共识。
外部仲裁:将分歧提交给用户或其他外部系统裁定。
六、多Agent应用场景
6.1 软件开发团队
多Agent系统最典型的应用场景之一是模拟软件开发团队。一个典型的角色配置如下:
| 角色 | 职责 | 输入 | 输出 |
|---|---|---|---|
| Product Manager (PM) | 需求分析,转化为产品规范 | 用户原始需求 | PRD文档 |
| Architect | 技术方案设计 | PRD文档 | 技术方案 |
| Coder | 代码实现 | 技术方案 | 代码实现 |
| Reviewer | 代码评审 | 代码实现 | 评审意见 |
| Tester | 测试验证 | 代码+评审意见 | 测试报告 |
这种多Agent协作可以覆盖从需求到上线的完整软件开发流程。
6.2 客服系统
在智能客服场景中,多Agent系统可以提供分级分类的专业服务:
分类Agent:首先对用户问题进行分类,判断问题类型(咨询、投诉、技术支持、退款等)
业务Agent:根据分类结果,由对应的业务Agent处理。如产品咨询由售前Agent处理,技术问题由技术支持Agent处理
升级机制:当业务Agent无法解决问题时,将任务升级到更高级别或人工客服
这种分层设计确保了问题能被高效、准确地处理,提升用户满意度。
6.3 研究助手
多Agent系统也非常适合作为研究助手:
检索Agent:负责在各种信息源中检索相关资料
分析Agent:对检索到的资料进行深度分析,提取关键信息和洞见
写作Agent:将分析结果整理成结构化的研究报告
三个Agent流水线协作,大大提升了研究效率。
6.4 游戏NPC系统
在游戏场景中,多Agent系统可以构建更智能的NPC生态:
对话Agent:负责与玩家进行自然语言对话
决策Agent:根据游戏状态和NPC角色设定做出决策
行为Agent:将决策转化为具体的游戏内行为
多个NPC之间也可以通过多Agent系统进行交互,形成更真实的社会模拟。
七、代码示例
7.1 LangGraph多Agent实现
下面我们使用LangGraph实现一个简单的多Agent系统,包含一个协调者和两个执行Agent(研究Agent和写作Agent)。
# langgraph_multi_agent.py
# 使用LangGraph构建多Agent协作系统
# 依赖安装: pip install langgraph langchain-core langchain-openai
from langgraph.graph import StateGraph, END
from langchain_core.messages import HumanMessage, AIMessage
from typing import TypedDict, Annotated
import operator
# --------------------------------------------------
# 1. 定义共享状态
# --------------------------------------------------
class AgentState(TypedDict):
"""多Agent系统的共享状态"""
messages: list # 对话历史
task: str # 当前任务描述
research_result: str # 研究Agent的结果
writing_result: str # 写作Agent的结果
next_step: str # 下一步操作标识
# --------------------------------------------------
# 2. 定义各Agent的逻辑
# --------------------------------------------------
def researcher_node(state: AgentState) -> AgentState:
"""
研究Agent节点:负责检索和分析相关信息
"""
task = state["task"]
# 模拟研究过程(实际项目中可接入搜索API或知识库)
research_output = f"【研究报告】针对任务「{task}」,已完成以下研究:\n" \
f"1. 相关技术原理分析\n" \
f"2. 行业最佳实践调研\n" \
f"3. 竞品对比分析\n" \
f"研究结论:建议采用XXX方案。"
# 更新状态,追加消息
state["messages"].append(AIMessage(content=f"研究Agent完成:{research_output}"))
state["research_result"] = research_output
state["next_step"] = "write"
print(f"[Researcher] 完成研究任务: {task}")
return state
def writer_node(state: AgentState) -> AgentState:
"""
写作Agent节点:负责将研究成果转化为报告
"""
research = state["research_result"]
task = state["task"]
# 模拟写作过程(实际项目中可调用LLM生成)
writing_output = f"【研究报告】\n\n## 任务:{task}\n\n" \
f"## 研究成果\n{research}\n\n" \
f"## 建议\n基于以上研究,建议采取以下行动方案。"
state["messages"].append(AIMessage(content=f"写作Agent完成报告撰写"))
state["writing_result"] = writing_output
state["next_step"] = "end"
print(f"[Writer] 完成报告撰写")
return state
def coordinator_node(state: AgentState) -> AgentState:
"""
协调者节点:负责任务分解和流程控制
"""
task = state["task"]
# 模拟协调者的规划过程
plan = f"已将任务「{task}」分解为:\n" \
f" Step 1: 研究分析\n" \
f" Step 2: 报告撰写"
state["messages"].append(AIMessage(content=plan))
state["next_step"] = "research"
print(f"[Coordinator] 已规划任务执行流程")
return state
# --------------------------------------------------
# 3. 定义条件路由函数
# --------------------------------------------------
def should_continue(state: AgentState) -> str:
"""
根据当前状态决定下一步走向
返回值必须是图中某个节点的名字
"""
return state.get("next_step", "end")
# --------------------------------------------------
# 4. 构建图并注册节点
# --------------------------------------------------
def build_multi_agent_graph():
"""
构建多Agent协作图
图结构: coordinator -> researcher -> writer -> END
"""
# 创建图构建器
workflow = StateGraph(AgentState)
# 注册节点(节点名: 函数)
workflow.add_node("coordinator", coordinator_node)
workflow.add_node("researcher", researcher_node)
workflow.add_node("writer", writer_node)
# 设置入口点
workflow.set_entry_point("coordinator")
# 添加条件边:根据coordinator的输出决定下一步
workflow.add_conditional_edges(
"coordinator",
should_continue,
{
"research": "researcher", # 如果next_step是research,进入researcher
"end": END # 如果是end,结束
}
)
# researcher完成后进入writer
workflow.add_edge("researcher", "writer")
# writer完成后结束
workflow.add_edge("writer", END)
# 编译图
return workflow.compile()
# --------------------------------------------------
# 5. 执行示例
# --------------------------------------------------
if __name__ == "__main__":
# 初始化图
graph = build_multi_agent_graph()
# 初始状态
initial_state = AgentState(
messages=[HumanMessage(content="请帮我研究并撰写一份关于大语言模型在客服领域应用的分析报告")],
task="大语言模型在客服领域的应用分析",
research_result="",
writing_result="",
next_step=""
)
print("=" * 50)
print("开始执行多Agent协作任务")
print("=" * 50)
# 执行图
final_state = graph.invoke(initial_state)
print("\n" + "=" * 50)
print("任务执行完成")
print("=" * 50)
print("\n【最终报告】")
print(final_state["writing_result"])
运行结果:
==================================================
开始执行多Agent协作任务
==================================================
[Coordinator] 已规划任务执行流程
[Researcher] 完成研究任务: 大语言模型在客服领域的应用分析
[Writer] 完成报告撰写
==================================================
任务执行完成
==================================================
【最终报告】
【研究报告】
## 任务:大语言模型在客服领域的应用分析
## 研究成果
【研究报告】针对任务「大语言模型在客服领域的应用分析」,已完成以下研究:
1. 相关技术原理分析
2. 行业最佳实践调研
3. 竞品对比分析
研究结论:建议采用XXX方案。
## 建议
基于以上研究,建议采取以下行动方案。
7.2 CrewAI角色定义代码
下面使用CrewAI实现一个软件开发团队的多Agent协作:
# crewai_software_team.py
# 使用CrewAI构建软件开发团队
# 依赖安装: pip install crewai crewai-tools
from crewai import Agent, Task, Crew, Process
# --------------------------------------------------
# 1. 定义各角色Agent
# --------------------------------------------------
# 产品经理Agent
pm_agent = Agent(
role="产品经理",
goal="将用户需求转化为清晰、准确的产品需求文档(PRD)",
backstory=(
"你是一名经验丰富的产品经理,拥有10年互联网产品经验,"
"擅长将模糊的用户需求转化为具体的产品功能规格,"
"你对用户体验有敏锐的洞察力,总能从用户角度思考问题。"
),
verbose=True,
allow_delegation=True # 允许将任务委托给其他Agent
)
# 架构师Agent
architect_agent = Agent(
role="技术架构师",
goal="设计高质量、可扩展的技术方案",
backstory=(
"你是一名资深技术架构师,精通微服务架构、云原生设计、"
"数据库设计等核心技术,你有丰富的系统设计经验,"
"能够权衡技术方案的利弊,做出合理的技术决策。"
),
verbose=True,
allow_delegation=False # 架构决策不适合委托
)
# 开发者Agent
coder_agent = Agent(
role="后端开发者",
goal="根据技术方案高质量地完成代码实现",
backstory=(
"你是一名全栈工程师,精通Python、JavaScript等编程语言,"
"擅长编写清晰、可维护的代码,对代码质量有极高要求,"
"熟悉设计模式和最佳实践,能写出生产级别的代码。"
),
verbose=True,
allow_delegation=False
)
# 评审Agent
reviewer_agent = Agent(
role="代码评审员",
goal="发现代码中的问题,提升代码质量和安全性",
backstory=(
"你是一名严谨的代码评审专家,有多年的代码审查经验,"
"你对代码质量、命名规范、安全漏洞有极高的敏感度,"
"你善于发现问题并提出建设性的改进建议。"
),
verbose=True,
allow_delegation=False
)
# --------------------------------------------------
# 2. 定义各阶段任务
# --------------------------------------------------
# 任务1:需求分析
prd_task = Task(
description=(
"用户需求:开发一个在线文档协作平台,支持多人实时编辑、"
"评论、版本管理和权限控制。请撰写一份完整的产品需求文档,"
"包含功能清单、用户故事、非功能性需求等。"
),
agent=pm_agent,
expected_output="一份完整的产品需求文档(PRD),包含功能列表、优先级、用户流程图"
)
# 任务2:技术方案设计
architecture_task = Task(
description=(
"基于产品需求文档,设计一个在线文档协作平台的技术架构方案,"
"包括技术栈选型、系统架构图、数据库设计、API设计等。"
),
agent=architect_agent,
expected_output="一份详细的技术设计方案文档,包含架构图和API规范",
context=[prd_task] # 依赖前一个任务的输出
)
# 任务3:代码实现
coding_task = Task(
description=(
"根据技术方案,使用Python实现一个简单的文档协作后端服务,"
"包括文档创建、读取、更新、删除(CRUD)功能,"
"使用Flask框架,实现基础的REST API。"
),
agent=coder_agent,
expected_output="可运行的Python代码,包含Flask REST API实现",
context=[architecture_task]
)
# 任务4:代码评审
review_task = Task(
description=(
"对开发者提交的代码进行评审,重点关注:"
"1. 代码规范和可读性"
"2. 潜在的安全风险"
"3. 错误处理是否完善"
"4. 是否有改进空间"
"请给出具体的改进建议。"
),
agent=reviewer_agent,
expected_output="详细的代码评审报告,包含问题列表和改进建议",
context=[coding_task]
)
# --------------------------------------------------
# 3. 创建团队并执行
# --------------------------------------------------
# 创建团队,设定协作流程为顺序执行
software_crew = Crew(
agents=[pm_agent, architect_agent, coder_agent, reviewer_agent],
tasks=[prd_task, architecture_task, coding_task, review_task],
process=Process.sequential, # 顺序执行,确保依赖关系
verbose=True
)
# 启动团队协作
if __name__ == "__main__":
print("=" * 60)
print("软件开发团队开始协作")
print("=" * 60)
result = software_crew.kickoff()
print("\n" + "=" * 60)
print("团队协作完成,最终成果:")
print("=" * 60)
print(result)
7.3 Agent间通信示例
下面实现一个更底层的Agent间通信示例,展示消息传递、状态共享和结果汇总的机制:
# agent_communication.py
# 展示Agent间通信机制:消息传递、状态共享、结果汇总
# 依赖安装: pip install langchain-openai
import json
from datetime import datetime
from typing import Any
from collections import defaultdict
# --------------------------------------------------
# 1. 消息类定义
# --------------------------------------------------
class Message:
"""Agent之间传递的消息"""
def __init__(self, sender: str, receiver: str, content: Any, msg_type: str = "text"):
self.sender = sender # 发送者
self.receiver = receiver # 接收者,"* "表示广播
self.content = content # 消息内容
self.msg_type = msg_type # 消息类型:text/task/result/query
self.timestamp = datetime.now().isoformat()
def to_dict(self):
return {
"sender": self.sender,
"receiver": self.receiver,
"content": self.content,
"type": self.msg_type,
"timestamp": self.timestamp
}
def __repr__(self):
return f"[{self.timestamp}] {self.sender} -> {self.receiver}: {self.content[:50]}..."
# --------------------------------------------------
# 2. 共享状态存储
# --------------------------------------------------
class SharedState:
"""
多Agent共享状态存储
支持读写权限控制和变更通知
"""
def __init__(self):
self._state = defaultdict(dict)
self._versions = defaultdict(int) # 追踪版本变化
def set(self, key: str, value: Any, owner: str = "system"):
"""设置状态值"""
self._state[key] = {
"value": value,
"owner": owner,
"version": self._versions[key] + 1
}
self._versions[key] += 1
def get(self, key: str) -> Any:
"""获取状态值"""
return self._state.get(key, {}).get("value")
def get_with_meta(self, key: str) -> dict:
"""获取状态值及元信息"""
return self._state.get(key, {})
def get_all(self):
"""获取所有状态"""
return {k: v["value"] for k, v in self._state.items()}
# --------------------------------------------------
# 3. Agent基类
# --------------------------------------------------
class BaseAgent:
"""所有Agent的基类"""
def __init__(self, name: str, shared_state: SharedState):
self.name = name
self.shared_state = shared_state
self.inbox: list[Message] = [] # 收件箱
self.outbox: list[Message] = [] # 发件箱
def send_message(self, receiver: str, content: Any, msg_type: str = "text"):
"""发送消息"""
msg = Message(sender=self.name, receiver=receiver, content=content, msg_type=msg_type)
self.outbox.append(msg)
print(f" [📤 {self.name}] -> {receiver}: {msg_type} - {str(content)[:50]}...")
return msg
def receive_message(self, message: Message):
"""接收消息"""
self.inbox.append(message)
print(f" [📥 {self.name}] <- {message.sender}: {message.content[:50]}...")
def update_state(self, key: str, value: Any):
"""更新共享状态"""
self.shared_state.set(key, value, owner=self.name)
def read_state(self, key: str) -> Any:
"""读取共享状态"""
return self.shared_state.get(key)
def process(self):
"""处理消息,子类实现具体逻辑"""
raise NotImplementedError
# --------------------------------------------------
# 4. 具体Agent实现
# --------------------------------------------------
class ClassifierAgent(BaseAgent):
"""分类Agent:分析用户问题并分类"""
CATEGORIES = ["技术咨询", "售后支持", "投诉建议", "业务合作"]
def process(self, user_input: str) -> str:
print(f"\n[{self.name}] 开始分类任务...")
# 模拟分类逻辑(实际项目中调用LLM)
if "怎么" in user_input or "如何" in user_input:
category = "技术咨询"
elif "没用" in user_input or "差" in user_input:
category = "投诉建议"
elif "合作" in user_input or "商务" in user_input:
category = "业务合作"
else:
category = "售后支持"
# 将分类结果写入共享状态
self.update_state("last_category", category)
self.update_state("last_query", user_input)
# 通知其他Agent
self.send_message("router", {"category": category}, msg_type="result")
return category
class RouterAgent(BaseAgent):
"""路由Agent:接收分类结果,决定分发策略"""
def process(self):
print(f"\n[{self.name}] 等待分类结果...")
# 从收件箱中获取分类结果
category_msgs = [m for m in self.inbox if m.msg_type == "result"]
if not category_msgs:
print(f" [{self.name}] 未收到分类结果,等待中...")
return None
latest_msg = category_msgs[-1]
category = latest_msg.content["category"]
print(f" [{self.name}] 收到分类结果: {category}")
# 根据类别决定分发目标
routing = {
"技术咨询": "tech_agent",
"售后支持": "support_agent",
"投诉建议": "feedback_agent",
"业务合作": "biz_agent"
}
target = routing.get(category, "support_agent")
# 分发任务
query = self.read_state("last_query")
self.send_message(target, {"query": query, "category": category}, msg_type="task")
return target
class TechAgent(BaseAgent):
"""技术支持Agent"""
def process(self):
print(f"\n[{self.name}] 处理技术支持请求...")
task_msgs = [m for m in self.inbox if m.msg_type == "task"]
if not task_msgs:
return
task = task_msgs[-1].content
query = task["query"]
# 模拟技术解答
response = f"针对您的问题「{query}」," \
f"这是技术支持部门的专业解答:我们建议您先检查网络连接," \
f"然后查阅官方文档的第3.2节,如果问题仍未解决,请联系技术支持热线。"
# 将结果写入共享状态
self.update_state("tech_response", response)
# 返回给用户
self.send_message("summarizer", {"response": response}, msg_type="result")
class SupportAgent(BaseAgent):
"""售后支持Agent"""
def process(self):
print(f"\n[{self.name}] 处理售后支持请求...")
task_msgs = [m for m in self.inbox if m.msg_type == "task"]
if not task_msgs:
return
task = task_msgs[-1].content
query = task["query"]
response = f"感谢您的反馈!针对「{query}」," \
f"我们的售后团队将尽快跟进,通常会在24小时内与您联系。"
self.update_state("support_response", response)
self.send_message("summarizer", {"response": response}, msg_type="result")
class FeedbackAgent(BaseAgent):
"""投诉建议Agent"""
def process(self):
print(f"\n[{self.name}] 处理投诉建议...")
task_msgs = [m for m in self.inbox if m.msg_type == "task"]
if not task_msgs:
return
task = task_msgs[-1].content
query = task["query"]
response = f"非常抱歉给您带来不便!我们高度重视您的反馈「{query}」," \
f"已将问题转交相关部门处理,并将持续跟进直至解决。"
self.update_state("feedback_response", response)
self.send_message("summarizer", {"response": response}, msg_type="result")
class BizAgent(BaseAgent):
"""商务合作Agent"""
def process(self):
print(f"\n[{self.name}] 处理商务合作咨询...")
task_msgs = [m for m in self.inbox if m.msg_type == "task"]
if not task_msgs:
return
task = task_msgs[-1].content
query = task["query"]
response = f"感谢您的商务合作意向!我们将安排专人针对「{query}」与您沟通," \
f"请留下联系方式或发送邮件至 business@example.com。"
self.update_state("biz_response", response)
self.send_message("summarizer", {"response": response}, msg_type="result")
class SummarizerAgent(BaseAgent):
"""汇总Agent:收集所有Agent的响应,生成最终答案"""
def process(self):
print(f"\n[{self.name}] 汇总各Agent响应...")
result_msgs = [m for m in self.inbox if m.msg_type == "result"]
if not result_msgs:
print(f" [{self.name}] 未收到任何响应")
return None
# 收集所有响应
responses = [msg.content["response"] for msg in result_msgs]
# 生成最终回复
final_response = "\n\n".join(responses)
print(f"\n{'='*60}")
print("【最终回复】")
print(f"{'='*60}")
print(final_response)
return final_response
# --------------------------------------------------
# 5. 模拟运行
# --------------------------------------------------
def simulate_message_delivery(from_agent: BaseAgent, to_agent: BaseAgent, message: Message):
"""模拟消息传递(实际系统中通过消息队列实现)"""
to_agent.receive_message(message)
def run_simulation():
"""运行多Agent通信模拟"""
print("=" * 60)
print("多Agent通信系统模拟")
print("=" * 60)
# 初始化共享状态
shared_state = SharedState()
# 创建所有Agent
classifier = ClassifierAgent("Classifier", shared_state)
router = RouterAgent("Router", shared_state)
tech_agent = TechAgent("TechAgent", shared_state)
support_agent = SupportAgent("SupportAgent", shared_state)
feedback_agent = FeedbackAgent("FeedbackAgent", shared_state)
biz_agent = BizAgent("BizAgent", shared_state)
summarizer = SummarizerAgent("Summarizer", shared_state)
agents = {
"Classifier": classifier,
"Router": router,
"TechAgent": tech_agent,
"SupportAgent": support_agent,
"FeedbackAgent": feedback_agent,
"BizAgent": biz_agent,
"Summarizer": summarizer
}
# 用户输入
user_query = "这个软件怎么导出PDF文件?"
print(f"\n【用户输入】: {user_query}\n")
# Step 1: Classifier分类
classifier.process(user_query)
# 模拟消息传递:Classifier -> Router
if classifier.outbox:
simulate_message_delivery(classifier, router, classifier.outbox[-1])
# Step 2: Router路由
target = router.process()
# Step 3: 分发的Agent处理
if target and target in agents:
# 模拟消息传递:Router -> Target Agent
if router.outbox:
simulate_message_delivery(router, agents[target], router.outbox[-1])
# 目标Agent处理
agents[target].process()
# 模拟消息传递:Target Agent -> Summarizer
if agents[target].outbox:
simulate_message_delivery(agents[target], summarizer, agents[target].outbox[-1])
# Step 4: Summarizer汇总
summarizer.process()
# 打印共享状态
print(f"\n{'='*60}")
print("【共享状态】")
print(f"{'='*60}")
for key, value in shared_state.get_all().items():
print(f" {key}: {value[:50]}...")
if __name__ == "__main__":
run_simulation()
运行结果:
============================================================
多Agent通信系统模拟
============================================================
【用户输入】: 这个软件怎么导出PDF文件?
[Classifier] 开始分类任务...
[📤 Classifier] -> router: result - {'category': '技术咨询'}...
[📥 Router] <- Classifier: result - {'category': '技术咨询'}...
[Router] 等待分类结果...
[📥 Router] 收到分类结果: 技术咨询
[📤 Router] -> TechAgent: task - {'query': '这个软件怎么导出...', ...
[TechAgent] 处理技术支持请求...
[📥 TechAgent] <- Router: task - {'query': '这个软件怎么导出...', ...
[📤 TechAgent] -> Summarizer: result - 针对您的问题「这个软件...
[Summarizer] 汇总各Agent响应...
============================================================
【最终回复】
============================================================
针对您的问题「这个软件怎么导出PDF文件?」,这是技术支持部门的专业解答:我们建议您先检查网络连接,然后查阅官方文档的第3.2节,如果问题仍未解决,请联系技术支持热线。
============================================================
【共享状态】
============================================================
last_category: 技术咨询
last_query: 这个软件怎么导出PDF文件?
tech_response: 针对您的问题「这个软件怎么导出PDF文件?」...
八、总结与展望
多Agent系统代表了LLM应用开发的重要方向。通过将复杂任务分解为多个专业子任务,由不同的Agent分工协作,可以突破单一Agent的能力边界,实现更复杂、更可靠的LLM应用。
核心要点回顾:
-
为什么需要多Agent:复杂任务需要多种专业能力,单一Agent难以胜任
-
协作模式:层级模式适合有明确分工的场景,并行模式适合可独立执行的子任务,协作模式适合需要多方协商的决策场景
-
主流框架:LangGraph适合复杂状态机工作流,CrewAI适合角色驱动的协作,AutoGen适合对话驱动的交互,MetaGPT适合软件工程场景
-
协作机制:信息共享、任务分配、结果汇总、冲突解决是多Agent系统落地的关键技术点
-
应用场景:软件开发、客服系统、研究助手、游戏NPC等领域都有广阔的应用前景
未来展望:随着LLM能力的不断提升和Agent技术的成熟,多Agent系统将在更多领域发挥重要作用。Agent之间的自主协作、动态组队、自我学习等高级能力,将是未来研究的重要方向。