Agent 架构 · 2025

Flow: Modularized Agentic Workflow Automation

Flow 将多智能体任务执行流程表示为 Activity-on-Vertex 图,用并行度和依赖复杂度筛选初始 workflow,并在执行过程中根据子任务状态、历史数据和失败信号动态更新任务图。论文强调模块化设计,让子任务尽量并行且降低依赖集中度,从而提升效率、容错性和可维护性;在 Gobang 游戏开发、LaTeX Beamer 写作和网站设计任务中,Flow 相比 AutoGen、CAMEL、MetaGPT 获得更高成功率和人工评分。

作者
Boye Niu1Yiliao Song2Kai Lian1Yifan Shen3Yu Yao1Kun Zhang3,4Tongliang Liu1
机构
  1. University of Sydney悉尼大学
  2. University of Adelaide阿德莱德大学
  3. Mohamed bin Zayed University of Artificial Intelligence穆罕默德·本·扎耶德人工智能大学
  4. Carnegie Mellon University卡内基梅隆大学
进入中英精读arXiv

读前先抓住结论

Flow 这篇论文处理的是一个非常工程化、也非常常见的问题:多智能体框架可以把复杂任务拆给多个 LLM agent 做,但很多系统一旦生成初始 workflow,就很难在执行过程中高质量地调整它。任务真实运行时会出现缺信息、某个子任务失败、某个模块输出质量不够、下游依赖被卡住等情况。如果 workflow 只是静态清单,系统往往只能继续按原计划往下跑,最后把局部错误放大成整体失败。

论文的核心做法是把 agentic workflow 表示成 Activity-on-Vertex 图。在这个图里,顶点是子任务,边是依赖关系,智能体被分配到不同子任务上。这样一来,workflow 不再只是自然语言步骤列表,而是一个可计算、可调度、可检查、可更新的运行时对象。Flow 进一步用两个指标筛选任务图:平均并行度越高越好,依赖复杂度越低越好。前者鼓励更多子任务同时执行,后者避免依赖集中在少数关键节点上。

最重要的结论是:Flow 不是单纯让 LLM 生成更好的计划,而是让计划在执行中持续变成更合适的图结构。它先生成多个候选 AOV 图,选出更模块化的初始图;执行过程中再根据子任务状态和生成数据动态更新图。实验覆盖 Gobang 游戏开发、LaTeX Beamer 课件写作和会议网站设计,Flow 平均成功率达到 93%,人工满意度达到 3.54/4,整体高于 AutoGen、CAMEL 和 MetaGPT。

论文原图:Flow 与 AutoGen、CAMEL、MetaGPT 在网站设计和五子棋任务上的输出对比。
论文原图:Flow 与 AutoGen、CAMEL、MetaGPT 在网站设计和五子棋任务上的输出对比。

问题背景

现有 LLM 多智能体框架已经证明了角色分工的价值。MetaGPT 会预设产品经理、项目经理、工程师等角色,用类似 SOP 的顺序流程完成编程任务;CAMEL 让两个预定义智能体相互对话;AutoGen 可以根据任务需求自动创建角色列表。它们共同说明,多智能体协作确实能把复杂任务拆成更小的工作单元。

但论文指出,这些框架的 workflow 往往仍然偏静态、偏顺序。静态意味着初始计划生成后,很难根据执行过程中的新信息重构任务;顺序意味着即使某些子任务本来可以同时做,系统也可能让它们排队等待。对于网页、游戏、课件这类复合任务,这种限制会直接造成效率损失,也会让某个子任务失败时影响后续多个模块。

Flow 的切入点是把多智能体系统从“角色协作”推进到“工作流结构可优化”。作者并不否认现有框架的角色生成、任务分解和对话能力,而是认为这些能力需要一个更合适的任务图承载。只有当系统知道哪些子任务互相依赖、哪些子任务可以并行、哪些输出已经完成、哪些模块失败,才可能在运行时做有根据的调整。

静态顺序 workflow

先生成完整任务序列,再按顺序执行;局部失败往往影响后续步骤;并行机会依赖人工设计。

Flow 的 AOV workflow

把子任务、依赖、状态和智能体放入图结构;可并行节点同步执行;失败后用当前数据重新生成并筛选候选图。

Related Work 中的 ReAct、Reflexion、ADAPT 主要改善单个或少量 agent 的推理、反思和任务分解;DyLAN、MACNET、GPTSwarm、DataInterpreter 和 AFlow 则更接近 workflow 或图结构方向。Flow 与这些工作的差异在于,它把模块化明确变成图选择准则,并把运行时更新纳入同一个图表示中。

方法总览:把 workflow 变成可更新的 AOV 图

Flow 的第一步是形式化。论文定义 G=(V,E,A)G=(V,E,A)VV 是子任务集合,EE 是有向依赖边,AA 是智能体集合。如果存在边 eij=(vi,vj)e_{ij}=(v_i,v_j),就表示子任务 viv_i 必须在 vjv_j 开始前完成。每个智能体 aja_j 有一个角色,并负责某个子任务子集 Tj\mathcal{T}_j。这个定义让多智能体 workflow 变成一个 DAG,而不是一段散乱提示词。

