7.2 函数调用:大模型的工具使用格式
7.1 节介绍了工具调用的基本原理和工具定义方式。本节深入一层,讲解函数调用(Function Calling)的数据格式和交互协议。这是大模型调用外部工具的核心机制——模型不直接执行代码,而是通过结构化的数据格式,告诉应用程序该调用哪个函数、传入什么参数。
理解这套数据格式,是后续学习 MCP 协议、构建金融智能体工具链的基础。
7.2.1 Function Calling 的诞生
2023 年 6 月,OpenAI 在 GPT 模型的 API 中率先推出函数调用(Function Calling)功能。这是大模型工具使用领域的一个分水岭。
在此之前,开发者想让模型调用工具,只能靠提示词引导模型输出特定格式的文本,再用正则表达式解析。这种方式脆弱且不可靠——模型稍微改变措辞,解析就会失败。
Function Calling 改变了这一局面。模型不再输出自由文本让开发者猜测意图,而是直接返回结构化的 JSON 数据,明确指定要调用的函数名和参数值。格式固定、字段明确、机器可直接解析。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,由键值对组成。例如 {"name": "贵州茅台", "code": "600519"} 就是一条 JSON 数据。它是当前 Web 开发和 API 通信中最主流的数据格式。
各大模型厂商迅速跟进。Anthropic 为 Claude 推出了 Tool Use 功能,Google 为 Gemini 推出了 Function Calling 支持。虽然各家的数据格式略有差异,但核心思路一致:模型通过结构化输出声明工具调用意图,应用程序负责实际执行。
下表汇总了主流厂商的工具调用功能:
| 厂商 | 功能名称 | 推出时间 | 格式特点 |
|---|---|---|---|
| OpenAI | Function Calling | 2023 年 6 月 | tools + tool_calls 字段 |
| Anthropic | Tool Use | 2024 年 4 月 | content block 模型 |
| Function Calling | 2023 年 12 月 | functionCall 字段 | |
| 智谱 AI | Function Call | 2024 年 | 兼容 OpenAI 格式 |
| MiniMax | Function Call | 2024 年 | 兼容 OpenAI 格式 |
国内厂商(智谱、MiniMax 等)大多兼容 OpenAI 格式,这降低了开发者的迁移成本。
7.2.2 工具定义的数据格式
函数调用的第一步,是告诉模型有哪些工具可用。工具定义遵循 JSON Schema 规范,由三个核心字段构成。
三个核心字段
| 字段 | 作用 | 重要程度 |
|---|---|---|
name |
工具的唯一标识符,模型据此调用 | ★★★ |
description |
功能描述,模型依赖此信息判断何时调用 | ★★★ |
parameters |
参数定义,规定输入数据的结构 | ★★★ |
其中 description 的质量至关重要。模型根据 description 判断当前问题是否需要调用该工具。描述越精确,模型的调用决策越准确。
description 是工具定义中最关键的字段。一个好的描述应回答三个问题:这个工具做什么?什么时候该用它?返回什么结果?模型完全依赖这段文字来决定是否调用工具。
下面用一个查询 A 股行情的工具定义来说明完整格式。这是 OpenAI 风格的定义方式,也是目前最通用的格式:
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "查询 A 股股票的实时行情数据,包括最新价、涨跌幅、成交量。当用户询问某只股票的价格、涨跌情况时调用此工具。",
"parameters": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "6 位 A 股股票代码,如 600519 表示贵州茅台"
},
"metrics": {
"type": "array",
"items": {
"type": "string",
"enum": ["price", "change", "volume", "turnover", "pe_ratio"]
},
"description": "需要查询的指标列表,默认返回全部"
},
"include_history": {
"type": "boolean",
"description": "是否包含最近 5 个交易日的历史数据,默认为 false"
}
},
"required": ["symbol"]
}
}
}逐层解读这段定义:
- 最外层的
"type": "function"声明这是一个函数类型的工具。 name是函数名,必须是合法标识符(字母、数字、下划线)。description详细说明功能和适用场景。parameters采用 JSON Schema 格式定义输入参数。
参数类型系统
JSON Schema 提供了六种常用参数类型,足以覆盖绝大多数金融场景:
| 类型 | 说明 | 金融应用示例 |
|---|---|---|
string |
字符串 | 股票代码、公司名称 |
integer |
整数 | 持股数量、交易天数 |
number |
浮点数 | 价格、收益率、权重 |
boolean |
布尔值 | 是否含历史数据、是否复权 |
array |
数组 | 多个股票代码、指标列表 |
enum |
枚举(限定取值范围) | 市场类型、订单类型 |
必需参数与可选参数
required 数组列出的参数为必需参数,模型必须提供。未列入的参数为可选参数,模型可根据情况决定是否填写。
在上面的例子中,symbol 是必需参数——查股票必须指定代码;metrics 和 include_history 是可选参数——不指定也能返回默认结果。
设计工具参数时,尽量减少必需参数的数量。只把真正不可或缺的参数设为 required,其余用合理的默认值处理。这能降低模型的调用门槛,提高工具被正确使用的概率。
7.2.3 请求与响应的完整数据流

