中级Agent架构技术一面
ReAct模式:Agent的思考-行动循环
理解ReAct范式如何让LLM实现推理与行动的交替执行,以及在生产环境中的实际应用
#ReAct#推理#工具调用#Agent循环
情景对话
大J
聊聊你对ReAct这个范式的理解吧。它到底解决了什么问题?
小Y
ReAct的核心是把「思考」和「行动」交替进行。在它之前,LLM的推理和外部交互是割裂的——要么纯靠链式思考(CoT)在脑子里推演,要么直接调工具但缺少中间推理过程。
打个比方,就像你查一个复杂bug的过程:先根据报错猜一个原因(Thought),去打个日志或者跑个命令验证(Action),看到输出结果(Observation),再调整判断继续查。ReAct就是让Agent也能这么干。
大J
嗯,类比不错。那你说说它的循环具体是怎么跑的?从LLM收到用户请求开始。
小Y
整个循环是这样的:
用户请求进来后,LLM先生成一段Thought——这是它的内部推理,比如「用户问的是天气,我需要调用天气API,参数是城市名」。然后它输出一个Action,指定要调用的工具和参数。系统执行这个工具调用,把结果作为Observation反馈给LLM。LLM看到Observation后,再决定是继续下一轮Thought-Action,还是认为信息够了直接生成最终Answer。
关键点在于,这个循环不是固定次数的,LLM自己判断什么时候该停。
大J
好。那你在项目中实际用过ReAct吗?有没有踩过什么坑?
小Y
用过。之前做一个内部的数据分析Agent,用户用自然语言提问,Agent去查数据库、做计算、生成报告。
踩的坑主要有两个:
第一个是循环失控。有时候LLM会在几轮之后进入一种「强迫症」状态,反复去查已经查过的数据。解决方案是加了一个最大轮次限制,同时在每轮的Thought里注入当前已有的信息摘要,告诉它「你已经知道这些了,不需要重复」。
第二个是Action格式不稳定。LLM有时候输出的工具调用格式会漂移,尤其是参数比较复杂的时候。后来我们用了structured output配合严格的JSON Schema约束,把这个问题基本解决了。
大J
循环失控这个挺常见的。那你刚说加了轮次限制,到了上限怎么办?直接报错吗?
小Y
不是直接报错,那样体验太差了。我们设计了一个降级策略:
到了上限后,把当前已收集的所有Observation汇总,强制让LLM基于已有信息生成一个「尽力而为」的回答,同时标注哪些部分是完整验证过的,哪些是基于部分信息的推断。用户看到之后可以选择接受或者让Agent继续查。
说白了就是「有限信息下的best effort」,比卡死或报错好得多。
大J
嗯,这个降级思路对了。最后一个问题——ReAct和Plan-and-Execute这两种范式,你怎么选?
小Y
看任务复杂度和确定性。
ReAct适合探索性任务——你不太确定需要几步、每步结果会影响下一步决策的场景。因为它是逐步决策的,灵活性高。
Plan-and-Execute适合目标明确、步骤可预判的任务——比如「帮我把这份报告翻译成英文并发邮件」,步骤清晰,先规划再批量执行效率更高。
实际项目中我倾向于混合使用:外层用Plan-and-Execute做大的任务拆解,每个子任务内部如果需要探索就用ReAct循环。类似于你做项目时先列task list,但每个task执行时可能需要灵活调试。
核心概念
ReAct的核心执行单元。LLM先推理决定下一步该做什么,执行动作,接收环境反馈,如此循环直到任务完成或达到终止条件。
CoT(纯推理)和工具调用(纯行动)的融合。让LLM的推理有据可依,行动有理可循。
循环次数不预设,LLM根据已积累的Observation自行判断信息是否充足,充足则输出最终答案。
通过Observation将LLM的推理锚定到真实数据上,减少幻觉,形成自我纠错的闭环。
交互演示
ReAct循环演示
0 / 5思考行动观测输出
点击「自动播放」或「下一步」开始
评分维度
延伸追问
可以引入并行Action机制——当Thought阶段判断出多个独立的信息需求时,同时发起多个工具调用,合并Observation后再进入下一轮推理。但要注意处理工具调用之间的依赖关系,有依赖的必须串行。
Thought1: 搜索跑步鞋+价格过滤 → Action1: 商品搜索API → Observation1: 15条结果 → Thought2: 需要排序 → Action2: 排序服务 → Top5 → Answer: 个性化推荐。关键是每步Thought要体现决策原因。
常见策略:1) 对历史Observation做摘要压缩;2) 维护working memory记录“当前已知事实”;3) 滑动窗口只保留最近N轮完整内容,更早的压缩为摘要。