这件事的意义在于,图结构天然支持调度。没有未完成前置依赖的节点可以并行执行;有依赖的节点必须等待上游完成;如果某个节点失败,系统可以评估它影响哪些下游节点。Flow 因此能够把“任务拆分”“角色分配”“并行执行”“失败更新”放在同一个数据结构里处理。

论文原图:Flow 从初始化任务图开始,让子任务并行执行;检测到错误后修改任务图并继续迭代。
论文原图:Flow 从初始化任务图开始,让子任务并行执行;检测到错误后修改任务图并继续迭代。
1初始化

LLM 根据任务需求生成多个候选 AOV 图

2筛选

按并行度优先、依赖复杂度次之选择最优图

3执行

拓扑排序后并行运行所有就绪子任务

4检查

检查子任务状态、数据和需求满足度

5更新

根据当前图和执行数据生成新候选图并继续执行

Flow 的闭环并不复杂,但每一步都服务于同一个目标:保持 workflow 的高并行、低依赖和可修复。初始阶段选择模块化图,是为了避免一开始就让任务图过度顺序化;执行阶段根据 <code>num_parents_not_completed</code> 找就绪节点,是为了落实并行;更新阶段重新生成候选图,是为了利用运行中产生的新信息。

核心机制:模块化如何被量化

论文没有只用“模块化”这个词做直觉描述,而是定义了两个可计算指标。第一个是平均并行度。设 StS_t 表示第 tt 个执行步骤中可并行执行的子任务集合,TT 是 DAG 的最大深度或总步骤数。Flow 用各步骤并行子任务比例的平均值衡量整体并行潜力。

Pavg=1Tt=1TStP_{\text{avg}} = \frac{1}{T} \sum_{t=1}^{T} S_t

平均并行度衡量 workflow 每个执行层里能同时推进多少子任务。数值越高,说明任务图越能压缩总执行步骤。

第二个指标是依赖复杂度。只看并行度还不够,因为两个图可能有相同并行层数,却有完全不同的依赖结构。论文用每个节点的连接数分布来衡量依赖是否集中:如果某些节点连接特别多,它们就可能成为瓶颈或错误传播中心。

Cdependency=σdeg(vi)=1VviV(deg(vi)dˉ)2C_{\text{dependency}} = \sigma_{\deg(v_i)} = \sqrt{\frac{1}{|V|}\sum_{v_i \in V}(\deg(v_i)-\bar{d})^2}

依赖复杂度是节点度数的标准差。标准差越大,说明依赖越集中;Flow 倾向选择复杂度更低、更均衡的图。

这两个指标共同定义了 Flow 的选择策略:先最大化并行度,再最小化依赖复杂度。并行度解决效率问题,依赖复杂度解决鲁棒性和可更新性问题。一个任务图如果并行度高但依赖集中,仍然可能被少数关键节点卡住;一个任务图如果依赖分散但并行度低,也无法充分利用多 agent 的并发优势。

论文还用定理说明额外依赖会降低期望完成子任务数量。直觉是:一个子任务成功不仅取决于自身不失败,还取决于所有前置依赖成功。给某个子任务增加一个额外前置依赖,就相当于给它的成功概率再乘一个不超过一的因子。依赖越多,成功链条越长,局部失败传播到下游的可能性越大。

算法与实现细节

Flow 的核心算法可以拆成两个层次:<code>UpdateGraph</code> 负责生成和选择候选图,外层 <code>Flow</code> 负责执行、监控和循环更新。论文在附录给出了伪代码,最关键的是候选图筛选逻辑:每次让 LLM 生成多个候选工作流,对每个候选计算并行度和依赖复杂度,然后保留最高并行度、最低依赖复杂度的图。

AlgorithmUpdateGraph:按并行度与依赖复杂度选择候选 AOV 图
1Require: current workflow \tilde{G}, task prompt P, workflow prompt P_init or P_update2Ensure: selected workflow \tilde{G}_{optimal}3Generate candidate workflows {\tilde{G}_1, ..., \tilde{G}_K} using LLM4P_max ← -∞; C_min ← +∞; \tilde{G}_{optimal} ← None5for each candidate \tilde{G}_k:6  P_k ← P_avg(\tilde{G}_k)7  C_k ← C_dependency(\tilde{G}_k)8  if P_k > P_max or (P_k == P_max and C_k < C_min):9    P_max ← P_k; C_min ← C_k; \tilde{G}_{optimal} ← \tilde{G}_k10return \tilde{G}_{optimal}

这段算法把 Flow 的模块化偏好写成选择规则:先比较候选图能并行多少,再比较依赖是否更分散。它既用于初始 workflow,也用于运行时更新。

算法输入里的 G~\tilde{G} 是当前 workflow,PP 是任务需求,PinitP_{init}PupdateP_{update} 是提示词。初始化时,模型根据任务需求生成多个候选图;更新时,模型还会看到当前子任务状态和执行数据。无论在哪个阶段,筛选准则保持一致,因此 Flow 不会因为进入运行时就放弃模块化目标。

实现上,论文把每个子任务存成字典项:

G~[v]={subtask requirement,status,data,num_parents_not_completed,child,agent}\tilde{G}[v] = \{\text{subtask requirement}, \text{status}, \text{data}, \text{num\_parents\_not\_completed}, \text{child}, \text{agent}\}

