Google:ReAct 推理与行动协同框架
2026/6/27 3:17:30 网站建设 项目流程

论文信息

  • 论文标题:ReAct: Synergizing Reasoning and Acting in Language Models

  • 论文链接:arXiv:2210.03629

  • 论文作者:Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Izhak Shafran, Karthik Narasimhan, Yuan Cao

  • 一句话总结:ReAct 把“思考文字(Thought)”和“外部动作(Action)”交错写进同一条推理轨迹,让大模型一边想、一边查、一边改计划,从而显著降低纯 CoT 的幻觉问题,并提升交互式任务成功率。

背景与动机

过去两条路线各自很强,但都缺一块:

  1. CoT / Reason-only会推理,但它只能在模型参数里“闭门思考”,一旦内部知识不够新、不够准,就容易把后续整条链条带偏。

  2. Act-only会调用环境,但如果没有显式的中间思考,它常常不知道下一步为什么要搜、搜什么、什么时候该停。

论文要解决的是:能不能把 reasoning 和 acting 交错起来,让两者互相补短板

作者给出的核心 insight 很直接:

  • reason to act:先写出思路,帮助模型拆目标、定子目标、决定下一步动作;

  • act to reason:先去环境里拿信息,再把新观察塞回上下文,支撑后续推理。

这使得 LLM 不再只是一次性吐完答案,而是在一条显式轨迹里循环执行:Thought → Action → Observation → Thought …

ReAct 不是再造一个新网络,而是重新定义了LLM 在推理时该输出什么:除了最终答案,它还要输出中间想法和可执行动作。

整体架构

下面这张图就是全文最核心的总览图:左上是标准问答,左下是纯 CoT,右上/右下是 ReAct 在 HotpotQA 和 ALFWorld 里的实际轨迹。

端到端数据流可以概括成 6 步:

  1. 输入任务描述(问题、指令、当前环境观察)和少量 ReAct 示例;

  2. LLM 基于当前上下文先生成一段Thought,用于分解目标、提炼线索、决定下一步;

  3. LLM 再生成一个Action,例如Search[...]Lookup[...]click[...]Finish[...]

  4. 外部环境执行动作,返回Observation

  5. Thought / Action / Observation追加到上下文,形成新的轨迹前缀;

  6. 重复循环,直到输出Finish[...]或到达步数上限。

论文在形式化定义里给了这个交互框架:

o t ∈ O , a t ∈ A , c t = ( o 1 , a 1 , … , o t − 1 , a t − 1 , o t ) , π ( a t ∣ c t ) o_t \in \mathcal{O},\quad a_t \in \mathcal{A},\quad c_t=(o_1,a_1,\ldots,o_{t-1},a_{t-1},o_t),\quad \pi(a_t\mid c_t)otO,atA,ct=(o1,a1,,ot1,at1,ot),π(atct)

变量说明:

  • o_t \in \mathcal{O}:第t步环境返回的观察。

  • a_t \in \mathcal{A}:第t步可执行动作。

  • c_t:到第t步时,模型当前能看到的完整历史上下文。

  • \pi(a_t\mid c_t):给定上下文后,模型输出动作的策略。

如果把这套流程展开成 LLM 的 token 级实现,可把上下文看成:

  • C_t \in \mathbb{N}^{B \times L_t}:batch 内第t轮 prompt token 序列;

  • B:batch size;

  • L_t:当前上下文 token 长度,会随着交互轮次增加。

模块拆解

3.1 轨迹上下文构造器:把任务状态压成一条可续写的文本轨迹

模块作用:把问题、历史 Thought、Action、Observation 统一拼成 LLM 可继续生成的单条上下文。

输入:

  • 初始任务文本x \in \mathbb{N}^{B \times L_x}

  • 历史 thought tokenT_{1:t-1}

  • 历史 action tokenA_{1:t-1}

  • 历史 observation tokenO_{1:t}

输出:

  • 当前上下文C_t \in \mathbb{N}^{B \times L_t}

可写成:

C t = C o n c a t ( X , T 1 , A 1 , O 1 , … , T t − 1 , A t − 1 , O t ) C_t = \mathrm{Concat}(X, T_1, A_1, O_1, \ldots, T_{t-1}, A_{t-1}, O_t)Ct=Concat(X,T1,A1,O1,,Tt1,At1,Ot)

