
2023年6月13日 OpenAI 公布了 Function Calling(函数调用) 功能,Function Call 允许开发者向 GPT-4 和 GPT-3.5-turbo 模型描述函数,模型会智能地选择输出一个包含调用这些函数参数的JSON对象。这是一种更可靠地将 GPT 的功能与外部工具和 API 相连接的新方法。
GPT4 及 GPT-3.5-turbo 模型之所以能够使用函数 Function Calling 功能,是因为这些模型经过训练,不仅可以检测到何时需要调用函数(根据用户的输入),并且又可以回复符合函数参数的 JSON对象,而不是直接返回常规的文本,简而言之:函数调用使开发者能够更可靠地从模型中获得结构化数据。
1、信息实时性:大模型训练时使用的数据集往往有时间限制,无法包含最新的信息,如最新的新闻、实时股价等。通过Function Calling,模型可以实时获取最新数据,提供更加时效的服务。
2、数据局限性:模型的训练数据量庞大但有限,无法覆盖所有可能的查询,如医学、法律等领域的专业咨询。Function Calling允许模型调用外部数据库或API,获取特定领域的详细信息。
3、功能扩展性:大模型虽然功能强大,但不可能内置所有可能需要的功能。通过Function Calling,可以轻松扩展模型能力,如调用外部工具进行复杂计算、数据分析等。
总的来说,Function Calling功能的出现,极大地提升了大型语言模型的实用性和灵活性,使其能够更好地服务于用户的各种需求。
我们通过举例分别对比有无Function Calling功能时GPT模型工作流程的差异:
当没有函数调用(funciton-call)时候,我们调用GPT构建AI应用的模式非常简单。
用户(client)发请求给我们的服务(chat server)
我们的服务(chat server)给GPT提示词

当有函数调用(funciton-call)时候,我们调用GPT构建AI应用的模式比之前要复杂一些
用户(client)发请求提示词以及可以调用的函数给我们的服务(chat server)
GPT模型根据用户的提示词,判断是用普通文本还是函数调用的格式响应我们的服务(chat server)
如果是函数调用格式,它会输出一个结构化的JSON请求,其中包含了要调用的函数名和参数,那么Chat Server就会执行这个函数,并且将结果返回给GPT 然后模型使用提供的数据,用连贯的文本响应。返回

一、预定义工具:
每次调用模型(或每个会话)都要把 tools 定义带进去:
tools = [
{
"type": "function",
"name": "get_weather",
"description": "Get weather by location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string"
}
},
"required": [
"location"
]
}
},
{
"type": "function",
"name": "get_stock_price",
"description": "Get stock price by ticker",
"parameters": {
"type": "object",
"properties": {
"ticker": {
"type": "string"
}
},
"required": [
"ticker"
]
}
}
]二、模型返回“工具调用指令”(结构化 JSON)
{
"tool_calls": [
{"name":"get_weather","arguments": {"location":"Beijing"}},
{"name":"get_stock_price","arguments": {"ticker":"AAPL"}}
]
}三、我们自己后台程序做工具调用
def get_weather(location):
returnweather_api.query(location)
def get_stock_price(ticker):
returnmarket_api.query(ticker)四、拿到工具结果,组装提示词最终调用模型生成回答
tool_results = [
{"name":"get_weather","content":"..."},
{"name":"get_stock_price","content":"..."}
]
final = llm_call(messages + tool_results)
可以看出,并不是大模型调用了我们的工具,还是我们自己的应用程序调用了工具
Function Calling解决的问题就是:单个模型怎么“按你定义的 JSON 协议”去调你自己的API的问题
不同厂商、不同版本的API可能有细微差异
要为多个模型适配
特性 | OpenAI | Anthropic | Google Gemini |
|---|---|---|---|
字段名 | tools | tools | tools 或 tool_declaration |
工具定义 | 嵌套在 function 里 | 直接定义 | function_declarations |
参数定义 | parameters | input_schema | parameters |
模型输出 | tool_calls | tool_use (在block中) | function_call |
参数获取 | tool_call.function.arguments (需json.loads) | block.input (直接是dict) | part.function_call.args |
工具选择 | tool_choice | 自动或指定 | 自动 |
返回格式 | JSON字符串 | 字典对象 | Protobuf对象 |
InternalError.Algo.InvalidParameter: The tool call is not supported
这通常意味着我们尝试调用一个模型不支持的函数或工具。在大型语言模型的API调用中,当我们使用函数调用(Function Calling)或工具调用(Tool Calling)时,我们需要确保我们传递给模型的工具描述是符合模型要求的,并且模型确实支持这种工具调用。
Function Calling是大模型(LLM)与外部代码间一种结构化的交互方式,用于描述和调用Tool
但这也有两个问题:
第一,如果Tools工具过多(数组过多),这个也是要占用上下文长度的,所以真实使用会做很多小处理
第二,Fuction Calling 使用好坏非常依赖于模型本身对意图识别的能力,模型判断要不要调用一个函数,主要是根据description参数来的
再进一步发展, 单个Agent调用单个工具,没什么问题,但如果工具很多,Agent也很多的情况下,就带来了问题:维护工作量成倍增长
例如: 企业中有10个AI Agent(N)需要接入20个数据源/工具(M)
如果每个应用都为每个工具编写专用适配代码,就需要200个集成点。这里面维护成本是较高的,任何工具API变更都会很烦。
可能同时调用ChatGPT、Gemini还有DeepSeek,而他们每个Tools调用接口都不一样,这个维护起来就更麻烦了,不过这个问题上一篇介绍了Spring AI的意义,也就解决了这个问题。
如何解决这些问题,下回分解MCP
计算机领域中的所有问题都可以通过增加一个中间层来解决,无论后端是什么工具,MCP提供统一接口