harness_evolve/notes/ref15_aflow.md

AFlow: Automating Agentic Workflow Generation

一句话总结:把"多次调用 LLM 的 agentic workflow"整体表示成一段可执行代码(LLM 调用是节点 Node,代码控制流是边 Edge),再用一个为 workflow 优化定制的蒙特卡洛树搜索(MCTS)在这个代码空间里搜——用"树结构经验 + 执行反馈 + soft 混合概率选择 + LLM 当优化器扩展节点"迭代改写,几乎从空模板出发就能自动长出媲美人类专家手工设计的工作流;在 6 个基准上平均超手工方法 5.7%、超已有自动化方法 19.5%,还能让小模型以 4.55% 的成本追平/超过 GPT-4o。


TL;DR 速览

tags: #agentic-workflow #workflow自动化 #MCTS #code-represented-workflow #LLM-as-optimizer #自我改进 #operator #成本效率

related: [[ref13_adas-automated-design-agentic-systems]](最近亲:同样 code 表示 workflow,AFlow 用 MCTS 替掉其线性搜索)· [[ref09_meta-harness]]("优化 harness 的 harness",把结构从外环下放到 Agent 的更彻底版本)· [[ref19_gepa]](反思式 prompt 进化,另一条自动优化路线)· [[ref07_ace-agentic-context-engineering]] · [[ref08_mce-meta-context-engineering]] · [[ref17_self-harness]](自我改进 harness 谱系)


摘要

LLM 通过遵循详细指令与操作序列的 agentic workflow 来解决跨域复杂任务,但构建这些 workflow 需要大量人力,限制了可扩展性与泛化性。已有工作试图自动化 workflow 的生成与优化,但仍依赖初始手工设置,未能实现"完全自动 + 有效"的 workflow 生成。为此我们把 workflow 优化重新形式化为在代码表示的 workflow 上的搜索问题(LLM 调用节点由边连接),提出 AFLOW——一个用 MCTS 高效探索该空间的自动化框架,通过代码修改、树结构经验、执行反馈迭代精炼 workflow。

在 6 个基准上,AFlow 相对 SOTA 基线平均提升 5.7%;更进一步,AFlow 让更小的模型在特定任务上以 GPT-4o 4.55% 的推理成本(美元计)超过 GPT-4o。


1 介绍:为什么要"自动生成 agentic workflow"

论文的动机链条非常清楚:

  1. LLM 在代码生成、数据分析、决策、问答等任务上已成为强工具,但其能力发挥高度依赖手工设计的 agentic workflow——一串带详细指令的 LLM 调用序列。
  2. 设计和精炼这些 workflow 要大量人力,限制了 LLM 向新领域的可扩展性、也阻碍了跨任务技能迁移。
  3. 已有自动化尝试都没到"完全自动":DSPy(Khattab et al.)需要先手工搭好 workflow 再自动优化 prompt;TextGrad / GPTSwarm(Yüksekgönül / Zhuge et al.)的优化目标无法表达足够多样的 workflow 结构;ADAS(Hu et al.)用代码表示 workflow 已经比较完整,但线性启发式搜索太低效,有限迭代内搜不出有效 workflow。

[!TIP] 什么是 agentic workflow(智能体工作流)? agentic workflow 是"用预定义的静态流程 + 多次 LLM 调用来完成任务"的一种 LLM 应用范式。它和 autonomous agent(自主智能体)是两条不同的路线: - agentic workflow:流程事先定好(比如"先生成 3 个解 → 投票选最优 → 用代码验证 → 失败则修"),LLM 在每个节点上执行一个被规定好的动作,没有自主决策权。 - autonomous agent:在环境里动态自主决策下一步做什么(如 ReAct / Voyager)。

本文只做前者。作者的论点是:agentic workflow 可以基于已有人类领域经验 + 迭代精炼来构建,因此比 autonomous agent 更适合自动化构造——因为它有稳定的结构可供搜索,而不需要在开放环境里学一套决策策略。本文的目标就是把"人工设计 workflow"这件事自动化掉。

核心 idea:把 workflow 建模成互联的 LLM 调用节点——每个节点是一个 LLM 动作,边定义节点间的逻辑、依赖与流转。这一下就把 workflow 变成一个巨大的搜索空间,涵盖海量可能的配置。目标是高效地逛这个空间,自动生成"最大化任务性能、最小化人工干预"的优化 workflow

两大挑战:(1) 任务多样复杂,每个任务的需求/操作/依赖都不同,很难用"统一又灵活"的方式表示;(2) workflow 搜索空间由海量代码结构 + 节点配置组成,近乎无界,高效探索非常难。

