AutoGen 的消息驱动执行模型

沿着自动回复、代码执行与群聊发言选择,拆解 AutoGen 的控制流,并分析 Nexus 消息、唤醒和运行生命周期的分工。

AutoGen 原论文中的一个基本组合只有两个 Agent。AssistantAgent 生成代码,UserProxyAgent 执行代码或接收人工输入,再把结果发回去。代码报错后,下一次模型调用读到的是执行反馈。工作因此形成了回路。

这个例子解释了 AutoGen 的设计重点。开发者要定义一个成员如何回应消息,也要定义回应会把执行带到哪里。两项规则共同构成论文所说的 conversation programming。AutoGen v2,第 2 节

三个成员通过传递消息协作完成任务的手绘概念插画

概念插画,由 imagegen 生成。

从一次函数调用到一条反馈回路

通常调用语言模型时,应用先准备输入,再等待输出。若输出里有工具请求,应用还要负责执行、回填结果和再次调用模型。AutoGen 将这些处理包装进可对话的 Agent,让消息收发成为组织执行的接口。

ConversableAgent 可以组合模型、工具和人工输入。AssistantAgentUserProxyAgent 是两种预配置形式。这里的 user proxy 有具体含义,它可以代替人接收代码并执行,也可以在配置要求时等待人的意见。因此,一个 Agent 不必等同于一个始终由模型生成文本的角色。

论文图 1 的左侧列出能力组合,中间列出连接方式。把两部分分开看,才能理解同一套收发接口为何能支持代码执行、人工介入和多成员讨论。

AutoGen 原论文图 1 展示 Agent 能力组合和多种对话模式

Qingyun Wu 等,AutoGen 原论文图 1,版本 2308.08155v2。按 CC BY 4.0 引用,原文及图注。图片未修改,网页按宽度缩放。

以论文展示的代码生成与执行组合为例,一轮交互包含以下动作。

  1. Assistant 收到任务,生成代码并发给 UserProxy。
  2. UserProxy 按配置处理人工输入或执行代码,将输出作为回复。
  3. Assistant 读取反馈,决定修改代码还是结束。

“错误应该如何修复”由模型判断,“是否允许执行、何时停止等待”由程序配置。这种分工把模型的判断能力放进了可编程的调用链。它也解释了为什么只复制 Agent 的系统提示词,无法复现一个完整应用。

自动回复把控制流藏在哪里

AutoGen 的自动回复机制在消息到达时调用回复处理,再把回复送回通信对象。开发者还可以注册自定义回复函数,在回应前咨询另一个 Agent。复杂协作由这些局部处理串联起来,不必为每一轮往返单独写调度代码。第 2.2 节

消息触发回复,再根据停止条件继续或结束的 AutoGen 简化流程

图中的回路是简化表示。实际对话可能交替经过不同 Agent,也可能在自定义回复函数里进入另一段对话。分析这类程序时,单看消息列表还不够,需要同时检查回复函数、终止条件与工具配置。控制流分布在这些位置。

这带来一个工程取舍。局部规则便于复用,整条链路的行为却可能难以从单个成员的代码中看清。一次回复究竟会调用工具、等待用户,还是咨询其他成员,取决于配置与当前上下文。排查循环时,应沿着消息的发送者、接收者和回复处理逐步追踪,直到找到没有改变任务状态的那条边。

停止条件也有两层。模型可以生成约定的结束标记,程序则可以限制自动回复次数。前者表达模型对任务的判断,后者限制执行。达到次数上限说明流程停止,业务是否完成还要检查产物。将两种含义合成一个“成功”状态,会丢失失败原因。

GroupChatManager 增加的是发言选择

当参与者超过两个,谁接着发言成为独立问题。原论文的 GroupChatManager 选择下一位发言者,再向群体传播回复。它使对话可以依据当前进展改变路径,适合无法预先列出全部步骤的任务。群聊机制

发言选择与任务依赖仍需分开。选择了一个复核者,只能确定下一次处理交给谁;复核需要的文件是否存在、文件属于哪个版本、上游任务是否完成,需要应用提供依据。若工作顺序已经明确,用固定交接规则能够减少一次模型选择。若下一步依赖内容判断,动态选择才有施展空间。

这也是阅读实验时需要保留的区别。论文展示六类应用,群聊探索使用 12 道人工构造任务。它们说明这种编程方式能表达哪些流程,以及在指定配置下如何工作,不能据此估计任意团队任务的收益。数学应用还混合了不同规模的评测,比较数字前应检查参与该组实验的基线与样本范围。第 3 节及附录 D

Nexus 的交接还包含运行生命周期

Nexus 的 Room 要处理持续存在的成员与公共记录。一个成员的运行时退出后,Room 中的消息仍然需要存在;下一位成员暂时不能执行时,请求也不能随运行上下文一起消失。官网的运行时架构说明因此将消息与 wake 分开描述。

公共消息记录谁向谁提出了什么请求。wake 为目标成员提供运行机会。默认 nxs 通过 bridge 接入宿主,Runtime session 承担该成员的执行上下文。这些职责与 AutoGen 的消息驱动思路可以对照,但属于不同的抽象层。

一个有用的排查顺序是先确认公共记录,再确认目标成员是否获得运行机会,最后查看该轮执行结果。消息已写入但没有执行,和执行过却没有交付,是两种故障;重复发送同一句请求可能掩盖前者,也可能让后者重复操作。

因此,借鉴 AutoGen 时应保留它对回复能力和控制流的区分,再把控制动作接到 Nexus 的生命周期上。需要追踪依赖和验收的工作还应使用工作图@成员 本身不会建立完整的任务记录。若问题集中在交接内容的完整性,可以接着看 MetaGPT 的产物依赖设计

本文依据 2023 年 AutoGen v2 论文分析设计机制,并与 Nexus 公开文档对照。产品对照不表示历史采用关系,也不构成同任务性能比较。