论文精读 01|ReAct:把推理、动作与观察编排成闭环

论文档案

项目内容
论文ReAct: Synergizing Reasoning and Acting in Language Models
作者Shunyu Yao 等
发表ICLR 2023
原文OpenReview / arXiv
项目ReAct 项目主页与代码
本文定位Agent Harness 控制循环的起点,而不是完整运行时方案

先记住四件事

  1. ReAct 的核心不是让模型“多想一会儿”,而是把 Thought、Action、Observation 放进同一条可继续的轨迹。
  2. 推理负责形成和修订计划,动作负责获取外部证据或改变世界,观察把真实结果带回下一轮。
  3. 它解决的是开环生成问题,没有自动解决权限、隔离、幂等、审计和成功判定。
  4. 论文最有价值的证据不是某个总分,而是:纯 CoT 容易凭内部先验幻觉,纯 Act 又缺少维护长期意图的工作区。

研究问题:两种半成品怎样拼成闭环

ReAct 出现前,语言模型解决复杂任务常见两条路线。

Chain-of-Thought 路线让模型先生成中间推理,再给最终答案。它对算术和常识推理有效,但整个过程仍封闭在模型上下文里。当模型缺少事实时,一条流畅的推理链也可能只是在放大错误先验。

Action-only 路线让模型直接选择搜索、点击、拿取物体等动作。它可以接触环境,却容易退化成缺少计划的局部反应:不知道已经验证过什么、下一步为何合理,也很难从一次失败观察中调整长期策略。

ReAct 的命题是:推理与行动不应分成两个阶段,而应在时间上交错。抽象成状态机就是:

任务 + 历史
    │
    ▼
Thought: 当前知道什么、缺什么、下一步为何必要
    │
    ▼
Action: 在约束动作空间中执行一步
    │
    ▼
Observation: 环境返回的事实、错误或状态变化
    └──────────────────────► 下一轮 Thought

这恰好成为后来 Agent Harness 的最小数据面:模型输出决策,运行时执行动作,再把观察归一化回填。

方法拆解

Thought 不是最终解释,而是临时工作记忆

论文把自然语言 reasoning trace 当作一种可读的内部状态。它可用于:

  • 把大目标拆成当前子目标;
  • 跟踪已经检索到的事实;
  • 处理异常,决定重试、换查询或改变计划;
  • 判断信息是否足够并结束任务。

这并不意味着 Thought 忠实反映模型内部计算。工程上应把它视为策略生成的中间产物,可用于调试和条件生成,但不能把“模型说自己已经验证”当作真实验收证据。

Action 是受环境定义的协议

在 HotpotQA、FEVER 中,动作是 Search[...]、Lookup[...]、Finish[...] 一类文本命令;在 ALFWorld 中,是文本世界允许的移动、打开、拿取、加热等动作;在 WebShop 中,则是搜索、选择属性和购买等网页操作。

所以 ReAct 并没有规定唯一工具调用格式。它真正要求的是:

模型输出  --解析-->  合法动作  --环境执行-->  可观察结果

解析失败、动作越界、工具异常,都应该成为明确 Observation,而不是让模型在看不见的地方失败。

Observation 是外部事实,不是 prompt 装饰

观察的作用是打断模型的自说自话。搜索结果、游戏反馈和页面状态都可能否定上一轮假设。论文中 ReAct 在事实问答上的优势,正来自把外部检索结果引入推理链。

但 Observation 也会制造新问题:它可能过长、重复、无关,甚至包含恶意指令。ReAct 本身没有来源标记与信任分层;现代 harness 必须补上观察裁剪、数据/指令隔离和注入防护。

两类任务使用不同的推理密度

论文没有要求每一步动作前都写长推理:

  • 在知识密集型问答里,Thought 较密集,用于组织检索和证据组合;
  • 在 ALFWorld、WebShop 这类长轨迹决策里,推理可以稀疏出现,只在制定计划、发现异常或切换子目标时介入。

这给工程实现一个重要启示:不要把“每一步都生成固定长度 Thought”写死。推理频率本身是成本、延迟和性能的控制参数。

实验到底证明了什么

四类任务

任务环境特征ReAct 要解决的核心矛盾
HotpotQA多跳 Wikipedia 问答内部推理需要外部证据校正
FEVER事实核验结论必须落到可检索证据
ALFWorld文本化家居环境长动作序列要维护目标和对象状态
WebShop约 118 万商品、自然语言购买指令搜索、属性约束与网页导航要联合进行

HotpotQA 使用 6 条人工轨迹作为 few-shot 示例,FEVER 使用 3 条;ALFWorld 按 6 个任务类型各提供 3 条示范轨迹;WebShop 使用 one-shot 轨迹。论文主要模型是 PaLM-540B,因此这里的数字不能脱离模型、prompt 和当时环境直接对照今天的 API。

知识问答:Grounding 与灵活性的交换