AFlow 的应对:用 MCTS 系统性探索;用代码化的边把 workflow 建成图/网络;引入 operator(预定义可复用的节点组合,如 Ensemble、Review&Revise)当高级积木;四步循环(软混合概率选择 + LLM 扩展 + 执行评估 + 经验回传)保证效率。

三大贡献:(1) 问题形式化——统一定义 workflow 优化问题,把已有方法都归为特例;(2) AFlow——基于 MCTS、跨域最小人工干预地自动发现有效 workflow;(3) 大量评估——6 基准,超手工 5.7%、超自动化 19.5%,且让小模型有更好的成本-性能比。

下图是全文的招牌结果:

Figure 1: AFlow 与各方法在 6 基准上的性能对比

Figure 1 逐元素解读:横轴是 6 个基准(HotpotQA、DROP、HumanEval、MBPP、GSM8K、Math),纵轴 Performance(Math/GSM8K 用 solve rate,HotpotQA/DROP 用 F1,HumanEval/MBPP 用 pass@1)。每组柱子是 8 种方法:IO(直接调用)、CoT、CoT-SC、MedPrompt、MultiPersona、Self-Refine、ADAS,以及 Ours(黄色 = AFlow)。关键信息:黄色柱在 6 个基准上全部最高——尤其在最难的 Math 上 56.2 远超次好的 MultiPersona 50.8、更把 ADAS 的 35.4 甩开一大截;在 MBPP 上 83.4 vs ADAS 的 53.4(ADAS 在这两个难任务上甚至弱于最简单的 CoT,暴露了它"线性搜索搜不动难题"的问题)。这张图一眼就说明:AFlow 既超手工、也超同类自动化。


2 相关工作:定位在"自动化 agentic 优化"的第三类

作者把 LLM 应用分成 agentic workflow 与 autonomous agent 两条线,然后把自动化优化分成三类,AFlow 属于最有潜力的第三类(自动 workflow 优化)。下面把关键前作讲透——理解它们的局限,才理解 AFlow "新在哪"。

[!TIP] ① 自动 prompt 优化 / 超参优化(只动局部,不动结构) - DSPy(Khattab et al., 2024):把"声明式的 LLM 调用"编译成 SOTA pipeline,用 LLM 优化 pipeline 里的 prompt。但workflow 结构要人先搭好,它只在固定结构内优化 prompt。 - TextGrad(Yüksekgönül et al., 2024):把"文字反馈"当作可反传的"梯度",串起多组件做优化。 - Large Language Models as Optimizers / OPRO(Yang et al., 2024a):把 LLM 当优化器,喂历史 (解, 分数) 让它提新解。 - Archon(Saad-Falcon et al., 2024):推理时技术的超参搜索框架。

共同局限:泛化到新任务弱,且往往仍需中等人力做任务专用设计。它们优化的是"填空",不是"结构本身"。

[!TIP] ② 自动 workflow 优化(动整个结构,AFlow 的直接赛道) - GPTSwarm(Zhuge et al., 2024):把 agent 表示成可优化的图,用强化学习优化图结构。局限:图结构难以表达带条件状态的 workflow(条件分支、循环等)。 - ADAS(Hu et al., 2024)用代码结构表示 workflow,把历史 workflow 存成线性列表,目标与 AFlow 最接近。局限:受限于搜索算法效率——它在搜索中用过于简化的经验表示(只按"生成顺序 + 分数"区分历史 workflow),导致难以发现有效 workflow。见 [[ref13_adas-automated-design-agentic-systems]]。 - AutoFlow(Li et al., 2024b)/ Symbolic Learning(Zhou et al., 2024b):其它 workflow 自动化尝试。

AFlow 与 ADAS 的关键差异(这段是全文"新在哪"的最凝练表述):

维度 ADAS AFlow
workflow 表示 代码 代码 + 更基础的 named node(含 model/temperature/prompt/format 多参数)
高级积木 Operator(预定义节点组合的统一接口)
历史经验存储 线性列表(顺序 + 分数) 树结构经验(每次修改 + 相对父节点涨跌)
搜索算法 线性启发式 为 workflow 定制的 MCTS(软混合概率选择 + 回传经验)
结果 有限迭代搜不出好 workflow 有限迭代内高效发现有效 workflow

