【AI 大模型】函数调用 Function Calling ② ( Plugins、Actions 扩展 | 函数调用 Function Calling 引入 | 函数调用开发流程 | 代码示例 )

CSDN 2024-07-22 15:31:03 阅读 69

文章目录

一、Plugins、Actions 扩展1、GPT 大模型缺陷 - 引入 Plugins、Actions 扩展2、Plugins 插件3、Plugins 插件开发流程4、Plugins 插件弊端 - Actions 引入5、Actions 简介

二、ChatGPT 的平替 - Coze、Dify三、函数调用 Function Calling 引入四、函数调用开发流程1、调用 OpenAI 的接口2、函数定义3、大模型回调4、本地代码逻辑5、第二次大模型调用

五、函数调用代码示例

一、Plugins、Actions 扩展


1、GPT 大模型缺陷 - 引入 Plugins、Actions 扩展

GPT 大模型 有如下三种缺陷 :

非全知全能 : 用于训练的都是 公开知识文本 , GPT 不知道 内部 或 保密 知识信息 ;时效性差 : 大模型训练需要 半年 以上的时间 , 使用的都是半年以前的知识 ;没有真逻辑 : 基于概率生成文本 , 无法处理复杂的逻辑问题 ;

为了解决上述三种缺陷 , OpenAI 在 GPT 大模型中引入了 Plugins 和 Actions 两种 扩展机制 , 用于增强模型的功能 , 使 GPT 大模型 能够处理 更复杂 和 特定的 任务 ;

2、Plugins 插件

ChatGPT 的 Plugins 插件 可 用于扩展 ChatGPT 功能 , 允许 大模型 与 外部系统 进行交互 ; 可实现如下功能 :

连接 数据库 : 访问公司数据库 , 获取数据 , 检索内部知识库或个人笔记 ;调用 外部 API : 实现 预订航班 , 订票 等功能 ;调用 其他软件服务 : 获取 股票价格 , 天气预报 , 最新新闻 等实时信息 ;

ChatGPT 的 Plugins 插件 功能 仅对 付费会员开放 , 只支持 GPT4 以上的模型 在 设置中 开启插件功能 , 之后才能在 聊天过程中 使用 Plugins 插件 ;

3、Plugins 插件开发流程

ChatGPT 的 插件 开发 流程如下 :

开发环境搭建 : 申请 OpenAI 的开发者账号 , 获取 API 访问权限 , 配置 Python 或者 Node.js 开发环境 ;开发插件 : 定义 插件的 功能和接口 , 编写代码实现相应的插件逻辑 , 并在本地测试环境运行插件确保能返回正确结果 ;发布插件 : 将开发好的插件代码提交的 OpenAI 后台 , 按照流程发布审核 , 通过审核后用户即可在 ChatGPT 控制面板中 搜索、安装、使用 该插件 ;

4、Plugins 插件弊端 - Actions 引入

Plugins 插件 在 产品设计 层面 不完善 , 使用 Plugins 插件 需要靠用户 手工选择使用 哪三个 Plugin 插件 , 并不能 自动识别 并 自动调用 对应的插件 , 因此 Plugins 插件 功能 在 ChatGPT 中没有推广开 ;

基于上述问题 , OpenAI 将 Plugins 升级为了 Actions , 内置到了 GPTs 大模型中 , 解决了上述问题 ;

5、Actions 简介

Actions 是 ChatGPT 内置的一种特定扩展功能 , 通常是为了执行简单、快速的任务 ;

Actions 由 ChatGPT 平台的开发团队开发 , 外部开发者无法开发 Actions , Actions 开发完成后由 ChatGPT 平台直接支持 , 不需要额外安装 , 可以保证执行效率 和 安全性 ;

与 Actions 对比 , Plugins 需要额外安装 , 并且只能选 3 个 ;

二、ChatGPT 的平替 - Coze、Dify


ChatGPT 经常封号 , 账号申请很麻烦 , 注册各种给添堵 , 即使是付费用户也会被封 , 这里推荐两个平替 ;

字节跳动 coze : https://www.coze.com/ , 可以直接使用 +86 的中国手机号注册使用 , 这个需要挂上梯子才能用 , 对中国用户比较友好 ;

免费 ;

只提供了 Web 界面访问 , 不提供 API 访问 ;

在这里插入图片描述

Dify : https://dify.ai/zh , 这是开源的生成式 AI 平台 , 可以在本地局域网内部部署 ;

GitHub : https://github.com/langgenius/dify

提供了 Web 界面访问 和 API 访问 两种方式 ;

在这里插入图片描述

在这里插入图片描述

收费的 , 费用不便宜 ;

在这里插入图片描述

三、函数调用 Function Calling 引入


ChatGPT 引入 Plugins、Actions 扩展 , 这些都是针对通用需求开发的 , 并不能针对某个公司的某项需求进行功能的适配 , 开发 , 调优 , 集成到公司的某项业务中 , 也不是很方便 ;

