前言

上一章你已经知道了,一个工具 = 函数本体 + 名称 + 描述 + 参数定义,大模型靠工具描述来判断要不要调这个工具。

但这里有个关键问题还没解决:大模型做出「要调这个工具」的决策之后,它怎么告诉Agent去执行?

大模型只会「说话」,它的输出永远是文字。但Agent要调用工具,必须知道:

  • 调哪个工具?

  • 传什么参数?

  • 格式是什么?

这中间的信息交换,靠什么来保证准确?

这就是Function Calling要解决的核心问题。

在讲它是什么之前,我们先来看看没有它的时候,开发者有多惨。


一、没有Function Calling之前:靠自然语言「猜」

在Function Calling出现之前,开发者只能把工具的描述和调用规范,全部用自然语言写进System Prompt里

比如你想让AI能调用一个查天气的工具,System Prompt里就得这样写:

text

你是一个智能助手,你可以使用以下工具:

工具名:check_weather
功能:查询某个城市的天气
参数:
- city:城市名,中文,比如"上海"
- date:日期,格式必须是YYYY-MM-DD,比如"2026-03-19"
  date是可选的,不填默认查今天

当用户需要查天气时,你要调用这个工具,告诉我工具名和参数。

听起来还好?但问题是,大模型是个自由发挥的选手,你约束不住它

你让它查「上海明天的天气」,它可能给你返回:

错误类型 示例
散文式回复 「好的,我来帮你查询上海明天的天气,需要使用check_weather工具,城市是上海,时间是明天~」
参数顺序颠倒 {"date": "明天", "city": "上海"}("明天"完全不是YYYY-MM-DD格式)
直接编造天气 不调工具,根据训练数据给你生成一个「明天上海天气预报」
JSON里混自然语言 「调用工具:check_weather,参数city=上海,date=2026-03-20」
完全无视要求 给你一段介绍上海气候特点的科普文章

这就是传统System Prompt模式的本质问题——全靠AI猜:

  • 猜要不要调工具

  • 猜参数格式

  • 猜回复结构

猜对了正常运行,猜错了整个流程就崩了。

而开发者呢?就得写一大堆正则表达式和解析代码,尝试从AI五花八门的回复里「扒」出工具名和参数。工具越多,解析代码比业务代码还长。而且换个模型,还得重写一遍。

这种开发体验,完全是噩梦级别的。


二、Function Calling的出现:告别猜谜,统一规范

这就是Function Calling诞生的背景。

Function Calling的本质,是一套大模型和Agent之间的标准化工具调用协议。

  • 我们不再用自然语言告诉AI「你可以用这个工具」,而是用一套固定的JSON格式把工具定义清楚

  • 大模型也不再自由发挥,而是严格按固定的JSON结构返回调用指令

整个过程:你给我标准格式的工具说明书,我给你标准格式的调用指令——双向约定,零歧义,零猜测。

一个常见疑问:Tool和Function Call有什么关系?

概念 层面 解决什么问题
Tool(工具) 能力层 解决「有什么」:一个工具需要哪些要素才能让大模型认识和使用它
Function Calling 协议层 解决「怎么传」:大模型和Agent之间要用什么格式来交换信息

打个比方

概念 类比
Tool 外卖骑手(有姓名、有技能、能送餐)
Function Calling 美团的派单系统(规定了订单怎么下达、骑手怎么接单、送达后怎么确认)

骑手是「能力」,派单系统是「通信规范」。两者缺一不可,但解决的是完全不同层面的两件事。

两者的协作流程(以「查询北京明天天气」为例)

text

1. 用户提问:「北京明天天气怎么样?」
        ↓
2. 大模型分析:需要调用天气Tool
   → 生成Function Call格式的指令
        ↓
3. 系统解析指令:调用 get_weather("北京", "2026-03-21")
        ↓
4. Tool执行并返回结果:「北京明天晴,10~20°C」
        ↓
5. 大模型把结果整理成自然语言,回复给用户

三、Function Calling三部分核心结构

接下来,我们用天气查询的场景,把Function Calling完整的三部分结构拆解清楚,每行都讲明白作用。