[!NOTE] 一句话概括本文与前作的关系:GPTSwarm 图表示力不够、ADAS 有代码表示但搜索太笨。AFlow 把"代码表示"这个正确方向保留,再在两处做加法:(a) 用 operator 抬高搜索空间的抽象层级;(b) 用 MCTS 的树结构把"历史经验"从'一堆流水账'变成'带因果结构的成功/失败地图'。这正是它能在有限预算内跑赢 ADAS 的根因。


3 预备:把 workflow 优化形式化为代码空间搜索

本节是全文最需要读透的形式化部分。作者先给出 workflow / 搜索空间 / 优化目标的统一定义(§3.1),再讲 AFlow 的设计取舍(§3.2)。核心概念的图示见 Figure 2。

Figure 2: Node、Operator、Edge 三者的概念示意

Figure 2 逐面板解读(这张图是形式化的直观锚点): - 左「Node」:一个 LLM 调用节点的可选参数——Prompt("You're a helpful assistant… Let's think step by step…")、Temperature ∈ [0,1]、Models(图标示意可换不同底座)、以及输出被结构化成 <thought>…</thought><solution>…</solution>节点 = 一次被完整参数化的 LLM 动作。 - 中「Operator」:几个预定义算子的内部结构示意——Self-Consistency Ensemble(多个 Generate 节点 → 汇聚到一个 Ensemble 节点投票)、Multi-Agent Debate(带 History 与 Conditions 的循环 + Judge 节点)、Self-Refine(Review 节点 → Revise 节点 + Conditions 的循环)。每个 operator 都是"若干节点 + 边"打包成的可复用单元,右上角的 强调它本质是代码。 - **右「Edge」**:边的三种常见表示——**Graph**(节点连成的有向图,表达层级/顺序/并行)、**Code**(Python/多语言,)、Networks(网络结构,表达非线性可学习关系)。本文最终选 Code 作为主边结构

3.1 问题形式化

agentic workflow \(W\) 定义为一串 LLM 调用节点 \(N = \{N_1, N_2, \dots\}\) 用边 \(E\) 连接以定义执行顺序。每个节点 \(N_i\) 由四个参数刻画:

节点参数 含义
Model \(M\) 该节点调用的具体语言模型
Prompt \(P\) 提供给模型的输入 / 任务描述
Temperature \(\tau\) 控制该节点 LLM 输出随机性的温度,\(\tau \in [0,1]\)
Output format \(F\) 输出的结构化格式(xml / json / markdown / raw;受 Tam et al. 2024 启发,不同格式影响性能)

\(E\) 是定义节点关系、支配执行顺序的抽象结构,可用三种方式表示:Graph(灵活表达层级/顺序/并行,但要 Petri 网、BPMN 等复杂扩展才能自然表达并行与条件)、Neural Network(可自适应但对执行缺乏精确控制)、Code(能用标准编程构造表达线性序列、条件、循环,并可内嵌图/网络结构,对 LLM 的执行控制最精确)。因此 AFlow 采用 code 作为主边结构以最大化表达力。

自动 workflow 优化:给定任务 \(T\) 与评估函数 \(G\),目标是找到最大化 \(G(W,T)\) 的 workflow \(W\)。搜索空间 \(S\) 涵盖所有节点参数与边结构的可能配置:

\[ S = \{(N, E)\mid E \in \mathcal{E}\},\quad N = \{N(M,\tau,P,F)\mid M\in\mathcal{M},\ \tau\in[0,1],\ P\in\mathcal{P},\ F\in\mathcal{F}\} \]

于是优化问题写成:

\[ W = A(S, G, T),\qquad W^{*} = \arg\max_{W \in S} G(W, T) \]
符号 含义
\(S\) 搜索空间 = 所有 (节点配置, 边结构) 的组合
\(\mathcal{M},\mathcal{P},\mathcal{F},\mathcal{E}\) 可选的语言模型集、prompt 集、输出格式集、边配置集
\(A\) 搜索算法(AFlow 里 = 定制 MCTS)
\(G\) 评估函数(推理任务里是可显式计算的数值指标,如 solve rate / F1 / pass@1)
\(T\) 目标任务
\(W^{*}\) 最大化 \(G\) 的最优 workflow 配置