每个子任务都记录需求、状态、数据、未完成父节点数量、子节点和负责智能体,使程序调度和 LLM 更新可以共享同一份结构。

json
1{2  "Task_A": {3    "status": "not started",4    "data": null,5    "num_parents_not_completed": 0,6    "child": ["Task_B", "Task_C"],7    "agent": "Agent_1"8  }9}

<code>num_parents_not_completed</code> 是调度开关。当它为零,说明该子任务没有未完成前置依赖,可以启动;当多个子任务同时为零,它们就可以并行执行。如果同一智能体在同一步被多个子任务需要,Flow 会创建克隆智能体,让这些子任务同步推进。这个设计把并行从抽象指标落到了可执行条件上。

Flow 还做了双重检查。它不只看 agent 报告的 <code>status</code>,还会检查该子任务的需求是否真的被满足。这个细节很重要,因为 LLM agent 可能误报完成,或者输出看似完成但缺少关键数据。只有当状态和需求检查都通过,系统才把子任务视为可靠完成,并更新下游依赖。

动态更新怎么工作

动态更新发生在执行过程中。Flow 会把当前任务需求、当前 AOV 图、所有子任务的状态与输出数据交给更新提示词,让 LLM 生成新候选图。更新可以包括删除无用任务、添加补救任务、修改子任务要求、重跑失败任务、重新分配智能体,或者重连依赖边。由于初始图已经被鼓励模块化,这些调整通常可以局部发生,而不必推翻全部 workflow。

论文原图:五子棋任务中的动态更新示例,系统会新增桥接子任务来替换或弥补失败节点。
论文原图:五子棋任务中的动态更新示例,系统会新增桥接子任务来替换或弥补失败节点。
论文原图:网站设计任务中的 workflow 更新示例,系统根据已生成结构调整后续 CSS 和页面任务。
论文原图:网站设计任务中的 workflow 更新示例,系统根据已生成结构调整后续 CSS 和页面任务。

论文给出的两个案例很好理解。在网站设计中,当“定义网站结构”已经完成并产生足够 HTML 结构时,系统可以据此调整 CSS 创建任务,让后续样式开发直接依赖已完成结构,而不是继续等待不必要的信息。在五子棋任务中,如果某些子任务输出不足,系统会添加桥接任务,补齐逻辑和界面之间的缺口。

错误处理实验进一步说明更新机制的价值。作者随机把某些子任务输出遮蔽成空值,再比较 Flow 和 Flow without update。结果显示,动态更新让网站设计成功率达到 87%,五子棋达到 93%,LaTeX Beamer 达到 93%;不更新时分别只有 46%、0%、67%。这个对比说明,Flow 的收益不只是初始图更好,还来自执行时的修复能力。

实验怎么读

论文设计了三类任务来测试多智能体协作。五子棋游戏开发要求生成带简单 AI 和用户界面的游戏,并正确处理胜负和平局;LaTeX Beamer 写作要求生成强化学习课件,包含动机、问题、直觉解法和数学公式,并满足页数要求;网站设计要求为 ICLR 会议生成专业网页,包含日程、地点、地图和样式。三者都不是单一问答任务,而是需要拆分模块、协调依赖和整合输出的复合任务。

指标分为成功率和人工评分。成功率根据任务拆成多个子指标:五子棋看能否编译、能否交互、规则是否正确;Beamer 看能否编译、内容是否完整、页数是否满足;网站看能否渲染、基础信息是否完整、是否包含要求章节。人工评分由 50 名有编程和机器学习背景的参与者排序,反映最终质量。

主结果可以这样读:Flow 在五子棋任务上达到 100% 总成功率和 4.00 人工评分;在 Beamer 任务上达到 100% 总成功率和 3.33 评分;在网站任务上达到 80% 总成功率和 3.28 评分。三类任务平均后,Flow 成功率为 93%,人工满意度为 3.54/4,高于 AutoGen、CAMEL 和 MetaGPT。

论文原图:五子棋任务中的 Flow workflow 示例,规则、主逻辑、AI 与界面被拆成可协调模块。
论文原图:五子棋任务中的 Flow workflow 示例,规则、主逻辑、AI 与界面被拆成可协调模块。

基线失败模式也值得看。AutoGen 经常能生成部分可运行代码,但可能出现编译错误、界面缺陷或内容过浅;MetaGPT 在编程组织上较强,却可能把五子棋误做成井字棋,或者在网页任务中缺少关键功能区;CAMEL 受限于两个 agent 的互动模式,在复杂网站和游戏任务中容易漏功能。这些失败都与 workflow 结构有关:任务拆分不够细、依赖组织不清、运行时缺少修复。

消融、模型与成本

附录分析了不同 LLM 对更新的影响。GPT-3.5-Turbo 在五子棋、网站和 Beamer 任务中的变更比例分别为 44%、66%、71%;GPT-4o-mini 对应为 35%、47%、53%。这说明模型越弱,执行中越容易产生不足或错误,workflow 越需要被动态调整。但即便换成较强模型,更新仍然存在,因为复杂任务中的需求变化和模块整合问题并不会完全消失。

Flow w/o update

依赖初始 workflow。若某个子任务输出为空或不足,下游仍可能继续执行,导致代码缺失、页面结构不完整或课件内容不满足要求。

