ReAct和Function Calling之间的纠葛与恩恩怨怨

目录

  • 引言
  • 一、ReAct策略
  • [二、Function Calling策略](#二、Function Calling策略)
  • [三、ReAct和Function Calling之间的区别](#三、ReAct和Function Calling之间的区别)
  • [四、Dify上的ReAct和Function Calling](#四、Dify上的ReAct和Function Calling)
    • [Function Calling例子](#Function Calling例子)
    • ReAct例子

引言

这个文章标题甚是有趣,ReActFunction 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。

我们追踪下调用过程。

第一轮模型进行了思考调用了时间工具。

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

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


  • 彩蛋的位置
相关推荐
HySpark2 小时前
基于声纹预处理技术的智能语音识别实现
人工智能·语音识别
l1m0_2 小时前
UI设计规范工程化,AI生成Ant Design设计稿流程拆解
人工智能·ui·产品经理·设计·arco design·设计规范
kong79069282 小时前
使用SpringAI实现对话机器人
人工智能·对话机器人·springai·deepseek
玄同7652 小时前
面向对象编程 vs 其他编程范式:LLM 开发该选哪种?
大数据·开发语言·前端·人工智能·python·自然语言处理·知识图谱
意法半导体STM322 小时前
【官方原创】一站式生成STM32N6的ExtMemLoader, FSBL, Appli的点灯工程 LAT1614
人工智能·stm32·单片机·嵌入式硬件·mcu·stm32n6
小付爱coding2 小时前
AI Agent 思考模式
人工智能
diligence2 小时前
Claude Code 配置 Chrome DevTools MCP 指南
人工智能
沈浩(种子思维作者)2 小时前
梦境意识之谜——豆包补充
人工智能·python·量子计算
yunni82 小时前
安全+智能双保障:企业级慧听AI本地化部署方案
人工智能·安全