[!TIP] 把这个形式化讲透 + 用"前人方法是特例"来理解 这套定义的野心在于它把已有方法都收编成特例: - 只搜 \(P\)(固定 \(N\) 的结构和 \(E\) → 就是 prompt 优化(DSPy / OPRO)。 - 只搜 \(E\) 但用受限的图结构 → 就是 GPTSwarm(图表达力不足 → 表达不了条件状态)。 - 同时搜 \(P\)\(E\)、且 \(E\) 用代码 → 就是 ADAS / AFlow 的赛道(表达力最完整)。

换句话说,作者把"自动化 workflow"这件事画成了一张统一坐标图,指出维度越全(连边都能改、还用代码表示)表达力越强,然后论证 AFlow 站在最全的那个角。这是"问题形式化"作为独立贡献的价值:它让后续研究能在"节点层"和"workflow 层"分别定位自己。

3.2 AFlow overview:把搜索空间简化到"可搜"

形式化(引入 Operator 后的简化搜索空间):直接搜 \((M,\tau,P,F,E)\) 全维度太贵,AFlow 做两步简化: 1. 固定 \(M\)\(\tau\)\(F\)——把搜索聚焦在代码化的边 \(E\) 和 prompt 上。 2. 引入 Operator \(O\)——把常见 agentic 操作(Ensemble、Review、Revise 等)封装成"组合 \(N\)\(E\) 的统一接口",当作高级积木。

于是 AFlow 的搜索空间与优化问题变成(论文式 (1)(2)):

\[ S_{\text{AFlow}} = \{(P_1,\dots,P_n,\ E,\ O_1,\dots,O_n)\mid P_i\in\mathcal{P},\ E\in\mathcal{E},\ O_i\in\mathcal{O}\} \tag{1} \]
\[ W^{*} = \text{AFLOW}(S_{\text{AFlow}}, G, T) \tag{2} \]
符号 含义
\(\mathcal{O}\) 预定义算子集合(Ensemble / Review&Revise / Test / Programmer / Custom …)
\(P_i\) \(i\) 个(Custom 节点里的)可优化 prompt
\(E\) 代码表示的边(控制流)
\(W^{*}\) AFlow 搜出的最优 workflow

[!TIP] 什么是 Operator(算子)?为什么它是效率关键? Operator 是 AFlow 的核心工程发明:它把"若干 LLM 调用节点 + 它们之间的边"打包成一个预定义、可复用、有统一调用接口的单元,代表一种常见的 agentic 操作。本文实现了 7 个: - Generate(Contextual / Code 两种):基础生成节点。 - Format:把解格式化成要求的形式。 - Review & Revise(Madaan et al. 2023 的 Self-Refine):先审查再修订。 - Ensemble(Wang et al. 2022 的 Self-Consistency):多解投票选最优。 - Test(Zhong et al. 2024a):跑公开测试用例,失败则反思修正(代码任务专用)。 - Programmer:生成并执行 Python 代码(带超时/异常保护),给数学题提供精确数值计算能力。 - Custom:默认算子,用于构建基础节点,Optimizer 可自由生成/修改其 prompt。

为什么重要:搜索空间近乎无界,若让 LLM 从零拼节点,很多轮都浪费在"重新发明 ensemble"上。Operator 相当于把"人类已知有效的 agentic 模式"当先验注入搜索空间,让 MCTS 直接以"加一个 Ensemble / 加一个 Test"为动作,大幅压缩有效搜索的步数。妙处在于:即使一个 operator 都不给,AFlow 也能只用 Custom 从头拼出 workflow(消融里仍达 93.1%,还自发长出 ensemble)——operator 是"加速器"而非"必需品"

任务范围:本文聚焦有数值评估函数的推理任务(QA / 代码 / 数学)。operator 集合可轻松扩展以适配不同任务。


4 AFlow 的设计细节(核心中的核心)

[!TIP] 什么是 MCTS(蒙特卡洛树搜索)?在 AFlow 里被改成了什么样? MCTS 是 AlphaGo 用的那套搜索算法,经典四步:Selection(按 UCT 等策略从根往下选一个有前途的节点)→ Expansion(扩展一个新子节点)→ Simulation/rollout(随机模拟到终局拿一个回报)→ Backpropagation(把回报沿路径回传,更新每个节点的价值估计)。它的精髓是"在利用已知好路径 vs 探索未知新路径之间平衡"。

AFlow 对 MCTS 做了为 workflow 优化定制的三处改造: 1. 树节点 = 一个完整的 workflow(不是单个 LLM 调用节点),这样搜出的是"一类问题的通用解"。 2. 没有真正的 rollout 模拟——因为推理任务有显式评估函数 \(G\)直接在验证集上真跑 workflow 拿分当回报(比蒙特卡洛模拟更准)。 3. Selection 用"软混合概率"而非纯 UCT,且任意轮都能从空白模板重新生成以逃离局部最优。

AFlow 的核心是用 LLM 当优化器、在 MCTS 变体里发现有效 workflow。迭代循环:软混合概率选择 → LLM 优化扩展 → 执行评估 → 经验回传,直到最大轮数或收敛。整体框架见 Figure 3。

Figure 3: AFlow 整体框架(Search Space → Search via AFlow → Search Result)

Figure 3 逐面板解读(全文方法的心脏图,建议对照下面的四步细读): - 左「Search Space」:定义搜的是什么。Node 分 Fixed Parameters(Model / Temperature / Output Format 固定)与 Variable Parameters(Prompt 可变,图里就是那段 "Think step by step…" 的 prompt);下方一排 Operators(Format / ContextualGenerate / CodeGenerate / Review&Revise / Test / Programmer / Ensemble)当积木;最底 Code Represented Edges——一段 def __call__ 里带 await self.generate(...)await self.custom(...)if response=='False': … else: … 的代码,说明边就是代码控制流。 - 中「Search via AFlow」:MCTS 的四步循环围成一个环——Soft Mixed Probability Selection(从候选里软概率选一个父 workflow)→ LLM-Based Expansion(LLM 当优化器改代码生成新 workflow,图里从 Selected 长出 Expanded)→ Executing Evaluation(真跑拿 performance)→ Experience Backpropagation(把经验回传),中间标注 if max N rounds or no improvement 就退出。m/n 标记节点。 - 右「Search Result」:搜出的三个不同结构的 workflow 实例——Math Workflow(生成→refine→detail→simplify→ensemble)、Question-Answering Workflow(identity check→fact check→analysis→format)、Code Generation Workflow(带 if…else…True/False 分支的 fix-code 循环)。同一个 AFlow,针对不同任务自动长出结构迥异的 workflow——这就是"自动适配任务复杂度"的可视化证据。

下面按 Algorithm 1 逐步讲清四个阶段。

[!NOTE] Algorithm 1|AFlow 主循环(伪代码复述) 输入: 初始 workflow W0, 评估器 G, 数据集 D, 轮数 N=20, top-k=3, 早停轮数 n=5, 算子集 O 1. 把 D 随机切成 验证集 DV(20%) 和 测试集 DT(80%)(seed=42) 2. 在 DV 上跑 5 次空白 W0 → 选"分数方差高"的题作为最终 DV(省算力、信号强) 3. W* ← W0 4. for round = 1..N: 5. round=1 时 parent←W0; 否则 parent←SelectParent(results) # 软混合概率 6. context ← LoadContext(parent, experiences) # 加载父节点的树结构经验 7. W_round, modification ← Optimizer(context, O) # LLM 当优化器,改代码扩展 8. for i=1..5: score,cost ← Executor(W_round, DV) # 真跑 5 次求均值+方差 9. avgScore ← mean; experience ← (parent, modification, avgScore) # 记录经验 10. experiences.append(experience); 若 avgScore>best 则更新 W* 11. 若 top-k workflow 连续 n 轮不变 → 早停 return W* 12. return W*

阶段 0 — Initialization(初始化)

模板 workflow \(W_0\)(只提供调用节点/算子的框架,LLM 优化器只需补全 call 函数)出发。数据集按 20%/80% 切成验证/测试集(seed=42)。为省算力,先在验证集上跑 5 次空白模板挑出"分数方差高"的那批题当最终验证集——这些题最能区分 workflow 好坏,信号最强。

阶段 1 — Selection(软混合概率选父)

这是 AFlow 逃离局部最优的关键设计。从 top-k workflow 加上初始 workflow里按下式采样父节点:

\[ P_{\text{mixed}}(i) = \lambda \cdot \frac{1}{n} + (1-\lambda)\cdot \frac{\exp(\alpha\cdot(s_i - s_{\max}))}{\sum_{j=1}^{n}\exp(\alpha\cdot(s_j - s_{\max}))} \tag{3} \]
符号 含义 / 取值
\(n\) 候选 workflow 数量
\(s_i\) workflow \(i\) 的分数;\(s_{\max}\) 是当前最高分
\(\alpha\) 控制"分数影响力"的温度(正文 §Selection 取 0.4
\(\lambda\) 平衡探索/利用的权重(正文取 0.2
第一项 \(\lambda/n\) 均匀分布(纯探索:每个候选等概率)
第二项 score-based 分布(softmax,高分候选概率大 = 利用)

[!TIP] 把式 (3) 讲透 + 举例 + 一处需要注意的不一致 这是一个均匀 + 打分两个分布的凸组合\(\lambda\) 越大越偏探索(均匀),\(\lambda\) 越小越偏利用(追高分)。

数值举例(取正文 \(\lambda=0.2,\ \alpha=0.4\),3 个候选分数 \(s=[0.90, 0.85, 0.50]\)\(s_{\max}=0.90\)): - score 项的未归一权重 \(w_i=\exp(0.4\cdot(s_i-0.90))\)\(w=[\exp(0),\exp(-0.02),\exp(-0.16)]=[1.000, 0.980, 0.852]\),归一后 \(P_{\text{score}}=[0.353,0.346,0.301]\)。 - 均匀项 \(P_{\text{uniform}}=[0.333,0.333,0.333]\)。 - 混合:\(P_{\text{mixed}}=0.2\times0.333 + 0.8\times P_{\text{score}} = [0.349,0.344,0.307]\)

注意 \(\alpha=0.4\) 很小 → softmax 很"平",即使最低分候选(0.50)也有约 30% 概率被选中。这正是设计意图刻意保留对"当前看起来不好"的分支的探索,加上"把初始空白模板永远放进候选池",让 AFlow 任何一轮都能从零重启一条新路径,避免陷入局部最优。

一处文献内不一致(读者需知):正文 §Selection 写 "\(\alpha\) (0.4) controls score influence, \(\lambda\) (0.2) balances exploration",但附录 A.6 的 CalculateMixedProbabilities 伪代码里写成 "\(\lambda\gets0.4,\ \alpha\gets0.2\)"——两处 \(\alpha,\lambda\) 取值对调了。以正文为准\(\lambda=0.2\) 偏利用更符合"20% 探索"的常见设定)。

阶段 2 — Expansion(LLM 当优化器扩展)

用一个 LLM 当 optimizer(本文用 Claude-3.5-Sonnet),基于选中 workflow 的经验,通过改代码来生成新 prompt 或修改节点连接,产出新 workflow。喂给 optimizer 的经验极其丰富:包含对该 workflow 的所有修改及其对应的涨/跌,外加预测与期望输出的精确日志。优化 prompt(附录 A.1)明确允许它 add/modify/delete 节点/参数/prompt,可用 review/revise/ensemble/selfAsk 等思路和 Python 控制流,并约束"图复杂度不超过 10"。

阶段 3 — Evaluation(执行评估)

因为推理任务有显式评估函数,AFlow 直接执行 workflow 拿反馈。每个新 workflow 在验证集上跑 5 次,算均值和标准差。虽然增加了每轮成本,但更准的反馈 → 更高的搜索效率 → 最终反而减少所需迭代数。这是"用评估成本换搜索效率"的关键权衡。

阶段 4 — Backpropagation(经验回传)

执行后记录三样东西:(1) workflow 的性能;(2) optimizer 相对父 workflow 做了什么修改;(3) 相对父节点是成功还是失败。这份信息存入 experience 并回传到父 workflow,性能分则加入全局记录供 selection 用。

[!TIP] 什么是"树结构经验(tree-structured experience)"?它凭什么比 ADAS 的线性列表强? 这是 AFlow 相对 ADAS 的最核心区别。附录 C.1 给了一份真实的 experience(GSM8K 上)长这样(简化): json {"1": {"score":0.487, "success":{"2":{"modification":"Add Programmer operator...", "score":0.524}}, "failure":{"8":{"modification":"Add ScEnsemble operator...", "score":0.434}}}, "2": {"score":0.524, "success":{"3":{"modification":"Add ScEnsemble...", "score":0.528}}, ...}} 即:每个节点记下"从我出发做了哪些修改、各自涨/跌到多少",形成一棵带因果标注的树。

凭什么强:ADAS 把所有历史 workflow 塞进 prompt,只按"生成顺序 + 分数"区分——随着迭代累积,信息量爆炸、无关信息堆积,LLM 在里面像"无限可能性的探索者"而非"寻优的设计者"(作者原话)。而树结构让 LLM 重访某节点时精确复用成功、规避已知失败,把"历史"从一本流水账变成一张可导航的成功/失败地图。附录 C 总结了它带来的四种收益:Path Discovery(并行探多个方向、剪掉差分支)、Incremental Improvement(每步都知道该修改是否有益)、Pattern Recognition(识别高分分支的共性,如 Programmer+Custom+ScEnsemble)、Error Recovery(跌了就回溯到之前的成功态)

阶段 5 — Terminal Condition(早停)

top-k 平均分连续 \(n\) 轮无提升则终止,否则跑满 \(N\) 轮。用早停砍掉无谓的执行成本。

[!NOTE] 信息流串一遍(把四步连起来)空白模板 W0 → 在验证集选高方差题 → 软混合概率从 top-k+W0 里挑一个父 → 加载父的树结构经验LLM optimizer 读经验、改代码生成新 workflow(加个 operator 或改个 prompt)→ 在验证集真跑 5 次拿均值 → 把"改了什么 + 涨跌"回传进树 → 更新全局分数供下一轮 selection → 循环,直到早停/到轮数 → 返回全程最优 \(W^{*}\)整个过程 = "LLM 提改动 + 真执行给反馈 + 树把反馈结构化"三者闭环。


5 实验

5.1 设置

5.2 主结果

Table 1(全 GPT-4o-mini 执行,测 3 次取平均):AFlow 6 基准平均 80.3%,超所有手工 +5.7%、超 ADAS +19.5%;在难任务 MATH-lv5 与 MBPP 上比 ADAS +57%

Method HotpotQA DROP HumanEval MBPP GSM8K MATH Avg.
IO 68.1 68.3 87.0 71.8 92.7 48.6 72.8
CoT 67.9 78.5 88.6 71.8 92.4 48.8 74.7
CoT-SC (5) 68.9 78.8 91.6 73.6 92.7 50.4 76.0
MedPrompt 68.3 78.0 91.6 73.6 90.0 50.0 75.3
MultiPersona 69.2 74.4 89.3 73.6 92.8 50.8 75.1
Self-Refine 60.8 70.2 87.8 69.8 89.6 46.1 70.7
ADAS 64.5 76.6 82.4 53.4 90.8 35.4 67.2
AFlow (Ours) 73.5 80.6 94.7 83.4 93.5 56.2 80.3

[!IMPORTANT] ADAS 在 MBPP(53.4)、MATH(35.4)、HumanEval(82.4) 上甚至低于最朴素的 IO/CoT——这不是代码表示的锅,而是线性搜索在有限迭代内根本搜不动难任务。AFlow 用同样的"代码表示 workflow"却在这些难任务上大幅领先,直接坐实了"搜索算法(MCTS + 树经验)才是效率瓶颈的解药"这一核心论点

Table 2(可迁移性):用 GPT-4o-mini 或 DeepSeek-V2.5 搜出的 workflow,迁移到其它模型上执行,绝大多数仍强于基线——说明 workflow 有泛化性。但也观察到:用 DeepSeek 搜出的 workflow 在 GPT-4o-mini 上明显弱于"用 GPT-4o-mini 自己搜的"——不同模型需要不同 workflow 才能达最优(这点与 [[ref17_self-harness]] "harness 是模型专属的"完全呼应)。

5.3 成本分析:让弱模型打赢强模型

Figure 4(HumanEval 的成本-pass@1 Pareto 前沿,未嵌入)给出最有商业冲击力的结果:AFlow 能找到"让弱模型在成本-效率 Pareto 前沿上超过强模型"的 workflow。附录 D 的精确数字: - AFlow(GPT-4o-mini) 用 DeepSeek 执行 → 4.55% 的 GPT-4o 成本追平 GPT-4o 的 IO; - AFlow(DeepSeek) 用 DeepSeek、AFlow(GPT-4o-mini) 用 GPT-4o-mini → 分别以 5.92% / 8.05% 成本超过 GPT-4o IO。

意义:AFlow 既省掉了"人工设计 workflow"的人力成本,又打开了"用便宜模型 + 好 workflow 换取高性能"的门。

5.4 消融:operator 有用,但不是必需

Figure 5: GSM8K 上有/无 operator 的性能曲线 + 发现的最优 workflow 代码

Figure 5 逐元素解读: - (A) 左图:GSM8K 上 4 条 solve-rate 曲线(横轴迭代 1–20)——w/ operator(红,test/validation)和 w/o operator(蓝,test/validation)。关键信息:有 operator 收敛更快、终值更高(约 93.5% vs 93.1%),但即使完全没有 operator,AFlow 仍达 93.1%——超过所有手工设计。选 GSM8K 做消融是因为它数据量大,同样百分比的提升代表更多题被答对,避免小数据集的波动干扰对比。 - (B) 右图:AFlow 在 GSM8K 上搜出的最优 workflow 代码——async def __call__ 里:先 for _ in range(5) 用 Custom 生成 5 个解 → sc_ensemble 投票 → 用 Programmer operator 加一个代码验证步 → 若 verification['output'] 有值就返回验证结果,否则退回 ensemble 结果。这是一个"多解投票 + 代码验证"的混合结构,比任何单一 prompt 都强。

[!NOTE] 消融最惊艳的一点:去掉所有 operator 后,AFlow 仍自发进化出一个 "ensemble-like" 结构(附录 B:用三个不同 approach 的 prompt 分别解题 → 再用一个 compare-and-select 的 Custom 节点选最优)。这说明 AFlow 对"多解 + 选优"这种鲁棒策略有内在倾向——即便没被喂 Ensemble 积木,它也能从代码空间里重新发明出来,是"迈向完全自动化"的有力信号。

5.5 案例研究:从空模板到专家级 workflow

Figure 6: AFlow 在 GSM8K 上的树结构迭代过程

Figure 6 逐元素解读:这是 AFlow 搜索轨迹的可视化。中间的树:节点标着轮次(1→2→3→8→10…),实心黄圈 = 在最优路径上,虚线圈 = 不在最优路径上。每条边标注了"分数 + 这轮改了什么": - 1→2(0.859→0.887,Score 0.8872):Add a ScEnsemble operator。 - 2→30.9160):Add a review step using the Programmer operator。 - 80.9333):Modify the custom prompt for formatting the final answer。 - 100.9352):Modify the custom prompt for reasoning and checking step by step。 - 两侧黄框:对比两版 MATH_SOLVE_PROMPT——左边强调"只输出纯数字、不要解释文字",右边强调"每步都 double-check、把解代回原题验证"。紫色部分是本轮 prompt 的主要修改点