Flow w/ update

根据当前图和子任务数据重新生成候选图,添加、删除、修改或重连子任务,让后续执行绕开或修复局部失败。

时间成本部分展示了另一个 trade-off。动态更新需要额外模型调用和检查,因此通常比不更新略慢。例如在 GPT-4o-mini 下,LaTeX Beamer 的 Flow w/o update 平均时间为 53.19,Flow w/ update 为 83.34。但与部分基线相比,Flow 仍保持竞争力,因为并行任务执行能抵消一部分更新开销。

这个结果提醒读者:Flow 的优势不是“永远更快”,而是“在复杂任务中用可控成本换更高成功率和更好质量”。如果任务很简单、失败代价低、或者不需要多模块协作,动态更新可能不划算;如果任务复杂、模块多、下游依赖多,Flow 的结构化表示和局部更新就更有价值。

论文原图:LaTeX Beamer 写作任务中的 Flow workflow,多个内容组件可以并行生成后再整合。
论文原图:LaTeX Beamer 写作任务中的 Flow workflow,多个内容组件可以并行生成后再整合。

局限与复用启发

Flow 的第一个边界是评估规模。论文实验每个任务运行五次,并使用三类精心设计的任务,足以展示方法倾向,但还不足以证明它覆盖所有复杂工程任务。尤其是任务需求更开放、缺少明确成功率指标、或输出质量高度主观时,如何定义检查信号和更新触发条件会更困难。

第二个边界是更新成本。动态重构需要额外 LLM 调用,也需要维护任务状态、依赖图和输出数据。如果系统没有稳定的子任务日志,或者 agent 输出难以结构化,Flow 的优势会被实现复杂度抵消。论文实际选择“子任务完成后再更新”的策略,正是为了减少不必要 API 调用,而不是让更新和所有执行完全并发。

第三个边界是指标设计。平均并行度和依赖复杂度很直观,但它们不直接衡量语义正确性。一个图可以并行度高、依赖分散,却把任务拆得不合理。因此工程复用时不能只照搬指标,还需要加上任务相关的可验证检查,例如测试用例、页面需求列表、编译结果、人工审查或自动评分器。

对实际 agent 系统来说,Flow 最值得复用的是三件事。第一,把 workflow 存成可读写的状态图,而不是只存在 prompt 里;第二,为每个子任务保留状态、数据和依赖计数,让调度和更新都能基于事实;第三,在更新时让模型看到全局信息,但只允许它做结构化修改,这样可以减少“重新想一遍”的不稳定性。

论文原图:网站设计任务中的 Flow workflow,页面模块被拆成相对独立的子任务以提升并行度和容错性。
论文原图:网站设计任务中的 Flow workflow,页面模块被拆成相对独立的子任务以提升并行度和容错性。

如果把 Flow 迁移到自己的项目,可以从一个小版本开始:先定义任务图 JSON schema,再记录每个节点的 <code>status</code>、<code>data</code>、<code>parents</code> 和 <code>children</code>;然后实现一个简单调度器,只运行父节点完成的任务;最后再加入 LLM 更新器,让它在测试失败或输出不足时提出图修改。这样做不需要一开始复刻完整论文系统,却能把“可更新 workflow”这个核心思想落地。

从论文结构反推作者真正关心的问题

如果只看标题,很容易以为 Flow 是又一个“自动生成工作流”的系统。但正文的重心其实更具体:作者关心的是多智能体系统如何在任务执行中保持结构可控。已有框架通常会把智能体角色、对话协议和任务步骤写进提示词或模板里,这样可以快速启动协作,却很难回答几个工程问题:当前哪个子任务真的完成了,哪个输出被下游依赖,哪个错误会影响多少后续节点,哪些任务可以立刻并行执行。Flow 的 AOV 图就是为了让这些问题有明确答案。

这种动机解释了为什么论文没有把重点放在“生成更多智能体”上。智能体数量不是决定性变量;关键是任务之间的依赖是否被清楚表达。一个系统可以有很多智能体,但如果所有步骤都被串成一条链,多智能体只是在模拟单线程执行。相反,即使智能体数量有限,只要任务图能暴露并行层,系统就能把独立模块同时推进。Flow 的贡献因此更像工作流运行时,而不是单纯的角色扮演框架。

论文把图表示和 LLM 结合起来,也是在平衡可解释性与灵活性。纯手写 DAG 可控,但需要人工提前知道任务结构;纯自然语言计划灵活,但机器很难稳定调度。Flow 让 LLM 负责提出候选图,再用显式指标选择图,并用状态字段执行图。这个组合把 LLM 的生成能力限制在结构化容器里,使后续检查、更新和调度都有程序入口。

AOV 图为什么适合多智能体任务

AOV 图把活动放在顶点上,边只表示先后依赖。对于多智能体任务,这比“步骤列表”更合适,因为列表默认强调顺序,而图默认允许分支。只要两个节点之间没有路径约束,它们就可以被看作潜在并行任务。Flow 正是利用这一点,把网站设计、课件写作、游戏开发这些复合任务拆成多个可同时推进的模块。