因此 OpenAI 提供了 函数调用 Function Calling 技术 , 用户可以将 自己的业务系统 与 ChatGPT 大模型进行关联使用 ;

函数调用 Function Calling 官方文档 : https://platform.openai.com/docs/guides/function-calling

在这里插入图片描述

函数调用 流程 :

① 开发者 开发的 应用程序 通过 API 调用 OpenAI ,

② 开发者 需要将

Prompt 提示词Function 函数定义

传给 OpenAI 大模型 ;

③ OpenAI GPT 大模型 分析 提示词 , 然后分析出 " 函数参数 " , 将 函数调用的参数 返回给 应用软件 ;

④ 在 应用软件 中 调用函数 , 传入 大模型返回的 参数 ;

⑤ 应用软件 调用 函数 得到 结果 , 将结果传递给 GPT 大模型 ;

⑥ GPT 大模型 结合 提示词 和 应用软件 函数调用结果 , 使用 自然语言 返回最终生成结果 ;

在这里插入图片描述

四、函数调用开发流程


1、调用 OpenAI 的接口

① 开发者 开发的 应用程序 通过 API 调用 OpenAI ; 在应用软件中 , 正常调用 OpenAI 软件包的函数 API 即可 ;

2、函数定义

② 开发者 需要将

Prompt 提示词Function 函数定义

传给 OpenAI 大模型 ;

提示词 就是 普通的文本 , 这里着重分析下 函数定义 ;

函数定义 , 需要在 client.chat.completions.create 函数中的 tools 参数中传入 , 此处可以传入多个 json 格式的函数定义 ;

下面开始分析 函数调用 中 函数定义 的 json 描述字段 :

<code>"type": "function" 表示这是一个 函数描述 ;description: "加法函数,可用于计算若干个数字之和" 这是 对 函数功能 的描述 ;parameters 字段描述 函数的参数信息 ;

type: "object" 表示 函数参数是对象 ;properties 字段 描述对象的属性 ;

numbers 表示 一个数组 , 包含了数字类型的元素 , 表示函数接受一个数字数组作为参数 ;

response = client.chat.completions.create(

model=model,

messages=messages,

temperature=0.5,

# 使用 json 描述 函数调用 的 函数信息 , 包括 函数名 函数描述 函数参数信息 等

# 可以定义多个 函数调用 , 具体调用哪个函数 , 由大模型决定

# 大模型根据 函数的描述信息 , 决定调用哪个函数

tools=[{

"type": "function",

"function": {

"name": "sum",

"description": "加法函数,可用于计算若干个数字之和",

"parameters": {

"type": "object",

"properties": {

"numbers": {

"type": "array",

"items": {

"type": "number"

}

}

}

}

}

}],

)

3、大模型回调

③ OpenAI GPT 大模型 分析 提示词 , 然后 分析出 " 函数参数 " , 将 函数调用的参数 返回给 应用软件 ;

大模型 收到 提示词 和 函数描述后 , 跟自动判定是否需要 调用 本地提供的 函数调用 ,

如果需要 , 则大模型会返回如下信息 ,

