当前位置: 首页 > news >正文

LLM:函数调用(Function Calling)

1 函数调用

  虽然大模型能解决很多问题,但大模型并不能知晓一切。比如,大模型不知道最新消息(GPT-3.5 的知识截至 2021年9月,GPT-4 是 2023 年12月)。另外,大模型没有“真逻辑”。它表现出的逻辑、推理,是训练文本的统计规律,而不是真正的逻辑,所以有幻觉。所以大模型需要连接真实世界,并对接真逻辑系统。这就需要用到“函数调用”。
  函数调用(Function Calling)可以使LLM具有与外部API交互的能力。让用户能够使用高效的外部工具、与外部API进行交互。其使用机制如下:
在这里插入图片描述
关于function calling,有以下几点需要注意:

  • 在最新版本的OpenAI API中,可以使用tools参数对函数进行描述。并让大模型智能地选择输出包含函数参数的JSON对象来调用一个或多个函数。
  • 最新的GPT模型(gpt-3.5-turbo-0125 and gpt-4-turbo-preview)可以自动检测何时应该调用函数(还有一个相关的参数tool_choice,一般不用自己设置),还可以输出更加符合函数签名的JSON串。
  • GPT不负责调用和执行外部函数,需要用户自己完成。

2 使用GPT进行函数调用

  在使用GPT模型进行函数调用时,需要用到tools参数进行函数声明,关于该参数有以下几点需要说明:

  • 该参数可以接收一系列JSON组成的array,一个函数对应一个JSON,当前最多可以接受128个函数。
  • JSON串的结构如下:
    在这里插入图片描述
    其中parameters参数的写法要遵循JSON Schema格式,具体可以参考:https://blog.csdn.net/yeshang_lady/article/details/137146295

2.1 使用函数调用完成加法计算

  大模型可以做加法是因为大模型记住了简单加法的统计规律,但大模型无法保证每次都能得到正确的加法计算结果。这里我们使用函数调用来完成加法计算。具体代码如下:

from openai import OpenAI
from dotenv import load_dotenv,find_dotenv
import json
from math import *_=load_dotenv(find_dotenv())
client=OpenAI()def get_completion(messages,model="gpt-3.5-turbo"):response=client.chat.completions.create(model=model,messages=messages,temperature=0.7,tools=[{"type":"function","function":{"name":"sum","description":"加法器,计算一组数的和","parameters":{"type":"object","properties":{"numbers":{"type":"array","items":{"type":"number"}}}}}}],)return response.choices[0].messageprompt="计算这些数据的和:345,2313,89,632."
messages=[{"role":"system","content":"你是一个数学家"},{"role":"user","content":prompt}
]
response=get_completion(messages)
print(response)
#GPT模型第一次的回复中有关于函数调用信息,包括GPT生成的函数调用的参数,所以这些信息需要返回给GPT模型。
messages.append(response)
if response.tool_calls is not None:tool_call=response.tool_calls[0]if tool_call.function.name=="sum":args=json.loads(tool_call.function.arguments)result=sum(args["numbers"])messages.append({"tool_call_id":tool_call.id,"role":"tool","name":"sum","content":str(result) })print(get_completion(messages).content)

其结果如下:

ChatCompletionMessage(content=None, role=‘assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=‘call_vYramfrhZX7kLZLYhqDiFVHP’, function=Function(arguments=‘{“numbers”:[345,2313,89,632]}’, name=‘sum’), type=‘function’)])
这些数据的和是3379.

2.2 同时启动多个函数调用

借助上述加法函数的代码,可以一次启动同一个函数的多次调用,具体代码如下:

from openai import OpenAI 
import json
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client=OpenAI()
def run_conversation(prompt,model='gpt-3.5-turbo'):messages=[{"role":"user","content":prompt}]tools=[{ "type": "function","function": {"name": "sum","description": "加法器,计算一组数的和","parameters": {"type": "object","properties": {"numbers": {"type": "array", "items": { "type": "number"}}}}}}]response=client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice="auto",)response_message=response.choices[0].messagemessages.append(response_message)print(response_message)tool_calls=response_message.tool_callsif tool_calls:for tool_call in tool_calls:function_name=tool_call.function.namefunction_args=json.loads(tool_call.function.arguments)function_response=sum(function_args.get("numbers"))messages.append({"tool_call_id":tool_call.id,"role":"tool","name":function_name,"content":str(function_response)})second_response=client.chat.completions.create(model=model,messages=messages,)return second_response.choices[0].message.content
if __name__=="__main__":prompt="小明第一天买了5本书2个苹果,第二天买了3本书4个橘子,第三天买了7个梨和10本书,那么小明总共买了多个水果和多少本书?"print(prompt)print("====GPT回复====")print(run_conversation(prompt))