一次完整的函数调用涉及两次 API 请求,分为四个阶段:
| 阶段 | 方向 | 数据内容 |
|---|---|---|
| ① 第一次请求 | 应用 → 模型 API | 用户消息 + 可用工具定义列表 |
| ② 模型返回调用指令 | 模型 API → 应用 | tool_calls 数组:工具名、参数、调用 ID |
| ③ 第二次请求 | 应用 → 模型 API | 完整对话历史 + 工具执行结果(通过调用 ID 匹配) |
| ④ 模型生成回复 | 模型 API → 应用 | 自然语言最终回复 |
以用户提问「帮我查一下贵州茅台的最新股价和市盈率」为例:阶段 ① 应用将问题和 get_stock_price 工具定义发送给模型;阶段 ② 模型返回调用指令,指定工具名 get_stock_price、参数 {"symbol": "600519", "metrics": ["price", "pe_ratio"]};阶段 ③ 应用执行实际 API 查询,将结果连同对话历史发回模型;阶段 ④ 模型将结构化数据组织成自然语言回复。
函数调用需要两次 API 请求才能完成一轮交互。第一次发送用户问题和工具定义,获取调用指令;第二次发送工具执行结果,获取最终回复。如果模型判断不需要工具,第一次请求就直接返回文本回复,无需第二次调用。
7.2.4 多工具调用与工具链
实际的金融分析场景往往需要多个工具协同工作。Function Calling 支持两种多工具使用模式。
并行调用:一次请求多个工具
当用户的问题涉及多个独立的数据查询时,模型可以在一次响应中同时调用多个工具。例如用户问「对比一下贵州茅台和五粮液的股价」,模型会返回:
{
"tool_calls": [
{
"id": "call_001",
"type": "function",
"function": {
"name": "get_stock_price",
"arguments": "{\"symbol\": \"600519\"}"
}
},
{
"id": "call_002",
"type": "function",
"function": {
"name": "get_stock_price",
"arguments": "{\"symbol\": \"000858\"}"
}
}
]
}tool_calls 数组中包含两个调用请求,应用程序可以并行执行,分别查询两只股票的数据,然后将两个结果都返回给模型。
顺序调用(工具链):一个工具的输出作为另一个的输入
有些任务需要按步骤完成。例如「分析贵州茅台的估值是否合理」,可能需要:
- 先调用
get_stock_price获取当前股价和市盈率 - 再调用
get_financial_report获取最近一期财报数据 - 最后调用
calculate_valuation计算估值指标
这就是工具链(Tool Chaining)。模型在每一步拿到结果后,决定下一步调用什么工具。整个过程可能涉及多轮 API 交互,每轮都遵循上一小节描述的四阶段流程。
设计工具集合时,每个工具应职责单一、边界清晰。一个工具只做一件事,通过工具链组合完成复杂任务。这与软件工程中的单一职责原则一致,也便于模型理解和选择工具。
7.2.5 从 Function Calling 到 MCP
各大模型厂商的 Function Calling 格式大同小异,但细节各有不同(如 OpenAI 用 parameters,Claude 用 input_schema;OpenAI 的工具结果用 role: "tool",Claude 用 role: "user" 加 tool_result 块)。格式差异对最终用户影响不大,智能体框架会自动处理适配。
Function Calling 解决了单个模型调用工具的问题,但它仍然是 API 级别的机制——每个模型厂商有自己的格式,每个应用需要为每个工具单独编写对接代码。
当工具数量增长、模型种类增多时,开发者面临 M 个模型 × N 个工具的集成难题。这正是下一节 MCP 协议要解决的问题:在 Function Calling 之上建立一层标准化协议,让任何模型都能通过统一接口访问任何工具。
Function Calling 是工具调用的数据格式,MCP 是工具连接的通信协议。前者规定调用请求的格式,后者规定工具如何被发现、连接和管理。理解了 Function Calling 的数据流,学习 MCP 就有了坚实的基础。