这道题我觉得本质上问的是:在复杂任务里,模型怎么能不只靠静态知识,而是像人一样,边想边查、边查边改。[[ReAct]] 的核心就是让推理和行动交错进行,形成一个 Thought→Action→Observation→Thought 的循环。
先划一下边界。纯 [[Chain-of-Thought]] 只做推理,不接触外部世界,知识停在训练时,容易产生 [[Hallucination]]。纯工具调用呢,只执行,没有显式的推理过程,决策像个黑盒。ReAct 把这两者结合起来了,让模型每一步都先想清楚要干什么,然后去查或算,拿到结果再接着想。但真正落地的时候,我很少只用 ReAct 一种,比如很多场景我还会配合 [[RAG]] 一起用,RAG 负责检索静态知识,ReAct 负责动态交互和工具编排,各有各的适用场景。
举个例子,客服退款场景。用户说“我买了个东西,但商家说满减政策变了,少退了50块”。纯 CoT 的话,模型只能根据训练数据猜测,很可能给出错误解释。用 ReAct 呢,模型会先 Thought:我需要查最新的满减政策。Action:调用政策查询接口。Observation:拿到政策原文,发现确实有调整。然后 Thought:再查用户的订单和实际退款金额。Action:调用订单查询接口。Observation:发现退款金额确实少算了。最后 Thought:那差额就是50,我帮用户申请补退。Action:调用工单创建接口。整个流程是透明的,每一步都能追溯。
这里有个坑,落地时几个前提不满足很容易失败。先看 Observation 的设计,接口返回的信息必须结构化、简洁,别给一大段文本把模型淹没了。接着说工具描述,每个工具的输入输出、适用场景要写清楚,不然模型可能选错工具。再补充容错机制,工具调用失败得有 Fallback,比如重试或换另一个工具。如果这些没做好,常见失败场景就是模型在一个错误的观察上反复推理,或者不断调用同一个失败的工具,陷入死循环。
另外,ReAct 对模型的推理能力本身要求很高,如果模型基础不好,Thought 会变得很啰嗦甚至跑偏。我遇到过一个 case,模型在“思考”环节写了一长段废话,最后 Action 还是错的。所以我会更倾向于先把基础 [[SFT]] 做好,让模型学会在什么时候该思考、什么时候该行动,然后再上 ReAct 框架。
所以整体来看,我把 ReAct 看成是解决复杂交互任务的脚手架,它提供了清晰的思考和行动循环,但真正效果取决于工具设计、模型能力和容错机制。我不会在所有场景都用它,简单问答直接 [[Zero-shot]] 就行,但一旦任务需要多步推理和动态信息获取,ReAct 就特别合适。