alitrack

ReAct 连 Go 函数注释都要上网搜:Agent 架构正在 DAG 化

上周我跑了个 benchmark,把同一个 LLM 用两种方式跑 6 个任务。结果连我自己都没想到。

最简单的任务——给 Go 函数写个注释——ReAct 模式花了 70 秒,烧了 18,000 多个 token。你猜它这 70 秒在干嘛?它竟然调了 web search,去网上搜怎么写 Go doc comment。一个 LLM 自己就能搞定的三行注释,它在"探索"。

同样的任务,ATG 模式 9.3 秒搞定,token 用了 1/10。

6 个任务跑下来:ATG 5 胜 1 平,4.5 倍加速,token 省了 78%。

这不是调参调出来的。这是架构层面的差异。


● ● ●

ReAct 是怎么把你拖垮的

ReAct(Reasoning + Acting,2022)是现在绝大多数 Agent 的默认模式:

Thought → Action → Observation → Thought → Action → Observation → ...

每一步都是一次 LLM 调用。每一步都把"之前想过的 + 做过的 + 看到的"全部塞回 prompt。第 6 步时,模型在重读前 5 步的全部历史。

复杂度接近 O(n²),但大多数人感觉不到——因为你不会让 Agent 跑 10 步以上的任务。3 步以内 ReAct 跑得挺好。

问题出在 4 步以后。

拿我 bench 里的"对比 SQLite 和 DuckDB"来说:ReAct 的模式是先想→搜资料→搜不到→再想→换关键词→再搜→…到第 6 轮工具调用时,上下文已经膨胀到 57,000 token,而且 web search 挂了,返回个空。76 秒过去,结果还算凑合,但过程惨不忍睹。

这不是 DeepSeek V4 的问题。同样的模型,ATG 模式 10.6 秒、2,926 token 搞定,结果完全正常。

架构差异造成的浪费,比模型差异大得多。


● ● ●

从 ReAct 到 DAG:三年演化

Agent 架构 DAG 演化

Agent 架构 DAG 演化

学术界其实早就看到了这个问题。过去三年,有一连串论文在尝试"让 Agent 先想清楚再动手"。

第一个拐点:ReWOO(2023)

ReWOO(Reasoning WithOut Observation)提出了一个很直接的洞察:推理不需要看到工具返回的结果。 你可以在看到任何数据之前,把整个计划写出来。

它把 Agent 拆成三层:

  • Planner:一次性写出完整计划,用 #E1、#E2 占位符代表工具调用结果
  • Worker:按顺序跑工具,填占位符(不调 LLM)
  • Solver:拿到所有结果,出最终答案(调一次 LLM)

总共就两次 LLM 调用。ReAct 是每步一次。实测 token 省了 5 倍,准确率反而高了 4.4%。因为模型不会被原始的工具输出干扰。

同一时期的 Plan-and-Execute 也是类似思路:一次规划,多次执行。Token 省 5-10 倍。

但两者有个共同死穴:计划是死的。 如果第 2 步返回了意料之外的结果,后续步骤全废。

第二个拐点:LLMCompiler(ICML 2024)

这是真正的突破。LLMCompiler 把"线性计划"升级成了 DAG(有向无环图):

  • Planner 流式输出 DAG 节点,不等全部计划完成就开始调度
  • Task Fetching Unit 按拓扑顺序取就绪任务,并行分发给 Worker
  • Joiner 拿到结果后判断是否满足,不满足就触发重规划

并行执行 + 动态重规划。实测 3.6 倍端到端加速。

第三个拐点:GraSP 和 DYNO(2025)

LLMCompiler 解决了并行和重规划,但还有个问题没解决:如果中间一个节点挂了,是全部重来还是只修那一块?

GraSP 的答案是 Typed DAG + 局部修复。每个节点的输入输出有类型约束,挂了之后只修复受影响的最小子图,复杂度 O(d^h)(d=节点深度,h=受影响的子图高度)。不用全局重来。

DYNO 更进一步——在 DAG 之上加了一层本体驱动的符号验证。规划出的 DAG 要经过知识图谱检查,避免生成逻辑上不可能的任务图。

这些论文要解决的问题其实就是一个:让 Agent 像编译器调度指令一样调度自己的子任务。


● ● ●

一表看全貌

论文时间核心机制并行修复实测加速死穴
ReAct2022Thought→Action→Obs 循环❌❌baseline上下文膨胀,>5步崩溃
Tree of Thoughts2023MCTS/BFS 搜索推理树❌回溯2-3× 搜索效率不适合工具调用
ReWOO2023Planner→Worker→Solver❌❌5× token计划不可变
Plan-and-Execute2023Plan once, execute many❌重规划5-10× token计划陈旧
**LLMCompiler**2024DAG 流式规划 + TFU✅重规划**3.6×**TFU 实现复杂
**GraSP**2025Typed DAG + 局部修复✅**O(d^h)**—Schema 维护成本
**DYNO**2025DAG + 本体验证✅重分解—本体构建门槛
TDAG2024动态子 Agent 生成✅❌—仅旅行规划验证
GNN+LLM2024GNN 替 LLM 做图导航N/AN/A3-9% 提升训练数据
ADAS2024Meta Agent 自动编程取决于生成取决于生成—搜索空间巨大

如果你只读一篇,读 LLMCompiler。它给的抽象最干净。


● ● ●

forge ATG 实测

我照着 LLMCompiler + GraSP 的思路,在 forge 里实现了 ATG(Automated Task Graph):

  1. 01Planner 把任务拆成 DAG
  2. 02拓扑并行执行(独立节点 goroutine 并发)
  3. 03失败节点最小子图修复(最多 3 轮)

跟 ReAct 同一模型、同一任务跑的:

═══════════════════════════════════════
               ReAct        ATG
═══════════════════════════════════════
  总耗时      5m43s       1m16s
  总 token    89,524      19,777
  工具调用    17 次       0 次
  成功率      6/6         6/6
  胜率        —           5/6 (83%)
  加速比      1×          4.5×
═══════════════════════════════════════

一个意外发现:ATG 的工具调用是 0。不是 ATG 不能用工具,而是 planner 在分解阶段就把所有推理做完了,执行阶段每个子节点都是纯推理,不需要"探索"——搜索、grep、翻文档这些事,模型脑子里本来就有。

ReAct 的 17 次工具调用,大部分是"试试看"——搜一下、翻一下、再看看。不是真的需要,是它的架构决定了它必须"走过场"。


● ● ●

一句话总结

ReAct 给 Agent 的是"直觉"——边走边看。碰到复杂任务,直觉不够用。

DAG 给 Agent 的是"规划"——先想清楚,再并行执行。失败只修那一块。

2026 年了,让 Agent 先动脑子再动手,不是什么新鲜想法。12 篇论文、3 年演化、4.5 倍加速,都在说同一件事。


跑 benchmark 的代码在 forge 的 --bench 模式,ATG 实现在 internal/atg/。