返回文章列表
PAPERReActAgent WorkflowTool Calling工程化

论文解读:ReAct 为什么改变了 Agent 工作流(以及如何工程化落地)

ReAct 把“推理”与“行动”交替编排,让 Agent 不必在一开始就把计划写死,也更容易在工具回执中纠错。本文从论文思想出发,拆解 ReAct 的优势边界、失败模式与工程落地方法:事件日志、状态机、工具契约与可观测指标,帮你把 ReAct 从 prompt 变成可上线工作流。

2026年3月4日
Synthly 团队
预计阅读 14 分钟
ReAct 的思维-行动交替工作流:推理与工具调用交错推进的示意图

📷 Photo by Google DeepMind via Pexels

先给结论:ReAct 把“工作流控制权”从一次性计划,移到了每一步的观察上

很多早期 Agent 工作流长这样:

  1. 模型先写出一份完整计划
  2. 然后按计划逐步执行工具

它的问题也很典型:计划写得越完整,越容易在第 2 步开始就与现实脱节。一旦中途发现信息缺失或工具失败,系统缺少“结构化的回到循环”的机制,最后只能靠“再生成一个计划”救场。

ReAct(Reason + Act)做的事情非常朴素:

  • 思考(Reason):基于当前上下文提出下一步假设/意图
  • 行动(Act):调用工具或采取外部动作
  • 观察(Observe):把工具回执当作新证据,更新下一步

也就是:把 Agent 设计成一个“可重入的控制循环”,而不是“先写计划再按剧本演”。

如果你刚看完我们前面的工程文章,可以把它和这两篇一起看:


一、ReAct 解决的不是“推理能力”,而是“闭环能力”

把 ReAct 的价值说透,需要先分清两个概念:

  • 长推理(Long Reasoning):把推理链写得更长、更完整
  • 闭环推理(Closed-loop Reasoning):让推理被外部反馈持续校正

ReAct 的关键是第二点。

1)为什么“闭环”会显著改变工作流?

在开放世界任务里,执行过程中会不断出现新信息:

  • 你以为用户要 A,实际回执显示是 B
  • 你以为数据存在,实际 404/空结果
  • 你以为工具可用,实际 429/超时

如果系统没有闭环,模型只能在“旧世界观”里继续推理,越推越错。

而 ReAct 把观察当成一等公民:观察改变了状态,状态改变了下一步决策。

2)一个工程视角的 ReAct:状态机而不是纯 prompt

你可以把 ReAct 写成一个明确的状态机:

  • THINK:生成下一步意图/工具选择
  • ACT:执行工具调用
  • OBSERVE:落地回执与证据
  • DONE / FAILED:终止

与其把它当作“提示词技巧”,不如把它当作“执行模型”。


二、ReAct 的优势边界:它更像“探索型执行器”

1)适合:信息不全、需要试探的任务

典型如:

  • “帮我查一下这个客户上周的沟通记录,并总结风险点”
  • “根据工单系统找出导致退款的主要原因”
  • “把这份模糊需求拆成可执行的实施步骤,并确认依赖”

这些任务的共同点:你不可能在开始时就把信息拿全

2)不适合:强一致、强合规模型

当你的任务具备这些特征,ReAct 反而可能是负收益:

  • 每一步都有确定性校验
  • 任何多走一步都会增加风险(比如资金/删除操作)
  • 延迟和成本极其敏感

这时更好的策略是:严格工作流 + 关键节点人工确认(HITL),或 Planner-Executor + 强校验。


三、工程落地:把 ReAct 从“文本链”变成“事件链”

如果你只在 prompt 里写:

  • Thought: ...
  • Action: ...
  • Observation: ...

你会遇到一个线上问题:这些“Thought/Observation”不是系统数据,无法可靠追踪、也无法成为可控的重放输入。

工程化落地的关键,是把每一次循环固化为事件。

1)定义最小事件模型

建议至少落这些字段(可脱敏):

{
  "runId": "...",
  "step": 3,
  "state": "ACT",
  "tool": "searchTickets",
  "toolInput": { "query": "..." },
  "toolOutput": { "items": 12 },
  "latencyMs": 842,
  "error": null,
  "budget": { "maxSteps": 12, "usedSteps": 3 }
}

这样你才能做:

  • 重放:复现“第 7 步为什么突然走偏”
  • 诊断:错误是模型选择错,还是工具回执异常
  • 评估:哪个工具造成主要延迟,哪个步骤最常失败

2)工具契约:让 Observation 可被机器理解

ReAct 特别依赖 Observation 的质量。

如果工具输出是“人类可读的自然语言”,模型容易误读;如果输出是“结构化但不稳定”,系统就会出现不可预测的漂移。

建议:

  • 输入用 JSON Schema 约束(并禁用额外字段)
  • 输出统一 { success, data, error }
  • 错误用可枚举的 error.code

工具契约越硬,ReAct 越稳定。


四、失败模式:ReAct 并不会自动变强,它只是更容易“暴露弱点”

1)循环爆炸:步数越跑越多

症状:不断检索、不断追问、不断“再试一次”。

根因:没有预算和早停。

工程策略:

  • 步数上限(hard cap)
  • 工具调用上限(per-tool cap)
  • 超时预算(总 budget + 分段 budget)
  • 失败分类后早停(证据不足/权限不足直接停)

2)错误传播:一次坏回执毁掉后续推理

症状:第 2 步工具返回缺字段,第 3 步模型开始编造字段,第 5 步输出看似合理但完全错。

工程策略:

  • 回执校验(缺字段直接进入 FAILED 或补救分支)
  • 结构化“观察摘要”:把关键字段提取出来,避免被截断
  • 对关键工具输出做“二次确认”(例如对订单金额/收件人)

3)重复执行:重试导致副作用被放大

ReAct 鼓励“再试一次”,如果你的工具是写操作,就会出事故。

工程策略:

  • 任何写操作必须具备幂等键
  • 记录每次写操作的幂等键与结果
  • 重试只允许发生在“已确认无副作用”的动作

更系统的稳定性基线可参考:


五、把 ReAct 用好:一套可上线的“最小改造清单”

你不需要重写整个 Agent,只要把 ReAct 的闭环接到系统里:

  1. 把循环外置到代码:模型只决策下一步,不负责维护“历史真相”
  2. 把 Observation 结构化:用契约与校验保证回执可靠
  3. 把预算变成一等公民:步数、工具、时间三种预算都要有
  4. 把失败变成分支:错误分类 → 对应动作(停/追问/降级/补偿)
  5. 把日志变成产品能力:可重放、可分析、可定位

当你做到这五件事,ReAct 才不是“提示词工作流”,而是“可运营的执行循环”。


常见问题

ReAct 能减少幻觉吗?

它更准确的作用是:把“幻觉的机会”移到可校正的环节。因为它鼓励使用工具回执做证据,幻觉更容易被事实打断;但如果你的工具回执不可靠,幻觉会以另一种形式回归。

我应该先做 ReAct,还是先做事件日志?

先做事件日志。没有事件日志,你无法知道 ReAct 变好还是变坏;你只会得到“感觉更聪明/更啰嗦”。

想看更多工程化文章见 /articles,也可以在 /apps/new 体验 Agent 能力。