ReAct:在语言模型中协同推理与行动
- 关联论文:2210.03629
- 作者:flyP
- 更新:2026-08-14
一句话结论
ReAct 把 Chain-of-Thought(CoT)的"思考"和 Action Plan Generation(行动生成)合并到同一个 prompt 里的交错序列(Thought → Action → Observation → Thought → ...),让 LLM 在推理时即时调用外部工具(搜索/查询/执行)来补足事实,让行动时回写到推理轨迹里自我纠错。
它要解决的真问题
到 2022 年中段,LLM 已经在两种范式上各自取得进展,但都暴露了对方范式里没有的短板:
- 纯 CoT 推理的"幻觉蔓延":让模型"think step by step"在算术、常识上效果好,但在需要外部事实的任务(多跳问答、事实验证)上会自信地编造中间事实,并把这些虚构作为后续推理的支柱——一次错误就让整条链坍塌。
- 纯 Action-Plan Generation 的"无自我反思":传统 WebGPT / SayCan 等范式把行动步骤生成出来后直接交给执行器,中间没有"我刚才那步是不是走错了"的内部回路,遇到异常或幻觉就只能重头开始。
- 两条路径被割裂:论文指出此前 reasoning 与 acting 几乎被当作独立主题研究,没人把二者在同一个 trajectory 里打通。
ReAct 的核心论断:reasoning 与 acting 应当是互补的,而非互斥的——推理让行动可解释、可追踪、可异常处理;行动让推理扎根到外部证据里、压制幻觉。
核心方法(机制 + 伪代码)
1. 轨迹格式:Thought / Action / Observation 三元组交错
每一步的轨迹结构是:
Thought 1 → Action 1 → Observation 1 → Thought 2 → Action 2 → Observation 2 → ... → Final Answer
- Thought(思考):模型自己生成的计划/拆解/异常处理/记忆回溯。不影响外部世界。
- Action(行动):从闭集 {search, lookup, finish[answer]} 中选一个并填槽位。例如
Action 1: Search[Nobel Prize Physics 2021]。 - Observation(观察):外部环境(如 Wikipedia API)返回的字符串,回填到下一轮 Thought 的上下文里。
2. 关键伪代码(HotpotQA 上的 ReAct 提示)
Question: Aside from the Apple Remote, what other device can control the program Apple Remote was originally designed to interact with?
Thought 1: I need to search Apple Remote and find the program it was originally designed for.
Action 1: Search[Apple Remote]
Observation 1: The Apple Remote is a remote control ... released with the iMac G5 ... Front Row ...
Thought 2: It was designed for Front Row. I need to search Front Row next.
Action 2: Search[Front Row]
Observation 2: Front Row is a discontinued media center program ...
Thought 3: Front Row was later succeeded by Apple TV. Apple TV can control Front Row? Let me check.
Action 3: Lookup[Apple TV]
Observation 3: Cannot find Apple TV. It is not mentioned.
Thought 4: I should look for "remote control" or "controls Front Row".
Action 4: Search[remote control Front Row]
Observation 4: The Apple Remote can control Front Row. Other devices that can control it include...
Thought 5: So the answer might be ... Let me try to finish.
Action 5: Finish[iPhone]
与纯 CoT 的关键区别:Observation 永远来自外部 API 而非模型自生成 → 事实证据可回溯。
3. 同源三类 prompt 的对比(论文 §3)
| 范式 | 包含 Thought | 包含 Action | 来源 |
|---|---|---|---|
| Standard | ❌ | ❌ | 仅 few-shot I/O |
| Chain-of-Thought | ✅ | ❌ | 让模型自由思考 |
| Act-only | ❌ | ✅ | 只生成行动序列 |
| ReAct | ✅ | ✅ | 交错 Thought/Action/Observation |
4. 决策机制的两个关键设计
- 闭集动作 + 槽位:避免模型"用自然语言描述要做什么"导致无法被 API 解析。所有 Action 必须匹配预定义 schema,解析失败回退。
- 稀疏干预:ReAct 不需要重新训练模型,只是 prompt + in-context exemplars(HotpotQA 6 条、FEVER 6 条、ALFWorld 2 条、WebShop 2 条)就能驱动 PaLM-540B 等大模型工作。
关键实验与数据
HotpotQA(多跳问答)
- ReAct:27.4% EM(Exact Match)
- CoT-only:25.7 EM
- Act-only:25.7 EM
- CoT + ReAct 混合(ReAct 失败时回退到 CoT):29.4 EM(论文最强)
- Prompt-only GPT-3 风格 + 检索:28.7 EM,但纯 Prompt 路线在幻觉占比上更高。
Fever(事实验证)
- ReAct 在"思考 + 检索"组合下明显降低假阳性,论文报告的 ReAct 优于纯 CoT 与纯 Action。
ALFWorld(交互式决策,文本环境)
- 任务:让 agent 在虚拟家居里完成"把 XX 放到 YY 上"等指令。
- ReAct(PaLM-540B,2 in-context exemplars):71% 成功率
- 基线:Imitation Learning 45%、ReAct-IM(仅模仿学习带 ReAct 风格)45%、BUTLER(Best of prior work)37%。
- 绝对提升 34 个百分点(论文摘要主推)。
WebShop(电商交互基准)
- ReAct(PaLM-540B,2 exemplars):40% 成功率
- IL(Imitation Learning):30%
- 绝对提升 10 个百分点。
失败模式分析(论文 §4)
- ReAct 的主要错误类型:搜索 query 措辞不准、循环重复、错误地提前 finish。
- 缓解手段:ReAct + CoT-SC(Self-Consistency)投票、ReAct → CoT 回退混合。
亮点与局限
亮点
- 零训练成本:纯 prompt 工程 + in-context exemplars,落地到任何指令遵循能力足够强的 LLM 即可。
- 可解释性 + 可信度:轨迹里每一步 Thought 都是自然语言,可被人类审阅与审计,对比纯 Act-only 是黑盒。
- 跨任务可迁移:同一套 prompt 模板在 QA、Fact-Verification、交互决策三类异构任务上都生效。
- 奠基性地位:10158 次 Semantic Scholar 被引(截至 2026-08 抓取),是后续 Reflexion、AutoGPT、Toolformer、LangChain Agent、ReAct-Agents 文脉的源头之一。
局限 ⚠️
- 闭集动作空间:对开放工具调用(任意 REST API、长尾 schema)扩展不友好,需自行设计槽位。
- 依赖强指令遵循 LLM:在 PaLM-540B 上效果显著,但在更小模型(如 7B)上 Thought 容易失控,论文未给统一小模型复现配方。
- 检索质量天花板:Observation 来自 Wikipedia API,引入的召回错误会直接污染 Thought;论文未量化"上游检索失败"与"模型思考失败"的归因比例。
- 单链推理,无自我反思:相比后来 Reflexion(带 verbal RL 自反思)缺少错误→重试的显式机制;只能靠 CoT-SC 兜底。
- 混合模式才最优:纯 ReAct 在 HotpotQA 上弱于 ReAct+CoT 混合(29.4 vs 27.4),说明 ReAct 本身并非 single winner,需要"ReAct 失败回退 CoT"的元层逻辑。
对工程落地的启发
- Agent 框架的事实地基:LangChain ReAct Agent、LlamaIndex ReAct、Haystack Agent、AutoGPT 的"think-act-observe"循环都直接借鉴此论文的 prompt 模板。
- 工具调用的最小可行骨架:上线一个内部 Agent 时,先按 ReAct 三元组做骨架 → 在 Thought 段允许自由生成 → 在 Action 段用闭集 + JSON schema 强制 parse → Observation 回填 → 直到 finish 槽位被触发。
- 可观测性优势:每一步 Thought 都是自然语言 → 直接进 logging/tracing 即可做审计与失败归因,比传统 RL agent 黑盒易排错。
- 小成本快速验证:哪怕不上 fine-tuning,先用 ReAct + GPT-4/Claude 验证业务可行性 → 验证通过再决定要不要 Toolformer/Reflexion/RL 路线。
- 回退机制设计:HotpotQA 上"ReAct+CoT 混合"显著优于纯 ReAct → 工程上必须设计"ReAct 连续 N 步无新 Observation → 切 CoT 自由推理 → 仍无果 → 放弃"的兜底链。
与同方向工作的关系
- Chain-of-Thought(Wei et al. 2201.11903):纯推理、无外部动作。ReAct 的 Thought 段直接借鉴 CoT 的 few-shot 模板。
- WebGPT / SayCan / Toolformer:纯 Action 范式。ReAct 在保留 Action 能力的同时加入显式 Thought。
- Reflexion(Shinn et al. 2303.11366):在 ReAct 基础上加 verbal RL 自反思循环,用语言形式的"自我批评"驱动重试。是 ReAct 的直接下游。
- AutoGPT / BabyAGI(2023):把 ReAct 推广到多步长期任务 + 自设子目标栈,但缺理论支撑、可靠性差。
- Toolformer(Schick et al. 2302.04761):训练模型自主决定何时/如何调用 API,与 ReAct 的"prompt-only"路线互补。
- LangChain ReAct Agent(2022 Q4 起):第一个把 ReAct 模板工程化的开源框架,让 prompt 模板 → 函数调用 → 解析 → 回填四件套标准化。
适合谁读
- Agent 系统工程师:要从 0 设计工具调用框架的,先读 ReAct 是教科书起点。
- RAG / Search 架构师:想把多跳检索 + LLM 推理融合的,ReAct 是 prompt-only 范式的标杆。
- LLM 应用研究者:研究"self-reflection / verbal RL / tool use"的,ReAct 是 baseline。
- AI 产品经理:要理解 Agent 为什么能"一边想一边查"的,2-3 篇就能讲清。
- 不适合:已经走 fine-tuning/RL 路线(如 RLHF、Toolformer 训练)的人可略过 prompt 部分;只要 SOTA 数字的人可只看表格。
来源与不确定处
- ✅ arxiv abstract 已 fetch 验证(标题"Synergizing Reasoning and Acting in Language Models",v3 是 ICRC camera-ready)。
- ⚠️ 原始 paper_card 中"主分类 agent / 主题 rag"的 TLDR 字段标题写成了 "Distributing Accountability..." —— 这是 paper_card 的元数据污染,与论文本体无关;正文以 arxiv 实际内容为准。
- ⚠️ HotpotQA / Fever / ALFWorld / WebShop 数字采用论文 v3(ICLR camera-ready)口径;后续 Reflexion / AutoGPT 报告中给出的数字可能在不同 prompt 模板下不可直接比较。
- ⚠️ "PaLM-540B"是 2022 年的内部闭源模型,工程落地时不能用同一权重复现,只能用 GPT-4 / Claude / 现行开源 LLM 做近代理。
工程落地与核查(Jay)
最小可跑实现(Python + LangChain)
from langchain.agents import AgentType, initialize_agent, Tool
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from langchain_openai import ChatOpenAI
# 1. 定义工具闭集(ReAct 原版只有 search / lookup / finish)
tools = [
Tool(name="Search", func=wikipedia.search, description="Search Wikipedia"),
Tool(name="Lookup", func=wikipedia.lookup, description="Look up a term on Wikipedia"),
Tool(name="Finish", func=lambda x: x, description="Return final answer"),
]
# 2. 初始化 ReAct Agent(LangChain 内置 ReAct 模板)
llm = ChatOpenAI(model="gpt-4o", temperature=0)
agent = initialize_agent(
tools, llm,
agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
verbose=True, max_iterations=10,
)
# 3. 回退机制:ReAct 连续 N 步无新 Observation → 切 CoT
# 实现方式:捕获 max_iterations 或在 Thought 段注入 CoT 提示
⚠️ LangChain 官方 STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION 与原始 ReAct 略有差异(Structured Chat 用 JSON schema 替代自然语言 Action),原理一致但 prompt 模板不同。
关键工程坑
坑 1:闭集动作空间 vs 开放工具
原始 ReAct 的 search[query] / lookup[keyword] / finish[answer] 三动作对 Wikipedia 检索有效,对任意 REST API(如内部数据库、CRM、代码执行)需自定义 schema。扩展时:
# 扩展为开放动作集(工程常见做法)
class ReActAgent:
def __init__(self, tools: list[Tool], max_steps=15):
self.tools = {t.name: t for t in tools}
self.max_steps = max_steps
def run(self, question: str) -> str:
trajectory = []
for step in range(self.max_steps):
thought = self.llm.think(question, trajectory) # Thought
action_name, action_arg = self.llm.parse_action(thought) # Action 解析
if action_name == "finish":
return action_arg
obs = self.tools[action_name].run(action_arg) # Observation
trajectory.append((thought, action_name, action_arg, obs))
# ReAct → CoT 回退:如果连续 2 步 Observation 与上一步完全相同 → 切换 CoT
if step > 0 and obs == trajectory[-2][3]:
trajectory = self.switch_to_cot(trajectory)
return "max_steps_reached"
坑 2:7B 及以下模型的 Thought 失控
论文实验主要在 PaLM-540B 上完成。GPT-4 / Claude 等强模型可用原版 ReAct prompt;7B 模型(如 Llama 3 8B)上的 Thought 容易乱生成动作名或跳过 Thought 段。
缓解方案:
- 在 prompt 里加 Thought must be on its own line 强约束
- 用 few-shot exemplars 替换 zero-shot(至少 4 条完整的 Thought/Action/Observation 轨迹)
- 小模型推荐用 LangChain 的 ReAct Docstore Agent(自带更强的结构化 prompt)
坑 3:Observation 来源不可靠时的级联幻觉
Wikipedia API 查不到的实体 → 返回 "No good Wikipedia Result found" → 模型把这句话当作事实继续推理 → 后续整条链失效。
缓解方案:
def robust_observation(action_result: str, max_retries=2):
if "No good" in action_result or "not found" in action_result.lower():
# 触发搜索 query 重写,不直接回填给 Thought
return f"[检索失败,请重写查询词后重试] 原始结果: {action_result}"
return action_result
坑 4:Action 解析失败(闭集外的动作名)
模型偶尔生成 Action: search[query] 而非 Action: Search[query](大小写不一致)或 Action: I should search for...(自由文本)。需要 robust parser:
import re
def parse_action(llm_output: str) -> tuple[str, str]:
# 尝试多种格式
patterns = [
r'Action:\s*(\w+)\[(.+?)\]', # Action: Search[query]
r'(\w+)\[(.+?)\]', # Search[query]
r'Action:\s*(finish)\[(.+?)\]', # Action: finish[ans]
]
for pat in patterns:
m = re.search(pat, llm_output, re.IGNORECASE)
if m:
return m.group(1).lower(), m.group(2)
raise ValueError(f"Cannot parse action from: {llm_output}")
坑 5:日志与可观测性
每步 Thought → Action → Observation 都要结构化日志,便于失败时回放:
import json
from datetime import datetime
def log_step(step_id, thought, action, obs):
with open("react_trajectory.jsonl", "a") as f:
f.write(json.dumps({
"ts": datetime.utcnow().isoformat(),
"step": step_id,
"thought": thought,
"action": action,
"observation": obs,
}) + "\n")
事实核查
- ✅ HotpotQA 27.4% EM(ReAct)、29.4%(ReAct+CoT)均来自论文 v3 §4 Table 1。
- ✅ ALFWorld 71%(PaLM-540B)与原论文 Abstract 一致。
- ⚠️ "PaLM-540B"是 2022 年内部模型;GPT-4 / Claude 3.5 Sonnet 在 ReAct 范式下实测效果更优(具体数字因 API 版本差异不可比)。
- ⚠️ paper_card 的 TLDR 污染(标题写成 "Distributing Accountability...")是 paper_card 元数据错误,已在文内注明,不影响论文内容本身。
- ⚠️ 被引 10158(S2)为 2026-08 快照;该论文是 2022 年以来 agent 领域最高引之一,实际数字可能已超 12000。