这种表示还有一个好处:它把“下游影响范围”变得可计算。假设一个子任务负责生成游戏规则,另一个子任务负责界面布局,第三个子任务负责把规则和界面连接起来。如果规则模块失败,系统可以沿着出边找到受影响节点,只重跑规则和连接相关任务;如果界面模块已经成功,就没有必要重新生成界面。传统顺序提示词很难做到这种局部修复,因为它往往没有明确记录输出之间的依赖边。

Flow 的图还承担了智能体分配表的作用。每个节点不仅有任务需求,还有负责智能体。这样一来,系统不只是知道“下一步做什么”,还知道“谁来做”。当多个就绪节点需要同一个智能体能力时,Flow 可以复制该智能体角色并行执行;当某个节点失败时,更新提示词也可以重新考虑角色和任务的匹配。这使得角色分工和任务结构不再分离。

模块化指标的含义不能只按公式读

平均并行度看似只是一个效率指标,但它其实隐含了一种任务分解偏好。高并行度要求图中有更多同层节点,这意味着任务被拆成相对独立的模块。例如网站设计可以把页面结构、样式、地图、日程、会议信息拆开,而不是让一个“大网页生成”节点一次完成所有内容。这样的拆分不仅能加速,也让错误更容易定位。

依赖复杂度则更像风险指标。一个图如果有一个超级中心节点,许多后续任务都依赖它,那么这个节点一旦失败,整个工作流都会被卡住。论文用节点度数标准差来惩罚这种集中依赖,鼓励更均衡的依赖分布。这个设计很朴素,却符合工程直觉:越多关键功能压在少数模块上,系统越脆弱;越能把功能分散到边界清晰的模块,越容易并行、测试和替换。

两个指标的优先级也值得注意。Flow 先比较并行度,再比较依赖复杂度,而不是把两者简单加权。这说明作者更强调工作流能不能形成有效并行层;当并行潜力相同或接近时,再用依赖复杂度选更稳的图。工程上这样做也减少了权重调参问题,因为不同任务的并行收益和依赖风险很难用同一个线性权重统一衡量。

不过这两个指标仍然只是结构指标,不保证语义正确。一个图可以把任务拆得很碎,得到不错的并行度,却出现模块边界不合理的问题。例如把五子棋胜负判断和棋盘状态更新拆得过远,可能导致接口不一致;把课件的动机、公式和例子分给完全独立节点,可能造成叙事断裂。Flow 依赖 LLM 生成候选图,因此还需要后续执行检查来弥补结构指标无法判断语义质量的缺口。

动态更新不是“推翻重来”

很多自动规划系统一旦发现错误,就会倾向于重新生成完整计划。Flow 的更新更克制:它把当前 workflow、子任务状态和已有数据一起交给更新过程,让模型在已有图上提出修改。这一点很关键,因为复杂任务执行到中途时,已经有很多可复用成果。完全重来会浪费成本,也可能引入新的不确定性。

论文中的网站案例体现了这种局部更新思想。页面结构生成后,后续样式任务可以直接依赖这个结构;如果某些信息已经完成,就不需要让样式任务等待额外无关节点。更新不是为了让计划更漂亮,而是为了让剩余任务更贴合已经产生的中间结果。换句话说,Flow 把执行数据变成下一轮图生成的上下文。

五子棋案例则展示了另一类更新:补桥。游戏开发中经常会出现某些模块各自完成,但连接处缺失的情况,例如规则逻辑和界面事件没有正确串起来。Flow 可以新增桥接子任务,把已有模块整合起来,而不是简单重跑所有代码。这类更新对工程任务特别重要,因为很多失败不是单个模块完全错误,而是模块之间缺少接口契约。

动态更新也有触发节奏。论文选择在子任务完成后检查状态和需求,再决定是否更新,而不是让更新器与所有执行完全并发。这是一种成本控制:如果每个细小事件都触发 LLM 重新规划,系统会非常昂贵,也可能因为过度更新而不稳定。等子任务产生可检查输出后再更新,可以让每次修改都有更明确依据。

伪代码背后的运行时模型

外层 Flow 算法可以理解为一个循环调度器。它维护一组未完成节点,找到所有前置依赖已经满足的节点,把它们交给对应智能体执行,然后更新状态和依赖计数。这个过程很像构建系统或任务编排器,只是节点内部执行者不是传统函数,而是 LLM agent。这样的类比能帮助理解论文:Flow 不是让智能体随意聊天,而是让智能体在一个有依赖约束的运行时里完成任务。

每个节点的 data 字段尤其重要。它保存的不只是最终答案,还包括后续节点需要读取的中间产物。网站任务中的 HTML 结构、游戏任务中的规则逻辑、课件任务中的章节内容都属于这种中间产物。没有 data 字段,更新器只能根据状态猜测;有了 data 字段,更新器才能判断哪些输出可复用,哪些缺口需要补任务。

status 字段也不能只看成完成标记。论文强调还要检查子任务需求是否满足,这相当于给每个节点加一层验收。LLM agent 可能声称自己完成了任务,但输出缺少关键内容;如果系统只相信自报状态,下游任务会基于错误前提继续执行。Flow 的双重检查把“agent 说完成”和“任务真的满足”区分开,这是多智能体系统落地时非常实际的设计。