在 HotpotQA 与 FEVER 上,ReAct 的优势是事实落地,缺点是可能在检索中卡住。作者对 200 个 HotpotQA 样本做人工错误分析,观察到 CoT 的主要失败类型是事实幻觉;论文报告该类失败约占 CoT 错误的 56%。ReAct 能搜索外部信息,因此幻觉更少,但会被无关或重复文档拖入循环。

结果中常常是 ReAct 与 CoT-SC 的组合最好,而不是单一方法统治所有任务。原因很直接:

  • CoT 的闭卷推理更灵活,偶尔能靠先验直接完成;
  • ReAct 更可验证,但检索策略和搜索接口成为新瓶颈;
  • 两者互补说明“何时调用环境”本身也是策略问题。

ALFWorld:推理对长轨迹很重要

ALFWorld 评测包含 134 个未见环境、6 类家务任务。论文报告最佳 ReAct 试验达到 71% 成功率,最佳纯 Act 试验为 45%,此前 BUTLER 基线为 37%。但 ReAct 不同试验间波动明显,最差一次约 48%。

作者还做了 ReAct-IM 消融:把显式内部推理换成较弱的内隐式形式,成功率从 71% 降到 53%。这支持“语言工作记忆帮助长程决策”,同时也暴露 few-shot 轨迹和采样随机性对结果影响很大。

WebShop:动作闭环带来直接收益

WebShop 含约 118 万商品和 1.2 万条人工指令。ReAct 在论文设置下相对此前最佳方法取得约 10 个百分点的绝对成功率提升。这里的重要信息不是网页 Agent 已经成熟,而是自然语言推理能协调搜索词、商品属性和页面动作。

失败模式比总分更值得学

检索循环

如果查询没有命中关键实体,模型可能只做同义改写,然后反复看到类似结果。Harness 应识别:

  • 连续相同或高度相似动作;
  • Observation 没有新增实体或证据;
  • 同一错误连续出现;
  • 预算消耗上升但任务状态不变。

检测后可触发查询改写、切换工具、回滚到 checkpoint 或直接结束,而不是无限继续 ReAct 循环。

上下文膨胀

轨迹越长,历史 Thought 和 Observation 越容易淹没当前状态。论文已经指出复杂动作空间需要更多示例与上下文,而示例本身又挤占任务轨迹空间。现代实现需要把“原始事件日志”和“给模型看的上下文视图”分开:日志完整保存,视图可以裁剪、分页或总结。

动作正确但目标错误

一个动作可能语法合法、执行成功,却把 Agent 带向错误子目标。工具层只能检查类型和权限,任务层还要检查进度与不变量。例如购买任务中,点击成功不代表尺寸、价格和颜色同时满足。

观察不可信

网页文本与检索文档都可能包含 prompt injection。ReAct 将它们直接送回模型,在论文的非对抗设置中合理,在生产系统中却不是安全边界。最少应保留来源、信任级别、内容摘要和产生该观察的动作 ID。

从论文映射到 Harness

ReAct 概念Harness 中更严格的实现
Thought可选的策略草稿;默认不作为事实或授权依据
Action带版本的结构化命令,先校验再执行
Observation有来源、大小限制和敏感级别的执行结果
Trajectory追加式事件流,包含因果 ID、时间、成本与状态摘要
Finish结束请求;是否成功仍由独立 evaluator 决定
Few-shot trajectory可版本化策略资产,需防止泄露答案与过拟合

一个可测试的循环可以写成:

while budget.allows_next_step():
    view = context_builder.render(task, state, events)
    proposal = policy.next_action(view)
    action = protocol.validate(proposal)
    decision = policy_gate.authorize(action, state)
    observation = executor.run(decision.action)
    events.append(observation)
    state = reducer.apply(state, observation)
    if evaluator.is_terminal(state):
        break

关键差异是 Finish 不直接等于成功,authorize 也不能交给同一个模型自批。

最小复现实验

不要先复刻全部四个基准。用一个确定性小环境就能验证论文机制:

  1. 设计 20 个必须两次查询才能回答的任务;
  2. 给模型 search(key)、lookup(id)、finish(answer) 三个动作;
  3. 比较一次性回答、Act-only、ReAct 三种策略;
  4. 固定模型、温度、任务顺序和最大步数;
  5. 记录任务成功率、动作数、重复动作率、无新增信息步数;
  6. 人工标注失败是知识缺失、错误计划、工具选择、参数还是停止判断。

随后加入三个 harness 消融:重复动作熔断、观察分页、独立答案验证。这样能区分收益来自“更会推理”,还是来自运行时纠错。

不能从论文推出什么

  • 不能证明 Thought 是模型真实、忠实或安全的解释;
  • 不能证明增加更多思考总会提升效果;
  • 不能证明文本动作优于结构化工具调用;
  • 不能证明 ReAct 自带记忆、权限和故障恢复;
  • 不能把 2022 年模型上的数字当作今天的模型排行。

ReAct 的历史价值在于给出了一个简洁而可迁移的交互语法。它是 harness 的数据面原型,不是完整 harness。真正落地时,最需要补的恰好是论文没有试图解决的控制面:验证、权限、预算、状态、审计和恢复。

延伸阅读