ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

AutoGen多智能体协作实践:从对话驱动到生产环境落地

AutoGen多智能体协作实践:从对话驱动到生产环境落地 这篇是智能体开发系列的6.2节主题是微软开源的AutoGen框架。作为大模型开发工程师我最近半年测试过的agent框架不下五种但真正在项目里留下来当主力工具的AutoGen算一个。它解决的并不是把大模型API包一层这种简单问题而是多个AI角色之间如何通过对话完成协作——你让一个Agent写代码另一个Agent审查代码还有一个代理负责执行和反馈这种场景用AutoGen非常顺手。这篇文章我会从设计原理讲到实际代码再讲我在生产环境中踩过的坑适合想系统了解AutoGen、或者正在做多智能体方案选型的开发者阅读。1. 从单模型调用到多智能体对话AutoGen要解的问题1.1 为什么单Agent不够用大模型应用开发刚起步的时候大家写的大多是单轮调用程序用户抛一个问题拼一个prompt丢给GPT或者国产大模型拿到结果就完事。这种模式处理翻译、摘要、文案改写确实够了但一旦碰到需要分步骤完成的任务立刻捉襟见肘。比如帮我把这个Excel里所有重复的客户记录找出来然后生成一份去重报告模型不是不能做而是它需要在一次回答里同时完成理解数据结构、写数据处理代码、检查代码能不能跑、解释结果这一整套动作prompt稍微复杂一点模型就开始顾此失彼。更麻烦的是很多任务天然需要不同视角的介入。写代码的人容易忽略边界条件审查的人专门挑毛病如果让同一个模型既写代码又检查自己的代码它往往自己看自己什么都好。我早期用一个Agent做代码生成加自查连续几次都在同样的逻辑漏洞上翻车后来改成两个独立角色的对话式Agent问题立刻少了很多。这其实就是多智能体对话最朴素的动机把一个人格拆成多个专业角色让它们各自专注一件事再通过消息机制协作。单Agent不够用还有一个原因是上下文窗口的物理限制。一个复杂的业务任务中间过程会产生大量中间态——读取的数据、生成的中期报告、执行后的错误日志。如果这些全部堆在同一个对话里token消耗涨得飞快轮次一多模型还会把早期的指令逐渐遗忘。多Agent结构把任务分阶段拆开每个Agent只维护自己相关的上下文反倒让整体更可控。1.2 AutoGen的设计哲学对话即编排既然需要多角色分工那自然要选一个编排方案。市面上常见思路有两种一种是流程驱动像写程序一样定义好节点和跳转条件Agent只是流程里的一个执行单元另一种就是AutoGen主打的对话驱动不给任务规定死路径而是让多个Agent在对话中动态决定下一步怎么做。对话即编排这个理念一开始我也有点怀疑——让模型自由对话会不会跑偏后来在项目里用下来的感受是对话本身就是一种天然适合LLM的协议。模型最擅长的事情就是用自然语言沟通与其去定义复杂的流程图状态机不如给Agent设定角色和目标让它们商量着来。AutoGen把编排逻辑藏在了对话轮次的背后开发者只需要关心角色怎么设计、对话怎么收敛心智负担小很多。这个设计跟人很像。一个研发团队做需求不会每一步都走严格的审批流而是产品、开发、测试在一个群聊里来回讨论聊到信息对齐再动手。AutoGen的GroupChat就是这个思路的工程化实现——多个Agent在一个会话里轮流发言谁该说话、说什么由会话管理器动态裁决。你会发现它更接近现实中的协作形态而不是一张冷冰冰的流程图。2. AutoGen的组件体系这几个类搞明白框架就懂了一半2.1 一切可对话的智能体都从ConversableAgent派生AutoGen整个框架的核心抽象就一个——ConversableAgent可对话智能体。从名字也能看出来这个框架里所有参与协作的成员本质都是能收发消息的对象。它不是一个大而全的框架更像一套基础通信协议你往里面塞什么角色它就变成什么角色。创建ConversableAgent时最关键的几个参数是nameAgent在对话中的名称会被模型看到所以尽量起有角色感的名字比如coder、reviewer。system_message角色设定。这里要写得具体直接决定Agent在会话里的行为方式。llm_config大模型配置。如果设为False这个Agent就不依赖LLM只靠代码逻辑响应比如负责执行代码和接收人工输入的代理。human_input_mode什么时候需要人工输入。可选值有NEVER、TERMINATE、ALWAYS生产环境通常设成NEVER靠终止条件自动收尾。你不需要继承这个类去写复杂逻辑大多数场景下直接实例化、设定参数就够了。AutoGen把灵活性和复杂度都收敛在这一个类里这一点和很多动辄让你写十几行配置的框架不太一样。2.2 两个开箱即用的角色AssistantAgent与UserProxyAgent如果没有现成的角色AutoGen默认给你两个AssistantAgent和UserProxyAgent。这俩是框架里出场率最高的角色理解它们的分工基本就理解了整个框架的协作方式。AssistantAgent是由LLM驱动的助手它负责生成回复内容可以是方案、代码、分析结论。它不执行代码只动嘴。UserProxyAgent则是用户的代理它的特点是可以执行代码、可以请求人工输入。这两者天然形成一条工作链UserProxyAgent把任务交给AssistantAgentAssistantAgent回复一段代码UserProxyAgent把代码在本地或Docker里运行再把运行结果成功或报错作为新消息发给AssistantAgentAssistantAgent根据结果修正代码。这个循环反复进行直到任务完成。我第一次跑通这个循环的时候最大的感受是它把一个人用ChatGPT写代码再手动跑的过程完全自动化了。人不需要在每一轮都出现只在关键节点把关就行。默认情况下UserProxyAgent的human_input_mode是TERMINATE意思是它只在需要判断要不要结束时才问人平时自动执行。2.3 群聊模式GroupChat与GroupChatManager双Agent对话只覆盖一个问、一个答的场景真实业务往往需要更多角色参与这时候就用GroupChat。GroupChat维护一个会话列表和多个AgentGroupChatManager负责调度——每一轮决定由哪个Agent发言。管理器怎么决定谁发言默认是让LLM根据当前的对话上下文从Agent列表中挑一个最该说话的人。这个机制很有意思它让发言顺序完全由内容驱动。比如三个Agent在讨论一个架构方案前几轮是架构师在输出后面实施工程师发现方案有遗漏插进来补充管理器会自动把话语权交给它。不需要开发者预判每次发言的轮次。GroupChat有一个max_round参数限制总对话轮数防止讨论无休止进行。这个参数在开发阶段一定要设而且要设得小一点否则模型兴致上来能聊几十轮给你看。3. 第一步实操安装、模型配置和最小对话3.1 安装与版本选择先看清你找到的资料是哪代API安装很简单一条命令pip install pyautogen但这个坑我必须提前说AutoGen在0.4版本经历了一次非常大的核心重构0.4及之后的版本换成基于异步事件驱动的架构包名、API用法和0.2系列几乎不兼容。你现在去网上搜资料会看到两种完全不同的写法搜到0.2的教程硬套0.4的代码基本跑不通。我的建议是如果你是新手先装0.2系列因为网上存量教程、Stack Overflow问题、社区示例绝大多数都是0.2的写法遇到问题更容易百度到答案如果你已经熟悉框架想用到极致再去看0.4的异步机制。本文代码基于0.2系列Python版本建议3.9以上。3.2 配置模型不只是OpenAI兼容接口都能接AutoGen的模型配置通过config_list传入它的设计很聪明支持同时配置多个模型base_url允许自定义所以任何兼容OpenAI接口协议的服务都能无缝接入。下面这段配置用DeepSeek的API就能跑通不需要OpenAI的Keyllm_config { config_list: [ { model: deepseek-chat, api_key: YOUR_API_KEY, base_url: https://api.deepseek.com/v1, } ] }如果你用Ollama跑本地模型base_url改成http://localhost:11434/v1model改成你本地拉取的名字比如qwen2.5:14b就行。本地模型的优势是数据不出内网对隐私要求高的项目很合适代价是响应速度和推理能力跟云端API有差距。有一点要提醒不同模型对多Agent对话的角色扮演能力差异很大。我实测下来指令遵循能力比较强的模型比如GPT-4系列、DeepSeek的V3系列在多Agent场景表现稳定偏轻量的模型在角色多、任务复杂时偶尔会答非所问。如果预算允许生产环境尽量给LLM驱动的Agent配高端模型省下调试prompt的功夫。3.3 最小双Agent对话代码示例与运行解读装好环境、配好模型之后写一个最小对话只需要十几行代码from autogen import AssistantAgent, UserProxyAgent llm_config { config_list: [ { model: deepseek-chat, api_key: YOUR_API_KEY, base_url: https://api.deepseek.com/v1, } ] } assistant AssistantAgent( nameassistant, llm_configllm_config, system_message你是一个Python专家负责编写高质量代码。代码用markdown代码块输出。, ) user_proxy UserProxyAgent( nameuser_proxy, human_input_modeTERMINATE, max_consecutive_auto_reply5, code_execution_config{ work_dir: coding, use_docker: False, }, ) user_proxy.initiate_chat( assistant, message写一个Python脚本计算斐波那契数列前20项并打印结果。, )看运行日志你会发现一个很有意思的过程user_proxy把用户问题发给assistant。assistant生成一段Python代码用markdown代码块包起来。user_proxy检测到代码块自动在coding目录下保存并在本地执行。执行成功user_proxy把输出结果斐波那契数列发回给assistant。assistant判断任务已完成给出最终总结。因为设置了human_input_modeTERMINATEuser_proxy会询问是否继续如果没有额外指令就结束会话。整个过程中我只在第一步输入了任务后面完全是自动的。看起来很简单但注意几个细节assistant输出代码必须用markdown代码块user_proxy才会识别并执行max_consecutive_auto_reply5限制了自动回复次数防止模型停不下来use_dockerFalse表示在本地直接执行开发环境图省事可以这样生产环境建议改成Docker。3.4 控制会话走向人工介入模式与终止条件human_input_mode和is_termination_msg是两个很容易被忽略但极其重要的参数。human_input_mode的取值逻辑NEVERAgent之间自动对话永不询问人类。适合流水线批处理比如定时任务里跑数据分析。TERMINATEAgent自动对话但每次要结束时问一下人类。适合半自动化场景人有最终决定权。ALWAYS每轮都询问人类。调试阶段用看得清楚每步在干什么但很累赘。生产环境我强烈建议用NEVER配合is_termination_msg精确控制结束。is_termination_msg是一个回调函数判断某条消息是否代表任务结束def is_termination_msg(msg): content msg.get(content, ) return TERMINATE in content配合这个函数你需要在assistant的system_message里明确告诉它任务完成时最后一条消息以TERMINATE作为结尾。模型确实会照做。这样做的好处是结束时机由业务内容决定而不是靠死板的轮数上限同时保留轮数上限作为兜底双保险。4. 实战进阶用GroupChat搭一个数据处理流水线4.1 场景设计与角色分工双Agent解决生成并执行代码足够但我想演示一个更贴近真实开发的多角色场景。假设要做这样一件事分析一个销售CSV文件找出销售额异常下降的区域生成一份带图表的可视化报告。这个任务单靠一个Agent又要写分析、又要保证代码质量、又要注意图表美观很容易翻车。我拆成四个角色pm产品经理明确任务目标拆解需求协调各方。coder程序员编写数据处理和可视化的Python代码。reviewer审查员审视代码的逻辑漏洞、边界情况给出修改意见。executor执行代理实际运行代码反馈运行日志可以由UserProxyAgent充当。这四个角色通过GroupChat协作让对话自由推进。角色之间的互动会产生真实感很强的讨论coder写代码reviewer挑毛病pm在旁边看到讨论偏离需求时拉回来executor把运行结果实时反馈整个流程比硬编码的流水线灵活得多。4.2 核心代码实现from autogen import AssistantAgent, UserProxyAgent, GroupChat, GroupChatManager llm_config { config_list: [ { model: deepseek-chat, api_key: YOUR_API_KEY, base_url: https://api.deepseek.com/v1, } ] } pm AssistantAgent( namepm, llm_configllm_config, system_message你是一个产品经理负责拆解需求、控制讨论方向。 当发现讨论跑偏时把话题拉回任务目标。, ) coder AssistantAgent( namecoder, llm_configllm_config, system_message你是资深Python开发负责编写数据分析代码。 代码必须用markdown代码块输出。, ) reviewer AssistantAgent( namereviewer, llm_configllm_config, system_message你是代码审查专家只关注逻辑漏洞、边界条件和代码质量。 发现问题就给修改建议问题未解决不要通过。, ) executor UserProxyAgent( nameexecutor, human_input_modeNEVER, code_execution_config{ work_dir: analysis, use_docker: False, }, is_termination_msglambda msg: TERMINATE in msg.get(content, ), ) group_chat GroupChat( agents[pm, coder, reviewer, executor], messages[], max_round12, ) manager GroupChatManager( groupchatgroup_chat, llm_configllm_config, ) pm.initiate_chat( manager, message分析sales.csv中各个区域的销售额趋势找出异常下降的区域 并生成一个可视化图表保存为trend.png。, )4.3 运行效果与调参心得这个配置跑起来后我观察到几个典型现象第一reviewer真的会拦代码。有一次coder生成的代码里读取CSV时没有处理空值reviewer直接说这里会有KeyError风险请修改后再提交。coder修改后再输出reviewer确认通过executor执行成功。这个写代码-审查-修改-执行-再审查的闭环在单Agent模式下很难自动形成因为模型不会自己主动否定自己。第二pm的控制力取决于system_message。如果pm的角色设定写得太弱它基本上就是个传话筒讨论跑偏也不管写清楚发现跑偏要拉回它在关键节点会主动发言纠正方向。所以每个角色的system_message值得花时间打磨这不是走形式是整个系统行为和输出质量的主要决定因素之一。第三max_round要按任务复杂度设。我一开始设成20结果任务已经完成了几个Agent还在客套地说感谢配合合作愉快白白消耗token。后来设成12同时在coder和reviewer的system_message里都强调输出最终结果时以TERMINATE结尾整个群聊能干净利落地收尾。第四如果发现GroupChat的对话质量不稳定优先检查管理器的模型选择。GroupChatManager默认也用llm_config来调度说话人调度模型的能力直接影响对话质量。预算允许的话给管理器配一个强模型Agent们可以配稍弱一点的模型这样性价比会好很多。5. 生产环境踩坑我总结的四个高频问题5.1 版本升级带来的API不兼容这个坑我前面提过但值得再展开。AutoGen 0.4把from autogen import ConversableAgent这一套顶层API改成了from autogen_agentchat import ...的包结构还引入了异步运行环境。如果你的项目已经基于0.2跑了一堆代码千万别脑子一热升级0.4迁移成本远比你想象得高。我的做法是开发新项目时单独建虚拟环境试用0.4老项目继续用0.2锁版本。锁定版本的正确姿势pip install pyautogen0.2.*5.2 模型生成代码的执行安全AutoGen的能力核心在于能自动执行代码但这也带来安全风险。模型生成的代码未必安全——它可能包含删除文件的命令、访问外网的请求或者在错误的工作目录里乱写文件。开发环境里我踩过一次Agent在一个临时目录里生成了个递归删除脚本幸好作用在指定工作目录下没有造成更大影响但也让我意识到不能把use_dockerFalse当成默认配置。生产环境的执行安全我建议至少做到三层用Docker隔离use_dockerTrue每个Agent执行代码都在独立容器环境里炸了不连累宿主机。专用工作目录给work_dir指定一个空目录并且在每次任务结束后清理。配置超时和交互审核max_consecutive_auto_reply设一个合理上限关键任务的执行结果必须经过人工确认再进入下一轮。5.3 无限对话与token成本失控多Agent对话最大的隐形成本是token消耗。每一次消息传递模型都要重新阅读整个对话历史来生成回复会话轮次越多历史越长单次调用的token成本急剧上升。我见过一个任务最多烧掉几十块钱的token最后整个对话因为循环逻辑错误完全跑偏了产出结果却没多少可用。控制成本主要靠三个手段max_consecutive_auto_reply限制单个Agent的连续自回复次数避免它自己跟自己较劲。is_termination_msg明确收尾信号防止模型进入不断优化的循环。对话记录定期裁剪对超长会话做截断或摘要只保留关键上下文。另外建议对接模型服务时开启token用量统计把每次调用的usage字段汇总保存。这样谁能知道每个Agent烧了多少token优化方向也不会靠猜。5.4 中文模型对角色指令的理解差异如果你用的是国产模型要特别注意一点它们对多Agent system_message的遵循程度跟GPT-4的差距可能超出预期。最典型的表现是让Agent以审查者的身份提意见结果它把自己当成被审查者开始自夸或者让Agent任务完成时输出TERMINATE它输出的是好的任务已完成。这类问题在主流的国产API上我都遇到过。解决办法有两个方向一是强化system_message把期望的输出格式写得跟模板一样具体比如你的回复必须以TERMINATE作为最后一行且不得包含其他解释二是对话过程中加规则校验在is_termination_msg之外用代码检查返回内容是否满足约定格式不满足就触发重试或终止。我倾向于两者都做毕竟模型的输出稳定性和网络波动一样属于不可控因素。6. AutoGen和LangGraph、MetaGPT、CrewAI怎么选6.1 四类框架的设计取向对比我在项目调研阶段画过一张对比表至今还在用框架核心抽象编排方式上手难度最适合的场景AutoGen可对话Agent对话驱动动态轮转中多智能体自由协商、代码生成闭环LangGraph图节点与状态图结构显式流程中高固定流程、可预测的工程管线MetaGPT角色与SOP标准作业流程中软件公司全流程模拟CrewAI角色与任务任务顺序/层级执行低快速原型、任务型Agent团队AutoGen的核心优势是对话驱动适合任务边界模糊、需要动态协商的场景LangGraph的优势是显式的状态图适合每一步都可预定的任务对调试和分支控制更友好MetaGPT偏重软件工程规范内置了文档、设计、编码、测试的完整流程CrewAI胜在简单直接定义好角色和任务就能跑。6.2 我的选型经验选框架先回答三个问题我的流程是固定的还是需要Agent自己探索我的Agent之间是协作还是上下级指派我对实时可观测性的要求有多高我做自动化数据清洗时用了AutoGen因为清洗规则在不同数据集上差别很大需要Agent在对话中自己判断该做什么清洗动作LangGraph那种预设流程图反而显得死板。但我做一个定时采集的Pipeline时选了LangGraph因为流程就是固定的抓取-解析-入库-告警状态机表达比自由对话可控得多出了问题也好定位在哪一步。如果你想要的是快速看到一个能跑的多Agent DemoCrewAI上手确实快写几个类就能跑起来但深入之后会发现可定制性不如AutoGen。如果你做的是偏研发流程的助手比如自动生成代码、自动评审、自动改bug那一套AutoGen的代码执行闭环是几个框架里最顺手的。注意框架没有绝对的好坏只有和场景匹配度的差异。我的建议是不要一开始就纠结哪个最强找几个标准任务比如生成代码并执行、多角色头脑风暴、固定流程信息抽取分别跑一遍看谁的调试成本和稳定性符合要求。最后再分享一个我的使用习惯AutoGen的代码示例看起来简单但真正让它稳定的是后面的约束项——迭代轮数、终止条件、生成参数、上下文清理。我会把会话历史和中间结果定时导出同时对每轮Agent调用开启token统计这样即使线上出了问题也能快速定位是哪个环节失控。多Agent协作不是越自由越好它需要边界而边界就是你在配置里写下的那些硬约束。
返回列表