当同一个智能体角色被多个并行任务需要时,Flow 使用克隆智能体同步推进。这里的克隆不是复制人格设定这么简单,而是复用同类能力配置,让同一类工作可以并发执行。比如多个页面模块都需要前端工程师角色,就可以创建多个相同角色实例处理不同节点。这个机制让角色成为可调度资源,而不是单一聊天参与者。

三个任务各自检验了什么

五子棋任务主要检验代码结构和规则一致性。一个成功的五子棋游戏需要棋盘渲染、用户交互、落子规则、胜负判断、平局判断和 AI 行为彼此配合。任何模块缺失都可能导致游戏不能玩,模块接口不一致也会让程序编译或运行失败。因此它非常适合测试 Flow 的模块拆分与桥接更新能力。

LaTeX Beamer 任务检验的是内容组织和格式约束。课件不只是生成文字,还要满足页数、主题覆盖、数学公式和编译通过等要求。这里的挑战不是复杂交互,而是多部分内容能否形成完整叙事,并且最终通过排版系统验证。Flow 的并行模块可以分别生成动机、问题、直觉、公式和结论,再合并成课件。

网站设计任务检验的是前端结构、内容完整性和视觉整合。它需要地点、日程、地图、会议信息、页面布局和样式协同出现。这个任务的难点在于输出质量较主观,很多系统即使能渲染网页,也可能缺少关键信息或视觉层级。Flow 在这个任务上的成功率低于另外两个任务,反而说明它不是被简单任务刷高分,而是在更开放的设计任务中仍然体现优势。

三类任务合在一起,覆盖了编程、文档生成和网页设计三种常见 agent 应用场景。它们共同点是都能拆成多个模块,也都有可检查的终态。Flow 适合这些任务,是因为模块之间既有独立性,又有必须整合的依赖。如果任务完全不可拆,AOV 图帮助有限;如果任务只有独立批处理,没有下游整合,动态更新的价值也会下降。

如何解读实验结果中的差距

Flow 在五子棋上的优势最明显,因为游戏开发对模块接口和规则完整性非常敏感。基线如果把任务拆得不清楚,容易出现能显示棋盘但规则错误、能落子但不能判胜、或代码无法编译的问题。Flow 通过明确子任务和依赖,使规则、界面和 AI 之间更容易被连接,也让失败后补桥任务有明确位置。

Beamer 任务中,Flow 与部分基线的差距相对温和,因为课件生成对工作流结构的依赖没有游戏那么强。很多模型即使按顺序生成,也能产生可编译内容。但 Flow 仍然保持较高成功率,说明它在内容模块完整性和格式约束上更稳。对于这种任务,动态更新的主要价值不是修复复杂程序逻辑,而是补齐内容缺口和结构约束。

网站任务中,Flow 的成功率不是满分,这很值得重视。网页设计包含更多开放审美和信息组织因素,结构化 workflow 只能保证任务覆盖和模块整合,不能完全保证视觉设计优秀。人工评分中 Flow 仍然领先,说明它在整体完成度上更好,但该任务也暴露了方法边界:当评价强依赖审美、创意和细节 polish 时,图结构只是基础,不能替代专业设计判断。

消融结果比主结果更能说明动态更新的必要性。作者故意把部分子任务输出遮蔽为空值,这等于模拟运行时失败。没有更新的系统会把空缺传播到下游;有更新的 Flow 则能根据缺口调整图。五子棋任务中无更新版本成功率为零,说明这个任务对中间模块完整性非常敏感,也说明静态 workflow 在面对局部失败时非常脆弱。

和其他 workflow 自动化工作的关系

Flow 与 AFlow 名字相近,但关心点不同。AFlow 更像是在搜索或优化工作流程序结构,把工作流作为可迭代改写的代码对象;Flow 则强调多智能体执行时的 AOV 图、模块化指标和动态更新。一个偏向离线或外层自动优化,一个偏向运行时任务图调度。把两者放在一起看,可以发现 agent workflow 研究正在从“写提示词”走向“管理可执行结构”。

与 GPTSwarm、DyLAN、MACNET 等图式多智能体方法相比,Flow 的特点是把依赖图直接对应到任务分解和执行状态,而不是只表示智能体之间的通信关系。有些系统关注谁和谁通信,有些系统关注哪个智能体更重要;Flow 更关注任务节点之间的先后关系和可并行性。这种视角更接近工程工作流,也更容易落到具体任务产物上。

与 MetaGPT 这类 SOP 驱动系统相比,Flow 更灵活。SOP 的优点是稳定、清晰、符合人类团队流程,但缺点是预设流程可能不适合每个任务,也不一定能根据中间输出重构。Flow 不预设固定职能链,而是让 LLM 生成候选图,再用结构指标筛选。这种方式牺牲了一部分流程确定性,换来更强的任务适配能力。

与 AutoGen、CAMEL 相比,Flow 的差异在于它不把对话本身当成主要组织机制。对话可以产生内容,但对话历史不是一个好的调度结构。Flow 让对话和生成发生在节点内部,把节点之间的关系交给图结构管理。这样可以减少“大家都在聊天但任务状态不清楚”的问题。

复用时应怎样设计检查器