ChatCompletionMessage(content='', role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_LTy6rJlBVFLxAW3OAx3dIJSl', function=Function(arguments='{"numbers":[1,2,3,4,5]}', name='sum'), type='function')])code>

ChatCompletionMessage 是消息的主要对象 , 用于描述聊天模型生成的一条完成消息 ;content=''code> 是 消息的内容 , 空的 , 这是由于 GPT 大模型判断出 需要 进行函数调用 , 本次返回信息专门返回函数调用的一系列参数 ;role='assistant'code> 表示 消息的角色 , 消息是由 assistant 生成的 ;function_call=None 描述一个 函数调用的对象 , 但在这个例子中是空的 ;tool_calls :工具调用 , 此处放的是 函数调用的 参数信息 ;

ChatCompletionMessageToolCall 是 工具调用的描述对象 , 包含了多个工具调用信息 ;

核心就是

tool_calls=[ChatCompletionMessageToolCall(id='call_LTy6rJlBVFLxAW3OAx3dIJSl', function=Function(arguments='{"numbers":[1,2,3,4,5]}', name='sum'), type='function')]code>

id='call_LTy6rJlBVFLxAW3OAx3dIJSl'code> : 是 工具调用的唯一标识符 , 可能用于跟踪和识别特定的调用。function=Function(arguments='{"numbers":[1,2,3,4,5]}', name='sum')code> 参数描述了一个 函数调用 ;

arguments='{"numbers":[1,2,3,4,5]}'code> 表示 函数调用的参数 ;name='sum'code> 表示 调用的函数名是 sum ; type='function'code> 表示 这个工具调用是一个函数类型的调用;

4、本地代码逻辑

④ 在 应用软件 中 调用函数 , 传入 大模型返回的 参数 ;

如果发现 GPT 大模型返回的 tool_calls 字段 , 就说明需要进行函数调用 , 收到对应的 函数调用 请求后 , 开始进行逻辑计算 ;

将计算结果 封装到 json 中 , 如下代码所示 :

# 将本地的 函数调用结果 封装为指定格式的 json 串

messages.append(

{

"tool_call_id": tool_call.id, # 用于标识函数调用的 ID

"role": "tool",

"name": "sum",

"content": str(result) # 数值result 必须转成字符串

}

)

"tool_call_id": tool_call.id 用于标识函数调用的 ID , 在前面的 函数调用 参数 json 中可以找到 , 是 call_LTy6rJlBVFLxAW3OAx3dIJSl 值 ;"role": "tool" 指示 条目的角色是工具 tool , 与前面提到的 role='assistant'code> 相对应 ;"name": "sum" 设置函数的名称 , 这里是 sum 函数调用结果 ;"content": str(result) 是 函数调用的结果 , 转为字符串 ;

5、第二次大模型调用

⑤ 应用软件 调用 函数 得到 结果 , 将结果传递给 GPT 大模型 ;

⑥ GPT 大模型 结合 提示词 和 应用软件 函数调用结果 , 使用 自然语言 返回最终生成结果 ;

五、函数调用代码示例


代码示例 :

import json

from openai import OpenAI

client = OpenAI(

api_key="sk-6o3KJuuocEXpb1Ug39D0A4913a844fCaBa892eDe9814Df8a",code>

base_url="https://api.xiaoai.plus/v1",code>

)

def get_completion(messages, model="gpt-3.5-turbo-1106"):code>

response = client.chat.completions.create(

model=model,

messages=messages,

temperature=0.5,

# 使用 json 描述 函数调用 的 函数信息 , 包括 函数名 函数描述 函数参数信息 等

# 可以定义多个 函数调用 , 具体调用哪个函数 , 由大模型决定

# 大模型根据 函数的描述信息 , 决定调用哪个函数

tools=[{

"type": "function",

"function": {

"name": "sum",

"description": "加法函数,可用于计算若干个数字之和",

"parameters": {

"type": "object",

"properties": {

"numbers": {

"type": "array",

"items": {

"type": "number"

}

}

}

}

}

}],

)

return response.choices[0].message

# 提示词

prompt = "计算 1+2+3+4+5 的结果"

# 将提示词封装到 message 中

messages = [

{ "role": "system", "content": "计算数学式子"},

{ "role": "user", "content": prompt}

]

# 第一次调用 : 将 提示词 和 函数定义 传给 GPT 大模型

response = get_completion(messages)

# 解决 OpenAI 400 bug

if (response.content is None):

response.content = ""

# 把大模型的回复加入到对话历史中

messages.append(response)

print("第一次 将 提示词 和 函数定义 传给 GPT 大模型 的 回复 :")

print(response)

# 拿到第一次回复后 , 查看是否需要执行 函数调用

# 如果 tool_calls 不为空 , 则需要进行函数调用

# 下面就是 tool_calls 字段

# tool_calls=[ChatCompletionMessageToolCall(id='call_Qr0uXYu6C6CZ2JhTWWnPNVl9', function=Function(arguments='{"numbers":[1,2,3,4,5,6,7,8,9,10]}', name='sum'), type='function')]code>

if (response.tool_calls is not None):

# 是否要调用 sum

tool_call = response.tool_calls[0]

# 判定 大模型 要调用的函数的 函数名称 , 就是 name 字段

# 根据不同的函数名称 , 执行不同的代码逻辑

if (tool_call.function.name == "sum"):

# 获取函数的一系列参数

args = json.loads(tool_call.function.arguments)

# 调用 Python 内置函数 , 进行加法运算

result = sum(args["numbers"])

print("\nsum 函数调用 返回结果 : ")

print(result)

# 将本地的 函数调用结果 封装为指定格式的 json 串

messages.append(

{

"tool_call_id": tool_call.id, # 用于标识函数调用的 ID

"role": "tool",

"name": "sum",

"content": str(result) # 数值result 必须转成字符串

}

)

# 再次调用大模型

print("\n第二次将 提示词 函数定义 和 函数调用结果 传给 GPT 大模型 的 回复 : ")

print(get_completion(messages).content)

执行结果 :

Y:\002_WorkSpace\PycharmProjects\pythonProject\venv\Scripts\python.exe Y:/002_WorkSpace/PycharmProjects/HelloPython/FunctionCalling.py

第一次 将 提示词 和 函数定义 传给 GPT 大模型 的 回复 :

ChatCompletionMessage(content='', role='assistant', function_call=None, tool_calls=[ChatCompletionMessageToolCall(id='call_LTy6rJlBVFLxAW3OAx3dIJSl', function=Function(arguments='{"numbers":[1,2,3,4,5]}', name='sum'), type='function')])code>

sum 函数调用 返回结果 :

15

第二次将 提示词 函数定义 和 函数调用结果 传给 GPT 大模型 的 回复 :

1 + 2 + 3 + 4 + 5 = 15.

Process finished with exit code 0

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。