简介:本书是第18届国际多智能体系统大会(PRIMA 2015)的会议论文集,由Springer出版,面向人工智能、分布式计算及多智能体系统方向的研究人员和从业者。内容精选大会论文,涵盖智能体理论、系统工程与跨学科应用,围绕基于信任的协同评估、社会规范演化、实时承诺逻辑、基于论证的决策机制等前沿主题,系统展示多智能体系统在协作、安全与智能化方向的最新进展。资源为1个PDF电子书文件,压缩包体积44.8MB,便于阅读、检索与标注。读者既可从中获取形式化建模与算法设计的理论支撑,也能通过供应链管理、智能交通、网络安全等实际案例理解多智能体系统的落地路径,书中由多位国际学者分章撰写,章节组织清晰,适合用于科研入门或技术进阶。目前已有95人学习下载,适合作为人工智能与分布式计算领域的系统性参考读物。 这两年如果只让我选一个值得花时间跟进的AI方向,我会选多智能体系统,而不是继续单线程地堆提示词。原因很简单:单个大模型的能力边界越来越明显,而多个模型、多个角色之间通过分工、校验、迭代,能做出一个模型怎么调都调不出来的稳定结果。这篇就围绕“原理”和“实践”两条线展开,讲清楚多智能体系统的设计逻辑,再带你把一个能跑的流程从零搭起来。无论你是做AI应用开发、自动化流程设计,还是只想搞清楚多Agent到底怎么落地,这篇都应该能给你省不少弯路。
1. 先理解多智能体:核心概念与适用边界
1.1 多智能体到底是什么,和单Agent、自动化工作流有什么区别
多智能体系统并不是什么新概念,早在分布式人工智能里就有讨论,核心思想是把一个复杂任务拆成若干子任务,由多个相对独立的智能体(Agent)分别负责,再通过某种机制让它们协同、竞争、互相校验,最后拼装出整体结果。放到今天的大模型语境下,一个“智能体”就是一段被赋予了角色、目标和工具的代码,它背后可以是大模型,也可以是规则引擎,甚至是一个普通API调用。
和传统的自动化工作流相比,多智能体系统的区别在于“决策和反馈”是动态的。传统工作流更像流水线:A步骤输出固定格式,B步骤直接消费,中间几乎不需要判断。多智能体系统则更像一个团队:Research Agent发现手头数据不足,可以直接去调搜索工具,也可以把请求抛给另一个Agent;Critic Agent觉得产出质量不够时,不是简单丢弃,而是返回修改意见,让Draft Agent带着建议重新输出。
这些“反馈”会让整个流程产生循环和条件跳转。也正是因为这个原因,多智能体系统的设计和调试难度比传统工作流高了一个台阶。做得好,它能稳定产出高质量结果;做不好,它就会陷入无限循环、上下文污染、结果漂移,最后花了几倍的token成本,换来一个比单Agent还差的结果。
1.2 哪些场景真的适合多智能体,哪些只是伪需求
不是所有任务都需要上多智能体。我在实际项目里总结过:判断标准不是“这个任务很复杂”,而是“这个任务是否需要多个视角、多轮校验,或者是否可以并行拆解”。
适合上多智能体的场景,我梳理下来有三类。第一类是研究分析型任务,比如行业报告、竞品分析、技术调研,需要有人专门收集资料,有人专门做数据分析,有人专门把关数据引用是否可靠,最后才轮到撰写人员动笔。第二类是代码工程型任务,比如编写一个完整的模块,需要工程师角色写代码、测试角色写单测、审查角色检查潜在缺陷,三个角色循环协作。第三类是内容生产型任务,比如写一篇长文、做一个策划案,需要策划、写作、编辑、校对多个角色参与。这些任务的共同点是:单个Agent很难同时兼顾“发散创意”和“严谨审查”这两项需求,因为发散和收敛往往需要相反的参数设置和提示词风格。
反过来说,如果你只是想把一句话转成好看的文案,或者做一个简单的信息抽取,直接写一个Agent就够了。硬上多智能体,不仅推理成本翻倍,还会因为角色间来回传递信息导致响应时间明显变长,体验反而不如单Agent来得干脆。
2. 多智能体系统的设计要点:角色、通信与协作
2.1 角色拆分:不是越多越好,要按职责边界来
我刚接触多智能体时吃过一次亏。当时为了做一款写作辅助工具,一口气设计了六个角色:项目经理、产品经理、行业分析师、内容策划、初稿编辑、终审校对。听起来很完善,结果跑起来之后发现,有些角色的输出高度重叠,而且角色越多,上下文里堆积的中间产物越多,最后模型在“角色身份”之间反复横跳,生成质量比单Agent还差。
后来我戒掉了堆角色的毛病,遵循三个原则:角色间任务不重叠、每个角色都有独立产出物、每个角色最好都有独立的工具或数据来源。一个典型的精简团队是这样的:
| 角色 | 核心职责 | 常见工具 | 输出产物 |
|---|---|---|---|
| Planner | 拆解任务、制定执行计划 | 无,或简单检索 | 任务拆解清单 |
| Worker | 负责具体的内容生成或数据处理 | RAG、搜索 API、代码执行器 | 半成品内容 |
| Critic | 校验质量、检查错误、给出修改建议 | 代码检查工具、打分模型 | 修改意见或通过指令 |
| Editor | 整合结果、统一风格、输出终稿 | 格式化工具、写作模板 | 最终交付内容 |
这套结构对应的是“规划-执行-校验-整合”的经典闭环,也是目前社区里最常用的组织方式。角色并非越多越好,控制在三五个以内,每个角色都有明确的输入输出,系统才容易收敛。
2.2 通信与信息共享:消息传递、黑板模式,还是共享状态
多智能体的通信方式直接决定了系统的复杂度。常见的模式有三种:消息传递、黑板模式、共享状态。
消息传递要求Agent之间互相发信息,优点是比较灵活,缺点是Agent之间耦合度高,排查问题时需要追踪消息链路。黑板模式则更像一块公共白板,所有Agent都可以往上面写内容、从上面读内容,好处是解耦,缺点是需要严格定义白板的数据结构,否则容易出现“有人写的是JSON,有人读的是文本”这类低级错误。
在实践里,我推荐用共享状态的方式,这也是LangGraph这类编排框架默认的思路。把整个任务进度、中间结果、评审意见全部放到一个全局状态对象里,每个Agent只负责读取自己需要的字段、写入自己负责的字段。这样既避免了消息传递的复杂链路,又比黑板模式更容易控制数据格式。后续你想做断点续跑、异常回滚,也都更简单。
2.3 任务规划与仲裁机制:集中式、分布式,还是投票
任务规划解决的是“谁来决定下一步做什么”的问题。集中式规划是指由一个Planner Agent统一拆解任务、分配子任务,其他Agent只被动执行;分布式规划则允许各个Agent根据自身状态自主提出下一步行动,适合高度动态的场景;投票机制更多用在需要多角色共识的场景,比如多个审查Agent对同一份产出投票,少数服从多数。
对大多数项目,我建议先做集中式规划。原因不复杂:集中式更可控,也更容易维护。你可以先把任务拆解规则、执行顺序都写清楚,等跑通之后再去调整规划策略。投票机制是一个看起来很美好、实际很容易出问题的方案,因为LLM的投票结果可能随温度参数波动,同一份内容换个随机种子就可能得到完全相反的结论。如果真要用投票,尽量让投出来的票不仅包含“通过/不通过”,还要带上理由,方便后续人工回溯。
3. 实操:用 LangGraph 搭一个可用的多智能体工作流
3.1 技术选型:为什么选 LangGraph,而不是 AutoGen 或 CrewAI
现在市面上的框架不少,AutoGen、CrewAI、LangGraph、MetaGPT都有一批用户。我实际对比下来的感受是:AutoGen上手快,但调度逻辑藏在框架内部,出了问题不太好查;CrewAI的封装程度高,适合快速验证原型,但当你需要精细控制流程时会感觉被框架限制;LangGraph上手成本稍高,但它把状态、节点、边都显式暴露出来,特别适合需要自定义流程和多轮评审的复杂场景。
我最终选择LangGraph的原因有三点:第一,它的状态管理机制清晰,所有信息都集中在State对象里,调试体验好;第二,它天然支持条件路由,实现“Critic不通过就重新生成”这类循环逻辑非常方便;第三,它底层对调用过程的记录比较完整,方便做成本追踪。如果你只是做个Demo验证想法,用CrewAI会更省事;如果你想把系统做成一个长期维护的产品,LangGraph更稳妥。
3.2 定义状态、角色节点与工具函数
下面这个例子是我做“行业研究报告生成器”时的简化版本。先定义全局状态:
from typing import TypedDict, Annotated, List import operator class ReportState(TypedDict): topic: str research_data: str draft: str review_feedback: str final_report: str retry_count: int这里的关键字段分别是顶层任务主题、研究报告、草稿、评审意见、终稿和重试计数。重试计数的存在很重要,它是防止循环失控的第一道保险。
接下来定义核心节点函数。Research Agent负责搜索和整理资料:
def research_agent(state: ReportState) -> dict: topic = state["topic"] # 这里建议接入真实的搜索API或RAG检索,不要只靠模型生成 search_result = search_engine.search(topic, top_k=5) prompt = f""" 你是一名行业研究员。请基于以下检索结果,提炼出与任务相关的核心事实,并标注数据来源。 任务主题:{topic} 检索结果:{search_result} 请输出结构化的Markdown文本,控制在800字以内。 """ response = llm.invoke(prompt, temperature=0.2) return {"research_data": response.content}这里我特别控制了两个细节:一是temperature设置为0.2,因为研究阶段需要事实性输出,温度太高容易编造数据;二是明确要求“标注数据来源”,这是为了让后续Critic Agent能够核对引用。Draft Agent负责基于研究资料写初稿:
def draft_agent(state: ReportState) -> dict: research_data = state["research_data"] topic = state["topic"] prompt = f""" 你是一名行业分析师,请基于提供的调研资料撰写一份结构清晰的分析报告初稿。 报告主题:{topic} 参考资料:{research_data} 要求: 1. 结构完整,包含背景、现状分析、趋势判断和结论。 2. 引用资料数据时用括号标注来源。 3. 初稿长度控制在2000字左右。 """ response = llm.invoke(prompt, temperature=0.4) return {"draft": response.content}Draft Agent的temperature稍微高一点,给它一点语言组织和观点提炼的空间。Critic Agent是整个系统的守门人:
def critic_agent(state: ReportState) -> dict: draft = state["draft"] prompt = f""" 你是一名严格的报告审核编辑。请检查以下报告初稿,重点关注: 1. 是否有明确的数据来源和引用标记。 2. 结构是否完整、论点是否有支撑。 3. 是否存在前后矛盾或明显事实错误。 4. 文风是否专业、无口语化表述。 初稿如下: {draft} 如果内容达标,请仅回复:PASS 如果不达标,请指出具体问题和修改建议,控制在200字以内。 """ response = llm.invoke(prompt, temperature=0.1) feedback = response.content.strip() if feedback.upper().startswith("PASS"): return {"review_feedback": "PASS"} return {"review_feedback": feedback}Critic Agent的温度设为0.1,原因是评审环节要尽量稳定和保守。最后还需要一个终稿节点:
def finalize_agent(state: ReportState) -> dict: topic = state["topic"] draft = state["draft"] feedback = state["review_feedback"] prompt = f""" 你是主编。请根据评审意见对初稿进行修改,形成最终交付版本。 意见:{feedback} 原稿:{draft} 要求:不改变原有结构的前提下,逐条处理意见。输出完整终稿。 """ response = llm.invoke(prompt, temperature=0.2) return {"final_report": response.content}3.3 编排流程:执行顺序、条件路由与循环控制
节点函数定义好之后,关键就是把它们串起来。LangGraph里,用StateGraph来定义流程:
from langgraph.graph import StateGraph, END def should_revise(state: ReportState) -> str: if state["retry_count"] >= 2: return "accept" if state["review_feedback"] == "PASS": return "accept" return "revise" graph = StateGraph(ReportState) graph.add_node("research", research_agent) graph.add_node("draft", draft_agent) graph.add_node("critic", critic_agent) graph.add_node("finalize", finalize_agent) graph.set_entry_point("research") graph.add_edge("research", "draft") graph.add_edge("draft", "critic") graph.add_conditional_edges( "critic", should_revise, {"revise": "draft", "accept": "finalize"} ) graph.add_edge("finalize", END)这里的核心逻辑在should_revise函数里。可以看到,我设置了两个出口条件:一是评审通过,二是重试次数达到上限。为什么要设置重试上限?因为在真实运行中,Critic Agent的评审意见可能前后不一致,尤其是上次说“缺少数据支撑”,这次只说“字数不够”,很可能会让Draft Agent改了一个版本之后又被另一个新问题挡回来,这会变成无意义的死循环。
把编译后的图跑起来也很简单:
app = graph.compile() result = app.invoke({"topic": "新能源汽车行业2025年趋势分析", "retry_count": 0}) print(result["final_report"])运行过程中,LangGraph会把每个节点的输入、输出、耗时都记录下来,你可以非常清楚地看到哪一步花了最多时间、哪个节点在反复执行。
3.4 核心参数调整与效果对比
在多智能体系统里,参数调整不是只调“temperature”那么简单。从我自己的实验经验来看,四个参数最值得关注。
第一个是各Agent的温度。前面已经提到,研究同学和评审同学的温度要低,撰稿温度可以稍高。第二个是模型选型。如果你用的是同一个模型作为所有Agent,成本还好;但如果是不同模型,就要注意,弱模型当Critic可能看不出问题,当Worker又可能产出质量不足。第三个是输出长度限制。很多问题其实是其中一个Agent生成了超长文本,导致后续Agent的输入超出上下文窗口或注意力涣散。第四个是重试次数。重试次数太少,质量不够;太多,成本和延迟都兜不住。
我这个小规模跑过一次对比实验:用同一个模型,同样的任务,只调整Critic的温度。当Critic的温度是0.7时,平均每篇报告要跑4次评审流程,因为评审意见不断变化;当温度降到0.1时,平均2轮就能通过,且终稿评分反而更高。这说明一个规律:多智能体里,稳定性的优先级要高于创造性。
4. 实战中的常见问题和排查经验
4.1 上下文污染与任务漂移
上下文污染是排查中遇到最多的问题。典型场景是:Research Agent输出的资料里混入了一些结论性表述,Draft Agent直接把它当成既定事实写进了正文,Critic Agent又没能识别出来,最后整篇报告带着错误信息交付。
解决思路有两个。第一个是结构收敛,在Prompt里强制要求每个Agent只输出自己职责范围内的内容,比如让Research Agent输出“事实+来源”,不输出“建议”。第二个是状态隔离,不要让所有信息都堆在同一个状态字段里,可以把“研究资料”“草稿”“评审意见”放到不同字段,每个Agent只读取与自己相关的字段。这不只是逻辑上的整洁,更多是防止大模型在长上下文中混淆信息边界。
4.2 死循环与收敛控制
死循环在多智能体里太常见了。Critic Agent的反馈过于苛刻,Draft Agent修改后反而引入了新问题,Critic又挑出新毛病,如此循环。你盯着日志看,能明显看到同一个节点在执行第五遍、第六遍,成本也在飞速上涨。
处理死循环,我的经验是分级控制。首先在路由逻辑上设最大迭代次数,这是硬性兜底。其次在评审Prompt里加一条规则:每次提出问题时,顺手评估“这个问题是否阻碍核心结论产出”。如果只是措辞不够好这类主观问题,Critic应该直接打PASS,而不是追求一份“完美得无可挑剔”的报告。最后,还可以在每次进入修改节点前,让系统自动对比当前草稿和上一版草稿的差异,如果修改幅度特别小,就视为收敛并强制结束。
4.3 多模型成本与响应时间优化
多智能体系统最大的代价就是成本,因为每一条边、每一次循环都意味着一次模型调用。我用过一套组合拳:核心生成和评审用较强的模型,检索总结和格式整理用较弱的模型;同时把检索结果缓存起来,相同主题不要反复去搜;另外还可以把多次循环的上下文做摘要压缩,而不是把每一轮完整的报告都塞给Critic。
响应时间也一样。如果某个环节需要串行等待,可以检查是否真的存在依赖关系。比如Research Agent做完之后可以先让后台存储结果,不需要马上让Draft Agent消费。还有就是要警惕“非必要的多Agent串行”,比如Format Agent和Critic Agent之间没有依赖就硬排成串行,白白增加一轮延迟。
4.4 一些平时文档里不会写的细节
说几个容易踩的小坑。第一个,Prompt里的角色名要和状态字段名严格一致,不然排查起来特别痛苦。第二个,尽量让Critic只输出结构化结果,比如要么输出PASS,要么输出“问题列表+修改建议”,不要让它自由发挥,否则你还要再花一次调用去解析。第三个,异常处理一定要做好,因为外部搜索工具或者API随时可能超时,如果某个Agent节点抛异常,整个图就会卡住。第四个小技巧是给每个Agent的产出加“元字段”,比如生成时间、来源数据版本、token消耗量,方便后续追踪。
这些细节看起来不起眼,但在系统出问题时,它们能帮你节省大量排障时间。
做多智能体系统,最核心的体会是:它的难度不在于把几个大模型拼在一起,而在于如何设计好角色边界、通信方式和收敛机制。一个只有三个Agent的简单系统,如果角色设计得好,效果可能好过一个六角色的大杂烩。如果你正准备上手,我建议从最小闭环开始,先拿两个角色跑通流程,再逐步加入Critic和Editor。这样既不会一开始就被复杂度带偏,也能在迭代中对每个环节的预期效果有更清晰的感知。等这套框架稳定下来,你再去思考更复杂的协同策略也不迟。
本文还有配套的精品资源,点击获取