变量说明:

  • X \in \mathbb{N}^{B \times L_x}:任务输入,例如问题、指令、few-shot exemplars。

  • T_i \in \mathbb{N}^{B \times l_i^{th}}:第i轮 thought 的 token 序列。

  • A_i \in \mathbb{N}^{B \times l_i^{act}}:第i轮 action 的 token 序列。

  • O_i \in \mathbb{N}^{B \times l_i^{obs}}:第i轮 observation 的 token 序列。

  • L_t = L_x + \sum_{i=1}^{t-1}(l_i^{th}+l_i^{act}) + \sum_{i=1}^{t}l_i^{obs}:第t轮上下文总长度。

这里没有额外编码器、检索器或控制器,核心实现就是 prompt 轨迹本身

3.2 Thought 生成器:先想,再决定下一步怎么动

模块作用:在当前上下文上生成自由形式语言 thought,用来拆任务、抽线索、修正计划。

输入:

  • 当前上下文C_t \in \mathbb{N}^{B \times L_t}

输出:

  • 当前 thoughtT_t \in \mathbb{N}^{B \times l_t^{th}}

论文把语言空间加入动作空间后,定义为:

A ^ = A ∪ L , a ^ t ∈ L \hat{\mathcal{A}} = \mathcal{A} \cup \mathcal{L}, \quad \hat{a}_t \in \mathcal{L}A^=AL,a^tL

并把 thought 写入下一轮上下文:

C t + 1 ( p r e − a c t ) = ( C t , a ^ t ) C_{t+1}^{(pre-act)} = (C_t, \hat{a}_t)Ct+1(preact)=(Ct,a^t)

变量说明:

  • \mathcal{A}:原始外部动作空间,例如 Wikipedia API、网页点击动作。

  • \mathcal{L}:自然语言 thought 空间。

  • \hat{\mathcal{A}}:扩展后的动作空间,既能输出可执行动作,也能输出语言 thought。

  • \hat{a}_t \in \mathcal{L}:第t轮 thought,本质上是不会直接改变环境的“语言动作”。

  • C_{t+1}^{(pre-act)}:加上 thought 后、还没执行真实动作时的中间上下文。

论文明确列出的 thought 用途包括:

  • 分解问题和制定计划;

  • 从 observation 中抽取关键事实;

  • 做常识推断或简单算术;

  • 判断当前搜索无效,决定换关键词;

  • 跟踪子目标是否完成。

3.3 Action 生成器:把 thought 落成外部可执行动作

模块作用:基于 thought 更新后的上下文,生成真正会作用于环境的动作。

输入:

  • C_{t+1}^{(pre-act)} \in \mathbb{N}^{B \times (L_t + l_t^{th})}

输出:

  • 动作A_t \in \mathbb{N}^{B \times l_t^{act}},以及环境回传观察O_{t+1} \in \mathbb{N}^{B \times l_{t+1}^{obs}}

抽象写法:

a t ∼ π ( ⋅ ∣ C t + 1 ( p r e − a c t ) ) , o t + 1 ∼ E ( a t ) a_t \sim \pi(\cdot \mid C_{t+1}^{(pre-act)}), \quad o_{t+1} \sim E(a_t)atπ(Ct+1(preact)),ot+1E(at)

变量说明:

  • a_t:第t轮动作。

  • \pi:LLM 在当前 prompt 下的条件生成策略。

  • E(\cdot):外部环境执行器,例如 Wikipedia API、ALFWorld、WebShop。

  • o_{t+1}:环境反馈。

  • l_t^{act}:动作 token 长度,通常很短,因为动作是结构化字符串。

  • l_{t+1}^{obs}:环境返回文本长度。

不同任务里的动作空间不同:

  1. HotpotQA / FEVERsearch[entity]lookup[string]finish[answer]

  2. ALFWorldgo to ...open ...take ...put ...等文本动作

  3. WebShopsearch[...]click[...]Buy Now等网页交互动作

3.4 Observation 回写与闭环控制:把外部世界重新接入推理链

模块作用:把环境返回的 observation 再塞回上下文,驱动下一轮 thought。

输入:

  • 上一步动作a_t

  • 环境反馈o_{t+1}

输出:

  • 新上下文C_{t+1}

公式就是论文最关键的闭环更新:

C t + 1 = ( C t , a ^ t , a t , o t + 1 ) C_{t+1} = (C_t, \hat{a}_t, a_t, o_{t+1})Ct+1=(Ct,a^t,at,ot+1)

变量说明:

  • C_t:旧上下文。

  • \hat{a}_t:thought。

  • a_t:action。

  • o_{t+1}:新 observation。

  • C_{t+1}:下一轮完整上下文。

这一层解决了纯 CoT 的核心短板:模型不再只依赖参数里的静态知识,而是可以用动作把新信息拉进来,再继续推理

