深度揭秘 AI 大模型 Function Calling 原理:从理论到源码实践
本人掘金号,欢迎点击关注:掘金号地址
本人公众号,欢迎点击关注:公众号地址
一、引言
在 AI 大模型不断演进的当下,其功能愈发强大且复杂。Function Calling(函数调用)作为一项关键特性,为大模型与外部工具、系统以及更复杂的逻辑交互搭建了桥梁。它使得大模型不再局限于单纯的文本生成与理解,而是能够借助外部函数执行特定任务,极大地拓展了大模型的应用边界。无论是在智能客服调用知识库查询信息,还是在数据分析场景中调用专业计算函数处理数据,Function Calling 都发挥着不可或缺的作用。深入理解其原理,不仅有助于开发者更高效地利用大模型的能力,还能推动创新应用的开发。本文将全面深入地剖析 AI 大模型 Function Calling 的原理,并通过丰富的源码示例进行详细解读。
二、Function Calling 基础概念
2.1 什么是 Function Calling
Function Calling,简单来说,是指 AI 大模型在处理任务时,能够识别特定的指令或提示,进而调用预先定义好的外部函数来完成特定功能的过程。这些外部函数可以是各类编程语言编写的函数,涵盖从简单的数据处理函数到复杂的 API 调用函数等。例如,在一个对话系统中,用户询问 "明天北京的天气如何",大模型识别出这是一个获取天气信息的任务,通过 Function Calling 调用天气查询 API 对应的函数,获取并返回北京明天的天气数据。
2.2 Function Calling 的重要性
它显著增强了大模型的实用性和灵活性。通过 Function Calling,大模型能够整合各种专业工具和系统的能力,弥补自身在特定领域知识或功能上的不足。比如在金融领域,大模型可以调用金融计算函数进行复杂的风险评估;在图像领域,调用图像编辑函数对图片进行处理。这使得大模型能够更好地适应多样化的应用场景,提供更精准、专业的服务,极大地提升了用户体验和应用的价值。
三、Function Calling 的工作流程
3.1 指令识别与意图理解
当用户输入内容被大模型接收后,模型首先要对输入进行解析,识别其中是否包含需要调用外部函数的指令或意图。这涉及到自然语言处理的多个环节,包括分词、词性标注、句法分析和语义理解等。
以 Python 中使用 NLTK(Natural Language Toolkit)库进行简单的指令识别为例:
python
python
import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
# 假设用户输入
user_input = "我想查询上海明天的天气"
# 分词
tokens = word_tokenize(user_input)
print("分词结果:", tokens)
# 词性标注
tagged_tokens = pos_tag(tokens)
print("词性标注结果:", tagged_tokens)
在这段代码中:
-
首先导入
nltk
库,以及分词和词性标注的相关函数。nltk
是一个广泛用于自然语言处理的工具包。 -
定义了一个模拟的用户输入
user_input
,内容为 "我想查询上海明天的天气"。 -
使用
word_tokenize
函数对用户输入进行分词,将句子拆分成单个的词,结果存储在tokens
变量中,并打印出来。分词是自然语言处理的基础步骤,有助于后续对句子结构和语义的分析。 -
通过
pos_tag
函数对分词后的结果进行词性标注,为每个词标注其词性(如名词、动词、形容词等),标注结果存储在tagged_tokens
中并打印。词性标注能帮助模型更好地理解句子中每个词的作用,进而辅助识别指令意图。
在实际的大模型中,对指令的识别和意图理解更为复杂,可能涉及深度学习模型,如基于 Transformer 架构的编码器对输入文本进行编码,通过多层注意力机制捕捉文本中的关键信息,判断是否存在需要调用外部函数的意图。
3.2 函数匹配与选择
一旦识别出调用外部函数的意图,大模型需要在预先定义的函数库中找到与之匹配的函数。函数库包含了各种功能的函数定义及其描述信息。匹配过程通常基于指令中的关键词、语义以及函数的功能描述等。
假设我们有一个简单的函数库,包含天气查询函数和股票查询函数,以下是一个简单的函数匹配示例(使用 Python 字典模拟函数库):
python
python
# 定义函数库
function_library = {
"get_weather": {
"description": "获取指定城市指定时间的天气信息",
"parameters": ["city", "time"]
},
"get_stock_price": {
"description": "获取指定股票代码的实时价格",
"parameters": ["stock_code"]
}
}
# 假设经过意图理解后得到的关键词和参数
intent_keywords = ["天气", "上海", "明天"]
# 函数匹配逻辑
for function_name, function_info in function_library.items():
if "天气" in function_info["description"]:
# 检查参数是否匹配
required_parameters = function_info["parameters"]
provided_parameters = []
for param in required_parameters:
if param in intent_keywords:
provided_parameters.append(param)
if set(required_parameters) == set(provided_parameters):
print(f"匹配到函数: {function_name}")
在这段代码中:
-
首先定义了一个
function_library
字典,模拟函数库。每个函数在字典中以键值对的形式存在,键为函数名,值为包含函数描述和所需参数的字典。这里定义了get_weather
(获取天气信息)和get_stock_price
(获取股票价格)两个函数。 -
假设
intent_keywords
列表是经过意图理解后提取出的关键词和参数信息,这里包含了与天气查询相关的 "天气""上海""明天"。 -
通过循环遍历
function_library
,检查每个函数描述中是否包含与意图相关的关键词(这里是 "天气")。如果包含,进一步检查所需参数是否在intent_keywords
中都能找到。如果函数所需参数与提供的参数完全匹配,则认为找到了匹配的函数,并打印出函数名。
在真实场景中,大模型可能会使用更复杂的语义匹配算法,如基于词向量的相似度计算,来提高函数匹配的准确性和效率。
3.3 函数调用与参数传递
确定匹配的函数后,大模型将调用该函数,并将相关参数传递给它。参数的提取和整理是这一步的关键。参数可能来自用户输入的直接解析,也可能需要经过进一步的处理和转换。
继续以上述天气查询为例,假设我们有一个真实的天气查询函数get_weather_api
,以下是调用该函数并传递参数的代码:
python
python
import requests
# 模拟真实的天气查询API函数
def get_weather_api(city, time):
url = f"https://api.weather.com/weather?city={city}&time={time}"
response = requests.get(url)
if response.status_code == 200:
return response.json()
else:
return None
# 假设经过前面步骤确定的城市和时间参数
city = "上海"
time = "明天"
# 调用天气查询函数并传递参数
weather_data = get_weather_api(city, time)
if weather_data:
print("天气数据:", weather_data)
else:
print("获取天气数据失败")
在这段代码中:
- 首先导入
requests
库,用于发送 HTTP 请求获取天气数据。 - 定义了一个模拟的天气查询 API 函数
get_weather_api
,该函数接收city
(城市)和time
(时间)两个参数。在函数内部,构建了一个请求 URL,使用requests.get
方法向天气 API 发送请求。如果请求成功(状态码为 200),则返回 API 响应的 JSON 格式数据;否则返回None
。 - 假设通过前面的意图理解和函数匹配步骤,确定了要查询的城市为 "上海",时间为 "明天",并将其分别赋值给
city
和time
变量。 - 最后调用
get_weather_api
函数,并将city
和time
作为参数传递进去,将返回的天气数据存储在weather_data
中。根据返回结果判断是否成功获取天气数据,并进行相应的打印输出。
3.4 结果处理与反馈
函数执行完成后,会返回一个结果。大模型需要对这个结果进行处理,将其转化为适合用户理解或后续任务使用的形式,并反馈给用户或用于进一步的流程。
还是以天气查询为例,假设get_weather_api
函数返回的是一个包含天气信息的字典,我们对结果进行处理并反馈给用户:
python
python
# 假设get_weather_api返回的天气数据
weather_data = {
"city": "上海",
"time": "明天",
"weather_condition": "晴",
"temperature": "25℃"
}
# 结果处理与反馈
if weather_data:
result_message = f"明天上海的天气为{weather_data['weather_condition']},温度为{weather_data['temperature']}"
print("反馈给用户:", result_message)
else:
print("获取天气数据失败")
在这段代码中:
- 假设
weather_data
是调用get_weather_api
函数后返回的天气数据字典,包含城市、时间、天气状况和温度等信息。 - 通过判断
weather_data
是否有数据,对结果进行处理。如果有数据,则构建一个适合用户理解的结果消息result_message
,包含天气状况和温度信息。最后打印出反馈给用户的消息。如果weather_data
为空,则打印获取天气数据失败的提示。
四、Function Calling 在不同场景下的应用示例
4.1 智能客服场景
在智能客服系统中,Function Calling 可用于查询知识库、调用业务逻辑函数等。例如,当用户咨询产品信息时,大模型识别意图后,调用知识库查询函数获取相关产品介绍。
以下是一个简单的智能客服调用知识库函数的示例代码(使用 Python 和简易的知识库模拟):
python
python
# 模拟知识库,以字典形式存储产品信息
knowledge_base = {
"product1": {
"name": "智能手表",
"description": "一款具有多种健康监测功能的智能穿戴设备",
"price": "1999元"
},
"product2": {
"name": "无线耳机",
"description": "具备高音质和长续航的无线音频设备",
"price": "999元"
}
}
# 知识库查询函数
def query_knowledge_base(product_name):
if product_name in knowledge_base:
return knowledge_base[product_name]
else:
return None
# 假设用户输入
user_input = "给我介绍一下智能手表"
# 简单的意图识别,这里假设通过关键词匹配
if "智能手表" in user_input:
product_info = query_knowledge_base("product1")
if product_info:
result = f"产品名称: {product_info['name']},描述: {product_info['description']},价格: {product_info['price']}"
print("反馈给用户:", result)
else:
print("未找到相关产品信息")
在这段代码中:
- 首先定义了一个模拟的知识库
knowledge_base
,以字典形式存储产品信息,每个产品作为一个键值对,值为包含产品名称、描述和价格的字典。 - 定义了
query_knowledge_base
函数,该函数接收产品名称作为参数,在知识库中查询对应的产品信息。如果找到,则返回该产品的信息字典;否则返回None
。 - 假设用户输入为 "给我介绍一下智能手表",通过简单的关键词匹配识别出用户意图是查询智能手表信息。调用
query_knowledge_base
函数,传入产品编号 "product1"(假设智能手表对应产品编号为 1)。根据查询结果,如果找到产品信息,则构建反馈给用户的消息并打印;如果未找到,则打印提示信息。
4.2 数据分析场景
在数据分析场景中,大模型可以调用数据分析函数进行数据处理、统计计算等操作。例如,用户要求对一组销售数据进行统计分析,大模型调用相关的统计函数计算平均值、最大值等。
以下是使用 Python 的pandas
库进行简单数据分析函数调用的示例:
python
python
import pandas as pd
# 模拟销售数据
sales_data = {
"product": ["A", "B", "C", "A", "B"],
"sales_amount": [100, 150, 120, 90, 130]
}
df = pd.DataFrame(sales_data)
# 数据分析函数:计算销售金额的平均值
def calculate_average_sales():
return df["sales_amount"].mean()
# 数据分析函数:计算销售金额的最大值
def calculate_max_sales():
return df["sales_amount"].max()
# 假设用户输入
user_input = "计算销售金额的平均值和最大值"
# 简单的意图识别,这里假设通过关键词匹配
if "平均值" in user_input and "最大值" in user_input:
average_sales = calculate_average_sales()
max_sales = calculate_max_sales()
result = f"销售金额平均值为{average_sales},最大值为{max_sales}"
print("反馈给用户:", result)
在这段代码中:
- 首先导入
pandas
库,用于数据处理和分析。 - 定义了一个模拟的销售数据字典
sales_data
,包含产品名称和销售金额信息。使用pd.DataFrame
将其转换为pandas
的数据框df
,方便后续数据分析操作。 - 定义了两个数据分析函数
calculate_average_sales
和calculate_max_sales
,分别用于计算销售金额的平均值和最大值。这两个函数通过对数据框df
中的 "sales_amount" 列进行相应的计算操作来实现功能。 - 假设用户输入为 "计算销售金额的平均值和最大值",通过关键词匹配识别用户意图。如果匹配成功,则调用这两个数据分析函数,获取平均值和最大值,并构建反馈给用户的结果消息进行打印。
4.3 图像编辑场景
在图像编辑场景中,大模型可调用图像编辑函数对图像进行裁剪、滤波、风格转换等操作。例如,用户要求将一张图片进行高斯模糊处理,大模型识别意图后调用相应的图像编辑函数。
以下是使用 Python 的OpenCV
库进行简单图像编辑函数调用的示例(假设已安装OpenCV
库):
python
python
import cv2
import numpy as np
# 读取图像
image = cv2.imread('example_image.jpg')
# 图像编辑函数:高斯模糊
def gaussian_blur_image(image):
blurred_image = cv2.GaussianBlur(image, (5, 5), 0)
return blurred_image
# 假设用户输入
user_input = "对图片进行高斯模糊处理"
# 简单的意图识别,这里假设通过关键词匹配
if "高斯模糊" in user_input:
blurred_result = gaussian_blur_image(image)
cv2.imwrite('blurred_image.jpg', blurred_result)
print("已将高斯模糊后的图片保存为blurred_image.jpg")
在这段代码中:
- 首先导入
cv2
(OpenCV 库的别名)和numpy
库。OpenCV
是一个广泛用于计算机视觉和图像编辑的库。 - 使用
cv2.imread
函数读取名为example_image.jpg
的图像,将其存储在image
变量中。 - 定义了
gaussian_blur_image
函数,该函数接收一个图像作为参数,使用cv2.GaussianBlur
函数对图像进行高斯模糊处理。其中,(5, 5)
是高斯核的大小,0
是标准差。函数返回模糊后的图像。 - 假设用户输入为 "对图片进行高斯模糊处理",通过关键词匹配识别用户意图。如果匹配成功,则调用
gaussian_blur_image
函数对读取的图像进行高斯模糊处理,处理结果存储在blurred_result
中。然后使用cv2.imwrite
函数将模糊后的图像保存为blurred_image.jpg
,并打印提示信息。
五、Function Calling 的实现方式与源码解析
5.1 基于特定框架的实现
许多深度学习框架为 Function Calling 提供了支持。以 LangChain 框架为例,它专门用于构建与大模型交互的应用,对 Function Calling 有较为完善的支持。
下面是一个使用 LangChain 进行简单 Function Calling 的示例代码(假设已安装 LangChain 库):
python
python
from langchain.llms import OpenAI
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate
from langchain.tools import Tool
# 定义一个简单的工具函数,用于计算两个数的和
def add_numbers(a, b):
return a + b
# 创建一个LangChain的Tool对象,描述工具的功能和调用方式
add_tool = Tool(
name="AddNumbers",
func=add_numbers,
description="用于将两个数字相加,输入参数为两个数字a和b"
)
# 初始化OpenAI语言模型
llm = OpenAI(temperature=0)
# 定义一个PromptTemplate,用于生成调用工具的提示
prompt = PromptTemplate(
input_variables=["a", "b"],
template="请计算{a}和{b}的和,使用AddNumbers工具"
)
# 创建LLMChain,将语言模型、提示模板和工具组合在一起
chain = LLMChain(llm=llm, prompt=prompt, tools=[add_tool])
# 假设用户输入的两个数字
a = 3
b = 5
# 运行LLMChain,调用工具并获取结果
result =
运行 LLMChain,调用工具并获取结果
result = chain.run ({"a": a, "b": b})
print (f"计算结果: {result}")
plaintext
python
在这段代码中:
1. **工具函数定义**:
- 首先定义了一个简单的Python函数`add_numbers`,它接受两个参数`a`和`b`,并返回它们的和。这个函数就是我们希望大模型能够调用的外部功能,在这里是执行基本的加法运算。
2. **LangChain工具创建**:
- 使用`Tool`类从`langchain.tools`模块中创建一个工具对象`add_tool`。
- `name`参数指定了工具的名称为"AddNumbers",这个名称将在后续提示和调用中使用,方便识别和引用该工具。
- `func`参数直接指向我们定义的`add_numbers`函数,这告诉LangChain当调用这个工具时应该执行哪个具体的功能。
- `description`参数详细描述了工具的功能和输入参数要求。这对于大模型理解何时以及如何使用该工具非常重要。在实际应用中,更复杂的工具可能有多个参数和更详细的功能说明,清晰的描述有助于大模型准确地调用工具。
3. **语言模型初始化**:
- 从`langchain.llms`模块中导入`OpenAI`类,并初始化一个`OpenAI`语言模型实例`llm`。这里设置`temperature = 0`,`temperature`参数控制生成文本的随机性,值为0时生成的文本将更加确定性,更倾向于选择最可能的输出。
4. **提示模板定义**:
- 使用`PromptTemplate`类从`langchain.prompts`模块中创建一个提示模板`prompt`。
- `input_variables`参数指定了提示模板中需要的输入变量,这里是`["a", "b"]`,表示后续使用这个模板时需要传入`a`和`b`两个变量的值。
- `template`参数定义了具体的提示内容。在这个例子中,提示内容为"请计算{a}和{b}的和,使用AddNumbers工具"。这个模板会根据传入的`a`和`b`的值生成具体的提示文本,引导大模型调用`AddNumbers`工具进行计算。
5. **LLMChain创建与运行**:
- 使用`LLMChain`类从`langchain.chains`模块中创建一个链对象`chain`。这个链将语言模型`llm`、提示模板`prompt`和工具列表`[add_tool]`组合在一起。LLMChain负责管理整个流程,包括根据输入生成提示、调用合适的工具(如果需要)以及处理工具的返回结果。
- 假设用户输入两个数字`a = 3`和`b = 5`,通过`chain.run({"a": a, "b": b})`运行LLMChain。这里将`a`和`b`的值以字典的形式传入`run`方法,LLMChain会根据提示模板生成包含这两个值的提示文本,然后大模型会根据提示识别出需要调用`AddNumbers`工具,并将`a`和`b`的值作为参数传递给`add_numbers`函数。最后,`chain.run`方法返回工具调用的结果,并打印出来。
### 5.2 自定义实现Function Calling
在没有特定框架支持的情况下,也可以通过自定义代码实现Function Calling功能。以下是一个简化的自定义实现示例,展示如何通过解析用户输入、匹配函数并调用执行:
```python
# 定义一些示例函数
def multiply_numbers(a, b):
return a * b
def concatenate_strings(s1, s2):
return s1 + s2
# 构建函数库,将函数名与函数对象及描述关联起来
function_library = {
"multiply": {
"function": multiply_numbers,
"description": "将两个数字相乘",
"parameters": ["a", "b"]
},
"concatenate": {
"function": concatenate_strings,
"description": "将两个字符串连接起来",
"parameters": ["s1", "s2"]
}
}
# 简单的用户输入解析函数,这里仅作示例,实际应用需更复杂处理
def parse_user_input(user_input):
words = user_input.split()
if "相乘" in user_input:
numbers = [float(word) for word in words if word.isdigit()]
if len(numbers) == 2:
return "multiply", {"a": numbers[0], "b": numbers[1]}
elif "连接" in user_input:
strings = [word for word in words if word.isalpha()]
if len(strings) == 2:
return "concatenate", {"s1": strings[0], "s2": strings[1]}
return None, None
# 主程序,处理用户输入并调用相应函数
while True:
user_input = input("请输入指令(例如:3和5相乘 或 你 好连接):")
if user_input.lower() == "exit":
break
function_name, parameters = parse_user_input(user_input)
if function_name in function_library:
func_info = function_library[function_name]
func = func_info["function"]
try:
result = func(**parameters)
print(f"结果是: {result}")
except Exception as e:
print(f"调用函数时出错: {e}")
else:
print("未识别的指令或无法匹配到合适的函数")
在这段代码中:
-
示例函数定义:
- 定义了两个简单的示例函数
multiply_numbers
和concatenate_strings
。multiply_numbers
函数接受两个数字参数并返回它们的乘积,concatenate_strings
函数接受两个字符串参数并返回连接后的字符串。这些函数代表了可以被调用的外部功能。
- 定义了两个简单的示例函数
-
函数库构建:
- 创建一个
function_library
字典来模拟函数库。每个函数在字典中以键值对的形式存在,键是函数名(如 "multiply" 和 "concatenate"),值是另一个字典,包含函数对象、函数描述以及所需参数列表。这种结构使得在后续匹配和调用函数时能够方便地获取相关信息。
- 创建一个
-
用户输入解析函数:
parse_user_input
函数负责解析用户输入。它首先将用户输入按空格拆分成单词列表words
。然后根据输入中是否包含特定关键词(如 "相乘" 或 "连接")来判断用户意图。如果是 "相乘",则从单词列表中提取出所有数字并转换为浮点数,检查是否有两个数字,如果满足条件,则返回函数名 "multiply" 以及包含两个数字参数的字典。对于 "连接" 操作同理,提取出两个字符串并返回相应的函数名和参数字典。如果无法识别用户输入或参数不完整,则返回None, None
。
-
主程序逻辑:
- 使用一个无限循环来持续接收用户输入。用户输入指令后,如果输入为 "exit",则退出循环结束程序。
- 调用
parse_user_input
函数解析用户输入,得到函数名function_name
和参数字典parameters
。 - 检查
function_name
是否在function_library
中。如果存在,获取对应的函数信息func_info
,从中提取函数对象func
。然后使用**parameters
语法将参数字典解包后传递给函数进行调用,并打印出函数返回的结果。如果在调用过程中发生异常,则捕获异常并打印错误信息。如果function_name
不在函数库中,则打印未识别指令或无法匹配函数的提示。
5.2 与大模型集成的源码解析
以与 OpenAI 的 GPT 模型集成实现 Function Calling 为例,OpenAI 的 API 提供了支持 Function Calling 的接口。以下是一个使用 Python 和 OpenAI API 进行 Function Calling 的示例代码(需提前安装openai
库并设置好 API 密钥):
python
python
import openai
import os
# 设置OpenAI API密钥
openai.api_key = os.getenv("OPENAI_API_KEY")
# 定义一个示例函数,用于获取当前时间(这里简单模拟,实际可能调用系统时间函数)
def get_current_time():
import datetime
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 构建函数描述,用于向GPT模型说明函数功能和参数
functions = [
{
"name": "get_current_time",
"description": "获取当前的日期和时间",
"parameters": {}
}
]
# 与GPT模型交互并调用函数的函数
def call_function_with_gpt(prompt):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=[
{"role": "user", "content": prompt}
],
functions=functions,
function_call="auto"
)
response_message = response["choices"][0]["message"]
if response_message.get("function_call"):
function_name = response_message["function_call"]["name"]
if function_name == "get_current_time":
result = get_current_time()
second_response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=[
{"role": "user", "content": prompt},
response_message,
{
"role": "function",
"name": function_name,
"content": result
}
]
)
return second_response["choices"][0]["message"]["content"]
return response_message["content"]
# 假设用户输入
user_prompt = "现在是什么时间?"
result = call_function_with_gpt(user_prompt)
print(f"回答用户: {result}")
在这段代码中:
-
API 密钥设置:
- 使用
os.getenv("OPENAI_API_KEY")
从环境变量中获取 OpenAI API 密钥,并设置到openai.api_key
中。这是使用 OpenAI API 的必要步骤,确保代码能够合法访问 OpenAI 的服务。
- 使用
-
示例函数定义:
- 定义了一个
get_current_time
函数,用于获取当前的日期和时间。这里使用datetime
模块实现,实际应用中可能涉及更复杂的时间获取逻辑或调用系统相关函数。这个函数就是我们希望通过 GPT 模型间接调用的外部功能。
- 定义了一个
-
函数描述构建:
- 创建一个
functions
列表,其中每个元素是一个字典,描述了一个可调用的函数。在这个例子中,只有一个函数get_current_time
。字典中包含函数名name
、函数描述description
以及参数定义parameters
。由于get_current_time
函数不需要参数,所以parameters
为空字典。这个functions
列表将传递给 OpenAI 的 API,让 GPT 模型知道有哪些函数可供调用以及它们的功能和参数要求。
- 创建一个
-
与 GPT 模型交互并调用函数的函数:
call_function_with_gpt
函数负责与 GPT 模型进行交互并处理函数调用。- 首先,使用
openai.ChatCompletion.create
方法向 GPT 模型发送请求。model
参数指定使用的 GPT 模型版本为 "gpt-3.5-turbo-0613",该版本支持 Function Calling 功能。messages
参数是一个列表,包含了对话历史,这里只有一个用户消息,即用户输入的提示prompt
。functions
参数传入前面定义的函数描述列表,告诉模型有哪些函数可以调用。function_call
参数设置为 "auto",表示让模型自动决定是否调用函数以及调用哪个函数。 - 获取模型的响应
response
,并从中提取出response_message
。检查response_message
中是否包含function_call
字段,如果包含,则说明模型决定调用函数。提取出函数名function_name
,如果函数名是 "get_current_time",则调用本地的get_current_time
函数获取结果result
。 - 然后,再次使用
openai.ChatCompletion.create
方法向模型发送请求。这次messages
列表中除了原始用户消息和模型的函数调用消息外,还添加了一个函数响应消息,该消息包含函数名和函数执行结果。模型根据这些信息生成最终的回复,并返回给用户。
-
主程序调用:
- 假设用户输入为 "现在是什么时间?",将其作为
user_prompt
传递给call_function_with_gpt
函数。函数执行完成后,返回的结果将打印输出,作为对用户问题的回答。通过这种方式,实现了用户输入经由 GPT 模型引导,调用本地函数获取结果并返回给用户的完整 Function Calling 流程。
- 假设用户输入为 "现在是什么时间?",将其作为