第一部分:工具定义(Tool Definition)—— 给大模型的「工具说明书」

这一步是我们开发者要写的,相当于给大模型一份严格规范的工具说明书。大模型会完全按照这份说明书,判断要不要调用工具、怎么调用。

json

{
    "name": "check_weather",
    "description": "获取指定城市指定日期的天气情况,包括温度区间、晴雨状况、风力",
    "parameters": {
        "type": "object",
        "properties": {
            "city": {
                "type": "string",
                "description": "需要查询天气的城市中文名称,示例:北京、上海、广州"
            },
            "date": {
                "type": "string",
                "format": "YYYY-MM-DD",
                "description": "需要查询的日期,格式为年-月-日,示例:2026-03-19,不填默认查今天"
            }
        },
        "required": ["city"]
    }
}
每个字段的作用
字段 作用
name 工具的唯一标识,大模型调用时必须和这个名字完全一致
description 工具功能说明,是大模型判断「要不要调这个工具」的核心依据。写得越精准,大模型做对决策的概率越高
parameters 告诉大模型这个工具需要哪些参数、什么类型、什么格式。大模型会严格按照这里的约束来生成参数值
required 必填参数清单。如果用户没提供必填信息,大模型会主动去问用户,而不是瞎猜

对比之前System Prompt里用自然语言描述的「松散约定」,这里的JSON格式是严格的机器可读规范。大模型在服务端就会做格式校验,不合规的参数直接拒绝,从源头杜绝了参数乱传的问题。


第二部分:AI调用格式(Function Call)—— 大模型给Agent的「标准化执行指令」

当大模型判断需要调用工具时,会严格按照固定格式返回JSON,不再有任何自由发挥的自然语言

我们的Agent直接解析这个结构,拿到工具名和参数,不用做任何额外的猜解处理。

json

{
    "function_call": {
        "name": "check_weather",
        "parameters": {
            "city": "上海",
            "date": "2026-03-19"
        }
    }
}
关键点说明
字段 说明
function_call 固定标识,告诉Agent:这不是给用户看的回复,这是一条工具调用指令
name 要调用的工具名称
parameters 传给工具的参数

注意:这里的date字段,大模型自动把「明天」转换成了2026-03-19,完全符合我们在工具定义里约定的YYYY-MM-DD格式。

这就是标准化规范的威力——大模型知道格式要求,会自己做转换,不再把模糊的「明天」直接丢给工具。


第三部分:工具返回结果(Tool Response)—— Agent把结果回传给大模型

Agent拿到大模型的调用指令后,去执行对应的工具,然后把工具的执行结果,按规范格式回传给大模型。

大模型会基于这个结果,决定下一步是继续调用其他工具,还是直接给用户返回最终答案。

json

{
    "city": "上海",
    "date": "2026-03-19",
    "temperature": "16-22°C",
    "condition": "多云转晴",
    "wind": "3级西北风"
}

这一步是整个循环的闭环。大模型不是一次性就完成任务的,它需要看到工具的执行结果之后,才能做出下一步决策:

  • 天气查到了 → 整理成自然语言回复用户

  • 工具报错了 → 决定换个方式或者告知用户


四、对应Agent执行流程

把这三部分放回之前讲过的Agent执行循环,对应关系就清晰了。

先回顾Agent的7步执行流程

text

第1步:Agent把「用户需求 + 工具清单」打包,发给大模型
第2步:大模型做决策,返回调用指令
第3步:Agent执行指令,调用工具函数
第4步:Agent把工具执行结果回传给大模型
第5步:大模型根据结果,决定下一步
第6步:循环执行,直到任务完成
第7步:Agent把最终结果反馈给用户

Function Calling规范的是其中有「数据交换」的三步

步骤 规范内容 说明
第1步 工具定义(Tool Definition) Agent把工具清单传给大模型,用标准JSON格式写
第2步 AI调用格式(Function Call) 大模型返回严格的JSON指令,告诉Agent调哪个工具、传什么参数
第4步 工具返回结果(Tool Response) Agent把工具执行结果按规范格式回传给大模型