3.5 稠密 thought 与稀疏 thought:两类任务对应两种轨迹节奏

模块作用:根据任务类型控制 thought 的出现频率。

输入:

  • 任务类型标签d

  • 当前上下文C_t

输出:

  • 当前轮是否触发 thought 的决策m_t \in \{0,1\}

可概括为:

m t = g ( d , C t ) m_t = g(d, C_t)mt=g(d,Ct)

变量说明:

  • d:任务域。知识密集型 QA / FEVER 属于“每步都要想”的 dense-thought 模式;ALFWorld / WebShop 属于“关键位置才想”的 sparse-thought 模式。

  • m_t:是否插入 thought。1表示当前步先生成 thought,0表示直接行动。

  • g(\cdot):不是单独训练出来的分类器,而是通过 prompt 设计隐式实现的策略。

论文中的具体做法:

  • 知识密集型推理任务:Thought-Action-Observation 交替更密,因为每步都在围绕搜索和证据整合。

  • 长程决策任务:Thought 只出现在“定子目标、判断是否完成、决定下一个探索方向”这些关键位置,避免每步都写长思路把轨迹拖爆。

训练目标 / 损失函数

4.1 核心主结果:few-shot prompting,本身不训练参数

论文最主要的结果来自PaLM-540B few-shot prompting。这一部分没有新增参数,也没有单独设计 loss;模型只是基于 prompt 直接解码 Thought / Action / Observation 轨迹。

所以如果只看主实验,ReAct 更像一种推理时协议(inference-time protocol),不是一个额外训练出来的模块。

4.2 附录里的微调:标准自回归轨迹建模

论文在附录 B.1 里补充了微调实验:使用3000 条由 ReAct 生成且答案正确的轨迹,去微调较小的 PaLM-8B / 62B,让模型直接按输入问题生成整段轨迹。

虽然论文没有把 loss 公式显式写出来,但根据原文“decode trajectories conditioned on input questions/claims”的描述,微调目标就是标准 next-token NLL:

L FT = − ∑ i = 1 L y log ⁡ p θ ( y i ∣ x , y < i ) \mathcal{L}_{\text{FT}} = - \sum_{i=1}^{L_y} \log p_\theta(y_i \mid x, y_{<i})LFT=i=1Lylogpθ(yix,y<i)

变量说明:

  • x \in \mathbb{N}^{B \times L_x}:输入问题或 claim。

  • y \in \mathbb{N}^{B \times L_y}:目标轨迹 token 序列,里面包含 Thought、Action、Observation 以及最终 Finish。

  • y_i:第i个目标 token。

  • L_y:目标轨迹长度。

  • p_\theta:微调后的语言模型。

  • \mathcal{L}_{\text{FT}}:标准语言建模负对数似然损失。

附录 B.1 给出的训练细节:

  • batch size = 64

  • PaLM-8B:ReAct / Act 微调 4000 steps;Standard / CoT 微调 2000 steps

  • PaLM-62B:ReAct / Act 微调 4000 steps;Standard / CoT 微调 1000 steps

实验与分析

5.1 论文看什么任务

作者覆盖了四类完全不同的任务:

任务环境 / 数据集ReAct 主要动作核心挑战
多跳问答HotpotQAsearch/lookup/finish多跳证据检索 + 答案合成
事实核验FEVERsearch/lookup/finish需要最新、精确、可核验证据
文本环境决策ALFWorld导航、开关、拿取、放置等文本动作长程规划、子目标跟踪、常识探索
网页购物决策WebShop搜索、点商品、选属性、购买噪声网页文本理解 + 属性匹配

5.2 知识密集型推理:ReAct 让检索更“有脑子”

论文主表中的关键数字如下:

Prompt MethodHotpotQA EMFEVER Acc
Standard28.757.1
CoT29.456.3
CoT-SC33.460.4
Act25.758.9
ReAct27.460.9
CoT-SC → ReAct34.264.6
ReAct → CoT-SC35.162.0

这张表要读出 3 个结论:

  1. ReAct 一定强于 Act-only:HotpotQA 27.4 vs 25.7,FEVER 60.9 vs 58.9。

  2. ReAct 在 FEVER 上优于 CoT:60.9 vs 56.3,说明“先拿证据再判断”对事实核验非常重要。

  3. 最强不是单独 ReAct,而是 ReAct 与 CoT-SC 的切换组合:HotpotQA 最强是ReAct → CoT-SC,FEVER 最强是CoT-SC → ReAct

作者还做了人工错误分析:

