AI系列:大语言模型的function calling(上)

目录

  • 大语言模型(LLM) 的function calling
  • 实验:OpenAI之function calling
    • 序列图:function calling如何工作
    • 详情: 对话内容
    • 参考代码
  • 后续: 使用LangChain实现function calling
  • 参考

大语言模型(LLM) 的function calling

大语言模型(LLM)可以使用自然语言与人类对话。但在使用它完成某项复杂工作时,很多时候必须依赖其他外部工具,这包括但不限于:

  • 训练的知识库和提示词以外的知识。包括某些垂直细分领域以及非公开的数据。
  • 计算任务。相信我,即使它给出的结果看起来很像样,你也不能相信它在计算方面的能力;它无法保证100%的准确性。
  • 实时数据。需要外部工具提供。

能识别需要使用的外部工具,能根据其结果数据完成对话的功能叫做function calling。

实验:OpenAI之function calling

OpenAI的GPT作为LLM的代表作,我们将给它提出如下问题:

问题:一共有3个人,每个人有15个苹果,10个鸭梨,一共有多少苹果?
注: 这个简单的逻辑和算数题只作为实验用途;实际应用中可以扩展到复杂的计算。

我们将给GPT提供两个function/tool。一个是乘法,一个是加法。
注: 其中加法用来迷惑GPT。

我们期待的结果:GPT能判断使用乘法及其参数,并使用乘法function calling给出的结果数据,最终返回正确答案:
三个人一共有45个苹果。

序列图:function calling如何工作

我们的代码和GPT将怎样完成这个过程呢?这里将整个过程描绘在下面的时序图中:

代码 大模型LLM 1. 调用对话接口,告诉LLM提示词+可使用的functions/tools定义 2. 需要调用的functions/tools及调用参数 3. 将步骤2中LLM的回复加入对话 4. 循环执行function calling,并将结果加入对话 5. 调用对话接口,需要以上所有对话信息 6. 最终回答 alt [分支:需要function calling] [分支:不需要function calling] 代码 大模型LLM

详情: 对话内容

以下内容是真实的对话历史,程序和GPT配合按照我们的预想完成了整个过程,并最终给出了正确答案。
注:以下用到的UserMessage, AIMessage, FunctionMessage都是LangChain中的概念;它比较贴切的抽象了不同role的对话项。


步骤1中的对话项:HumanMessage | 向GPT输入对话提示词。

#提示词
{
    "role": "user",
    "content": "一共有3个人,每个人有15个苹果,10个鸭梨,一共有多少苹果?"
}

另外,在调用GPT接口时,定义了2个function type tools:乘法multiply和加法add。内容参见下一部分的代码部分。


步骤2中的对话项:AIMessage | GPT返回需要调用的functions/tools及其调用参数。

#这里GPT没有给出最终答案,它识别出了需要调用乘法multiply,参数一first_int为3个人,参数二second_int为15个苹果/每人。
{
    "content": null,
    "role": "assistant",
    "function_call": null,
    "tool_calls": [
        {
            "id": "call_ZMbo4SiA2iaZUSLJMyX8ZzkP",
            "function": {
                "arguments": "{\"first_int\":3,\"second_int\":15}",
                "name": "multiply"
            },
            "type": "function"
        }
    ]
}

步骤4中的对话项:FunctionMessage |function calling的调用结果数据。
tool_call_id对应步骤2中的tool_calls元素中的id。content为程序调用function/tool后的结果数据。

#将function calling的结果为3*15=45,设定role为tool,将其加入对话中。
{
    "tool_call_id": "call_ZMbo4SiA2iaZUSLJMyX8ZzkP",
    "role": "tool",
    "name": "multiply",
    "content": "45"
}

步骤6中的对话项:AIMessage | 程序将以上所有对话项发送给GPT,GPT用自然语言返回最终结论。

#最终结果为:三个人一共有45个苹果。
{
    "content": "三个人一共有45个苹果。",
    "role": "assistant",
    "function_call": null,
    "tool_calls": null
}

参考代码

function calling的实现代码如下:

__author__ = 'liyane'

import json

# 初始化环境和OpenAI
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client = OpenAI()

#调用GPT大模型
def get_completion(messages, tools, model="gpt-3.5-turbo"):
    response = client.chat.completions.create(
        model=model,
        messages=messages,
        # tool_choice支持设置 "auto"(由模型决定是否调用tool) 或者 "none" (不调用tool)作为value。 有tools定义时默认由模型决定。
        # 也可以强制要求必须调用指定的函数,如下所示
        # tool_choice= {"type": "function", "function": {"name": "multiply"}} ,  
        tools=tools
    )
    return response.choices[0].message

#定义function/tool 1: multiply
def multiply(first_int: int, second_int: int) -> int:
    """两个整数相乘"""
    return first_int * second_int

