ReAct:在语言模型中协同推理与行动

  • 关联论文:2210.03629
  • 作者:flyP
  • 更新:2026-08-14

一句话结论

ReAct 把 Chain-of-Thought(CoT)的"思考"和 Action Plan Generation(行动生成)合并到同一个 prompt 里的交错序列(Thought → Action → Observation → Thought → ...),让 LLM 在推理时即时调用外部工具(搜索/查询/执行)来补足事实,让行动时回写到推理轨迹里自我纠错。

它要解决的真问题

到 2022 年中段,LLM 已经在两种范式上各自取得进展,但都暴露了对方范式里没有的短板:

  1. 纯 CoT 推理的"幻觉蔓延":让模型"think step by step"在算术、常识上效果好,但在需要外部事实的任务(多跳问答、事实验证)上会自信地编造中间事实,并把这些虚构作为后续推理的支柱——一次错误就让整条链坍塌。
  2. 纯 Action-Plan Generation 的"无自我反思":传统 WebGPT / SayCan 等范式把行动步骤生成出来后直接交给执行器,中间没有"我刚才那步是不是走错了"的内部回路,遇到异常或幻觉就只能重头开始。
  3. 两条路径被割裂:论文指出此前 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 回退混合。

亮点与局限

亮点

  1. 零训练成本:纯 prompt 工程 + in-context exemplars,落地到任何指令遵循能力足够强的 LLM 即可。
  2. 可解释性 + 可信度:轨迹里每一步 Thought 都是自然语言,可被人类审阅与审计,对比纯 Act-only 是黑盒。
  3. 跨任务可迁移:同一套 prompt 模板在 QA、Fact-Verification、交互决策三类异构任务上都生效。
  4. 奠基性地位:10158 次 Semantic Scholar 被引(截至 2026-08 抓取),是后续 Reflexion、AutoGPT、Toolformer、LangChain Agent、ReAct-Agents 文脉的源头之一。

局限 ⚠️

  1. 闭集动作空间:对开放工具调用(任意 REST API、长尾 schema)扩展不友好,需自行设计槽位。
  2. 依赖强指令遵循 LLM:在 PaLM-540B 上效果显著,但在更小模型(如 7B)上 Thought 容易失控,论文未给统一小模型复现配方。
  3. 检索质量天花板:Observation 来自 Wikipedia API,引入的召回错误会直接污染 Thought;论文未量化"上游检索失败"与"模型思考失败"的归因比例。
  4. 单链推理,无自我反思:相比后来 Reflexion(带 verbal RL 自反思)缺少错误→重试的显式机制;只能靠 CoT-SC 兜底。
  5. 混合模式才最优:纯 ReAct 在 HotpotQA 上弱于 ReAct+CoT 混合(29.4 vs 27.4),说明 ReAct 本身并非 single winner,需要"ReAct 失败回退 CoT"的元层逻辑。

对工程落地的启发

  1. Agent 框架的事实地基:LangChain ReAct Agent、LlamaIndex ReAct、Haystack Agent、AutoGPT 的"think-act-observe"循环都直接借鉴此论文的 prompt 模板。
  2. 工具调用的最小可行骨架:上线一个内部 Agent 时,先按 ReAct 三元组做骨架 → 在 Thought 段允许自由生成 → 在 Action 段用闭集 + JSON schema 强制 parse → Observation 回填 → 直到 finish 槽位被触发。
  3. 可观测性优势:每一步 Thought 都是自然语言 → 直接进 logging/tracing 即可做审计与失败归因,比传统 RL agent 黑盒易排错。
  4. 小成本快速验证:哪怕不上 fine-tuning,先用 ReAct + GPT-4/Claude 验证业务可行性 → 验证通过再决定要不要 Toolformer/Reflexion/RL 路线。
  5. 回退机制设计: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。