论文信息
论文标题: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 的幻觉问题,并提升交互式任务成功率。
背景与动机
过去两条路线各自很强,但都缺一块:
CoT / Reason-only会推理,但它只能在模型参数里“闭门思考”,一旦内部知识不够新、不够准,就容易把后续整条链条带偏。
Act-only会调用环境,但如果没有显式的中间思考,它常常不知道下一步为什么要搜、搜什么、什么时候该停。
论文要解决的是:能不能把 reasoning 和 acting 交错起来,让两者互相补短板。
作者给出的核心 insight 很直接:
reason to act:先写出思路,帮助模型拆目标、定子目标、决定下一步动作;
act to reason:先去环境里拿信息,再把新观察塞回上下文,支撑后续推理。
这使得 LLM 不再只是一次性吐完答案,而是在一条显式轨迹里循环执行:Thought → Action → Observation → Thought …。
ReAct 不是再造一个新网络,而是重新定义了LLM 在推理时该输出什么:除了最终答案,它还要输出中间想法和可执行动作。
整体架构
下面这张图就是全文最核心的总览图:左上是标准问答,左下是纯 CoT,右上/右下是 ReAct 在 HotpotQA 和 ALFWorld 里的实际轨迹。
端到端数据流可以概括成 6 步:
输入任务描述(问题、指令、当前环境观察)和少量 ReAct 示例;
LLM 基于当前上下文先生成一段Thought,用于分解目标、提炼线索、决定下一步;
LLM 再生成一个Action,例如
Search[...]、Lookup[...]、click[...]、Finish[...];外部环境执行动作,返回Observation;
把
Thought / Action / Observation追加到上下文,形成新的轨迹前缀;重复循环,直到输出
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)ot∈O,at∈A,ct=(o1,a1,…,ot−1,at−1,ot),π(at∣ct)
变量说明:
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 token
T_{1:t-1};历史 action token
A_{1:t-1};历史 observation token
O_{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,…,Tt−1,At−1,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}。
输出:
- 当前 thought
T_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^=A∪L,a^t∈L
并把 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(pre−act)=(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(pre−act)),ot+1∼E(at)
变量说明:
a_t:第t轮动作。\pi:LLM 在当前 prompt 下的条件生成策略。E(\cdot):外部环境执行器,例如 Wikipedia API、ALFWorld、WebShop。o_{t+1}:环境反馈。l_t^{act}:动作 token 长度,通常很短,因为动作是结构化字符串。l_{t+1}^{obs}:环境返回文本长度。
不同任务里的动作空间不同:
HotpotQA / FEVER:
search[entity]、lookup[string]、finish[answer]ALFWorld:
go to ...、open ...、take ...、put ...等文本动作WebShop:
search[...]、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=1∑Lylogpθ(yi∣x,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 主要动作 | 核心挑战 |
|---|---|---|---|
| 多跳问答 | HotpotQA | search/lookup/finish | 多跳证据检索 + 答案合成 |
| 事实核验 | FEVER | search/lookup/finish | 需要最新、精确、可核验证据 |
| 文本环境决策 | ALFWorld | 导航、开关、拿取、放置等文本动作 | 长程规划、子目标跟踪、常识探索 |
| 网页购物决策 | WebShop | 搜索、点商品、选属性、购买 | 噪声网页文本理解 + 属性匹配 |
5.2 知识密集型推理:ReAct 让检索更“有脑子”
论文主表中的关键数字如下:
| Prompt Method | HotpotQA EM | FEVER Acc |
|---|---|---|
| Standard | 28.7 | 57.1 |
| CoT | 29.4 | 56.3 |
| CoT-SC | 33.4 | 60.4 |
| Act | 25.7 | 58.9 |
| ReAct | 27.4 | 60.9 |
| CoT-SC → ReAct | 34.2 | 64.6 |
| ReAct → CoT-SC | 35.1 | 62.0 |
这张表要读出 3 个结论:
ReAct 一定强于 Act-only:HotpotQA 27.4 vs 25.7,FEVER 60.9 vs 58.9。
ReAct 在 FEVER 上优于 CoT:60.9 vs 56.3,说明“先拿证据再判断”对事实核验非常重要。
最强不是单独 ReAct,而是 ReAct 与 CoT-SC 的切换组合:HotpotQA 最强是
ReAct → CoT-SC,FEVER 最强是CoT-SC → ReAct。
作者还做了人工错误分析:
| 类别 | 定义 | ReAct | CoT |
|---|---|---|---|
| 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 的结果如下。
| 任务 | 指标 | Act | ReAct |
|---|---|---|---|
| ALFWorld | best-of-trials success rate | 45 | 71 |
| WebShop | Score | 62.3 | 66.6 |
| WebShop | Success Rate | 30.1 | 40.0 |
对比基线时,作者还给出:
| WebShop 方法 | Score | SR |
|---|---|---|
| IL | 59.9 | 29.1 |
| IL + RL | 62.4 | 28.7 |
| ReAct | 66.6 | 40.0 |
| Human | 82.1 | 59.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 框架的祖先形态:
Thought / Action / Observation 的轨迹接口,后来几乎成了 agent 论文的通用母版;
把推理链暴露出来,让诊断、纠错、人工接管都变得可做;
把“工具调用”从外挂变成推理主循环的一部分,这点比单纯 tool-use 更关键。