工具调用方法怎么选?
大模型中 Function Calling、ReAct 等 4 种实现原理与场景对比
原题:请列举并详细说明大模型中实现工具调用的主要方法,包括其工作原理、适用场景以及各自的优缺点。
Agent · 百度真题
回答与解析
大模型工具调用主要有三类实现路径,核心差异在于结构化程度与推理控制权的分配:
1. Function Calling(函数调用)
原理:模型原生输出结构化JSON(如{"name": "search", "arguments": {"query": "..."}}),由外部系统解析执行后,再将结果注入上下文。
- 适用:需要精确参数传递的场景(计算器、数据库查询)
- 优点:可靠性高、延迟低、易于校验参数schema
- 缺点:需模型专门训练(或SFT),灵活性受限;不支持开放式工具描述
2. ReAct(Reasoning + Acting)
原理:模型在CoT推理与工具执行间交替循环,自主决定"想什么→调什么→观察结果→再决策"。
Thought: 用户问北京天气,我需要调用天气API
Action: get_weather(location="北京")
Observation: {"temp": 25, "condition": "晴"}
Thought: 已获得数据,可以生成回答
- 适用:多步推理、工具组合、需要解释决策过程的Agent
- 优点:透明可解释、容错性强(失败可重试)、无需特殊训练
- 缺点:延迟高(多轮交互)、token消耗大、需精心设计prompt边界
3. 通用Tool Use(Toolformer/开源方案)
原理:模型在生成文本中内嵌特殊标记(如[TOOL: calculator] 2+2 [/TOOL]),后处理提取执行。
- 适用:开源模型无原生Function Calling能力时的替代方案
- 优点:无需修改模型架构,通过prompt+后处理即可实现
- 缺点:准确性依赖正则匹配,易幻觉工具标记
选型建议
| 场景 | 推荐方案 |
|---|---|
| 单工具、高可靠 | Function Calling |
| 多工具链、需规划 | ReAct |
| 快速原型、开源模型 | 通用Tool Use |
实际坑点:工具描述(description)的质量直接决定调用准确率;需做好超时降级和结果格式容错(如API返回HTML而非JSON时的兜底处理)。
学习建议
建议系统学习该知识点
口语版讲法(约4分钟)
- 一句话定位:这道题考的是结构化程度和推理控制权的权衡
- Function Calling:高可靠但灵活受限
- ReAct:多步推理但延迟高
- 通用Tool Use:开源模型的替代方案
- 落地风险与选型建议
这道题其实问的是大模型怎么和外部工具交互,核心就是在结构化程度和推理控制权之间做权衡。我主要说三种主流方法。
先说 Function Calling,它本质上是模型原生输出一个结构化的 JSON,比如 {"name": "search", "arguments": {"query": "..."}},外部系统解析后执行,再把结果塞回上下文。这方案最大的好处是可靠性高,参数校验很严格,延迟也低,适合那种单工具、需要精确参数传递的场景,比如计算器或者数据库查询。但缺点也很明显,它需要模型专门训练过,比如 SFT,灵活性受限,工具描述不能太开放。
再一个就是 ReAct,它让模型在推理和行动之间循环,自己决定想什么、调什么、观察结果、再决策。你可以想象成模型一边思考一边动手,比如用户问北京天气,它会先想‘我需要调用天气API’,然后执行 get weather(location="北京"),拿到结果再继续。这方案适合多步推理和工具组合的场景,比如智能客服处理退款,可能需要先查订单状态,再查库存,最后生成回复。它的优点是透明可解释,容错性强,失败了可以重试,而且不需要特殊训练。但延迟高,token消耗大,需要精心设计 System Prompt 来约束行为。
第三种是通用Tool Use,像 Toolformer 这类方案,模型在生成文本里内嵌特殊标记,比如 [TOOL: calculator] 2+2 [/TOOL],后处理提取执行。这主要是给开源模型用的,它们没有原生Function Calling能力。好处是不用改模型架构,通过prompt加后处理就能实现。但准确性依赖正则匹配,容易幻觉工具标记。
实际落地时,我很少只用一种方法。 比如在电商客服场景,退换货流程通常需要多步操作,我会用ReAct来规划,但在执行具体查询时,比如查订单号或库存,我会切到Function Calling来保证参数准确。这里有个坑:工具描述的质量直接决定调用准确率,描述写得太模糊模型就会瞎猜。另外,一定要做好超时降级和结果格式容错,比如API返回了HTML而不是JSON,你得有兜底逻辑。
说到容错,其实还有个挺有意思的点:当工具调用失败时,模型能不能自我纠错?比如用 Self-Refine 或 Reflexion 让模型基于错误反馈重试,这比简单重试效果要好,但也更复杂。
所以我的判断是:Function Calling适合做高可靠的基础调用,ReAct适合做需要规划的复杂流程,两者结合才是工程上最稳妥的做法。 我不会迷信单一方案,而是根据场景灵活组合,同时把容错和描述优化放在首位。
关键一句:工具调用失败时,模型能否自我纠错?比如用Self-Refine或Reflexion让模型基于错误反馈重试。
面试官还可能这样问
- 问法 1 · 场景切入
我看你做过客服机器人,假设用户说‘帮我查一下订单’,然后你调了一个查询接口。现在用户又说‘再帮我算算运费’,这时候你打算怎么让模型去调用不同的工具?具体怎么实现的?
- 问法 2 · 层层追问
大模型怎么调用外部工具?……调用方式有好几种,你了解哪些?……那它们各自原理是什么?比如模型怎么知道该调哪个工具、参数怎么填?……适用场景和优缺点呢?
- 问法 3 · 直球架构
列举大模型工具调用的主要方法,说清楚原理、适用场景和优缺点。比如 Function Calling、ReAct 这些,它们怎么工作的?各有什么坑?