ReAct 出自论文《ReAct: Synergizing Reasoning and Acting in Language Models》,第一作者为普林斯顿大学计算机科学系的 Shunyu Yao,合作者包括 Jeffrey Zhao、Dian Yu、Nan Du、Izhak Shafran、Karthik Narasimhan 和 Yuan Cao,分别来自普林斯顿大学和 Google Research Brain 团队。论文于 2022 年 10 月首次发布于 arXiv(编号 2210.03629),后发表于 ICLR 2023。
论文基于 PaLM-540B 大模型,在多跳问答数据集 HotpotQA、事实验证数据集 FEVER、交互式决策基准 ALFWorld 和 WebShop 上进行了系统评估。实验结果表明,ReAct 在需要与环境交互的任务上显著优于当时的最优方法,同时生成的任务求解轨迹具有更强的人类可解释性。
ReAct 的核心洞察在于:推理和行动并非相互排斥,而是可以相互增强。推理帮助模型规划下一步应该做什么、跟踪任务进度、处理异常情况;行动则让模型能够与外部环境交互,获取内部知识之外的实时信息。两者交织形成闭环,使模型既不会在封闭的知识空间里"闭门造车",也不会在没有方向的情况下盲目调用工具。
纯推理方法(如链式思维)只能在模型参数内部进行推导,一旦遇到训练数据之外或需要实时验证的问题,容易产生幻觉且错误会沿推理链传播。纯行动方法虽然能调用外部工具,但缺乏高层推理来指导"为什么要调这个工具""下一步该做什么",导致执行路径混乱。ReAct 通过将两者交错整合,用推理引导行动方向,用行动结果校正推理偏差。
ReAct 的工作流程是一个迭代循环,每一轮包含三个核心环节:
a. Thought(思考):模型分析当前状态,推理下一步需要做什么。例如:"我需要查找爱因斯坦的出生日期。"
b. Action(行动):模型根据思考结果,选择一个工具并传入参数。例如:Search["Albert Einstein birth date"]。
c. Observation(观察):工具执行后返回结果,作为下一轮思考的输入。例如:"Albert Einstein was born on March 14, 1879."
循环持续进行,直到模型输出 Finish[answer] 给出最终答案,或达到预设的最大步数限制。
在需要长期规划的任务(如 ALFWorld)中,模型可以采用稀疏推理策略——仅在关键决策点生成 Thought,其余步骤直接执行 Action,从而提高效率。而在知识密集型任务(如多跳问答)中,密集的 Thought 有助于保持推理链条的完整性。
链式思维(CoT)是一种纯内部的推理技术,模型在单次前向传播中生成中间推理步骤后直接输出答案。这种方式虽然在数学推理等封闭域任务上表现良好,但无法获取训练数据之外的信息。ReAct 在 CoT 的基础上引入了工具调用和环境反馈机制,将推理过程从"闭卷考试"升级为"开卷查阅"。
根据原论文的失败模式分析,在 HotpotQA 任务中,CoT 方法有 56% 的失败案例源于幻觉(即模型基于错误的内部知识进行推理),而 ReAct 的幻觉率为 0%。这是因为 ReAct 的每一步推理都建立在实际检索到的信息之上,而非模型的参数记忆。
在 PaLM-540B 上的实验结果显示:
方法 | HotpotQA (EM) | FEVER (准确率) |
|---|---|---|
标准提示 | 28.7% | 57.1% |
CoT | 29.4% | 56.3% |
CoT 自洽采样 | 33.4% | 60.4% |
仅行动 | 25.7% | 58.9% |
ReAct | 27.4% | 60.9% |
ReAct + CoT 混合 | 35.1% | 64.6% |
值得注意的是,ReAct 单独使用在 HotpotQA 上略低于 CoT,但在 FEVER 上超越了 CoT。最佳效果来自两者的混合策略,说明内部推理和外部检索应当根据任务特性灵活选择。
ReAct 不需要预先知道完整的解决方案路径。在每一步中,模型根据当前的 Observation 决定下一步行动,这使得它能够应对环境变化和意外情况。例如,当搜索结果为空时,模型可以自动调整搜索关键词重新尝试。
由于每一步 Thought 都是显式的,模型可以在推理过程中发现矛盾或不一致之处,并通过额外的工具调用来验证或修正。这种自我校验能力是纯推理方法所不具备的。
在企业级应用场景中,ReAct 可以在一次交互中串联多个信息源——知识库、数据库、外部 API——形成完整的推理链路。这种"跨系统组合推理"能力使其特别适合需要综合多维度信息的复杂任务。
包括多跳问答、事实核查、学术文献检索与总结等。这类任务的共同特征是答案分散在多个信息源中,需要通过多次检索和推理才能得出完整结论。
包括智能日程规划、电商商品筛选、旅游路线设计等。这类任务需要根据用户的模糊需求,动态调用多个工具(如地图 API、价格查询接口)并进行权衡判断。
ReAct 驱动的客服系统可以处理复杂的客户请求,例如"查询我上周的订单状态,并把账户里的优惠券用在还没发货的商品上"。AI 依次调用订单系统和用户账户系统的 API,完成跨系统操作。
在机器人领域,ReAct 框架可以将高层指令(如"把客厅的零食拿到书房")分解为感知、定位、抓取、导航等一系列底层动作,并通过传感器反馈不断调整执行策略。
以 HotpotQA 风格的问题为例:
问题:除了 Apple Remote 之外,还有什么设备可以控制 Apple Remote 最初设计配合使用的程序?
Thought 1:我需要先找出 Apple Remote 最初是为哪个程序设计的。
Action 1:Search["Apple Remote original purpose"]
Observation 1:The Apple Remote was initially designed to work with Front Row media application.
Thought 2:现在我需要找出还有哪些设备可以控制 Front Row。
Action 2:Search["Front Row controls devices"]
Observation 2:Front Row can be controlled using an Apple Remote or the keyboard.
Thought 3:我已经有了足够的信息。
Action 3:Finish[keyboard]同样的问题如果交给纯 CoT 方法,模型可能基于训练数据中的模糊记忆给出错误答案(如猜测"鼠标"或"触控板")。ReAct 通过实际检索维基百科,确保每一步都有事实依据。
在 ALFWorld 这类需要多步规划的模拟环境中,ReAct 通过 Thought 步骤维持对当前目标和已完成子目标的跟踪。例如在"找到肥皂并将其清洗干净"的任务中,模型需要记住"已经找到了肥皂,接下来需要找到水槽"。
当某个行动未能达到预期效果时(如打开抽屉后发现里面没有目标物品),ReAct 的 Thought 机制允许模型识别这一异常并调整策略(如去其他位置搜索),而不是沿着错误路径继续执行。
ReAct 在 ALFWorld 上仅需 1-2 个示例就能达到 71% 的成功率,远超模仿学习(37%)和强化学习(45%)方法,后者通常需要数千到数万条训练样本。这证明了 ReAct 范式强大的少样本迁移能力。
实现 ReAct 需要定义一组可供模型调用的工具。每个工具需要有清晰的名称和功能描述,因为模型正是通过这些描述来决定何时调用哪个工具。常见的工具类型包括:
a. 搜索类工具:如搜索引擎 API、维基百科查询接口 b. 计算类工具:如计算器、代码解释器 c. 查询类工具:如数据库查询、API 调用 d. 终结工具:用于提交最终答案
面对复杂问题时,ReAct 会自动将其分解为多个子查询,逐个执行后将结果整合。例如在金融尽调场景中,模型可能依次调用企业信息查询 API、财报数据库和新闻舆情接口,最终综合所有信息给出风险评估结论。
ReAct 的 Prompt 通常包含以下几个关键部分:
a. 任务描述:明确告知模型它的角色和能力范围 b. 工具列表:列出所有可用工具的名称、功能描述和参数格式 c. 输出格式示例:通过 Few-shot 示例展示 Thought-Action-Observation 的标准格式 d. 终止条件:说明何时应该输出 Final Answer
示例的数量和质量直接影响 ReAct 的表现。对于知识密集型任务,建议使用密集的 Thought 示例(每步都有详细推理);对于决策类任务,稀疏示例(仅在关键节点有 Thought)往往效果更好。原论文表明,1-6 个精心设计的示例就足以让模型掌握 ReAct 范式。
在生产环境中,建议使用结构化输出格式(如 JSON Schema 或 Function Calling 模式)来确保 Action 的可解析性。这可以有效避免模型输出格式不规范导致的解析失败问题。
Thought 是 ReAct 的灵魂所在。它不仅是模型的"内心独白",更承担着多重功能:规划下一步行动、跟踪任务进度、检测异常情况、整合历史信息。研究表明,即使 Thought 本身不直接贡献于最终答案的正确性,它的存在也大幅提升了人类对模型行为的理解和信任。
动作空间定义了模型可以采取的所有可能行动。一个设计良好的动作空间应当满足:互斥性(各工具职责不重叠)、完备性(覆盖任务所需的全部能力)、原子性(每个工具只做一件事并做好)。
Observation 是连接模型内部推理与外部世界的桥梁。高质量的反馈应当准确、简洁且信息丰富。过长的 Observation 会导致上下文膨胀,过短则可能遗漏关键信息。
这是 ReAct 最常见的故障模式之一。当模型反复执行相同的 Action 而无法取得进展时,就会陷入死循环。根据工程实践统计,在没有步数限制的情况下,约 30%-50% 的复杂任务会遇到此类问题。
一旦某一步的 Observation 包含错误信息(如 API 返回了不相关的搜索结果),后续的所有 Thought 都会基于这个错误前提进行推导,导致最终输出完全偏离正确轨道。ReAct 本身缺乏对 Observation 的质疑和验证机制。
当可用工具数量较多或工具描述存在重叠时,模型可能选择错误的工具或传入不正确的参数格式。这个问题在弱模型上尤为突出, malformed JSON 是最常见的生产错误。
随着循环轮次的增加,模型的推理质量会逐渐下降。研究表明,一个每步可靠度为 95% 的 Agent,在连续执行 10 步后的整体可靠度会降至约 60%。这种指数级的可靠性衰减是长程任务的主要瓶颈。
每一轮 T-A-O 循环都会向对话历史中追加内容,多轮之后可能导致上下文窗口溢出。这不仅增加了 Token 成本,还会引发"中间信息丢失"(Lost in the Middle)效应,使模型难以关注到早期步骤的关键信息。
学术界和工业界常用的评估基准包括:
a. HotpotQA:多跳问答数据集,使用精确匹配率(EM)作为指标 b. FEVER:事实验证数据集,使用准确率(Accuracy)作为指标 c. ALFWorld:文本模拟家庭环境中的任务完成基准,使用成功率作为指标 d. WebShop:模拟电商购物流程的基准,使用任务完成率作为指标
除了任务成功率之外,全面的评估还应当考虑:
a. Token 效率:完成任务所需的平均 Token 消耗量 b. 延迟:从用户输入到最终输出的端到端响应时间 c. 可解释性:人类审计者能否理解模型的决策过程 d. 鲁棒性:在工具失败或返回噪声时的容错能力
对错误案例进行人工标注分类是理解 ReAct 表现的重要手段。原论文采用的分类体系包括:幻觉、推理错误、检索错误、标签歧义等类别,这种方法可以帮助开发者有针对性地优化系统。
Self-Ask 的核心是递归问题分解——将一个复杂问题拆解为一系列可以被直接回答的子问题,每个子问题通过外部工具(主要是搜索引擎)获取答案,最后将所有中间答案聚合为最终回复。ReAct 的核心则是推理-行动循环——在每一步中根据当前状态决定做什么,执行后根据结果调整下一步策略。
维度 | Self-Ask | ReAct |
|---|---|---|
核心定位 | 事实拆解型推理 | 任务执行型交互 |
推理逻辑 | 先拆分子问题,查询后再作答 | 思考-行动-观察循环执行 |
工具依赖 | 主要依赖搜索类工具 | 支持全类型工具 |
灵活性 | 较低,流程标准化 | 较高,动态适应各类场景 |
典型场景 | 多跳问答、事实核查 | 智能客服、工具调用、实时交互 |
简而言之,Self-Ask 适合路径可预测的事实类问题,ReAct 适合需要动态调整的交互式任务。
Self-Ask 的输出结构是"Follow-up Question → Intermediate Answer"的嵌套对,整个推理过程更像是一个预定义的分解树。ReAct 的输出结构是"Thought → Action → Observation"的线性序列,每一步都依赖于上一步的实际结果,具有更强的适应性。
在多智能体系统中,每个独立的 Agent 通常都运行着自己的 ReAct 循环。例如在 CrewAI 框架中,每个角色(研究员、写作者、审核员)都是一个独立的 ReAct Agent,拥有自己的工具集和记忆空间。
多智能体系统的通信架构经历了从星型拓扑(中心化调度)到网状拓扑(去中心化协作)再到分层拓扑(平衡效率与可管理性)的演进。无论采用哪种拓扑,底层的单个 Agent 大多遵循 ReAct 范式进行自主决策。
在企业级部署中,多 Agent 系统可以将复杂工作流分解为由不同专业 Agent 处理的子任务。例如在客户服务场景中,可以有专门负责工单分类的 Agent、负责知识库检索的 Agent、负责执行操作的 Agent,以及负责任务路由的协调 Agent。每个 Agent 内部都运行 ReAct 循环,Agent 之间通过标准化的消息协议进行通信。
研究表明,当 Agent 规模扩展到一定程度时,协调开销可能超过性能增益,出现边际收益递减的现象。如何在 Agent 数量与系统效率之间找到最优平衡点,是当前多智能体研究的重要课题。
目前主流的 Agent 框架都内置了 ReAct 支持:
a. LangChain / LangGraph:提供 create_react_agent 预构建函数,支持工具注册、状态管理和流式输出。LangGraph 通过 recursion_limit = 2 * max_iterations + 1 来控制最大循环步数。
b. LlamaIndex:提供 ReActAgent 类,使用文本格式的 Thought-Action-Observation 循环,兼容不支持 Function Calling 的开源模型。
c. CrewAI:基于角色的多 Agent 框架,每个 Agent 内部都是 ReAct 循环。
d. AutoGen(微软):支持多 Agent 对话,每个 Agent 可以独立运行 ReAct 循环。
a. 设置步数上限:必须配置 max_iterations 防止无限循环,一般建议 10-15 步。
b. 工具描述精准化:工具名称应语义清晰,描述应互斥且完备,这是减少工具选择错误的最有效手段。
c. 使用结构化输出:优先使用 Function Calling 模式而非文本解析,可以大幅降低格式错误的概率。
d. 错误包装而非抛出:当工具执行失败时,应将错误信息作为 Observation 返回给模型,让其自行判断是否需要重试或换用其他工具。
行业共识(包括 Anthropic 在 2024 年底发布的《Building Effective Agents》工程指南)建议:能用简单方案解决的不要用复杂方案。具体到 ReAct 的应用——
a. 纯推理任务(如数学证明)优先使用 CoT b. 需要外部信息的任务使用 ReAct c. 步骤固定且可预测的任务使用 Workflow 编排而非 Agent d. 对准确性要求极高的场景可在 ReAct 基础上叠加 Reflexion 自我反思机制