Beyond Chatbots:ReAct 框架如何让 LLM 进化成真正的 Agent
前言
⚠️ 时间线说明: 这篇文章实际上是在《Agent 生产落地:从 demo 到产品的血泪经验》之前完成的,一直躺在草稿箱里忘了发。阅读顺序上,建议先看这篇理解 ReAct 原理,再看那篇的生产实践经验。
想象一下你现在要煮盆饺子。烧水、打料内心独白支配着每一个动作:”水开了,我该下饺子了。”当发现缺少关键调料,内心独白会调整策略:”没辣椒了?我用老干妈代替。”面对技术难点时,这个思维过程会触发外部行动:”我不确定需要煮多久,我需要打开美食APP查下。”
这种边想边做、边做边调整的能力,是人类解决问题的基本方式。但传统的大语言模型(LLM)完全没有这种能力——它们更像一个闭卷考试的学生,只能凭记忆一口气写到底,错了也没法改。
在人工智能领域,传统的大语言模型(LLM)一直像静态黑盒一样运作。虽然这些模型擅长语言模仿,但它们缺乏功能性的”工作记忆”和与世界动态交互的能力。这种隔离滋生了两种系统性失败:“幻觉循环”,即模型自信地编造事实;以及“错误传播”,即单一的逻辑失误会毁掉整个回答。
ReAct(Reason + Act)框架代表了 AI 架构的范式转变。 通过在孤立认知与外部执行之间搭建结构性桥梁,ReAct 将 LLM 从对话者转变为能够规划、执行和自我纠正的自主 Agent。
这篇是我学习 ReAct 的笔记,想把它讲清楚,也给自己留个档。
一、ReAct 到底在解决什么问题
传统的 AI 能力其实是分裂的。要么你用 Chain-of-Thought(CoT)让模型在脑子里一步步推理,要么你用 Action-generation 让模型调用外部工具——但两者各自有坑:
纯推理(CoT)的问题: 模型完全依赖内部参数知识,是个封闭系统。它没法查资料,没法更新自己的认知,结果就是自信满满地编事实(幻觉),而且一步错步步错(错误传播)。
纯行动(Act-only)的问题: 模型可以调用工具,但缺乏显式的长期规划能力。它没法跟踪子目标,也没法系统地探索环境,很容易陷入重复或无意义的操作。
ReAct 的做法是:把两者缝合起来。 推理痕迹帮助模型诱导、跟踪和更新行动计划,处理异常情况;而行动让模型能够对接外部信息源(Wikipedia API、浏览器、数据库)来获取实时信息。
核心机制:反馈循环
ReAct 把 Agent 的活动结构化成一个三段式交替序列:
1 | Thought(思考)→ Action(行动)→ Observation(观察)→ Thought(再思考)... |
- Thought: LLM 用思维链把大任务拆成可管理的小任务,分析数据,决定下一步做什么
- Action: 模型输出使用某个预定义工具的意图(比如搜索数据库)。注意:LLM 自己不执行工具,只输出工具名和参数
- Observation: 外部系统执行工具,把结果反馈给 LLM
Agent 基于这个观察重新评估进度,生成下一个 Thought。循环往复,直到输出最终答案。
这个循环看起来直白,但效果非常显著。在 HotpotQA 基准测试里,传统 CoT 的幻觉率(编瞎话的概率)是 14%,上了 ReAct 之后直接降到 6%[^1]。
二、五个核心要点:为什么 ReAct 有效
要点 1:推理与行动的协同
ReAct 范式打破了传统上推理与执行的二分。其核心是形式化表达 Â = A ∪ L。在这个等式中,Agent 的行动空间从物理或程序步骤(A)扩展到包含内部的”语言空间”(L)。通过将”思考”视为模型轨迹中的另一种行动类型,ReAct 允许 Agent 生成口头推理痕迹——或称”想法”——与特定任务的动作交错进行。
这种协同使模型能够诱导、跟踪和更新计划,同时实时处理异常。正如 Yao 等人在其奠基性研究中所言:
通过交错这些痕迹,模型使用推理来决定检索什么信息,而由此产生的观察又为后续推理提供基础。
要点 2:通过观察环节打破幻觉循环
传统的思维链(Chain-of-Thought, CoT)提示鼓励模型”一步步思考”,但它完全依赖模型的内部参数知识——一个容易”幻觉”不存在事实的封闭系统。ReAct 通过引入强制的 Observation(观察) 步骤来解决这个问题,将模型锚定在外部现实中。
在知识密集型任务中,ReAct 使用特定的动作词汇——包括 search[entity]、lookup[string] 和 finish[answer]——与 Wikipedia 等外部实体交互。这种迭代的 Thought-Action-Observation 循环迫使模型在继续之前根据真实知识库验证其逻辑。结果是统计学上显著的改进:在 HotpotQA 基准测试中,误报率(幻觉事实或逻辑的频率)从标准 CoT 的 14% 暴跌至 ReAct 框架下的 6%[^1]。这种锚定将 Agent 从创意作家转变为可信的调查者。
要点 3:代理技能的效率悖论
ReAct 扩展分析中最深刻的见解之一是:“代理技能”通常比原始模型大小更具参数效率。 我们在”小模型悖论”中看到了突破:教模型如何推理和行动,比强迫它在权重中记忆海量事实更具泛化能力。
数据揭示了一个惊人的层级关系:一个较小的 PaLM-8B 模型,仅在 3,000 条 ReAct 轨迹上微调,就能胜过完全依赖提示的巨大 PaLM-540B 模型。更令人印象深刻的是,微调的 62B 模型超过了 540B 提示版本的性能[^1]。这表明 AI 的未来不在于构建越来越大的记忆数据仓库,而在于提炼模型导航工具集和环境的程序能力。
| 模型 | 方式 | 表现 |
|---|---|---|
| PaLM-540B | Zero-shot 提示 | 基准线 |
| PaLM-8B | ReAct 微调(3,000 轨迹) | 超越 540B |
| PaLM-62B | ReAct 微调 | 大幅超越 540B |
数据来源:Yao et al., ReAct: Synergizing Reasoning and Acting in Language Models[^1]
要点 4:可解释性:终于能看懂 AI 在想什么了
传统模型的黑盒问题一直让人头疼。输入一个问题,输出一个答案,中间发生了什么?不知道。
ReAct 的”草稿本(scratchpad)”机制解决了这个问题。每一轮循环的 Thought、Action、Observation 都被记录下来,形成一条完整的”思维链”。
如果出错了,你能精确定位到是哪一步出的问题:
- 推理错误:模型陷入了重复循环,比如一直问同一个问题
- 检索错误:外部 API 返回了不相关的信息
- 行动错误:调用了错误的工具或参数
更有意思的是,这种透明性支持人在回路(Human-in-the-loop)的干预。这有点像你带新人:他在那自言自语分析问题,你说”这一步想偏了”,他马上就能纠正。
ReAct 通过其人类可读的”草稿本”,为 AI 的”黑盒”提供了一个罕见的窗口。Agent 过程的每一步都被记录为想法、行动和观察的序列,提供了以前不可能的诊断水平。
如果 Agent 失败,开发者可以精确定位确切的失败模式——比如模型陷入重复循环的”推理错误”,或外部 API 返回无信息结果的”搜索错误”。这种透明性还促进了“人在回路(Human-in-the-loop)”的纠正。在 ALFWorld 环境(一个基于文本的任务模拟器)中,研究人员证明,人类可以通过简单编辑草稿本上的”想法”来引导失败的 Agent 回到正轨——删除幻觉或添加提示——使 AI 能够立即重新校准其计划[^1]。
示例:ReAct 轨迹
1 | Thought: 用户询问 2024 年诺贝尔物理学奖得主,我需要确认最新获奖信息。 |
要点 5:复杂环境的动态规划
虽然标准 LLM 在多步骤任务上挣扎,但 ReAct 在 ALFWorld(合成家庭任务)和 WebShop(拥有 118 万产品的在线购物环境)等交互式环境中表现出色。与遵循 rigid 脚本的”仅行动(Act-only)”Agent 不同,ReAct Agent 利用动态推理将高级目标分解为可管理的子目标。
所以ReAct 的真正威力,在处理多步骤、需要探索的任务时才会显现出来。
ALFWorld 里有个典型任务:”把一个发烫的平底锅放到冷却架上”。这看起来简单,但模型需要:
- 找到平底锅(可能在灶台上)
- 判断它是不是”发烫”的状态
- 找到冷却架(可能在橱柜里)
- 规划一条合理的移动路径
传统”只行动不思考”的 Agent(Act-only)在这种任务上成功率只有 45%,而 ReAct 能达到 71%[^1]。
ReAct 利用预训练的”常识知识”——例如,知道胡椒罐更可能在橱柜里而不是冰箱里——以手术般的效率探索环境。通过维护其进度的内部记录,ReAct Agent 避免了困扰纯反应式系统的无产出循环。
三、如何构建一个 ReAct Agent
你可以用 LangChain、LangGraph 或 BeeAI 等开源框架快速搭建(比如 LangChain 的 ZERO_SHOT_REACT_DESCRIPTION),也可以从零用纯 Python 手写。下面是手写版本的逻辑拆解:
步骤 1:定义工具集
首先确定模型能用的具体行动。写 Python 函数(计算器、搜索等),然后把它们的签名和描述提取成 LLM 能理解的格式(JSON 或字符串)。
1 | # 示例工具定义 |
步骤 2:编写 ReAct 提示词
ReAct Agent 极度依赖特定的提示技巧来结构化输出。系统提示必须:
- 引导模型一步步思考,交错想法和行动
- 提供可用工具列表
- 定义严格的输出格式,通常用标签如
Thought:、Action:、Action Input:、Observation:
提示词模板示例:
1 | 你是一个能够使用工具的 AI 助手。按以下格式解决问题: |
步骤 3:构建执行循环
把提示词和用户问题传给 LLM 后,你需要一个程序循环来处理执行:
- 解析输出: 拦截 LLM 的文本输出,提取
Action(工具名)和Action Input(参数) - 执行工具: 你的 Python 代码调用对应的函数
- 返回观察: 把函数结果格式化为
Observation,追加到对话历史 - 重复: 把更新后的上下文传回 LLM,让它基于新数据生成下一个
Thought - 终止: 当 LLM 确定有最终答案并使用 “Finish” 动作或输出最终响应标签时,循环结束
伪代码示意:
1 | max_iterations = 10 |
四、生产环境的优化技巧
要让 ReAct Agent 稳定、高效地运行,避免常见陷阱,你需要以下优化:
1. 使用少样本示例(Few-Shot Exemplars)
虽然可以构建”零样本”ReAct Agent,但性能会在你加入人工编写的完整 Thought-Action-Observation 轨迹示例后显著提升。提供 3 到 6 个 高质量、任务特定的示例,能教会模型如何格式化想法、分解任务、处理不同工具。
2. 与 Chain-of-Thought 和自一致性结合
研究表明,ReAct 高度依赖搜索结果质量;如果工具返回无用数据,模型的推理会跑偏。反过来,标准 CoT 受困于幻觉。
最佳实践是构建混合系统:
- 如果 ReAct Agent 在给定步数内无法返回答案,回退到内部 CoT 推理(使用 Self-Consistency,即采样多条 CoT 路径并取多数答案)
- 如果 CoT-SC 置信度低,切换到 ReAct 收集外部事实
这种”双保险”策略在知识密集型任务上效果最好。
3. 设置严格的循环限制
因为框架本质上是反馈循环,ReAct Agent 有时会陷入重复生成相同想法和行动的困境,导致高延迟和 token 成本爆炸。你必须在代码中设置最大迭代次数或特定结束条件(如置信度阈值)来防止无限循环。
1 | # 示例:多层防护 |
4. 微调实现可扩展性
纯粹从上下文提示中学习复杂推理和行动是困难的,尤其是对较小语言模型。然而,在几千条正确的 ReAct 轨迹上微调较小模型(如 8B 参数模型),能让它们大幅超越仅依赖标准提示的更大模型(如 PaLM-540B)。
工程建议:
- 收集生产环境中的高质量轨迹作为微调数据
- 使用 LoRA 等高效微调技术降低计算成本
- 小模型+ReAct 往往比大模型裸跑更省算力、更可控
5. 实现人在回路(Human-in-the-Loop)纠正
因为 ReAct 生成可读的、 verbalized 的推理痕迹,系统具有高度可解释性。你可以设计 Agent 允许人类检查其内心独白。如果模型产生了幻觉想法或走错了路,人类可以直接编辑生成的 Thought 文本。这能纠正模型的后续行为,引导它成功,无需重写代码或手动执行动作。
典型应用场景:
- 客服 Agent 遇到边界案例时,人工客服介入修正推理方向
- 代码生成 Agent 逻辑走偏时,程序员编辑 Thought 引导它回到正轨
- 研究 Agent 检索到无关信息时,研究员删除幻觉并提供正确线索
五、写在最后
ReAct 给我的最大启发,不是技术细节,而是一种设计哲学的转变。
以前我们总想造一个”什么都知道”的 AI——把人类知识全塞进模型参数里。ReAct 走的是另一条路:承认模型不可能全知,给它一套”查资料+推理”的机制,让它像人一样边做边学。
当前 AI 的最先进水平并不依赖单一框架,而是协同的切换方法。最有能力的系统将 ReAct 与 CoT-自一致性结合,对逻辑任务利用内部参数知识,当内部置信度低时切换到 ReAct 进行外部锚定。
随着我们从对话式聊天机器人过渡到能够浏览网页、使用软件工具和管理工作流的自主 Agent,Thought-Action-Observation 循环正在成为安全和可靠性的行业标准。我们不再只是构建会说话的模型;我们正在构建为了行动而思考的 Agent。
参考
[1]: ReAct Prompting - Prompting Guide
[2]: What is a ReAct Agent? - IBM
[3]: ReAct Paper (PDF) - arXiv
[4]: ReAct: Synergizing Reasoning and Acting in Language Models