#定义function/tool 2: add
def add(first_add: int, second_add: int) -> int:
    """两个整数相加"""
    return first_add + second_add

#将function calling的schema格式告诉大模型
tools=[{
    "type": "function",
    "function": {
        "name": "multiply",
        "description": "两个整数相乘",
        "parameters": {
            "type": "object",
            "properties": {
                "first_int": {
                    "type": "integer",
                    "description": "第一个乘数",
                },
                "second_int": {
                    "type": "integer",
                    "description": "第二个乘数",
                }
            },
            "required": ["first_int", "second_int"],
        }
    }
    },
    {
    "type": "function",
    "function": {
        "name": "add",
        "description": "两个整数相加",
        "parameters": {
            "type": "object",
            "properties": {
                "first_add": {
                    "type": "integer",
                    "description": "第一个加数",
                },
                "second_add": {
                    "type": "integer",
                    "description": "第二个加数",
                }
            },
            "required": ["first_add", "second_add"],
        }
    }
}]

# 调用LLM接口,将LLM回复加入对话上下文
prompt = "一共有3个人,每个人有15个苹果,10个鸭梨,一共有多少苹果?"
messages = [
    {"role": "user", "content": prompt}
]
response = get_completion(messages, tools)
messages.append(response)  

# 如果LLM需要function calling,调用相应的函数,并将函数结果数据加入对话上下文,继续调用LLM。
while (response.tool_calls is not None):
    for tool_call in response.tool_calls:
        selected_tool = {"add": add, "multiply": multiply}[tool_call.function.name]
        args = json.loads(tool_call.function.arguments)
        tool_output = selected_tool(**args)

        messages.append({
            "tool_call_id": tool_call.id,  # 用于标识函数调用的 ID
            "role": "tool",
            "name": tool_call.function.name,
            "content": str(tool_output)  # 数值result 必须转成字符串
        })

    response = get_completion(messages, tools)
    messages.append(response)  

print("=====最终回复=====")
print(response.content)


后续: 使用LangChain实现function calling

后续更新AI系列:大语言模型的function calling(下)- 使用LangChain:如何使用LangChain实现function calling,LangChain对比原生调用能提供哪些便利。

参考

OpenAI / function calling
LangChain / Tool/function calling

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/555933.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PTA L1-009 N个数求和 【C++】【辗转相除法】【Python】

C: 辗转相除法: 每次算最小公倍数和最大公约数都是用的常规思路,本身是不会有错的,但是当数据很大时,就会出现错误,时间复杂度过高 辗转相除法,又称欧几里德算法(Euclidean Algori…

接口压力测试 jmeter--增强篇(二)

前期准备 1. JMeter的插件的安装 下载Jmeter Plugins Manager对插件进行管理 (1)下载地址:https://jmeter-plugins.org/install/Install/ (2)下载后,将jar包放到jmeter包目录下/lib/ext目录下 &#xff0…

【YOLOv8改进[检测头Head]】YOLOv8的“新头”之动态头(DynamicHead)

目录 一 DynamicHead 二 YOLOv8的“新头”之动态头 1 总体修改 2 配置文件 3 训练 其他 一 DynamicHead 官方论文地址:https://arxiv.org/pdf/2106.08322.pdf 官方代码地址:GitCode - 开发者的代码家园 在计算机视觉应用中,目标检测…

启动appium服务的2种方法(python脚本cmd窗口)

1.通过cmd窗口命令来启动 2.通过python代码启动 2.1启动单个appium服务 2.2启动多个appium服务 3.端口说明 一.端口号设置Appium服务器端口:4723 bp端口:4724 Appium服务器端口:4725 bp端口:4726可以看到appium服务器端口和bp端…

SpringBoot(一)【入门】

前言 1、SpringBoot 快速入门 1.1、SpringBoot 简介 SpringBoot 是用来简化 Spring 应用的初始搭建以及开发过程 首先我们回顾一下 SpringMVC 项目的开发过程: 导入依赖(javax.servlet-api 和 spring-webmvc)Servlet 容器配置类&#xff…

VirtualBox虚拟机使用win11系统,忘记密码如何重置密码

1. 点击重启同时按住Shift(按住不放) 2. 直到出现下面的界面,释放Shift,并进入疑难解答 3. 进入高级选项 4. 进入命令提示符 5. 发现当前是在X盘? 6. 进入C:\Windows\System32 c: cd Windows\System32 7. 备份osk.exe…

SpringCloud系列(5)--SpringCloud微服务工程公共部分提取

前言:在上一章节中我们创建了两个个SpringCloud工程,但在两个工程中分别存在着一些重复的部分,例如重复的实体类(如图所示),这样会造成系统的冗余,所以我们需要把公共的类提取到一个工程里&…

预约小程序新选择:强大后端管理功能一览

拥有一个功能齐全、操作便捷的小程序对于商家来说至关重要。为了满足广大商家的需求,乔拓云平台提供了丰富的模板资源,帮助用户快速搭建预约型小程序,并配备了强大的后端管理功能,让商家能够轻松管理预约订单,提升运营…

Centos7 ElasticSearch集群搭建

1. 服务器环境配置 1.1 配置hosts文件 3台服务器都要执行 vim /etc/hosts; # 将以下内容写入3台服务器hosts文件 192.168.226.148 es001 192.168.226.149 es002 192.168.226.150 es003 1.2 关闭防火墙 3台服务器都要执行 systemctl stop firewalld; systemctl disable…

【opencv】dnn示例-speech_recognition.cpp 使用DNN模块结合音频信号处理技术实现的英文语音识别...

模型下载地址: https://drive.google.com/drive/folders/1wLtxyao4ItAg8tt4Sb63zt6qXzhcQoR6 终端输出:(audio6.mp3 、audio10.mp3) [ERROR:00.002] global cap_ffmpeg_impl.hpp:1112 open VIDEOIO/FFMPEG: unsupported parameter…

# 从浅入深 学习 SpringCloud 微服务架构(一)基础知识

从浅入深 学习 SpringCloud 微服务架构(一)基础知识 1、系统架构演变: 1)单体应用架构。如电商项目。 用户管理、商品管理、订单管理,在一个模块里。 优点:开发简单,快速,适用于…