其执行结果如下:

小明第一天买了5本书2个苹果,第二天买了3本书4个橘子,第三天买了7个梨和10本书,那么小明总共买了多个水果和多少本书?
ChatCompletionMessage(content=None, role=‘assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=‘call_XB4SBFVfhMtyeo4zRu1lvpim’, function=Function(arguments=‘{“numbers”: [2, 4, 7]}’, name=‘sum’), type=‘function’), ChatCompletionMessageToolCall(id=‘call_d0B4e1j7Fhi1OPxxH9skJRAi’, function=Function(arguments=‘{“numbers”: [5, 3, 10]}’, name=‘sum’), type=‘function’)])
GPT回复: 小明总共买了13个水果和18本书。

关于这段代码,需要注意一点:

  • 这段代码中的模型使用的是gpt-3.5-turbo,更确切的说是最新的gpt-3.5-turbo-0125。OpenAI官方已经将gpt-3.5-turbo指向了gpt-3.5-turbo-0125。但如果使用的是国内代理的key的话,可能gpt-3.5-turbogpt-3.5-turbo-0125还是两个不同的模型,那运行上述代码时可能会遇到如下错误(输出second_response可以看到报错信息):

Invalid parameter: messages with role ‘tool’ must be a response to a preceeding message with ‘tool_calls’

2.3 同时定义多个函数调用

假设我们现在同时定义了加法和乘法的函数调用,让大模型自动完成加法和乘法的调用。具体代码如下:

from openai import OpenAI 
import json
from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
client=OpenAI()
def math_multiply(number,price):return number*price
def run_conversation(prompt,model='gpt-3.5-turbo-0125'):messages=[{"role":"user","content":prompt}]tools=[{ "type": "function","function": {"name": "sum","description": "加法器,计算一组数的和","parameters": {"type": "object","properties": {"numbers": {"type": "array", "items": { "type": "number"}}}}}},{"type":"function","function":{"name":"multiply","description":"乘法器,计算两个数的乘积","parameters":{"type":"object","properties":{"price":{"type":"number","description":"一种物品的价格"},"number":{"type":"integer","description":"一种物品的数量"},},"required":["price","number"],}}}]response=client.chat.completions.create(model=model,messages=messages,tools=tools,tool_choice="auto",)response_message=response.choices[0].messageavailable_function={"sum":sum,"multiply":math_multiply,}while response_message.tool_calls:print(response_message)messages.append(response_message)tool_calls=response_message.tool_callsfor tool_call in tool_calls:function_name=tool_call.function.namefunction_args=json.loads(tool_call.function.arguments)function=available_function[function_name]if function==sum:function_response=function(function_args.get("numbers"))elif function==math_multiply:function_response=function(function_args.get('number'),function_args.get('price'))messages.append({"tool_call_id":tool_call.id,"role":"tool","name":function_name,"content":str(function_response)})response_message=client.chat.completions.create(model=model,messages=messages,tools=tools,).choices[0].messagereturn response_message.content
if __name__=="__main__":prompt="小明第一天买了5本书和7个苹果,第二天买了3本书和2个苹果,第三天买了18本书和20个苹果,每一本书的价格是65元/本,每一个苹果的价格是7.5元/个,那么小明总共花了多少钱?"print(prompt)print("GPT回复:",run_conversation(prompt))

其执行结果如下(从输出内容可以知道,大模型先调用了两次加法运算完成书籍数量和水果数量的计算,接着调用两次乘法完成书本总价和水果总价的计算,最后调用加法完成总成本的计算。):