正文点出AFlow 每轮只做单步修改(要么加一个 operator,如 round 2/3;要么改一个 prompt,如 round 8/10),这让树搜索既能沿已知好路径深挖、又保留探索新路径的能力。也有失败轮:round 5 加了个"直接改答案、不额外推理"的 review 节点 → 掉分;round 14 试图重述问题却"过度关注 discount 信息" → 掉分。这些失败被树记录下来,供后续规避。

[!TIP] 附录里几个值得记住的"涌现"案例 - MBPP(附录 B.1):AFlow 从空模板长出一个类似 AlphaCodium(Ridnik et al. 2024)的 workflow——生成 3 个解 → ensemble → 生成额外测试用例 → 跑测试 → 失败则 FIX_CODE 修。人类专家的"flow engineering"被自动重现。 - HotpotQA(附录 B.1):AFlow 发现"格式化"是 QA 得分的关键因素之一(除了推理),并从执行反馈里自动学会正确格式(如"人名就只答人名,别加'The answer is'")——证明执行反馈的有效性。 - 开放式任务(附录 F):AFlow 甚至能扩展到没有数值反馈的任务——把评估函数换成 LLM-as-a-Judge(GPT-4o 打 4 维分),在"两万字小说生成""学术 idea 生成"上工作。对比很戏剧性:裸 Claude-3.5 面对"写两万字小说"直接拒绝("我做不到"),而 AFlow 优化出的 workflow(outline→character profiles→逐章生成的循环)真的产出了小说