Mac下brew安装php7.4

这里作者挂了梯子,所以很流畅! brew的下载,可参考另外一篇博文~Homebrew 安装与卸载 1、将第三方仓库加入brew brew tap shivammathur/php2、安装指定版本的PHP brew install php7.43、替换Mac自带PHP环境并刷新环境变量 -> …

基于simulink的模拟锁相环和数字锁相环建模与对比仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 模拟锁相环(PLL)的基本原理 4.2 数字锁相环(DPLL)的基本原理 5.完整工程文件 1.课题概述 模拟锁相环和数字锁相环建模的simulink建模,对…

OpenHarmony UI动画-recyclerview_animators

简介 带有添加删除动画效果以及整体动画效果的list组件库 下载安装 ohpm install ohos/recyclerview-animatorsOpenHarmony ohpm 环境配置等更多内容,请参考如何安装OpenHarmony ohpm 包 使用说明 引入组件库 import { RecyclerView } from "ohos/recycler…

Qt/C++音视频开发70-无感切换通道/无缝切换播放视频/多通道流畅切换/不同视频打开无缝切换

一、前言 之前就写过这个方案,当时做的是ffmpeg内核版本,由于ffmpeg内核解析都是代码实现,所以无缝切换非常完美,看不到丝毫的中间切换过程,看起来就像是在一个通道画面中。其实这种切换只能说是取巧办法,…

排序算法之计数排序

目录 一、简介二、代码实现三、应用场景 一、简介 算法平均时间复杂度最好时间复杂度最坏时间复杂度空间复杂度排序方式稳定性计数排序O(nk )O(nk)O(nk)O(k)Out-place稳定 稳定:如果A原本在B前面,而AB,排序之后A仍然在B的前面; 不…

稀碎从零算法笔记Day52-LeetCode:从双倍数组中还原原数组

题型:数组、贪心 链接:2007. 从双倍数组中还原原数组 - 力扣(LeetCode) 来源:LeetCode 题目描述 一个整数数组 original 可以转变成一个 双倍 数组 changed ,转变方式为将 original 中每个元素 值乘以 …

记录ubuntu20.04安装nvidia-525.85.05显卡驱动(学习笔记2024.4.15、4.16)

电脑:华硕天选X2024 显卡:4060Ti i5-14400F 架构:x86_64 我需要使用Linux系统使用IsaacSim进行仿真,所以安装的都是IsaacSim中的推荐版本。 一.对新鲜的电脑进行分盘 电脑刚到手,900多个G全在C盘里,给它…

学习笔记(4月18日)vector底层模拟实现(1)

1.迭代器 vector实际上是由迭代器进行维护的,关于迭代器是什么,为什么要叫这个名字,后面的学习会逐渐了解,现在先将迭代器是作为指针即可。 vector底层有三个迭代器,用来起到容量、数组头、元素个数的作用。 同时为…

数字零售力航母-看微软如何重塑媒体

数字零售力航母-看微软如何重塑媒体 - 从2024全美广播协会展会看微软如何整合营销媒体AI技术和AI平台公司 2024年,微软公司联合英伟达总司,赞助全美广播协会展会。本次展会微软通过搭建一个由全面的合作伙伴生态系统支持的可信和安全的平台,…
最新文章