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将怎样完成这个过程呢?这里将整个过程描绘在下面的时序图中:
详情: 对话内容
以下内容是真实的对话历史,程序和GPT配合按照我们的预想完成了整个过程,并最终给出了正确答案。
注:以下用到的UserMessage, AIMessage, FunctionMessage都是LangChain中的概念;它比较贴切的抽象了不同role的对话项。
步骤1中的对话项:UserMessage | 向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的实现代码如下:
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的格式告诉大模型
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"],}}
}]# 调用大模型
prompt = "一共有3个人,每个人有15个苹果,10个鸭梨,一共有多少苹果?"
messages = [{"role": "user", "content": prompt}
]
response = get_completion(messages, tools)# 把大模型的回复加入到对话中
messages.append(response) # 处理大模型需要function calling的情况
while (response.tool_calls is not None):# 循环进行function calling,将结果加入到对话中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
后续将更新:如何使用LangChain实现function calling,LangChain对比原生调用能提供哪些便利,以及其中可能出现的坑。
参考
OpenAI / function calling
LangChain / Tool/function calling
相关文章:
AI系列:大语言模型的function calling
目录 大语言模型(LLM) 的function calling实验:OpenAI之function calling序列图:function calling如何工作详情: 对话内容参考代码 后续: 使用LangChain实现function calling参考 大语言模型(LLM) 的function calling 大语言模型(LLM)可以使用自然语言与…...
conda 创建、激活、退出、删除虚拟环境
一、conda 本地环境常用操作 #获取版本号 conda --version 或 conda -V #检查更新当前conda conda update conda #查看当前存在哪些虚拟环境 conda env list 或 conda info -e #查看--安装--更新--删除包 conda list: conda search package_name# 查询包 cond…...
【Entity Framework】聊一聊EF中继承关系
【Entity Framework】聊一聊EF中继承关系 文章目录 【Entity Framework】聊一聊EF中继承关系一、概述二、实体类型层次结构映射三、每个层次结构一张表和鉴别器配置四、共享列五、每个类型一张表配置六、每个具体类型一张表配置七、TPC数据库架构八、总结 一、概述 Entity Fra…...
curaengine编译源码之libarcus编译记录
libArcus的编译(成功安装) This library contains C code and Python3 bindings for creating a socket in a thread and using this socket to send and receive messages based on the Protocol Buffers library. It is designed to facilitate the c…...
运用OSI模型提升排错能力
1. OSI模型有什么实际的应用价值? 2. 二层和三层网络的区别和应用; 3. 如何通过OSI模型提升组网排错能力? -- OSI - 开放式系统互联 - 一个互联标准 - 从软件和硬件 定义标准 - 不同厂商的设备 研发的技术 - 具备兼容性 -- O…...
【Node.js】Express学习笔记(黑马)
目录 初识 ExpressExpress 简介Express 的基本使用托管静态资源nodemon Express 路由路由的概念路由的使用 Express 中间件中间件的概念Express 中间件的初体验中间件的分类 初识 Express Express 简介 什么是 Express? 官方给出的概念:Express 是基于…...
Linux系统部署Tale个人博客并发布到公网访问
目录 ⛳️推荐 前言 1. Tale网站搭建 1.1 检查本地环境 1.2 部署Tale个人博客系统 1.3 启动Tale服务 1.4 访问博客地址 2. Linux安装Cpolar内网穿透 3. 创建Tale博客公网地址 4. 使用公网地址访问Tale ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通…...
CentOS7里ifcfg-eth0文件不存在解决方案/Centos7修改网络IP解决方案
Centos7网络IP地址手动设置 1、centos7没有ifcfg-eth0,我的centos7也没有其他博客说的什么ifcfg-ens33、ifcfg-ens32,然后我打开了我这里的ifcfg-eno***,结果发现就是centos6里的ifcfg-eth0里的网络配置。2、vim ifcfg-eno***(按t…...
go第三方库go.uber.org介绍
Uber 是一家美国硅谷的科技公司,也是 Go 语言的早期 adopter。其开源了很多 golang 项目,诸如被 Gopher 圈熟知的 zap、jaeger 等。2018 年年末 Uber 将内部的 Go 风格规范 开源到 GitHub,经过一年的积累和更新,该规范已经初具规模…...
Oracle 正则表达式
一、Oracle 正则表达式相关函数 (1) regexp_like :同 like 功能相似(模糊 匹配) (2) regexp_instr :同 instr 功能相似(返回字符所在 下标) (3) regexp_substr : 同 substr 功能相似&…...
MongoDB聚合运算符:$rand
MongoDB聚合运算符:$rand 文章目录 MongoDB聚合运算符:$rand语法举例生成随机数据点从集合中随机选择条目 $rand聚合运算符用于返回一个0~1之间的随机浮点数。 语法 { $rand: {} }$rand运算符不需要任何参数。每次调用$rand都会返回一个小数点后最多17位…...
如何在Linux通过docker搭建Plik文件系统并实现无公网IP管理内网文件
文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问,实现随时随地在任意设备上传或者…...
k8s部署efk
环境简介: kubernetes: v1.22.2 helm: v3.12.0 elasticsearch: 8.8.0 chart包:19.10.0 fluentd: 1.16.2 chart包: 5.9.4 kibana: 8.2.2 chart包:10.1.9 整体架构图: 一、Elasticsearch安装…...
AI模型大PK
🤖AI模型大PK!免费测试GPT-4等36款顶级聊天机器人 近年来,大型语言模型(LLM)的发展日新月异,各大科技巨头和研究机构纷纷推出了自己的聊天机器人。那么,如何才能知道哪个模型更强大、更智能呢&…...
Matlab|基于广义Benders分解法的综合能源系统优化规划
目录 1 主要内容 广义benders分解法流程图: 优化目标: 约束条件: 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序复现文章《综合能源系统协同运行策略与规划研究》第四章内容基于广义Benders分解法的综合能源系统优化规划&…...
vscode 打代码光标特效
vscode 打代码光标特效 在设置里面找到settings 进入之后在代码最下方加入此代码 "explorer.confirmDelete": false,"powermode.enabled": true, //启动"powermode.presets": "fireworks", // 火花效果// particles、 simple-rift、e…...
【代码随想录算法训练营第四十八天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III】
代码随想录算法训练营第四十八天 | LeetCode198.打家劫舍、213.打家劫舍II、337.打家劫舍III 一、198.打家劫舍 解题代码C: class Solution { public:int rob(vector<int>& nums) {if (nums.size() 0) return 0;if (nums.size() 1) return nums[0];ve…...
蓝桥杯 — —灵能传输
灵能传输 友情链接:灵能传输 题目: 输入样例: 3 3 5 -2 3 4 0 0 0 0 3 1 2 3输出样例: 3 0 3思路: 题目大意:给出一个数组,每次选择数组中的一个数(要求不能是第一个数与最后一个…...
智慧安防系统EasyCVR视频汇聚平台接入大华设备无法语音对讲的原因排查与解决
安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台支持7*24小时实时高清视频监控,能同时播放多路监控视频流,视频画面1、4、9、16个可选,支持自定义视频轮播。EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标…...
基于Pytorch框架的CNN-LSTM模型在CWRU轴承故障诊断的应用
目录 1. 简介 2. 方法 2.1数据集 2.2模型架构 1. 简介 CWRU轴承故障诊断是工业领域一个重要的问题,及早发现轴承故障可以有效地减少设备停机时间和维修成本,提高生产效率和设备可靠性。传统的基于信号处理和特征提取的方法通常需要手工设计特征&…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...