6 结论

AFlow 提出了自动 workflow 优化的框架:全面形式化了问题(把已有方法归为特例),用 MCTS + 代码表示的 workflow 高效逛巨大搜索空间。6 基准实验证明它超手工、超已有自动化方法;消融证明它能自主发现有效结构(甚至无 operator);成本分析证明它能让弱模型在 Pareto 前沿上超强模型。作者认为这有望"革命性地"推动 agentic workflow 跨域落地。


个人思考

与其他论文的关联(放进本项目"harness / 自我改进"的坐标系)

方法论启示(可迁移的通用思路)

  1. "把经验结构化"比"把经验堆给 LLM"重要得多:ADAS→AFlow 的进步不在于喂更多历史,而在于把历史组织成"带因果标注(谁改了什么、涨还是跌)的树"。这个 insight 可推广到任何"迭代改进 + LLM 决策下一步"的场景——别把流水账塞进 prompt,给它一张可导航的成功/失败地图
  2. operator = 把领域先验当"高级动作"注入搜索空间:与其让 LLM 从原子操作从头拼,不如把"人类已知有效的模式"打包成积木,大幅压缩有效搜索步数。这是"搜索空间设计"的通用技巧——抽象层级选对,搜索效率差一个量级
  3. 用"评估成本"换"搜索效率"是划算的:AFlow 每个 workflow 真跑 5 次求均值,单轮更贵,但反馈更准 → 总迭代数更少。在"评估便宜、搜索空间大"的任务里,这个权衡值得抄。
  4. soft 混合概率 + 永远保留空模板:一个极简却有效的"逃离局部最优"技巧——不追求复杂的 UCT,就用"均匀 + softmax"凸组合 + 允许任意轮重启。

在我的工作中能怎么用

开放问题 / 疑问

局限性