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






一、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 平台 , 可以在本地局域网内部部署 ;

提供了 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 描述字段 :

  • "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')])
  • ChatCompletionMessage消息的主要对象 , 用于描述聊天模型生成的一条完成消息 ;
  • content=''消息的内容 , 空的 , 这是由于 GPT 大模型判断出 需要 进行函数调用 , 本次返回信息专门返回函数调用的一系列参数 ;
  • role='assistant' 表示 消息的角色 , 消息是由 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')]
  • id='call_LTy6rJlBVFLxAW3OAx3dIJSl' : 是 工具调用的唯一标识符 , 可能用于跟踪和识别特定的调用。
  • function=Function(arguments='{"numbers":[1,2,3,4,5]}', name='sum') 参数描述了一个 函数调用 ;
    • arguments='{"numbers":[1,2,3,4,5]}' 表示 函数调用的参数 ;
    • name='sum' 表示 调用的函数名是 sum ;
  • type='function' 表示 这个工具调用是一个函数类型的调用;

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' 相对应 ;
  • "name": "sum" 设置函数的名称 , 这里是 sum 函数调用结果 ;
  • "content": str(result)函数调用的结果 , 转为字符串 ;

5、第二次大模型调用


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

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





五、函数调用代码示例



代码示例 :

import json

from openai import OpenAI

client = OpenAI(
    api_key="sk-6o3KJuuocEXpb1Ug39D0A4913a844fCaBa892eDe9814Df8a",
    base_url="https://api.xiaoai.plus/v1",
)

def get_completion(messages, model="gpt-3.5-turbo-1106"):
    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')]
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')])

sum 函数调用 返回结果 : 
15

第二次将 提示词 函数定义 和 函数调用结果 传给 GPT 大模型 的 回复 : 
1 + 2 + 3 + 4 + 5 = 15.

Process finished with exit code 0

在这里插入图片描述

评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值