小明第一天买了5本书和7个苹果,第二天买了3本书和2个苹果,第三天买了18本书和20个苹果,每一本书的价格是65元/本,每一个苹果的价格是7.5元/个,那么小明总共花了多少钱?
ChatCompletionMessage(content=None, role=‘assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=‘call_xkGwaSApyRoTXmsNFhrtNQci’, function=Function(arguments=‘{“numbers”: [5, 3, 18]}’, name=‘sum’), type=‘function’), ChatCompletionMessageToolCall(id=‘call_DQEKyCWNJT2JysmqH25OGLRO’, function=Function(arguments=‘{“numbers”: [7, 2, 20]}’, name=‘sum’), type=‘function’), ChatCompletionMessageToolCall(id=‘call_5VlzZ8U5EhDixYnbwhh2Lljf’, function=Function(arguments=‘{“price”: 65, “number”: 26}’, name=‘multiply’), type=‘function’), ChatCompletionMessageToolCall(id=‘call_qN12sj2Ze7TvcuF0vzcwZH9H’, function=Function(arguments=‘{“price”: 7.5, “number”: 29}’, name=‘multiply’), type=‘function’)])
ChatCompletionMessage(content=None, role=‘assistant’, function_call=None, tool_calls=[ChatCompletionMessageToolCall(id=‘call_XIdn5N1lhcRy8vG0UodSMfO9’, function=Function(arguments=‘{“numbers”:[1690,217.5]}’, name=‘sum’), type=‘function’)])
GPT回复: 小明总共花了1907.5元。

最后需要注意一点,是否执行函数调用由大模型自己决定。

相关文章:

LLM:函数调用(Function Calling)

1 函数调用 虽然大模型能解决很多问题,但大模型并不能知晓一切。比如,大模型不知道最新消息(GPT-3.5 的知识截至 2021年9月,GPT-4 是 2023 年12月)。另外,大模型没有“真逻辑”。它表现出的逻辑、推理,是训练文本的统计…...

ssm 房屋销售管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 房屋销售管理系统是一套完善的信息系统,结合springMVC框架完成本系统,对理解JSP java编程开发语言有帮助系统采用SSM框架(MVC模式开发),系统具有完整的源代码和数据库,系统主要采用B/S模…...

MySQL使用ALTER命令创建与修改索引

索引(index)分类 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引。组合索引,即一个索引包含多个列。 创建索引时,需要确保该索引是应用在 SQL查询语句的条件(一般作为 WHERE 子句的条件)。 实…...

54 npm run serve 和 npm run build 输出的关联和差异

前言 通常来说 我们开发的时候一般会用到的命令是 “npm run serve”, “npm run build” 前者会编译当前项目, 然后将编译之后的结果以 node 的形式启动一个服务, 暴露相关业务资源, 因此 我们可以通过 该服务访问到当前项目 后者是编译当前项目, 然后做一下最小化代码的优…...

iOS —— 初识KVO

iOS —— 初始KVO KVO的基础1. KVO概念2. KVO使用步骤注册KVO监听实现KVO监听销毁KVO监听 3. KVO基本用法4. KVO传值禁止KVO的方法 注意事项: KVO的基础 1. KVO概念 KVO是一种开发模式,它的全称是Key-Value Observing (观察者模式) 是苹果Fundation框架…...

什么是HTTP? HTTP 和 HTTPS 的区别?

文章目录 一、HTTP二、HTTPS三、区别参考文献 一、HTTP HTTP (HyperText Transfer Protocol),即超文本运输协议,是实现网络通信的一种规范 在计算机和网络世界有,存在不同的协议,如广播协议、寻址协议、路由协议等等… 而HTTP是…...

微信小程序如何进行npm导入组件

文章目录 目录 文章目录 前言 一、安装node 二、微信小程序通过npm安装组件(以Vant-weapp为例) 一、Vant-weapp下载 二 、修改 app.json 三 、修改 project.config.json 四 、 构建 npm 包 前言 微信小程序使用npm导入有很多的教程,我…...

MySQL编程实战LeetCode经典考题

文章简介 本文主要收集了LeetCode上关于MySQL的一些经典考题。 后续也会陆续把所有经典考题补充完整。 175.组合两个表 175.组合两个表 解答: select p.FirstName as firstName, p.LastName as lastName,a.City as city, a.State as state from Person p l…...

发生播放错误,即将重试 jellyfin