⚠️ 注意:第3步不在Function Calling的管辖范围内。那一步是Agent实际执行函数,是真正「干活」的部分,不涉及大模型和Agent之间的通信格式。

用一张图把对应关系标出来

text

┌─────────────────────────────────────────────────────────────┐
│                    Function Calling 覆盖范围                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  第1步 ──→ 工具定义(JSON格式的name/description/parameters) │
│              ↓                                              │
│  第2步 ──→ AI调用格式(function_call + name + parameters)   │
│              ↓                                              │
│  第3步 ──→ 【执行工具,不在Function Calling范围内】           │
│              ↓                                              │
│  第4步 ──→ 工具返回结果(Tool Response)                     │
│              ↓                                              │
│  第5-7步 ──→ 继续循环或结束                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Function Calling把第1、2、4步的数据格式全部标准化了——这三步恰好是大模型和Agent之间所有的「信息交换点」。有了这套规范,双方说的是同一种语言,不再靠猜。


五、Agent拿到Function Call后怎么做?

当Agent收到大模型返回的function_call结构后,它的处理逻辑非常直接:

python

# 伪代码示例
def handle_function_call(response):
    # 1. 解析工具名
    tool_name = response["function_call"]["name"]  # "check_weather"
    
    # 2. 查找对应函数(在工具注册表里找)
    tool_func = tool_registry[tool_name]
    
    # 3. 传入参数执行
    params = response["function_call"]["parameters"]  # {"city": "上海", "date": "2026-03-19"}
    result = tool_func(**params)
    
    # 4. 拿到结果回传
    return result

整个过程干净利落:

  • ✅ 不需要任何猜测

  • ✅ 不需要正则解析

  • ✅ 不需要处理各种奇怪的格式变体

因为Function Calling已经保证了调用指令的格式是固定的、可预期的。Agent只需要按格式拆开、对号入座、执行、回传,就完成了自己在这一轮循环中的全部工作。


六、一张表看懂:System Prompt传统模式 vs Function Calling标准化模式

对比维度 System Prompt传统模式 Function Calling标准化模式
工具描述方式 自然语言随意写,无统一规范 固定JSON格式,强制规范name/description/parameters必填项
调用返回格式 完全靠AI自由发挥,五花八门,无固定结构 严格固定JSON结构,字段统一,可直接解析
参数错误率 极高,经常出现参数顺序错、格式错、模糊值 极低,大模型严格按参数规范生成,格式和必填项有服务端校验
开发成本 极高,需要写大量解析、纠错、重试逻辑 极低,直接解析固定格式,无需处理额外兼容问题
模型兼容性 极差,换个模型就要重写一整套提示词 极好,主流大模型通用,一套工具定义可跨模型使用

七、总结

整理一下这一章的核心认知:

1. Function Calling是什么?

大模型和Agent之间的标准化工具调用协议。

解决的是「大模型做出调用决策后,如何精准传递指令」的问题,是整个Agent开发的底层基础

2. 为什么需要它?

没有Function Calling 有了Function Calling
用自然语言描述工具,格式松散 用固定JSON定义工具,格式规范
AI回复五花八门,完全不可控 AI返回严格JSON,可直接解析
需要大量正则和纠错代码 解析代码极其简单
换个模型就要重写提示词 一套定义跨模型通用

3. 三部分结构

部分 方向 作用
工具定义(Tool Definition) Agent → 大模型 告诉大模型「有哪些工具、怎么用」
AI调用格式(Function Call) 大模型 → Agent 告诉Agent「调哪个工具、传什么参数」
工具返回结果(Tool Response) Agent → 大模型 把执行结果回传给大模型,供下一步决策

4. 与Agent执行流程的对应

Function Calling规范的是第1、2、4步——即大模型和Agent之间所有的「信息交换点」。

  • 第1步:工具定义(我能用什么)

  • 第2步:AI调用格式(我要调哪个)

  • 第4步:工具返回结果(调完得到什么)

5. 一句话总结

没有Function Calling,Agent开发就是一场噩梦般的猜谜游戏。有了它,大模型和Agent之间有了共同语言,工具调用变得可靠、可预期、可维护。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