如果在真实项目里复用 Flow,最难的部分往往不是生成图,而是定义每个节点的验收条件。论文任务有相对明确的成功信号:代码能否编译、网页能否渲染、课件能否通过 LaTeX、功能是否覆盖。自己的项目也需要类似检查器,否则动态更新只能依赖模型自评,可靠性会下降。

检查器可以分三层。第一层是机器可验证信号,例如构建是否通过、测试是否通过、文件是否存在、JSON schema 是否合规。第二层是任务清单信号,例如页面是否包含日程、地图、地点,游戏是否包含胜负判断和平局处理。第三层是质量信号,例如内容是否连贯、视觉层次是否清楚、解释是否足够完整。Flow 的图更新越能接入这些信号,越能避免盲目重规划。

节点粒度也需要调。粒度太粗,图没有足够并行和局部修复空间;粒度太细,调度和更新成本会上升,模块接口也会变多。论文中的任务粒度大致对应可独立完成、又能被明确验收的工作单元。复用时可以遵循这个原则:一个节点应该产出可被下游消费的明确中间产物,并且有办法判断它是否满足需求。

更新权限也要限制。让 LLM 可以随意修改所有节点,可能导致工作流漂移;完全禁止结构变化,又失去 Flow 的优势。更稳妥的做法是要求更新器输出结构化 diff,例如新增节点、删除节点、修改节点需求、修改边、重新分配 agent,并让程序检查图是否仍然是 DAG、是否保留已完成成果、是否满足原始任务约束。

论文留下的开放问题

第一个开放问题是候选图数量。论文让模型生成多个候选 workflow,再按指标选择,但候选数量越多,成本越高;候选数量越少,可能错过更好的结构。真实系统可以考虑自适应策略:简单任务少生成候选,复杂任务或失败后多生成候选;也可以缓存常见任务模板,减少重复调用。

第二个开放问题是更新质量评估。Flow 用并行度和依赖复杂度选择图,但运行时更新还涉及已有成果保护、错误定位和补救任务设计。一个更新后的图可能结构指标更好,却删除了重要上下文;也可能为了修复一个错误引入更多不必要节点。因此未来系统可能需要把“保留已完成有效产物”“最小修改原则”“预期修复收益”也纳入选择标准。

第三个开放问题是多智能体通信成本。Flow 强调并行执行,但并行并不总是免费。多个 agent 同时工作可能产生不一致的接口假设,后续整合需要额外沟通。论文通过图依赖和 data 字段缓解这个问题,但对于更大规模任务,可能还需要接口规范、共享记忆或合并器 agent 来管理跨模块一致性。

第四个开放问题是人工监督位置。论文展示了自动更新能力,但在高风险任务里,某些图修改可能需要人类确认。例如删除关键步骤、改变安全约束、重写目标需求都不应完全自动化。工程落地时,可以把 Flow 的更新分为低风险自动修改和高风险待确认修改,让系统既有自主性,也保留可审计边界。

整体来看,Flow 的价值不在于提出一个复杂到难以复现的系统,而在于把多智能体 workflow 的三个问题放到一个清楚框架里:用图表示任务结构,用指标选择更模块化的图,用运行时状态驱动局部更新。这个框架足够简单,可以被迁移到很多 agent 项目;也足够具体,能提醒我们不要把多智能体协作简化成“多几个角色一起聊天”。

把 Flow 落到真实系统时的架构切分

真实系统里可以把 Flow 拆成四个服务边界。第一个是图生成器,负责根据用户任务、已有模板和历史案例提出候选图。第二个是图验证器,负责检查候选图是否无环、节点字段是否完整、依赖是否引用了不存在的节点、是否保留必须完成的任务。第三个是执行器,负责按照依赖计数调度节点,把任务交给对应 agent 或工具。第四个是更新器,负责在检查失败或中间产物不足时生成结构化修改。这样拆分后,LLM 只负责它擅长的语义规划,程序负责它擅长的约束校验。

其中图验证器非常重要。论文里候选图来自语言模型,语言模型可能生成循环依赖、缺少 agent 的节点、引用错误的子任务名,或者把已经完成的关键节点删掉。工程系统不能直接相信这些输出,而应该把候选图当成未验证提案。只有通过结构校验、字段校验和任务覆盖校验后,图才能进入执行器。这个步骤能显著降低动态更新带来的不确定性。

执行器最好保持简单。它不需要理解所有业务语义,只需要维护依赖计数、运行就绪节点、收集输出和触发验收。复杂语义交给每个节点的 agent 和检查器处理。这样设计的好处是可替换:今天节点执行者可以是 LLM agent,明天也可以是传统脚本、搜索工具、编译器或人工审核。Flow 的图结构不绑定某一种执行方式,因此适合作为混合自动化系统的骨架。

更新器则需要被严格记录。每一次图修改都应该产生变更日志,包括修改原因、涉及节点、旧依赖、新依赖、保留的中间产物和预期修复目标。没有日志,动态 workflow 很快会变成难以审计的黑箱。论文强调模块化和可更新性,但真实项目还要补上可观察性:当最终输出失败时,团队要能回看是哪次更新引入了错误。

对提示词设计的启发

Flow 的提示词不应该只要求模型“写一个计划”,而应该要求模型输出结构化任务图。一个好的初始化提示词需要明确节点粒度、依赖含义、agent 分配方式、输出字段和验收标准。否则模型容易生成漂亮但不可执行的自然语言步骤。把输出格式限制为图结构,会迫使模型显式说明哪些任务可以并行,哪些任务必须等待前置结果。

