ReAct 让大模型「边想边查」,但 90% 的人都没讲对
1. 什么是 ReAct
ReAct = Reasoning(推理)+ Acting(行动)。它让大模型在解题时,把"心里想的(Thought)"和"手上做的(Action)"交替写在同一段输出里,每做一次动作,就把外部环境返回的**观察(Observation)**再喂回去做下一步思考。
它定义了这样一个循环(论文称为 Thought–Action–Observation):
关键点:ReAct 不改模型权重,纯靠 prompting——给模型 3~6 个"思考+动作+观察"式的示范样例,模型就学会这种交替节奏。它把"语言本身"也变成了一种动作:Thought 是不影响环境的纯文本推理,Action 才是真正调用外部工具。
注:你可能在别处见过 “React”(前端框架),本文的 ReAct 是 LLM 推理/智能体范式,二者无关。
2. 它解决了什么痛点
ReAct 之前,LLM 的"推理"和"行动"是两个分叉、互不往来的方向,各有致命短板:
| 前身做法 | 能做到 | 致命痛点 |
|---|---|---|
| CoT(只推理) | 一步步把思路写出来 | 推理全靠模型内部记忆,不接地气——查不了实时/长尾事实,错了就一路错。论文统计:CoT 失败案例里 56% 是幻觉(凭空编造) |
| Act-only(只行动) | 直接调工具/执行动作 | 不会想——没有显式推理轨迹,不会做高层规划、不会把多次观察综合成结论,遇到异常不会自救 |
核心洞察:推理为行动指方向,行动为推理提供证据,两者必须交替才能解复杂问题。论文的侦探比喻很到位——只推理的侦探坐办公室靠记忆编理论(易错),只行动的侦探满世界收集信息却不会拼凑(无用),好侦探是"想→查→想→查→总结"。
3. 核心机制:底层工作原理
ReAct 本质是一套「Prompt 模板 + 外部执行外壳(Harness)」的协作协议。模型只负责"生成文本",真正"做事"的是外壳。
3.1 Prompt 怎么搭:把"思考+动作+观察"做成示范
给模型喂 3~6 个手写样例(few-shot exemplars),每个样例是一条完整轨迹:
Question: ...
Thought: 我应该先查 X
Action: search[X]
Observation: (外部返回的真实文本)
Thought: 接下来查 Y
Action: search[Y]
Observation: ...
Thought: 信息够了
Action: finish[答案]
模型从这些样例里"学"到的不是知识,而是格式与节奏——什么时候写 Thought、什么时候写 Action。
3.2 推理循环:模型只负责"写",外壳负责"做"
核心是一个 generate → parse → execute → append 的循环:
while 没遇到 finish 且 步数 < max_steps:
1. 模型基于当前上下文续写文本,产出 Thought + "Action: 工具[参数]"
2. 外壳用正则解析出 Action 名和参数
3. 校验 Action 是否在允许的"动作空间"内
4. 外壳调用外部工具/环境,拿到真实结果
5. 把 "Observation: <结果>" 追加回上下文
6. 回到第 1 步,让模型在"带着新事实"的状态下继续写
注意第 5 步:Observation 不是模型编的,是环境给的"硬事实",被强制写回上下文。这正是抗幻觉的关键。
3.3 动作空间与环境执行器
论文为不同任务定义不同的"动作集":
| 任务 | 动作空间 | 执行器 |
|---|---|---|
| 知识问答(HotpotQA/FEVER) | search[实体](返回 Wiki 页前 5 句)、lookup[字符串](在当前页做 Ctrl+F 找下一句)、finish[答案] | Wikipedia API |
| 家务游戏(ALFWorld) | go to 桌子1、take 苹果2 等环境指令 | 文本仿真器 |
| 网购(WebShop) | search[关键词]、click[商品] 等 | WebShop 环境 |
动作名和参数格式受严格约束——这正是 few-shot 能生效的原因:模型只需学会"schema",不用自己发明工具。
3.4 Thought 的本质:只进 context,不进环境
Thought 是纯文本推理,不产生 Observation、不影响外部世界,它的唯一作用是更新模型自己的上下文。论文归纳 Thought 干了 6 件事:拆解子目标、从观察里抽取关键信息、做常识推理、跟踪进度、处理异常、综合最终答案。
3.5 停止条件
出现 finish[答案] 即终止;或达到 max_steps(交互任务常设数十步)后强制停。
3.6 一个关键设计:dense vs sparse thought
- 知识任务(HotpotQA/FEVER):每步都带 Thought(dense),因为每查一次都要判断"接下来查什么";
- 决策任务(ALFWorld/WebShop):只在关键决策点写 Thought(sparse),大量连续动作之间不啰嗦。
4. 完整案例走查(贯穿全文的统一案例)
统一案例:HotpotQA 风格多跳问答
「同时执导了《盗梦空间》(Inception) 与《星际穿越》(Interstellar) 的导演,出生在哪座城市?」
说明:以下轨迹结构完全还原论文 Figure 1;检索片段为示意,但所用事实(Christopher Nolan 生于伦敦)为真实公开信息。
初始上下文 = 系统说明 + 几个 few-shot 轨迹 + Question: 同时执导了《盗梦空间》与《星际穿越》的导演,出生在哪座城市?
第 1 步
- 模型续写:
Thought: 需要先确认这两部电影的导演是不是同一人,先查《盗梦空间》。\nAction: search[Inception] - 外壳解析出
search,参数Inception→ 调 Wikipedia API → 返回《Inception》页面前 5 句:《Inception》(2010) 是一部科幻动作片,由 Christopher Nolan 执导并编剧…… - 外壳追加:
Observation: 《Inception》(2010)……由 Christopher Nolan 执导…… - 👉 内部:模型上下文已包含这条真实事实,下一步"想"的基础变了。
第 2 步
- 模型续写:
Thought: 《盗梦空间》导演是 Christopher Nolan,验证他是否也执导了《星际穿越》。\nAction: search[Interstellar] - 外壳调 API 返回:
《Interstellar》(2014)……由 Christopher Nolan 执导……→ 追加为 Observation - 👉 内部:模型现在手握"Nolan 导了 Inception"和"Nolan 导了 Interstellar"两条硬事实。
第 3 步
- 模型续写:
Thought: 确认 Christopher Nolan 同时执导两部电影,现在查他的出生地。\nAction: search[Christopher Nolan] - 返回:
Christopher Nolan(1970 年生)是英国导演,出生于伦敦……→ 追加为 Observation
第 4 步
- 模型续写:
Thought: 信息已齐备,答案为伦敦。\nAction: finish[伦敦 / London] - 外壳识别到
finish,终止循环,返回伦敦 / London。
对比 CoT 的同一题:CoT 会在第 1 步就凭记忆直接写"Nolan 出生在伦敦",全程没有一次外部校验——一旦记忆出错(或问的是更冷门的导演),没有任何纠错机会,且论文统计这种幻觉占 CoT 失败的 56%。ReAct 把"查"和"想"交织,每一步都拿真实 Observation 当锚。
5. 作用与好处(用论文实测数字背书)
| 任务 | 指标 | Standard | CoT(只推理) | Act-only(只行动) | ReAct | 最佳组合 |
|---|---|---|---|---|---|---|
| HotpotQA(多跳问答) | EM | 28.7 | 29.4 | 25.7 | 27.4 | 35.1(ReAct→CoT-SC) |
| FEVER(事实验证) | Acc | 57.1 | 56.3 | 58.9 | 60.9 | 64.6(CoT-SC→ReAct) |
| ALFWorld(家务文本游戏) | 成功率% | — | — | 45 | 71 | — |
| WebShop(网购) | 成功率% | — | — | 30.1 | 40 | — |
上述为 PaLM-540B 论文实测(HotpotQA 6-shot、FEVER 3-shot、ALFWorld 2-shot、WebShop 1-shot)。所有数字来自原论文 Table 1。
机制性好处:
- 可解释:每一步"为什么查这个、基于什么观察"都看得见,能 debug、能人工纠错;
- 抗幻觉:结论 grounded 在真实检索结果上(论文失败分析里幻觉占比从 CoT 的 56% 直接降到 0%,见第 9 章);
- 动态自适应:上一步观察不对,下一步 Thought 可以换关键词/换思路,比"先计划再执行"多了一层纠错;
- 少样本泛化:只需 1~6 个样例就能迁移到新任务。
⚠️ 必须纠正的误传:ReAct 并不是处处碾压 CoT。在 HotpotQA 上纯 ReAct(27.4)其实低于纯 CoT(29.4)——因为多跳问答有时"想"比"查"更关键。ReAct 真正大幅领先的是需要和外部世界交互的任务(ALFWorld +26pp、WebShop +10pp 吊打模仿/强化学习基线),以及需要事实 grounding 的 FEVER。论文最强成绩来自 ReAct 与 CoT-SC 互补兜底(见第 11 章)。
6. 使用场景与不适用场景
适合用 ReAct:
- 知识密集型问答 / 事实验证,且需要最新或长尾外部事实(HotpotQA、FEVER、医疗/法律检索);
- 交互式决策 / 具身或网页任务(ALFWorld 整理房间、WebShop 按需求买东西、网页导航);
- 工具增强型 Agent(接搜索、计算器、SQL、API)——今天 LangChain / AutoGen / 各类 Agent 默认模式都是 ReAct;
- 任务同时需要"规划"和"边查边做"。
不适合 / 性价比低:
- 纯创作、文本分类、简单抽取——没有工具可用,ReAct 反而更贵更慢;
- 延迟/成本敏感、要求单轮返回的场景(ReAct 多轮调用,延迟和 token 成本都高);
- 工具本身很烂时(论文 23% 的失败是"检索不到",工具质量直接卡上限)。
7. 与其他推理范式的关系与组合(衔接前四篇)
- ReAct 与 CoT/SC/ToT/GoT/MCTS 不是一回事,且正交可组合:ToT/GoT/MCTS 是在"思维空间里搜索",ReAct 是在"真实世界/工具空间里行动"。两者能叠加——例如 ReAct + MCTS(用搜索选动作)、ReAct + ToT(用树搜索规划多步工具调用)。
- ReAct 不是"强化版 CoT":纯推理任务上它弱于 CoT(HotpotQA 27.4 < 29.4),只在"需要和外部世界交互"时碾压。
- ReAct 是现代 RAG 的思想源头:RAG 是"先检索后生成"(一次性),ReAct 是"边想边检索"。整个 RAG 时代都站在 ReAct 肩上——RAG 是 retrieve-first,ReAct 是 reasoning-first(先决定需要什么证据,再去检索)。
8. 工程实现(代码骨架)
ReAct 的实现非常轻量,核心是"生成→解析→执行→追加"的循环。下面是论文思路的精简骨架(仅示意,动作解析用正则):
def react_solve(question, llm, tools, max_steps=15):
# tools: {"search": fn, "lookup": fn, "finish": lambda x: x}
prompt = FEW_SHOT_EXEMPLARS + f"Question: {question}\n"
for _ in range(max_steps):
text = llm.generate(prompt) # 1. 模型续写
action = parse_action(text) # 2. 正则抠出 Action: tool[arg]
if action.name == "finish": # 3. 终止条件
return action.arg
obs = tools[action.name](action.arg) # 4. 调外部工具
prompt += text + f"\nObservation: {obs}\n" # 5. 追加回上下文
return "未找到答案"
与现代框架的渊源:LangChain 的 ZeroShot ReAct Agent、AutoGen 默认模式,本质都是 ReAct——它是"现代 Agent 的祖先架构"。
从字符串解析 → Function Calling 的演进:ReAct 当年靠正则抠 Action 字符串;现在大模型用结构化 JSON 工具调用取代了它(模型直接输出带 schema 的 tool_call)。这是 ReAct 的工程进化,但"推理与行动交错"的思想完全一致。
9. 评测:怎么知道它对不对
ReAct 比 CoT 多一层——它有一整条 Thought/Action/Observation 轨迹,所以"对不对"要同时看结果层和过程层。
9.1 结果层:任务级正确性
| 任务 | 指标 | 含义 |
|---|---|---|
| HotpotQA | EM(Exact Match) | 答案字符串是否精确匹配金标准 |
| FEVER | Accuracy | 三分类 SUPPORTS/REFUTES/NOT ENOUGH INFO 是否判对 |
| ALFWorld | Success Rate | 任务是否真正完成 |
| WebShop | Success Rate / Score | 是否符合用户需求(属性匹配度) |
并且必须对照基线看相对提升:ReAct vs CoT vs Act-only vs CoT-SC。
9.2 过程层:轨迹"可不可信"(最关键)
光看 EM 会漏掉大问题:答案对了,可能是蒙对/编对的。论文人工标注了 ReAct 和 CoT 各 50 条正确 + 50 条错误轨迹(共 200 条),得到 Table 2(原论文实测):
| 类别 | 子类 | ReAct | CoT |
|---|---|---|---|
| ✅ 成功案例 | 真阳性(推理+事实都对) | 94% | 86% |
| ✅ 成功案例 | 假阳性(含幻觉) | 6% | 14% |
| ❌ 失败案例 | 推理错误(含卡在重复循环) | 47% | 16% |
| ❌ 失败案例 | 搜索结果错误(搜空/无用) | 23% | — |
| ❌ 失败案例 | 幻觉(凭空编造) | 0% | 56% |
| ❌ 失败案例 | 标签歧义(答案对但格式不符) | 29% | 28% |
这张表就是"怎么判断 ReAct 对不对"的核心:
- ReAct 在成功案例里 94% 是真阳性(推理和事实都站得住),而 CoT 只有 86%——同样"答对了",ReAct 更可信。
- ReAct 在失败案例里幻觉为 0%,而 CoT 高达 56%——CoT 错大多因为"编",ReAct 错大多因为"想歪了(47%)“或"没搜到(23%)”。后者更可调试、可修复。
9.3 实操清单:一次 ReAct 跑出来怎么验
- 对答案:最终
finish[...]是否匹配金标准(EM / 精确匹配 / 成功率)。 - 对轨迹(区分真阳性 vs 假阳性):最终答案是否真的从 Observation 推出来?每条 Thought 是否基于上一步 Observation?答案对但推理链在编造,就是"假阳性",不可信。
- 对工具:调的工具对不对?参数合不合理?搜索有没有返回有用信息?(对应 23% 的搜索错误)
- 错因归因:错了归到哪类(推理/搜索/幻觉/标签)?决定怎么改。
- 人工闭环验证(论文做法):直接改掉轨迹里一句可疑/幻觉的 Thought,看 ReAct 能否据此自我纠正并跑通。若能,说明推理链本身成立。
9.4 一个坑:EM 会低估 ReAct
ReAct 的失败里有 29% 是"标签歧义"——答案实质正确,只是没精确匹配标签格式;且部分 HotpotQA 标签本身已过时。所以纯 EM 会低估 ReAct,必须辅以人工判读"答案实质是否正确"。
9.5 工具质量层(ReAct 独有)
因为 ReAct 依赖外部工具,工具本身也要评。论文 23% 的失败来自"搜索失效"——这不是模型的问题,是检索器的问题。
10. 失败模式与局限
- 工具是上限:23% 的失败源于"搜索失效"——模型再聪明,检索器拉不到就崩。
- 推理错误反而比 CoT 高:失败案例里 ReAct 推理错误占 47%、CoT 才 16%——结构约束降低了灵活性,且 ReAct 特有**"重复循环"陷阱**(模型反复生成同样的 Thought/Action 出不来)。
- 上下文只增不减:每步 Observation 都追加入上下文 → Token 成本与延迟随步数线性增长。
- 动作空间必须预定义:模型不能自己发明新工具,只能从你给的
search/lookup/finish里选。 - 解析脆弱:Action 格式一旦不合规就直接崩,需要容错。
11. 重要演进
- ReAct ↔ CoT-SC 互补兜底(论文最强配置):先跑 ReAct,当外壳检测到"连续搜索失败 / 模型表达不确定"时,切换到 Self-Consistency 多路径投票 → HotpotQA 达 35.1;反过来 CoT-SC 没把握时切到 ReAct 去查 → FEVER 达 64.6。印证结论:内部推理(CoT)和外部知识(ReAct)互补,不是替代。
- 微调版 ReAct(反直觉结论):小模型(PaLM-8B)用 prompt 学 ReAct 最差,但用 3000 条轨迹微调后,8B 版超过所有 540B 的 prompt 方法。这决定了"该 prompt 还是该微调"。
- Reflexion(自我反思):ReAct 之后,把失败轨迹写成"语言化反思"塞进记忆,下次复盘——是 ReAct 最自然的后继。
- ReWOO 等变体:先一次性规划所有动作再执行(offline),与 ReAct 的 online 交错形成对比。
12. 安全与可控(AI 安全视角)
- 可审计:ReAct 的轨迹让人类能逐条审查"为什么调这个工具",还能 human-in-the-loop 改一句 Thought 直接纠偏(论文验证:替换一句幻觉 Thought,轨迹即可恢复成功)。
- 反过来要沙箱化:因为"模型生成动作字符串"可能触发危险操作,Action 空间必须有权限管控与沙箱——这是把 ReAct 投入生产前的必做项。
13. 常见误区
- ❌ ReAct 全面碾压 CoT → ✅ 纯推理不如 CoT,交互任务才强。
- ❌ 没工具也能用 ReAct → ✅ 没工具就退化成 CoT。
- ❌ 步数越多越好 → ✅ 越多越易循环、越贵。
更多推荐
所有评论(0)