ReAct 是 Agent 里一个很经典的思路。
它的名字来自两个单词:
Reasoning + Acting
也就是“思考”和“行动”。
如果只用一句话解释 ReAct:
让大模型一边做事,一边根据结果决定下一步做什么。
这和普通的大模型问答其实有很大的区别。
普通大模型是怎么工作的
平时我们问 ChatGPT 一个问题,大概是这样的:
用户提问
↓
模型思考
↓
生成答案
模型只需要回答问题就行。
但 Agent 经常要处理一些模型自己并不知道答案的事情。
比如:
帮我查一下今天北京的天气,再告诉我该穿什么。
模型本身不知道今天的实时天气,所以它得先调用天气工具。
用户提问
↓
模型调用天气工具
↓
获得天气结果
↓
模型生成答案
这已经有一点 Agent 的感觉了。
但 ReAct 真正重要的地方,是任务不一定一次调用工具就能完成。
ReAct 是怎么工作的
比如你让 Agent:
帮我找一家今晚还能预约的日料店。
它可能先搜索餐厅。
搜索之后发现十几家。
这时候它又要继续判断:
哪些评分比较高?
哪些距离比较近?
哪些今晚营业?
哪些还有位置?
整个过程可能变成:
搜索餐厅
↓
看看搜索结果
↓
筛选几家
↓
查询营业时间
↓
看看结果
↓
查询是否可以预约
↓
看看结果
↓
给用户答案
这就是 ReAct。
它不是一开始就把所有步骤完全计划好。
而是每做完一步,先看看结果,再决定下一步。
可以简单理解成:
思考
↓
行动
↓
看结果
↓
再思考
↓
再行动
一直循环,直到任务完成。
Thought、Action 和 Observation
很多介绍 ReAct 的文章都会提到三个词:
Thought、Action、Observation。
其实不用把它们想得太复杂。
Thought 就是:
我下一步应该做什么?
Action 就是:
去做这件事。
Observation 就是:
做完以后得到了什么结果?
比如:
Thought:
我需要先查天气。
Action:
调用天气工具。
Observation:
今天 15°C,有雨。
模型看到这个结果之后继续判断:
Thought:
温度比较低,而且下雨,需要建议用户穿外套并带伞。
然后输出最终答案。
所以 ReAct 最重要的其实不是这三个英文单词。
而是:
工具的结果会重新交给模型,模型根据这个结果继续做决定。
ReAct 和 Tool Calling 有什么区别
这个地方很容易混。
Tool Calling 解决的是:
模型怎么调用工具。
比如模型决定调用:
get_weather("北京")
程序收到以后执行天气查询。
而 ReAct 解决的是:
调用完工具以后怎么办。
例如天气工具返回结果以后,模型可能直接回答。
也可能觉得信息还不够,需要继续调用其他工具。
所以可以把它们理解成:
Tool Calling 是“使用工具的能力”。
ReAct 是“不断判断下一步该做什么的过程”。
很多 Agent 实际上就是把两者结合起来。
ReAct 本质上是一个循环
如果只看最核心的逻辑,ReAct 其实很简单:
while True:
response = llm()
if response 要调用工具:
result = 调用工具()
把 result 交给模型
else:
return 最终答案
模型决定调用工具。
程序执行工具。
工具结果重新放回模型。
模型再决定下一步。
一直循环,直到模型不再调用工具,而是直接输出答案。
这也是很多 Agent 最核心的一层结构。
为什么 ReAct 很重要
因为现实里的很多任务都没办法提前确定完整流程。
比如让 Agent 帮你修一个 Bug。
它可能先查看代码。
然后运行程序。
发现一个报错。
根据报错修改代码。
再运行一次。
又发现另一个问题。
继续修改。
整个过程可能是:
看代码
↓
修改
↓
运行
↓
发现报错
↓
继续修改
↓
再次运行
它没办法一开始就知道后面会出现什么错误。
只能根据每一次执行结果继续判断。
这其实就是 ReAct。
所以像 Coding Agent、Browser Agent、Research Agent,本质上都会大量使用这种思想。
ReAct 也有问题
ReAct 最大的问题之一就是:
它可能一直循环。
比如 Agent 搜索一个东西没找到。
换个关键词。
还是没找到。
再换一个。
然后又回到原来的关键词。
如果程序完全不限制它,就可能一直执行下去。
所以真正开发 Agent 时,一般都会限制最大执行次数。
比如:
最多执行 10 步。
超过以后就停止。
除此之外,还要考虑工具报错、参数错误、超时这些情况。
所以真正做 Agent,难点往往不是让模型“会调用工具”。
而是让这个循环稳定地运行。
最后
ReAct 不是什么特别神秘的算法。
它其实就是一个很简单的想法:
模型做一步,看一次结果,再决定下一步。
可以记成:
思考
↓
行动
↓
观察结果
↓
继续思考
Tool Calling 让模型拥有使用工具的能力。
ReAct 则让模型能够反复使用工具,并根据每一次结果调整自己的行为。
当这个循环跑起来以后,大模型才开始真正有一点“Agent”的样子。