更新提示词则要提供更丰富的上下文。它至少需要看到原始用户任务、当前图、每个节点状态、已完成节点的数据摘要、失败节点的错误信息、检查器反馈和禁止修改的约束。缺少这些信息时,模型可能只凭常识重写计划,而不是针对实际失败做局部修复。论文的核心经验之一就是让更新发生在“当前执行事实”之上,而不是发生在抽象任务描述之上。

提示词还应要求模型解释修改理由。这个解释不一定给最终用户看,但对调试非常有价值。例如更新器新增一个“整合规则与界面事件”的节点,应说明它发现规则模块和界面模块之间缺少连接;修改 CSS 节点依赖时,应说明页面结构已经完成,可以直接进入样式阶段。这样的理由能帮助程序或人工判断修改是否合理。

为什么这篇论文对 agent 产品有现实意义

很多 agent 产品最初都从单轮生成开始:用户给任务,模型给答案。进一步发展后,会加入工具调用、记忆和多轮交互。但当任务变得更长、更复杂时,真正的瓶颈常常不是模型不会生成,而是系统不知道如何组织工作。Flow 提醒我们,复杂 agent 产品需要一个工作流层,负责表示任务、追踪状态、管理依赖和吸收失败。

这种工作流层也能改善用户体验。用户不必只等待一个最终答案,而可以看到哪些子任务已完成、哪些模块正在执行、哪里失败并触发了修复。对于代码生成、报告撰写、网站搭建、数据分析这类长任务,可观察进度会提升信任感。Flow 的图结构天然适合展示这种进度,因为每个节点都有状态和依赖。

更重要的是,Flow 让失败变得可恢复。传统一次性生成失败后,用户往往只能重新提示或手动修改;静态多智能体流程失败后,也可能需要从头再跑。Flow 的局部更新提供了第三种路径:保留正确部分,只修复错误部分。这与真实软件开发很接近,因为工程师也不会因为一个模块失败就重写整个项目,而是定位依赖、补接口、重跑测试。

读完之后应该带走的判断

判断一个任务是否适合 Flow,可以看三个问题。第一,任务能否拆成多个有明确产物的子任务;第二,子任务之间是否存在真实依赖而不是完全独立;第三,是否有检查信号能判断中间产物好坏。如果三个答案都是肯定的,Flow 的图表示和动态更新大概率有价值。如果任务只是简单问答,或者没有任何可验证反馈,那么引入完整 Flow 运行时可能过重。

判断一个 Flow 实现是否靠谱,也可以看三个问题。第一,它是否真的把 workflow 存成可检查的数据结构,而不是只把计划写在 prompt 里;第二,它是否用程序检查图结构和节点状态,而不是完全相信模型自述;第三,它是否在更新时保留已有有效产物,而不是频繁推翻重来。满足这些条件,系统才接近论文想表达的“模块化可更新工作流”。

最后,Flow 的思想可以和很多已有工程实践合并。它可以接入测试驱动开发,用测试失败触发节点更新;可以接入前端构建流程,用编译和视觉检查作为验收;可以接入文档生成流程,用大纲覆盖率和引用检查作为节点信号;也可以接入数据分析流程,用表格 schema、图表生成和统计检查约束产物。论文虽然实验规模不大,但提供了一个可以扩展的结构化思路。

还需要注意的是,Flow 并不要求所有节点都由同一种模型完成。更合理的实现是按节点类型选择执行者:规划类节点用推理能力更强的模型,批量改写或格式化节点用便宜模型,编译、测试和截图检查交给确定性工具,关键审核节点交给人工或更严格的评估器。这样一来,图结构不仅组织任务,也可以组织成本。

这种成本组织能力是多智能体系统走向产品化时很重要的一步。没有显式图结构时,系统很难知道哪一步值得用强模型,哪一步可以用工具或缓存结果;有了节点和依赖之后,每个节点都可以绑定预算、超时、重试次数和验收策略。Flow 论文没有把这些工程字段全部展开,但它的表示方式已经给这些扩展留下了位置。

因此,读这篇论文时可以把它看成一个“agent workflow 操作系统”的雏形:它不直接保证每个智能体都聪明,却规定任务怎样被拆开、怎样并行、怎样检查、怎样在失败后继续前进。对于希望长期运行复杂任务的 agent 应用来说,这种运行时层往往比单次提示词优化更关键。

换句话说,Flow 讨论的不是某个提示词技巧,而是复杂任务执行时的控制面。它把任务、状态、依赖、产物和修复动作都纳入同一张图里,让系统可以解释自己为什么等待、为什么并行、为什么重试、为什么改图。这个控制面越清楚,后续加入缓存、权限、人工确认、评估器和成本策略就越自然。

从这个角度看,论文的实验虽然只覆盖三类任务,但方法论指向更普遍的问题:当智能体系统需要连续工作几十步时,最稀缺的不是“再生成一句回答”的能力,而是保持上下文边界、任务边界和失败边界的能力。Flow 用图结构把这些边界显式化,因此它比普通多轮对话更像一个可以维护、可以调试、可以迭代的工程系统。