ReAct——交错进行推理与行动。
ReAct 是生产级智能体的主力:一个让模型在思考与调用工具之间交替的循环,每个工具结果都重塑下一次思考。本文涵盖真实的控制流、为什么交错优于先推理后行动,以及在规模化时会咬人的失败模式。
核心思想:思考与行动共享一条轨迹。
ReAct 出自 Yao 等人(2022),它在单一交错流中协同推理(思维链)与行动(工具调用/环境交互)。模型发出一个想法,然后一个动作,观察结果,基于该观察发出下一个想法,如此重复,直到它决定作答。关键洞见是推理与行动相互强化:推理决定采取哪个动作以及如何解读杂乱的结果;动作注入外部事实,在推理累积成幻觉之前纠正它。
对比 ReAct 居于其间的两种失败模式。纯思维链推理流畅但无锚定——它会自信地编造事实。纯行动循环(调一个工具,再调一个)把每一步都锚定在现实中,但无法分解一个困难问题,也无法从无关结果中恢复。交错在单一轨迹中同时获得锚定与审慎。
明确写出这个循环。
使用现代工具调用 API 时,你并不提示字面字符串 "Thought:"/"Action:"——模型的推理活在它的文本内容里,动作是一次结构化工具调用。结构是相同的:
# The ReAct loop — framework-free history = [user_query] for step in range(MAX_STEPS): resp = model.call(history, tools=TOOLS) # thought + maybe action history.append(resp) if resp.stop_reason == "final_answer": return resp.text # model chose to stop for call in resp.tool_calls: # act obs = run_tool(call.name, call.args) history.append(tool_result(call.id, obs)) # observe # loop: next thought is conditioned on obs raise StepBudgetExceeded(history) # bounded by construction
三个性质让它达到生产级。它是有界的(步数预算限制成本与失控循环)。它是可观测的(每个想法与观察都在 history 中——你的 trace 就是数据结构本身)。如果你在步骤间持久化 history,它就是可恢复的。
杠杆最高的单一埋点:每步之后带步索引记录 history。ReAct 调试的九成就是读轨迹、找到想法不再锚定于上一个观察的那一步。
ReAct 何时见效。
- 开放式信息任务,下一动作确实取决于上一结果:研究、调试、多跳问答、客服分流。如果你无法预先写出计划,ReAct 的逐步适应性正是合适工具。
- 嘈杂或不完整的工具结果,模型必须先推理某结果是否相关,再决定下一步做什么。
- 中小规模工具集(大致 3–15 个工具),模型能在每步可靠地择一。
失败模式——以及真正奏效的缓解措施。
ReAct 的适应性也是它的隐患。这些有名字的失败模式,大致按它们投入生产的频率排序:
- 打转/抖动。智能体反复运行近乎相同的动作,因为每个观察都未推进目标。缓解:步数预算(始终要有),加上一个廉价的循环检测器,标记重复的(工具,归一化参数)元组并注入一条"你试过这个;换方法或停止"的消息。
- 长轨迹上的上下文腐烂。历史增长到早期锚定事实被埋没或被驱逐,模型开始漂移。缓解:周期性上下文压缩——把旧步骤摘要进一个持久草稿区,最近步骤保留原文。
- 过早承诺。模型在一个薄弱观察后就认定有了答案。缓解:在
final_answer前加反思或校验门控(有专文)——不要只在 ReAct 提示词里解决它。 - 规模化下的工具选择错误。工具相似且众多时模型选错。缓解:在循环前置一个路由层(有专文),而不是在系统提示词里堆更多散文。
反模式:"在系统提示词里修它"。上述每个失败都有结构性缓解。把指令("别重复动作、作答前校验、选对工具")堆进提示词,会产生一堵脆弱、模型时灵时不灵、你也无法测试的文字墙。优先用循环检测器、校验节点和路由器——可做单元测试的代码。
何时不要用朴素 ReAct。
当任务具有已知且稳定的结构时,ReAct 是错误的默认。如果你已经知道为客户开通服务的五个步骤,逐步重新审议就是浪费的延迟,也是偏离脚本的机会——改用 plan-and-execute 或在叶子处带模型调用的硬编码工作流。ReAct 在长视野任务上也会退化:没有全局计划,约 15–25 步后它会丢失主线。而对答案可校验的任务(代码、数学),单趟 ReAct 不如利用廉价正确性信号的搜索或评估者-优化者循环。
诚实的一句话权衡:ReAct 以全局连贯性与可预测成本为代价,买入最大的适应性。后续文章中的模式各自通过重新引入 ReAct 刻意省略的结构,找回一部分连贯性。