只靠模型「脑子里的知识」答题,要么算不对,要么编事实。ReAct(reasoning + acting)把两件事交错进行:模型写一步推理,调一次外部工具,再把查到的信息喂回推理。读完这篇你会知道 ReAct 提示长什么样、在哪些任务上真的有效,还能用 LangChain 搭一个会搜索、会算数的 ReAct 代理。如果接下来要做需要查资料、调工具的智能体,这套模式几乎是绕不开的第一课。
ReAct 是什么
ReAct 由 Yao 等人 2022 年提出。在这个框架里,大模型以交错的方式生成推理轨迹(reasoning trace)和任务特定操作(action)[1]。推理轨迹让模型能够归纳、跟踪、更新行动计划,甚至处理异常情况;操作则允许模型与知识库、搜索引擎这类外部源交互、收集信息 [1]。
它和思维链的关系值得说清楚:思维链只有推理,模型与外部世界没有接触,知识也不会更新,因此容易出现事实幻觉和错误传播 [1]。ReAct 把推理和行动结合起来——推理决定下一步查什么,查到的信息又支撑下一步推理,两者互相带路 [1]。交错结构还有两个实用好处:一是每个观察都来自工具的真实返回,模型的话有据可查,幻觉更少;二是整条轨迹人类可读,哪一步搜错了、哪一步推歪了,一眼就能看出来,调试比黑盒式的一问一答容易得多 [1]。作者发现,把 ReAct 与思维链结合的最好方式,是在推理过程中同时使用内部知识和检索到的外部信息 [1]。
ReAct 提示长什么样
一个 ReAct 轨迹由多个「思考—操作—观察」步骤组成。自由格式的思考负责分解问题、提取信息、做常识或算术推理、组织搜索词、合成最终答案;操作去调用外部工具;观察是工具返回的结果 [1]。出自 HotpotQA 数据集的一个例子,摘自论文并缩短为一条示例 [1]:
问题 科罗拉多造山带东部区域延伸到的区域的海拔范围是多少?
思考 1 我需要搜索科罗拉多造山带,找到科罗拉多造山带东段延伸的区域,然后找到该区域的海拔范围。
操作 1 搜索 [科罗拉多造山带]
观察 1 科罗拉多造山带是科罗拉多及其周边地区造山运动的一段。
思考 2 它没有提到东部地区。所以我需要查一下东部地区。
操作 2 查找 [东部地区]
观察 2 (结果 1 / 1) 东部区域延伸至高平原,称为中原造山带。
思考 3 科罗拉多造山运动的东部区域延伸到高平原。所以我需要搜索高平原,找到它的海拔范围。
操作 3 搜索 [高平原]
观察 3 高平原指的是两个截然不同的陆地区域之一。
思考 4 我需要搜索高平原(美国)
操作 4 搜索 [高平原(美国)]
观察 4 高平原是大平原的一个分区。从东到西,高平原的海拔从 1800 到 7000 英尺 (550 到 2130 米) 不等。[3]
思考 5 高平原海拔高度从 1800 到 7000 英尺,所以答案是 1800 到 7000 英尺。
操作 5 结束 [1800 到 7000 英尺]
...模型先搜「科罗拉多造山带」,发现没提到东部,就改查「东部地区」,得知延伸到高平原,再搜高平原的海拔范围,最后给出「1800 到 7000 英尺」并结束 [1]。可以看到两个方向的信息流动:检索为推理提供依据,推理决定下一步检索什么 [1]。
提示写法因任务而异:以推理为主的任务(如 HotpotQA)用较多的「思考—操作—观察」步骤;动作很多的决策型任务则少写思考 [1]。这些轨迹作为少样本示例放进提示,模型照着示例的节奏组织自己的搜索和推理。
效果如何
知识密集型任务上,用 PaLM-540B 作基座模型,在 HotPotQA 问答和 Fever 事实验证两个数据集上比较了不同提示方法 [1]:
- ReAct 通常优于纯行动的 Act(只有操作、没有思考);
- ReAct 在 Fever 上胜过 CoT,但在 HotpotQA 上落后于 CoT。
误差分析给出三个原因:CoT 存在事实幻觉;ReAct 的结构性约束降低了它在制定推理步骤上的灵活性;ReAct 高度依赖检索到的信息,搜索结果没有信息量时,模型推理会被带偏且难以恢复 [1]。把 ReAct 与「思维链 + 自我一致性」结合、在两者之间切换的提示方法,通常优于所有其他方法 [1]。
决策型任务上,ReAct 在 ALFWorld(文本游戏)和 WebShop(在线购物环境)两个基准上都优于 Act——没有思考的 Act 无法正确把目标分解成子目标 [1]。不过基于提示的方法在这类任务上离人类专家还很远 [1]。
写 ReAct 提示的几个要点
自己动手写 ReAct 提示时,几条经验值得带上:
- 按任务类型调整思考密度:推理为主的任务多写思考步,动作密集的任务少写思考,让操作快进 [1];
- 观察的格式要固定,把工具返回整理成一行文本再放进轨迹,轨迹读起来连贯,模型也更容易模仿;
- 最终答案要有格式约定,让轨迹的最后一步用「结束 [答案]」或「最终答案:」收尾,方便程序解析;
- 轨迹示例不只是教格式,也在教模型应对意外——示例里最好出现「观察没查到有用信息、换个搜索词再试」的段落,模型遇到空结果才知道回退重试。
用 LangChain 搭一个 ReAct 代理
ReAct 不只是论文里的提示写法,LangChain 已经内置了用它构建代理的能力,可以把大模型和多种工具组合起来执行任务 [1]。下面搭一个能搜索、会算数的代理。安装并导入必要的库 [1]:
%%capture
# 更新或安装必要的库
!pip install --upgrade openai
!pip install --upgrade langchain
!pip install --upgrade python-dotenv
!pip install google-search-results
# 引入库
import openai
import os
from langchain.llms import OpenAI
from langchain.agents import load_tools
from langchain.agents import initialize_agent
from dotenv import load_dotenv
load_dotenv()
# 载入 API keys; 如果没有,你需要先获取。
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")
os.environ["SERPER_API_KEY"] = os.getenv("SERPER_API_KEY")
然后配置模型、工具和代理:工具用搜索 API 查外部信息,用 LLM 当数学工具 [1]:
llm = OpenAI(model_name="text-davinci-003" ,temperature=0)
tools = load_tools(["google-serper", "llm-math"], llm=llm)
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)配置好后直接跑一个查询,这里不需要提供少样本示例 [1]:
agent.run("奥利维亚·王尔德的男朋友是谁?他现在的年龄的0.23次方是多少?")链的执行过程 [1]:
> 正在输入新代理执行器链......
我得查出奥利维亚·王尔德的男友是谁然后计算出他的年龄的 0.23 次方。
操作: 搜索
操作输入: “奥利维亚·王尔德的男友”
观察: 奥利维亚·王尔德与杰森·苏代基斯在多年前订婚,在他们分手后,她开始与哈里·斯泰尔斯约会 — 参照他们的关系时间线。
思考: 我需要找出哈里·斯泰尔斯的年龄。
操作: 搜索
操作输入: “哈里·斯泰尔斯的年龄”
观察: 29 岁
思考: 我需要计算 29 的 0.23 次方。
操作: 计算器
操作输入: 29^0.23
观察: 答案: 2.169459462491557
思考: 现在我知道最终答案了。
最终答案: 哈里·斯泰尔斯, 奥利维亚·王尔德的男朋友, 29 岁。他年龄的 0.23 次方是 2.169459462491557。
> 结束链。代理先搜出奥利维亚·王尔德的男友是哈里·斯泰尔斯,再搜出他 29 岁,然后调用计算器算 29 的 0.23 次方,最后把两步信息合成最终答案 [1]。注意这条链里每次「操作」都有明确的「思考」作为依据——这正是 ReAct 结构的体现。
什么时候用 ReAct
判断顺序可以这样排:任务只用模型内部知识就能完成,思维链就够了;答案依赖事实、需要查资料的任务,用 ReAct;两个都用上、能来回切换的提示效果最好,但实现也最复杂 [1]。同时要接受它的局限:代理的质量取决于检索质量,搜索结果不靠谱时整条链都会跑偏 [1]。上手顺序也简单:先用现成框架把代理跑通,再回头精调提示里的轨迹示例。
本文改编自 DAIR.AI 开源教程《Prompt Engineering Guide》的 ReAct 框架一节[1],原文以 MIT 许可证发布。
来源
- 1ReAct 框架 | Prompt Engineering GuideDAIR.AI Prompt Engineering Guide (MIT)
引用本页: ReAct 提示:边思考边行动. TellWorld, https://www.tellworld.net/zh/practice/practice-prompt-react. 更新于 2026-11-14