上周在家里的小主机上部署了jellyfin,真香,手机安卓端使用无问题,于是今天准备在电视上安装一个 首先是直接安装的手机版客户端,操作卡顿,而且很多操作没法实现,于是去下了一个tv版本 安装上后发现&#…...

BIONIOAIO

通信技术整体解决的问题 1.局域网内的通信要求 2.多系统间的底层消息传递机制 3.高并发下,大数据量的通信场景需要 4.游戏行业。无论是手游服务端、还是大型网络游戏,java的应用越来越广 IO模型基本说明 就是用什么样的通道或者说是通信模式和架构…...

SpringSecurity学习总结(三更草堂)

SpringSecurity安全框架的核心功能是认证和授权: 认证:验证当前访问系统的是不是本系统的用户,并且要确认具体是哪个用户。 授权:经过认证后判断当前用户是否具有进行某个操作的权限。 一般来说中大型的项目都是使用SpringSecurit…...

C++20中的jthread

一、多线程开发 c11以前,是不包含线程库的,开发多线程,必须使用OS系统自带的线程API,这就导致了很多问题,最主要的是,跨平台的开发,一般要保持几个主流应用的库的代码支持,特别是对…...

Xception模型详解

简介 Xception的名称源自于"Extreme Inception",它是在Inception架构的基础上进行了扩展和改进。Inception架构是Google团队提出的一种经典的卷积神经网络架构,用于解决深度卷积神经网络中的计算和参数增长问题。 与Inception不同&#xff0…...

【合合TextIn】AI构建新质生产力,合合信息Embedding模型助力专业知识应用

目录 一、合合信息acge模型获MTEB中文榜单第一 二、MTEB与C-MTEB 三、Embedding模型的意义 四、合合信息acge模型 (一)acge模型特点 (二)acge模型功能 (三)acge模型优势 五、公司介绍 一、合合信息…...

Flutter 拦截系统键盘,显示自定义键盘

一、这里记录下在开发过程中,下单的时候输入金额需要使用自定义的数字键盘 参考链接: https://juejin.cn/post/7166046328609308685 效果图 二、屏蔽系统键盘 怎样才能够在输入框获取焦点的时候,不让系统键盘弹出呢?同时又显示我们自定义的…...

内存泄漏是什么?如何避免内存泄漏?

1.2 内存泄漏 使用new开辟空间泄漏&#xff0c;抛出异常 int main() {int size 0;try{while (1){//int* p (int*)malloc(sizeof(int) * 1024 * 1024);/*if (p NULL){break;}*/int* p new int[1024 * 1024];size size 4 * 1024 * 1024;cout << p << endl;}}…...

linux 中的syslog的含义和用法

在Linux系统中&#xff0c;syslog是一种系统日志服务&#xff0c;用于收集、存储和管理系统和应用程序生成的日志消息。syslog服务负责记录系统的运行状态、错误信息、警告、调试信息等&#xff0c;以便系统管理员可以监控系统的健康状况、故障排查和性能优化。 含义和作用&am…...

kubernetes(K8S)学习(一):K8S集群搭建(1 master 2 worker)

K8S集群搭建&#xff08;1 master 2 worker&#xff09; 一、环境资源准备1.1、版本统一1.2、k8s环境系统要求1.3、准备三台Centos7虚拟机 二、集群搭建2.1、更新yum&#xff0c;并安装依赖包2.2、安装Docker2.3、设置hostname&#xff0c;修改hosts文件2.4、设置k8s的系统要求…...

巧克力(蓝桥杯)

文章目录 巧克力题目描述解题分析贪心 巧克力 题目描述 小蓝很喜欢吃巧克力&#xff0c;他每天都要吃一块巧克力。 一天小蓝到超市想买一些巧克力。超市的货架上有很多种巧克力&#xff0c;每种巧克力有自己的价格、数量和剩余的保质期天数&#xff0c;小蓝只吃没过保质期的…...

Python爬虫之pyquery和parsel的使用

三、pyquery的使用 1、准备工作 pip3 install pyquery2、初始化 2.1、字符串初始化 把HTML的内容当做参数&#xff0c;来初始化PyQuery对象。 html <div><ul><li class"item-0">first item</li><li class"item-1">&l…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

面向无人机海岸带生态系统监测的语义分割基准数据集

描述&#xff1a;海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而&#xff0c;目前该领域仍面临一个挑战&#xff0c;即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...