{"notes":[{"id":"transformers/react","category":"transformers","legacyPath":"","legacySlug":"","legacyPaths":[],"title":"ReAct","subtitle":"知行合一","author":"Z. Yuan","paperDate":"2022-10-06","publishedOn":"2026-07-03","world":"external/react","paperTitle":"ReAct: Synergizing Reasoning and Acting in Language Models","paperUrl":"https://arxiv.org/abs/2210.03629","bibliography":{"title":"ReAct: Synergizing Reasoning and Acting in Language Models","authors":["Shunyu Yao","Jeffrey Zhao","Dian Yu","Nan Du","Izhak Shafran","Karthik Narasimhan","Yuan Cao"],"url":"https://arxiv.org/abs/2210.03629","pdfUrl":"https://arxiv.org/pdf/2210.03629v3","codeUrl":null,"preprint":{"id":"2210.03629","submittedOn":"2022-10-06","url":"https://arxiv.org/abs/2210.03629"},"publication":null,"citation":"@misc{transformersreact2022,\n  title = {{ReAct: Synergizing Reasoning and Acting in Language Models}},\n  author = {Shunyu Yao and Jeffrey Zhao and Dian Yu and Nan Du and Izhak Shafran and Karthik Narasimhan and Yuan Cao},\n  year = {2022},\n  eprint = {2210.03629},\n  archivePrefix = {arXiv},\n  url = {https://arxiv.org/abs/2210.03629}\n}\n","citationPath":"/content/papers/citations/transformers/react.0a6bd417f7a8.bib"},"thumbnail":{"src":"/content/papers/assets/ae2cd6d5c68df8887227719a0ac6c5dee8763fa902af5af73260fdc0f1ca81cc.png","width":1122,"height":489},"locale":"zh-hans","path":"/content/papers/zh-hans/transformers/react.b53f5296803f.md","headings":[{"id":"定义问题","text":"定义问题","depth":2},{"id":"解决问题","text":"解决问题","depth":2},{"id":"把想也当成一种动作","text":"把「想」也当成一种动作","depth":3},{"id":"一个极简的维基百科工具","text":"一个极简的维基百科工具","depth":3},{"id":"怎么让模型这样做","text":"怎么让模型这样做？","depth":3},{"id":"什么时候该相信自己","text":"什么时候该相信自己？","depth":3},{"id":"讨论","text":"讨论","depth":2},{"id":"知识任务的结果","text":"知识任务的结果","depth":3},{"id":"错在哪里","text":"错在哪里？","depth":3},{"id":"小模型微调后反而最好","text":"小模型微调后反而最好","depth":3},{"id":"不只是问答","text":"不只是问答","depth":3},{"id":"不靠框架也做得出来","text":"不靠框架也做得出来","depth":3},{"id":"结论","text":"结论","depth":2}],"anchorAliases":{},"guide":null,"relatedReading":[]}],"text":"2022 年，Chain-of-Thought（CoT）让大家发现：请大型语言模型「一步一步想」，它在算术、常识推理上的表现会明显变好。\n\n但 CoT 有个问题：它只在自己脑袋里想。\n\n模型用的是参数里记住的知识，想到一半记错了一件事，后面每一步都会建立在这个错误上，最后很有条理地推出一个错误答案。\n\n另一边，也有研究让语言模型在环境里**行动**：规划机器人的动作、在网页上点按钮、调用搜索引擎。但这些做法多半只预测动作，很少让模型停下来想一想现在的状况。\n\n这篇来自普林斯顿大学与 Google Research（Brain 团队）的论文，发表于 ICLR 2023，提出把两件事交错着做：**想一步，做一步，看结果，再想下一步**。作者把它叫做 ReAct，取自 Reasoning 加 Acting。\n\n这也是后来许多「会自己查资料的 agent」最常被追溯的起点之一。\n\n## 定义问题\n\n先看论文用来说明问题的例子。题目来自 HotpotQA，一个需要结合多份维基百科资料的多跳问答数据集：\n\n> 除了 Apple Remote 之外，还有什么设备可以控制 Apple Remote 原本设计要搭配的程序？\n\n要回答这题，得先知道 Apple Remote 原本是搭配哪个程序，再查那个程序还能用什么控制。\n\n作者让模型用四种方式回答：\n\n[![HotpotQA 问题的四种解法比较：Standard、CoT、Act-Only 皆答错，ReAct 交错思考与搜索后答对](/content/papers/assets/ae2cd6d5c68df8887227719a0ac6c5dee8763fa902af5af73260fdc0f1ca81cc.png)](/content/papers/assets/ae2cd6d5c68df8887227719a0ac6c5dee8763fa902af5af73260fdc0f1ca81cc.png)\n\n*原论文 Figure 1(1)，取自 [**v3 PDF 第 2 页**](https://arxiv.org/pdf/2210.03629v3#page=2)，CC BY 4.0。红色标示错误或幻觉，绿色标示从搜索得到的正确信息；原图下半部的 ALFWorld 例子未截取。*\n\n**(1a) Standard**：直接回答「iPod」。错。\n\n**(1b) CoT**：模型开始一步一步想：「Apple Remote 原本是设计来搭配 Apple TV 的；Apple TV 可以用 iPhone、iPad 和 iPod Touch 控制。」推理过程很流畅，但第一句就是错的，红色标起来的部分都是幻觉。答案当然也错了。\n\n**(1c) Act-Only**：只搜索、不思考。模型搜了 Apple Remote，又搜了 Front Row，甚至找到了「Front Row (software)」。但它没办法从这些观察中整理出答案，最后回答「yes」。\n\n**(1d) ReAct**：\n\n- **Thought 1**：我需要搜索 Apple Remote，找出它原本是搭配哪个程序。\n- **Act 1**：`Search[Apple Remote]`\n- **Obs 1**：Apple Remote 是 Apple 在 2005 年推出的遥控器……原本设计用来控制 **Front Row 媒体中心**程序。\n- **Thought 2**：原本是搭配 Front Row。接下来要搜索 Front Row，看还有什么能控制它。\n- **Act 2**：`Search[Front Row]`\n- **Obs 2**：找不到 [Front Row]。类似的条目：「Front Row Seat to Earth」、「Front Row Motorsports」、「Front Row (software)」……\n- **Thought 3**：找不到 Front Row，我改搜 Front Row (software)。\n- **Act 3**：`Search[Front Row (software)]`\n- **Obs 3**：Front Row 是一个已停止开发的媒体中心软件……\n- **Thought 4**：Front Row (software) 可以用 Apple Remote 或**键盘功能键**控制。所以答案是键盘功能键。\n- **Act 4**：`Finish[keyboard function keys]`\n\n答对了。\n\n这四种方式对照下来，问题就很清楚：\n\n- **只想不查**（CoT），会被自己记错的事实带偏。\n- **只查不想**（Act），拿到了资料却不知道怎么用。\n\n作者想知道的是：**让推理和行动交错进行，能不能各补对方的缺点？**\n\n## 解决问题\n\n### 把「想」也当成一种动作\n\n作者先用智能体（agent）的框架描述问题。\n\n在时间 $t$，智能体收到环境的观察 $o_t$，根据到目前为止的上下文 $c_t=(o_1,a_1,\\dots,o_{t-1},a_{t-1},o_t)$ 选择动作 $a_t$。\n\nReAct 的想法只有一句话：**把动作空间扩大，加入语言。**\n\n$$\n\\hat{\\mathcal{A}}=\\mathcal{A}\\cup\\mathcal{L}\n$$\n\n$\\mathcal{A}$ 是原本能对环境做的动作，例如搜索；$\\mathcal{L}$ 是语言空间。从 $\\mathcal{L}$ 选出来的「动作」，就是一段**思考**（thought）。\n\n思考不会改变环境，所以不会得到新的观察。它的作用是整理目前的上下文，把结果写进去，让下一步可以用：\n\n$$\nc_{t+1}=(c_t,\\hat{a}_t)\n$$\n\n上面的例子里，思考做了好几种事：拆解问题（Thought 1）、从观察里抓出重点（Thought 2、4）、遇到例外时调整计划（Thought 3）、最后整理出答案（Thought 4）。\n\n### 一个极简的维基百科工具\n\n在 HotpotQA 和 FEVER 这两个知识任务上，作者设计了一个很简朴的维基百科 API，只有三个动作：\n\n1. **`search[entity]`**：如果有这个条目，返回页面的前 5 句；没有的话，列出搜索引擎找到的前 5 个相似条目。\n2. **`lookup[string]`**：返回目前页面中下一个包含这个字符串的句子，就像在浏览器里按 Ctrl+F。\n3. **`finish[answer]`**：提交答案，结束任务。\n\n作者特别说明，这组动作大多只能凭精确的条目名称取回一小段内容，远比当时最好的词汇或神经检索器弱。这是刻意的：他们想仿真人类查维基百科的方式，逼模型用语言推理决定该查什么。\n\nFEVER 是事实核查数据集，每个陈述要判断为「支持」、「反驳」或「信息不足」。两个任务都只给模型问题或陈述，不给任何参考段落。\n\n### 怎么让模型这样做？\n\n这篇论文的主要实验没有训练新模型，使用冻结的 PaLM-540B，只靠提示词里的少量演示。\n\n作者从训练集随机挑出 HotpotQA 6 题、FEVER 3 题，人工写出完整的「思考、动作、观察」轨迹，放在提示词里当示例。作者也提到，再多放示例并没有帮助。\n\n推理时的流程，可以写成一个循环：\n\n```python\ndef react(question, llm, tools, examples, max_steps=7):\n    prompt = examples + f\"Question: {question}\\n\"\n    for step in range(1, max_steps + 1):\n        # 模型接着写出这一步的思考与动作，例如：\n        # \"Thought 2: ...\\nAct 2: Search[Front Row]\"\n        output = llm(prompt, stop=[f\"Obs {step}:\"])\n        prompt += output\n\n        action, arg = parse_action(output)          # 例如 (\"search\", \"Front Row\")\n        if action == \"finish\":\n            return arg\n\n        observation = tools[action](arg)            # 调用维基百科 API\n        prompt += f\"\\nObs {step}: {observation}\\n\"  # 将观察结果接回提示词\n    return None                                     # 步数用完还没答出来\n```\n\n这段程序是本文依论文描述整理的示意。关键在 `stop`：模型写完思考和动作后就停下，由程序真正去运行搜索，再把结果当成观察接回去。观察是环境给的，不是模型自己编的。\n\n\n> [!TIP]\n> \n> **思考要多密？**\n> \n> HotpotQA 和 FEVER 这类以推理为主的任务，作者让思考和动作严格交替，每一步都先想再做。\n> \n> 但在 ALFWorld 这种文本冒险游戏里，完成一个任务可能需要几十个动作，像是「走到流理台 1」、「打开抽屉 2」。每一步都想一遍并不实际，所以作者让模型自己决定什么时候插入思考，通常是在规划、追踪进度或计划需要改变的时候。\n\n\n### 什么时候该相信自己？\n\n作者在分析结果时发现，ReAct 和 CoT 各有长处：ReAct 比较依据事实，CoT 比较擅长组织推理结构。\n\n所以他们设计了两种混合方式。这里的 CoT-SC 是 CoT 的自我一致性（self-consistency）版本：以温度 0.7 抽样 21 条推理，取多数决的答案。\n\n- **ReAct → CoT-SC**：ReAct 在限定步数内答不出来，就退回 CoT-SC。HotpotQA 限 7 步，FEVER 限 5 步；作者统计，答对的轨迹中需要用满 7 步或 5 步的，只占 0.84% 和 1.33%。\n- **CoT-SC → ReAct**：如果 $n$ 个 CoT-SC 样本中，多数答案出现的次数少于 $n/2$，代表模型对自己的知识没把握，就改用 ReAct 去查。\n\n## 讨论\n\n### 知识任务的结果\n\n| 方法 | HotpotQA（EM） | FEVER（准确率） |\n| --- | ---: | ---: |\n| Standard | 28.7 | 57.1 |\n| CoT | 29.4 | 56.3 |\n| CoT-SC | 33.4 | 60.4 |\n| Act | 25.7 | 58.9 |\n| ReAct | 27.4 | 60.9 |\n| CoT-SC → ReAct | 34.2 | **64.6** |\n| ReAct → CoT-SC | **35.1** | 62.0 |\n| 监督式 SoTA | 67.5 | 89.5 |\n\n*整理自原论文 Table 1，模型为 PaLM-540B。*\n\n先看 ReAct 和 Act：两个任务上 ReAct 都比较好。一样能搜索，多了思考，最后整理答案的能力就不同。\n\n再看 ReAct 和 CoT：FEVER 上 ReAct 赢（60.9 对 56.3）；HotpotQA 上反而略输（27.4 对 29.4）。作者的解释是，FEVER 的「支持」和「反驳」有时只差一点细节，查到准确的资料特别重要。\n\n最好的结果来自两种混合方式：HotpotQA 是 ReAct → CoT-SC 的 35.1，FEVER 是 CoT-SC → ReAct 的 64.6。作者另外画了随抽样数变化的曲线，两种混合方式只要 3 到 5 个样本，就能达到 CoT-SC 用 21 个样本的成绩。\n\n但也要注意最后一行：这些提示方法都离监督式训练的最佳模型很远。HotpotQA 的 67.5、FEVER 的 89.5，都是专门训练的系统。\n\n### 错在哪里？\n\n为了理解 ReAct 和 CoT 在 HotpotQA 上的差异，作者从两者各抽 50 条答对、50 条答错的轨迹，共 200 条，人工标注成功与失败的类型：\n\n| 类型 | 说明 | ReAct | CoT |\n| --- | --- | ---: | ---: |\n| 成功：真阳性 | 推理和事实都正确 | 94% | 86% |\n| 成功：假阳性 | 答对了，但推理或事实是编的 | 6% | 14% |\n| 失败：推理错误 | 推理错误，包括陷入重复步骤出不来 | 47% | 16% |\n| 失败：搜索结果错误 | 搜索没有返回，或没有有用信息 | 23% | — |\n| 失败：幻觉 | 推理或事实是编的 | 0% | 56% |\n| 失败：标签歧义 | 答案是对的，但和标准答案用字不同 | 29% | 28% |\n\n*整理自原论文 Table 2。成功与失败各自计算比例。*\n\n这张表很值得细看。\n\n**幻觉是 CoT 最大的问题**。CoT 答错的案例里，56% 是幻觉；就算答对，也有 14% 是靠编出来的推理碰巧答对。ReAct 答错的案例里，幻觉是 0%。\n\n**但 ReAct 有自己的毛病**。它的推理错误占失败的 47%，远高于 CoT 的 16%。作者观察到一个 ReAct 特有的错误模式：模型不断重复先前的思考和动作，跳不出循环。思考、动作、观察交错的结构，让推理更有依据，也让推理比较不灵活。\n\n**搜索失败会让 ReAct 脱轨**。23% 的失败来自搜索没找到有用的信息，模型很难从这种情况中重新组织思路。\n\n作者也发现，有些 HotpotQA 题目的标准答案已经过时。\n\n### 小模型微调后反而最好\n\n只用提示词的话，ReAct 在 PaLM-8B 和 62B 上是四种方法里最差的：小模型很难只从几个示例就同时学会推理和行动。\n\n作者接着用 ReAct 自己产生、而且答对的 3,000 条轨迹来微调小模型。结果翻转了：\n\n- 微调后的 PaLM-8B ReAct，胜过所有 PaLM-62B 的提示方法。\n- 微调后的 PaLM-62B ReAct，胜过所有 PaLM-540B 的提示方法。\n\n微调 Standard 或 CoT 的效果则差很多。作者的解释是，前者等于教模型背下（可能有幻觉的）事实，后者教的是「怎么推理、怎么去维基百科查」，是比较能推广的技能。\n\n### 不只是问答\n\n作者也在两个交互式决策任务上测试：\n\n- **ALFWorld**：文本版的居家任务游戏，例如找到胡椒罐放进抽屉。最好的 ReAct 试验平均成功率 71%，只行动不思考的 Act 最好是 45%，模仿学习方法 BUTLER 是 37%。\n- **WebShop**：一个有 118 万件真实商品的仿真购物网站，依用户描述找出符合条件的商品。\n\n摘要总结：在这两个任务上，只用一到两个演示的 ReAct，成功率分别比模仿学习与强化学习方法高出 34 与 10 个百分点，而后者用了 $10^3$ 到 $10^5$ 笔的任务数据训练。\n\n### 不靠框架也做得出来\n\nReAct 的另一个吸引力，是它简单到几乎不需要框架。\n\n2023 年 3 月，Simon Willison 写了一篇[**简单的 Python 实现**](https://til.simonwillison.net/llms/python-react-pattern)：用 `gpt-3.5-turbo`，系统提示要求模型依序输出 Thought、Action、PAUSE、Observation，最后给出 Answer；程序用正则表达式抓出 `Action:` 那一行，运行对应的工具（维基百科搜索、他自己的博客搜索、计算器），再把结果当成 `Observation:` 送回去，最多跑五轮。\n\n他也在文中提醒，计算器工具直接用了 Python 的 `eval()`，非常危险，应该放进 WebAssembly 这类沙盒；整个实现也还很不稳健。\n\n让模型决定要调用什么工具，安全与鲁棒性就成了工程上必须面对的事。这点在论文里着墨不多。\n\n## 结论\n\nReAct 的核心只有一个改动：**把「思考」加进智能体的动作空间**，让语言模型在推理和行动之间交错进行。\n\n论文的证据显示：\n\n1. **只查不想，用不好资料**。同样能搜索，ReAct 在 HotpotQA 和 FEVER 都胜过只行动的 Act。\n2. **只想不查，容易幻觉**。CoT 答错的案例中 56% 是幻觉，ReAct 是 0%；但 ReAct 的推理错误较多，也会陷入重复循环。\n3. **两者互补效果最好**。依信心或步数在 ReAct 与 CoT-SC 之间切换，在两个知识任务上都拿到最佳的提示结果。\n4. **微调能放大效果**。用 3,000 条轨迹微调后，小模型的 ReAct 胜过大模型的各种提示方法。\n\n这些提示方法仍然远落后于专门训练的系统，所用的维基百科工具也刻意做得很弱。\n\n但「想一步，查一步，看结果，再想下一步」这个循环留了下来。后来会自己搜索文件、运行指令的 coding agent，做的事情大致也是这样，只是工具从三个维基百科动作，换成了 grep、读取文件和终端。\n","imageSizes":{"/content/papers/assets/ae2cd6d5c68df8887227719a0ac6c5dee8763fa902af5af73260fdc0f1ca81cc.png":{"width":1122,"height":489}}}
