这道题其实是在问,当我们想让大模型像人一样去调用工具、完成任务的时候,怎么让它既能推理规划,又能实时获取外部信息,还能根据反馈调整。[[ReAct]]就是目前最主流的方案,它的核心思想很简单:推理和行动是交错循环的,而不是先想完再做或者边做边想。
具体来说,它的工作流程就是 Thought → Action → Observation 这样一个循环。Thought 是模型在内部推理,规划下一步;Action 是调用外部工具,比如查天气、搜数据库;Observation 是拿到工具返回的结果。然后模型根据 Observation 再产生新的 Thought,再 Action,直到任务完成。举个例子,用户问北京明天天气怎么样,模型先 Thought:需要查天气,然后 Action:调用 search_weather('北京', '明天'),拿到 Observation 说晴天25度,再 Thought:天气不错,可以建议防晒,最后 Action:finish 输出答案。整个流程就像人一样,边想边做,边做边看。
它的优势很明显。纯 [[Chain-of-Thought]] 只靠内部知识,容易产生 [[Hallucination]],比如模型可能编造一个不存在的天气;纯 Action 没有推理,碰到复杂任务就容易乱,比如连续调用多个 API 时没有规划。ReAct 把两者结合起来,既能获取外部信息,又能逐步规划,而且每一步的 Thought 都是可解释的,出了问题也能根据 Observation 反馈来纠错。
不过落地的时候有几个坑必须注意。先说 Prompt 设计,必须严格约束输出格式,让模型老老实实输出 Thought、Action、Observation 这些标签,否则解析不了。接着说工具描述要清晰,每个 Action 的输入参数和返回格式得写明白,不然模型会传错参数。再补充终止条件,要设最大循环次数,比如10次,防止模型死循环,同时要识别 finish 这种特殊 Action 来正常结束。
应用场景上,ReAct 特别适合需要多步骤工具调用的任务,比如订机票的时候还要查天气、规划路线。还有知识问答,比如问某公司最新财报的同比增长率,需要先搜财报、再算同比增长。但如果是纯文本生成或者简单问答,直接用 [[In-Context Learning]] 或者 [[Few-shot]] 就够了,没必要上 ReAct,因为循环调用会增加延迟和成本。
说到这,其实有个有意思的点:ReAct 和 [[Function Calling]] 经常被一起用,但它们的角色不一样。ReAct 是决策框架,决定什么时候调用什么工具;Function Calling 是工具调用的具体实现,把自然语言请求转成结构化的 API 调用。所以真正落地的时候,我倾向于用 ReAct 做顶层规划,底层用 Function Calling 来执行,这样既灵活又稳定。
总结一下,ReAct 不是银弹,它适合需要外部信息和多步推理的 [[Agent]] 场景,但前提是 Prompt 和工具描述要设计好,否则模型很容易跑偏。我更愿意把它看作 Agent 的决策骨架,配上好的工具和终止策略,才能做出靠谱的系统。