目录
- 引言
- 一、ReAct策略
- [二、Function Calling策略](#二、Function Calling策略)
- [三、ReAct和Function Calling之间的区别](#三、ReAct和Function Calling之间的区别)
- [四、Dify上的ReAct和Function Calling](#四、Dify上的ReAct和Function Calling)
-
- [Function Calling例子](#Function Calling例子)
- ReAct例子
引言
这个文章标题甚是有趣,ReAct 和Function Calling本是一类人,却有着本质的区别,但很多时候我们甚至认为他们也是可以互为替代的,很是矛盾。
这两者是大语言模型中两种不同的工具调用机制,主要区别体现在核心逻辑、执行流程、灵活性、适用场景和性能特点上。目前主流的Agent策略也就是ReAct和Function Calling,顶多再加一个分别兼容MCP工具的模式。
今天小马就一起随大家慢慢道来。

一、ReAct策略
在大模型的涌现能力刚被人们发掘的时候,人们意识到生成式AI的潜力可能不止局限于文本内容的生成,如果让大模型能够和外部世界交互,是不是就能获得更广泛的信息,甚至对外部环境造成一定影响?基于这个出发点,研究者把推理(例如思维链提示)和行动(例如 WebGPT、SayCan、ACT-1)进行结合,并提出了ReACT框架,其核心思想是将推理和行动结合起来,形成一个智能、自主的智能体结构,并拥有与外部环境交互的能力。

ReAct则结合了推理与行动,通过"思考-行动-观察"的循环迭代:模型先推理下一步行动,执行工具调用后根据结果调整策略,直至完成任务,强调动态调整。

二、Function Calling策略
Function Calling是一种直接的"指令-工具 "映射机制,模型根据用户意图精准匹配预定义函数并提取参数,无需复杂推理,执行流程通常是单步或固定序列。
OpenAI于23年6月份的更新的gpt-4-0613 and gpt-3.5-turbo-0613版本中为模型添加了Function Calling功能,通过给模型提供一组预定义的函数(Function list)以及用户提问(Query),让大模型自主选择要调用的函数,并向该函数提供所需的输入参数。随后我们就可以在自己的环境中基于模型生成的参数调用该函数,并将结果返回给大模型。
而后很多的开源模型也纷纷通过微调训练具备了Function Calling能力。

以下是Function Calling在整个模型响应规程中的流程:

后面MCP出现之后,Agent的两种策略模式ReAct和Function Calling都支持MCP。

三、ReAct和Function Calling之间的区别
Function Calling在任务定义明确时高效精准,但对模糊需求或需多步推理的任务适应性差,容易因预设流程僵化导致错误 。
ReAct通过迭代推理能自主应对未知情况(如工具返回意外信息),动态调整步骤,更适合复杂或开放性问题。
Function Calling适用于标准化 (标准输入输出格式,比如json)、流程固定 的场景,如调用外部API查询天气、计算数据或处理结构化任务。
ReAct更适用于需要多轮推理、探索性解决的问题,例如分析数据趋势、故障排查或需根据中间结果调整策略的任务。
Function Calling执行效率高、资源消耗低,单次调用即可完成任务,响应速度快且token开销小 。
ReAct因需多次迭代,可能效率较低,但通过动态决策提升解决问题的准确性,尤其在复杂场景下优势明显。
在两种策略间如何选择?
决策应基于以下几个核心维度:首先是任务复杂度与确定性。对于目标明确、路径清晰的指令型任务("打开音乐"、"查询话费余额"),函数调用是更优解。对于需要探索、推理、多步骤规划的开放性问题("分析这篇文献的主要贡献和不足"、"为产品设计一个营销策略"),ReAct的链式思考能力更能胜任。
在评估两种策略时,**性能(延迟)和成本(Token消耗)**是无法绕开的硬指标。函数调用范式在这方面通常占据优势。由于它避免了生成中间推理文本,一次简单的工具调用可能只需要LLM处理两次消息:一次是分析请求并决定调用,另一次是接收工具结果后组织最终回答。这直接转化为更快的响应速度和更少的Token费用。
ReAct范式则相反。每一个"推理-行动-观察"循环都意味着LLM需要生成一段可能很长的推理文本,并处理同样可能很长的工具返回结果。对于一个需要N步循环的任务,LLM的交互次数是2N次(每轮一次输入、一次输出),Token消耗会成倍增加,延迟也随之线性累积。在云服务按Token计费的模式下,这将对运营成本产生实质性影响。
然而,这种对比并非绝对。对于极其复杂的任务,一个设计良好的ReAct代理可能通过精准的规划,用较少的循环次数解决问题。而一个函数调用代理如果因为规划能力不足,在复杂任务中需要多次尝试调用不同函数(或多次调整参数),其总交互次数和延迟也可能上升。因此,性能与成本的权衡必须结合具体任务复杂度来考量。对于高并发、低延迟要求的简单服务(如客服问答、数据查询),函数调用的效率优势是决定性的;对于低频、高价值的复杂分析任务,ReAct带来的成功率和可解释性可能值得付出更高的成本。
可见在Agent策略的选择上并没有"银弹",就和很多研发方案一样,合适的才是最好的。总而言之,Function Calling的决策是固定的,ReAct的决策是动态的。
很多场景下我们的提示词会给出明确的已知执行步骤,此时选择ReAct或Function Calling策略在结果上似乎也没什么区别和影响。

四、Dify上的ReAct和Function Calling
我们可以看到,Dify上的Agent默认支持有两种策略,ReAct和Function Calling。

用同样的提示词,我们分别试下两种模式。
bash
# 提示词
你是一个MCP工具运用大师,如果用户给出的问题需要调用MCP工具,请调用工具列表内的工具。
工具列表:
获取当前时间
热点时间查询
我们提的问题是:
bash
前两天的股票行情
Function Calling例子
我们先试一下Function Calling。

我们追踪下调用过程。
第一轮模型进行了思考调用了时间工具。

第二轮模型根据时间思考下一步需要确定是哪支股票。

ReAct例子
再试一下ReAct。

我们追踪下调用过程。
第一轮模型进行了思考调用了时间工具。

第二轮模型根据时间思考下一步需要确定是哪支股票。

我们可以看到,其实在这种场景下两种策略的效果就是差不多的。
- 彩蛋的位置