类别定义ReActCoT
True positive推理链和事实都对94%86%
False positive答案碰巧对,但推理链或事实有幻觉6%14%
Failure: reasoning error推理步骤错误,含重复循环47%16%
Failure: search result error搜索结果空或无信息23%​-
Failure: hallucination虚构推理或虚构事实0%56%
Failure: label ambiguity预测合理,但和标注不完全匹配29%28%

最值得记住的一点:ReAct 的代价不是“更容易幻觉”,而是“更容易因为检索 / 轨迹结构受限而卡住”;相反,CoT 最大的问题恰恰是幻觉。

5.3 微调后,ReAct 的优势会被放大

论文的发现很有意思:

  • 只做 prompting 时,小模型(8B / 62B)很难同时学会 thought 和 act,所以 ReAct 不占优;

  • 但用 3000 条正确轨迹做微调后,ReAct 直接跃升成最强方法;

  • PaLM-8B 微调版 ReAct 超过所有 62B prompting 方法,PaLM-62B 微调版 ReAct 甚至超过 540B prompting 方法

这说明 ReAct 的真正价值不只是在“当场 prompting”,还在于它提供了一个非常好的可监督轨迹格式:模型学到的不是死记答案,而是“如何一边想一边查”。

5.4 决策任务:稀疏 thought 对长程任务特别关键

论文在 ALFWorld 和 WebShop 的结果如下。

任务指标ActReAct
ALFWorldbest-of-trials success rate4571
WebShopScore62.366.6
WebShopSuccess Rate30.140.0

对比基线时,作者还给出:

WebShop 方法ScoreSR
IL59.929.1
IL + RL62.428.7
ReAct66.640.0
Human82.159.6

这里最强的信息是:只靠 1-shot / few-shot prompting,ReAct 就已经超过了专门训练的 imitation / RL 基线

5.5 论文里的两个代表性案例

案例 A:用真实交互补上“知识过时”

Figure 4 展示了一个很典型的问题:数据集标注里的酒店规模已经过时,但 ReAct 通过真实检索 + 推理拿到了更新答案。这个案例说明:

  • CoT 的问题不是不会推,而是没有新证据;

  • Act-only 的问题不是拿不到网页,而是不知道该怎么沿着证据链继续找;

  • ReAct 两边都补上了。

案例 B:人类只改两句 thought,就能把失败轨迹扳回来

Figure 5 表明 ReAct 还有一个额外优点:可编辑。人不需要重写几十个动作,只要改两句 thought,后续动作就会整体转向正确轨迹。这件事对 agent 可控性很重要。

优势与局限

优势

  • 显著降低纯推理幻觉:在 HotpotQA 的人工分析里,ReAct 的 hallucination failure 为 0%,CoT 为 56%。

  • 跨任务通用:同一范式覆盖 QA、事实核验、文本环境、网页交互四类任务。

  • 解释性强:Thought、Action、Observation 分层清楚,人能直接检查哪一步错了。

  • 可人类干预:Figure 5 证明人可以直接改 thought,而不是只能改最终答案。

  • 非常适合后续监督学习:用正确轨迹微调后,ReAct 从 prompting 最弱变成 finetuning 最强。

局限

  • 结构约束会限制纯推理自由度:在 HotpotQA 上,ReAct 比 CoT 略低(27.4 vs 29.4),作者认为是因为交错结构降低了自由推理能力。

  • 搜索质量是瓶颈:ReAct 的一大错误来源就是 search result error(23%)。一旦第一次搜歪,后面很难恢复。

  • 长程任务对 prompt 容量敏感:复杂任务需要更多 demonstrations,但 in-context length 很快会顶满。

  • 主实验依赖超大闭源模型:核心 prompting 结果在 PaLM-540B 上完成,复现门槛高。

  • 环境交互仍受动作空间限制:论文里的 Wikipedia API 很简化,WebShop 也不是真实购买闭环,现实系统会更复杂。

我对这篇论文的核心提炼

ReAct 最重要的贡献,不是“让模型多写几句 thought”,而是把 LLM 从一次性文本生成器改造成了显式闭环决策器:模型先用语言组织计划,再通过动作拿外部信息,再把新信息回灌到后续推理里。

从今天看,ReAct 已经是很多 agent 框架的祖先形态:

  1. Thought / Action / Observation 的轨迹接口,后来几乎成了 agent 论文的通用母版;

  2. 把推理链暴露出来,让诊断、纠错、人工接管都变得可做;

  3. 把“工具调用”从外挂变成推理主循环的一部分,这点比单纯 tool-use 更关键。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询