Function Calling 简介
Function Call 是大模型在对话过程中调用外部函数的能力,它允许模型在无法直接回答问题时,返回一个函数调用请求,而不是生成文本。开发者需要手动解析这个请求,执行对应的函数,并将结果传回给模型,以生成最终答案。
通俗地讲,Function Calling允许模型返回一个结构化的“函数调用请求”,告诉你的程序:“我建议调用哪个函数,以及具体用什么参数”。但需要注意的是,模型本身并不会真的执行函数,执行的任务必须由你自己定义和实现。
相比之下,我们在上一节课学习到的 Tool(工具)是具体的可执行函数,Agent 可以直接调用它,省去手动解析的步骤,使得模型能够自主决策并执行任务。
在 OpenAI 的 API 设计中,Function Call 允许模型以 JSON 格式返回参数,供外部程序解析并执行。例如:
{
"name": "get_weather",
"arguments": {
"location": "Shanghai",
"unit": "Celsius"
}
}
这意味着模型“决定”调用 get_weather
这个函数,并传递参数 { "location": "Shanghai", "unit": "Celsius" }
。然后,外部程序可以执行该函数,并将返回的结果反馈给 LLM。
乍一看,相较于 Function Call,工具(Tool)的使用方式确实更加便捷。开发者只需定义一个函数,并在注释中描述其用途,模型便可直接调用它。然而,这种简便性往往伴随着潜在问题,最明显的就是 大模型可能会因幻觉(Hallucination)传入错误的参数或格式,从而导致输出结果异常。而由于 Tool 直接执行调用,开发者难以在调用前对输入数据进行验证和修正,增加了出错的风险。
相比之下,Function Call 采用 JSON 格式进行交互,使得开发者可以在获取模型返回的调用请求后,先对参数进行检查,确保数据的完整性和准确性。此外,Function Call 允许开发者在函数逻辑中增加 数据补充、格式转换、异常处理 等机制,避免因模型提供无效参数而导致调用失败或程序崩溃。这种更精细的控制方式极大地提升了模型应用的稳定性和可靠性。因此,在许多实际开发场景中,开发者更倾向于 使用 Function Call,而不仅仅依赖 Tool 的自动调用,以确保系统的稳健性和安全性。
那下面的课程里,我们将基于openai官方定义的function_call方法来解释一下我们如何具体的使用吧!
实操演示
1. 环境准备
首先我们要获取一个阿里云百炼大模型的api_key,这个具体的获取方式在我之前的课程中讲过,这里我就不作进一步的赘述了。那除此之外呢我们还需要安装一下以下的库,我们可以在终端输入下面的代码进行安装:
pip install openai==1.47.0
2. 函数设置及方法创建
前面我们提到了,对于Function Call这个调用方法来说,大模型只知道告诉你去调用哪个函数以及对应需要传入的参数是什么,因此我们其实要做的第一步就是创建好这些函数。 我们以最经典的天气查询函数为例,来看看具体操作步骤。
首先定义一个简单的函数,用于模拟天气API,并最后返回json格式内容:
def get_current_weather(location, unit="fahrenheit"):
# 根据用户提供的地点和温度单位,构建模拟的天气信息
weather_info = {
"location": location, # 用户输入的城市名称,例如"北京"或"New York"
"temperature": "72", # 示例固定温度,仅用于模拟演示
"unit": unit, # 温度单位,可选华氏(fahrenheit)或摄氏(celsius)
"forecast": ["sunny", "windy"] # 示例天气情况,用于演示
}
# 返回JSON格式的天气信息,便于后续处理
return json.dumps(weather_info)
接下来,我们需要告诉大模型有哪些函数可供调用,具体结构包括函数名、功能描述、参数说明和类型等,如下所示:
functions = [
{
"name": "get_current_weather", # 函数的唯一标识名称
"description": "获取指定位置的当前天气", # 函数的简要说明,用于模型理解用途
"parameters": { # 函数需要的参数定义
"type": "object", # 参数整体类型为对象
"properties": { # 对象包含的具体参数说明
"location": {
"type": "string",
"description": "城市名称,例如北京、上海或纽约"# 参数"location"的具体含义
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"], # 限定温度单位只能是摄氏或华氏
"description": "温度单位,可选摄氏或华氏" # 参数"unit"的具体含义
}
},
"required": ["location"] # 指定必须提供的参数
}
}
]
我们可以看到,functions其实是一个列表,所以我们假如有多个工具的情况可以在这个列表里再写入其他的函数
3. 构建大模型并进行调用
在这节课里,我们不再使用ChatTongyi来进行模型的调用,由于国内大部分的大模型服务商都适配openai的格式,所以我们可以尝试一下通过openai官方库来进行调用。
那由于我们不是直接使用openai的模型,所以我们先要配置一下具体的api_key以及模型服务商的地址base_url。这里max_retries=3
其实就是希望假如调用三次都失败就不调用了。
import openai
client = openai.OpenAI(
api_key='api_key', # 指定 OpenAI API Key(默认会从环境变量 `OPENAI_API_KEY` 读取)
base_url="<https://dashscope.aliyuncs.com/compatible-mode/v1>", # API 服务器的地址(可用于私有部署或代理)
max_retries=3, # 最大重试次数
)
然后我们就可以通过其调用方法进行调用,这里我们指定了其function_call需要用到的工具,假如我们不希望其使用function_call,那我们要把这个参数设置为”none”
,假如是让系统自动决定是否使用,那就需要使用”auto”
这个参数。另外,这里的messages我们可以自己来进行定义,system就代表系统提示词,user就代表用户提示词。最后我们打印一下response就可以看到返回的内容。
messages = [
{
"role": "system",
"content": "你是一个乐于助人、知识渊博的中文助手,请始终用中文回复用户的问题。"
},
{
"role": "user",
"content": "明天纽约的天气怎么样"
}
]
response = client.chat.completions.create( # ✅ 新的写法
model="qwen-turbo",
messages=messages,
functions=functions,
function_call={"name": "get_current_weather"}
)
print(response)
最后输出的内容为如下。我们会发现其不再是直接回答我们的具体问题,而是说返回一个调用的方法。其实里面最关键的内容就是function_call=FunctionCall(arguments='{"location": "New York, NY"}', name='get_current_weather')
这部分的内容,其明确定义了要输入的内容是什么,以及要调用的方法是哪一个。后续我们其实就可以基于这个输出的结果去进行手动的解析并调用。
ChatCompletion(
id='chatcmpl-4829de50-8335-9a62-a70d-6f8011aa3a1f',
choices=[
Choice(
finish_reason='stop',
index=0,
logprobs=None,
message=ChatCompletionMessage(
content='',
refusal=None,
role='assistant',
function_call=FunctionCall(
arguments='{"location": "New York, NY"}',
name='get_current_weather'
),
tool_calls=None
)
)],
created=1743032477,
model='qwen-turbo',
object='chat.completion',
service_tier=None,
system_fingerprint=None,
usage=CompletionUsage(
completion_tokens=14,
prompt_tokens=209,
total_tokens=223,
completion_tokens_details=None,
prompt_tokens_details={'cached_tokens': 0}
))
4. 解析并执行函数
当我们获取到了这部分信息后,我们就可以对其进行解析了,具体解析代码如下。我们首先要确保模型返回的是function_call的内容,然后提取其中的参数并找到对应的函数进行执行。
import json
# 获取模型返回的message
message = response.choices[0].message
# 如果模型返回了函数调用请求
if message.function_call:
# 提取函数名
function_name = message.function_call.name
# 提取并解析函数参数(注意:是字符串,要先 json.loads)
arguments_str = message.function_call.arguments
arguments = json.loads(arguments_str)
# 根据函数名选择执行你定义的函数(这里只定义了一个函数做示例)
if function_name == "get_current_weather":
result = get_current_weather(**arguments) # 执行函数
print("✅ 实际函数执行结果:")
print(result)
执行后的结果就是函数返回的内容。
{
"location": "\u5317\u4eac",
"temperature": "72",
"unit": "celsius",
"forecast": ["sunny", "windy"]
}
5. 将结果传输给模型进行回复
最后,我们可以通过messages.append的方式将function返回的结果传输给大模型进行回复。这样就能够实现大模型选择方法,执行函数,然后返回结果传给大模型进行回复的流程啦!
messages.append(
{
"role": "function",
"name": "get_current_weather",
"content": result,
}
)
response = client.chat.completions.create(
model="qwen-turbo",
messages=messages,
)
print(response.choices[0].message.content)
当然因为这个示例里没有真正的调用天气的函数所以输出的结果不太让人满意,但是大家也可以尝试自己来进行构建,来让大模型能够真实且稳定的让大模型能够调用外部的工具,从而实现更好的工作流!
完整的代码如下所示:
import json
import openai
def get_current_weather(location, unit="fahrenheit"):
# 根据用户提供的地点和温度单位,构建模拟的天气信息
weather_info = {
"location": location, # 用户输入的城市名称,例如"北京"或"New York"
"temperature": "72", # 示例固定温度,仅用于模拟演示
"unit": unit, # 温度单位,可选华氏(fahrenheit)或摄氏(celsius)
"forecast": ["sunny", "windy"] # 示例天气情况,用于演示
}
# 返回JSON格式的天气信息,便于后续处理
return json.dumps(weather_info)
functions = [
{
"name": "get_current_weather", # 函数的唯一标识名称
"description": "获取指定位置的当前天气", # 函数的简要说明,用于模型理解用途
"parameters": { # 函数需要的参数定义
"type": "object", # 参数整体类型为对象
"properties": { # 对象包含的具体参数说明
"location": {
"type": "string",
"description": "城市名称,例如北京、上海或纽约"# 参数"location"的具体含义
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"], # 限定温度单位只能是摄氏或华氏
"description": "温度单位,可选摄氏或华氏" # 参数"unit"的具体含义
}
},
"required": ["location"] # 指定必须提供的参数
}
}
]
messages = [
{
"role": "system",
"content": "你是一个乐于助人、知识渊博的中文助手,请始终用中文回复用户的问题。"
},
{
"role": "user",
"content": "明天天气怎么样"
}
]
client = openai.OpenAI(
api_key='api_key', # 指定 OpenAI API Key(默认会从环境变量 `OPENAI_API_KEY` 读取)
base_url="<https://dashscope.aliyuncs.com/compatible-mode/v1>", # API 服务器的地址(可用于私有部署或代理)
max_retries=3, # 最大重试次数
)
# OpenAI 1.0.0+ 需要先创建 client 实例
response = client.chat.completions.create( # ✅ 新的写法
model="qwen-turbo",
messages=messages,
functions=functions,
function_call={"name": "get_current_weather"}
)
# 获取模型返回的message
message = response.choices[0].message
# 如果模型返回了函数调用请求
if message.function_call:
# 提取函数名
function_name = message.function_call.name
# 提取并解析函数参数(注意:是字符串,要先 json.loads)
arguments_str = message.function_call.arguments
arguments = json.loads(arguments_str)
# 根据函数名选择执行你定义的函数(这里只定义了一个函数做示例)
if function_name == "get_current_weather":
result = get_current_weather(**arguments) # 执行函数
print("✅ 实际函数执行结果:")
print(result)
messages.append(
{
"role": "function",
"name": "get_current_weather",
"content": result,
}
)
response = client.chat.completions.create(
model="qwen-turbo",
messages=messages,
)
print(response.choices[0].message.content)
总结
通过本节内容,我们完整了解了 OpenAI Function Calling 的基本概念、使用方式以及与 Tool 的区别。我们不仅学会了如何定义一个标准的函数结构,并注册给模型使用,还掌握了如何解析模型返回的函数调用请求,执行函数并将结果重新传回模型以获取最终回复。这种方式为开发者提供了更高的灵活性与安全性,使得我们在构建模型应用时能够更稳定、更可控地完成复杂任务。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。