GPT应用开发:编写插件获取实时天气信息
欢迎阅读本系列文章!我将带你一起探索如何利用OpenAI API开发GPT应用。无论你是编程新手还是资深开发者,都能在这里获得灵感和收获。
本文,我们将继续展示聊天API中插件的使用方法,让你能够轻松驾驭这个强大的工具。
插件运行效果
首先给大家展示下插件的运行效果,如下图所示:
可以看到,每次询问GPT,它都会返回指定城市的实时天气信息,这个天气是真实的,不是GPT瞎编的,是GPT通过一个实时天气插件查询到的。
插件运行原理
知己知彼,百战不殆!首先让我们来了解下插件的运行原理。如下图所示:
首先我们在客户端发起一个聊天会话,比如询问GPT:“今天天气怎么样?”
为了使用我们自己的插件,我们还需要告诉GPT有哪些插件可用,目前这需要我们在发起聊天时传递一个支持的插件列表给GPT。
然后GPT收到我们的聊天后,它会根据用户的聊天内容去匹配插件,并在返回的消息中指示命中了哪些插件,这个匹配是根据GPT的语言理解能力做出的。
然后客户端就可以检查命中了哪些插件,并调用执行本地相应的插件方法。插件方法是在本地执行的,这也比较合理,如果放到GPT服务端,GPT不仅要适配各种计算能力,还可能面临巨大的安全风险。
然后客户端将插件的执行结果附加到本次聊天会话中,再次发起聊天请求,GPT收到后,会根据首次聊天请求和插件生成的内容组织本次聊天响应结果,再返回给用户。
这样就完成了一次基于插件的GPT会话。
插件使用示例
基于上面的运行原理,我们来编写一个GPT插件的示例程序。
在这个示例程序中,我将提供一个天气查询的插件,当用户询问GPT今天的天气时,GPT就会命中这个插件,然后插件会调用外部API获取实时的天气情况,最后GPT会使用插件生成的结果组织一段文字回复返回给用户。
编写天气插件
这里我们将使用“心知天气”提供的免费天气查询服务,大家感兴趣的可以去这里注册个账号:心知天气 - 高精度气象数据 - 天气数据API接口 - 行业气象解决方案,注册成功后,需要复制账号的私钥,调用天气接口时会用到。
然后我们就可以编写天气查询插件了,这里直接给出我的代码:
def get_city_weather(param):city = json.loads(param)["city"]params = {"key": "这里换成你的天气产品私钥","location": city,"language": "zh-Hans","unit": "c",}url = "https://api.seniverse.com/v3/weather/now.json"r = requests.get(url, params=params)data = r.json()["results"]address = data[0]["location"]['path']temperature = data[0]['now']["temperature"]text = data[0]['now']["text"]return address+",当前天气:"+text+",温度:"+temperature+ "℃"
可以看到就是一个Python函数,接收json格式的参数,返回天气描述信息。
注意这里的参数格式(包括有哪些参数)是和GPT大模型匹配过的,下文会讲到怎么定义参数。
接口的主要逻辑就是使用城市名称,调用实时天气接口获取天气信息,然后再拼接成一段话并返回。
我这里只使用了天气的部分指标,详细指标大家可以看接口文档:
此处为语雀内容卡片,点击链接查看:天气实况 · 心知科技
发起带插件的聊天
话不多说,看代码:
client = OpenAI(api_key='sk-xxx')# 聊天消息上下文
messages=[{"role": "user","content": "请问现在天气怎么样?",
}]# 天气插件
weather_tool = {"type": "function","function": {"name": "get_city_weather","description": "获取某个城市的天气","parameters": {"type": "object","properties": {"city": {"type": "string","description": "城市名称",},},"required": ["city"],},}}# 发起聊天请求
response = client.chat.completions.create(messages=messages,model='gpt-3.5-turbo-1106',stream=False,# 插件相关tool_choice="auto",tools=[weather_tool]
)
在上面这段代码中,我们首先声明了一个OpenAI客户端,没有API Key的同学可以看文章最后。
然后我们创建了一个很普通的聊天会话,就是以普通用户的身份询问GPT今天的天气情况。
然后我们定义了一个天气插件,其实就是一个Json对象。
- type:目前只能传 fucntion,也就是说目前插件就是外置函数。
- function:函数的定义。
-
- name:函数的名称,这里就是我们上边定义的 get_city_weather。
- description:函数的描述,GPT将使用这个描述来决定什么时候以及如何调用函数。
- parameters:函数的参数。
-
-
- type:固定object
- properties:定义函数的各个参数,每个参数包含两个属性:type和description,description也很重要,让GPT模型知道怎么来提供这个参数。
- required:数组,定义必填的参数。
-
最后我们向GPT发起本次聊天请求,其中增加了关于插件的两个参数:
- tool_choice:开启插件,固定值 auto,设置为none则不使用插件。
- tools:插件列表,包含我们上边定义的 weather_tool 插件。
处理插件命中
如果GPT大模型命中了插件,它会在返回值中携带一些信息。根据这些信息,我们可以知道要调用哪个插件的函数,然后再把函数的执行结果附加到消息上下文中,再请求GPT大模型,GPT大模型会使用函数返回值组织文本内容,最终返回给用户。
相关代码如下:
response_message = response.choices[0].message
if response_message.tool_calls is not None:tool_call = response_message.tool_calls[0]messages.append(response_message)messages.append({"role": "tool","content": get_city_weather(tool_call.function.arguments),"tool_call_id": tool_call.id})response = client.chat.completions.create(messages=messages,model='gpt-3.5-turbo-1106',stream=False,tool_choice="auto",tools=[weather_tool])print(response_message.choices[0].message.content)
判断是否命中插件使用的是 response_message.tool_calls is not None,也就是返回值中的 tool_calls 不为空,因为这里只有一个插件,所以我们没有做进一步的判断;如果有多个插件,可以遍历tool_calls,根据插件关联函数的 name,选择执行不同的方法。
注意这里我们把本次响应的消息又追加到了上下文中:messages.append(response_message)。
然后我们又追加了插件生成的消息,就是下面这段:
messages.append({"role": "tool","content": get_city_weather(tool_call.function.arguments),"tool_call_id": tool_call.id})
介绍下这几个字段:
- role:指定这个消息来自插件。
- content:指定消息的内容。get_city_weather 就是我们上边定义的插件方法,而它的参数 tool_call.function.arguments 则是大模型生成的 ,这个方法会在在本地执行,并生成一段天气信息描述。
- tool_call_id:这段消息关联的插件id,需要让大模型了解这个数据关系。
然后我们又通过 client.chat.completions.create 向GPT大模型发起请求 ,并拿到最终的返回结果。
完整的代码示例
因为上文中两次请求GPT大模型的方法都是一样的,所以我们这里把它抽象为一个方法。
另外为了充分展现插件的使用方法,这里会向GPT询问三个城市的天气信息,通过循环发起。
from openai import OpenAI
import json
import requests
import time# 获取天气的方法
def get_city_weather(param):city = json.loads(param)["city"]params = {"key": "这里换成你的天气产品私钥","location": city,"language": "zh-Hans","unit": "c",}url = "https://api.seniverse.com/v3/weather/now.json"r = requests.get(url, params=params)data = r.json()["results"]#print(json.dumps(data))address = data[0]["location"]['path']temperature = data[0]['now']["temperature"]text = data[0]['now']["text"]return address+",当前天气:"+text+",温度:"+temperature+ "℃"# 天气插件的定义
weather_tool = {"type": "function","function": {"name": "get_city_weather","description": "获取某个城市的天气","parameters": {"type": "object","properties": {"city": {"type": "string","description": "城市名称",},},"required": ["city"],},}}# 创建OpenAI客户端,获取API Key请看文章最后
client = OpenAI(api_key='sk-xxx')# 定义请求GPT的通用方法
def create_completion():return client.chat.completions.create(messages=messages,model='gpt-3.5-turbo-1106',stream=False,tool_choice="auto",tools=[weather_tool])# 我的三个问题
questions = ["请问现在天气怎么样?","请问上海天气怎么样?","请问广州天气怎么样?"]# 聊天上下文,初始为空
messages=[]print("---GPT天气插件演示--- ")# 遍历询问我的问题
for question in questions: # 将问题添加到上下文中messages.append({"role": "user","content": question,})print("路人甲: ",question)# 请求GPT,并拿到响应response_message = create_completion().choices[0].message# 把响应添加到聊天上下文中messages.append(response_message)#print(response_message)# 根据插件命中情况,执行插件逻辑if response_message.tool_calls is not None:tool_call = response_message.tool_calls[0]#print("tool_call: ",tool_call.id)# 追加插件生成的天气内容到聊天上下文weather_info = get_city_weather(tool_call.function.arguments)#print(weather_info)messages.append({"role": "tool","content": weather_info,"tool_call_id": tool_call.id})# 再次发起聊天second_chat_completion = create_completion()gpt_output = second_chat_completion.choices[0].message.content# 打印GPT合成的天气内容print("GPT: ",gpt_output)time.sleep(0.2)# 将GPT的回答也追加到上下文中messages.append({"role": "assistant","content": gpt_output,})
以上就是本文的主要内容,有没有感受到插件的强大能力!
后续我还会继续分享图片、语音、文档助手等API的使用方法。
如需GPT账号、学习陪伴群、AI编程训练营,推荐关注小册:大模型应用开发 | API 实操
关注萤火架构,加速技术提升!
相关文章:

GPT应用开发:编写插件获取实时天气信息
欢迎阅读本系列文章!我将带你一起探索如何利用OpenAI API开发GPT应用。无论你是编程新手还是资深开发者,都能在这里获得灵感和收获。 本文,我们将继续展示聊天API中插件的使用方法,让你能够轻松驾驭这个强大的工具。 插件运行效…...

揭开Spring MVC的真面目
官方对于Spring MVC的描述为: Spring Web MVC是基于Servlet API框架构建的原始Web框架,从一开始就包含在Spring框架中。它的正式名称“Spring Web MVC”来自其源模块的名称(Spring-webmvc),但它通常被称为“Spring-MVC…...

AI大模型开发架构设计(3)——如何打造自己的大模型
文章目录 如何打造自己的大模型1 新时代职场人应用AIGC的5重境界2 人人需要掌握的大模型原理职场人都能听懂的大语音模型的训练过程职场人都能听得懂的大语言模型的Transformer推理过程 3 如何构建自己的大模型需要具备三个方面的能力LangChain是什么?LangChain主要…...

Linux C语言开发(三)运算符和表达式
目录 一.什么是运算符 二.什么是表达式 一.什么是运算符 在C语言中,运算符是用于执行特定操作的符号。这些操作可以涉及一个或多个值(称为操作数),并产生一个新的值或效果。C语言提供了多种类型的运算符,用于执行算术、比较、逻辑和其他类型的操作。 以下是C语言中常见的…...

Spring-AOP入门案例
文章目录 Spring-AOP入门案例概念:通知(Advice)切入点(Pointcut )切面(Aspect) 目标对象(target)代理对象(Proxy)顾问(Advisor)连接点(JoinPoint) 简单需求:在接口执行前输出当前系统时间Demo原始未添加aop前1 项目包结构2 创建相…...

中仕教育:国考调剂和补录的区别是什么?
国考笔试成绩和进面名单公布之后,考生们就需要关注调剂和补录了,针对二者之间的区别很多考生不太了解,本文为大家解答一下关于国考调剂和补录的区别。 1.补录 补录是在公式环节之后进行的,主要原因是经过面试、体检和考察&#…...

ESP32-TCP服务端(Arduino)
将ESP32设置为TCP服务器 介绍 TCP(Transmission Control Protocol)传输控制协议,是一种面向连接的(一个客户端对应一个服务端)、可靠的传输层协议。在TCP的工作原理中,它会将消息或文件分解为更小的片段&a…...

HCIA-HarmonyOS设备开发认证-序
序 最近涉及到HarmonyOS鸿蒙系统设备开发,在网络上已经有很多相关资料,视频教程,我也移植了公司的一个stm32G474板卡,运行LiteOS-m L0系统。 一面看资料一面移植,遇到不少坑,当看到运行的LOGO时࿰…...

Med-YOLO:3D + 医学影像 + 检测框架
Med-YOLO:3D 医学影像 检测框架 提出背景设计思路网络设计训练设计讨论分析 魔改代码:加强小目标检测总结 提出背景 论文链接:https://arxiv.org/abs/2312.07729 代码链接:https://github.com/JDSobek/MedYOLO 提出背景&…...

Docker部署Golang服务
不管是开发还是生产环境,通过 docker 方式部署服务都是一种不错的选择,能够解决不同开发环境一致性的问题。 本文以项目:https://github.com/johncxf/go-api 为例。 Dockerfile 构建 Go 运用环境 在项目根目录下添加 Dockerfile 文件&…...

C#,字符串匹配(模式搜索)Sunday算法的源代码
Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法。 核心思想:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配&…...

makefile 编译动态链接库使用(.so库文件)
makefile 编译动态链接库使用(.so库文件) 动态链接库:不会把代码编译到二进制文件中,而是在运行时才去加载, 好处是程序可以和库文件分离,可以分别发版,然后库文件可以被多处共享 动态链接库 动态&#…...

Hive 数仓及数仓设计方案
数仓(Data Warehouse) 数据仓库存在的意义在于对企业的所有数据进行汇总,为企业各个部门提供一个统一、规范的出口。做数仓就是做方案,是用数据治理企业的方案。 数据仓库的特点 面向主题集成 公司中不同的部门都会去数据仓库中拿数据,把独…...

Ubuntu使用docker-compose安装redis
ubuntu环境搭建专栏🔗点击跳转 Ubuntu系统环境搭建(十三)——使用docker-compose安装redis 文章目录 Ubuntu系统环境搭建(十三)——使用docker-compose安装redis1.搭建文件夹2.docker-compose.yaml配置文件3.redis.co…...

大数据安全 | 期末复习(上)| 补档
文章目录 📚概述⭐️🐇大数据的定义、来源、特点🐇大数据安全的含义🐇大数据安全威胁🐇保障大数据安全🐇采集、存储、挖掘环节的安全技术🐇大数据用于安全🐇隐私的定义、属性、分类、…...

Kylin 安装novnc 远程访问
noVNC可以使用浏览器直接访问服务器,而不需要使用VNC客户端。 1.初始环境 关闭防火墙或允许IP访问本机 2.安装依赖 dnf install -y tigervnc-server git 3.git下载novnc git clone https://github.com/novnc/noVNC.git git clone https://gitee.com/yangyizhao…...

神经网络算法与逻辑回归:优势与差异
神经网络算法和逻辑回归都是预测模型中的重要工具,但它们在处理复杂和非线性问题时表现出不同的性能。本文将深入探讨神经网络算法相对于逻辑回归的优势,以及它们在不同场景下的适用性。 一、引言 神经网络算法和逻辑回归都是预测模型中的重要工具&…...

【蓝桥杯冲冲冲】动态规划初步[USACO2006 OPEN] 县集市
蓝桥杯备赛 | 洛谷做题打卡day13 文章目录 蓝桥杯备赛 | 洛谷做题打卡day13题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示样例说明数据规模与约定 思路:方程: 题解代码我的一些话 [USACO2006 OPEN] 县集市 The County Fair 题目描述 每年…...

C#,入门教程(30)——扎好程序的笼子,错误处理 try catch
上一篇: C#,入门教程(29)——修饰词静态(static)的用法详解https://blog.csdn.net/beijinghorn/article/details/124683349 程序员语录:凡程序必有错,凡有错未必改! 程序出错的原因千千万&…...

操作教程|JumpServer堡垒机结合Ansible进行批量系统初始化
运维人员常常需要对资产进行系统初始化的操作,而初始化服务器又是一项繁琐的工作,需要花费运维人员大量的时间和精力。为了提高效率,许多组织会使用自动化工具和脚本来简化这些任务。自动化工具的运用可以大幅降低运维人员的工作量࿰…...

序列化VS反序列化
序列化、反序列化定义 如果我们需要持久化 Java 对象比如将 Java 对象保存在文件中,或者在网络传输 Java 对象,这些场景都需要用到序列化。 序列化(Serialization)是指将对象转换为字节序列的过程,也可以称之为对象的持…...

新数智空间:阿里云边缘云持续保持中国公有云市场第一
全球领先的 IT 市场研究和咨询公司 IDC 发布 《中国边缘云市场解读(2023H1)》报告 中国边缘公有云服务市场 阿里云持续第一 稳居市场第一,“边缘”逆势生长 近日,全球领先的 IT 市场研究和咨询公司 IDC 最新发布《中国边缘云市…...

【开源】基于JAVA语言的陕西非物质文化遗产网站
目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 设计目标2.2 研究内容2.3 研究方法与过程2.3.1 系统设计2.3.2 查阅文献2.3.3 网站分析2.3.4 网站设计2.3.5 网站实现2.3.6 系统测试与效果分析 三、系统展示四、核心代码4.1 查询民间文学4.2 查询传统音乐4.3 增改传统舞…...

C++(Qt)软件调试---静态分析工具clang-tidy(18)
C(Qt)软件调试—静态分析工具clang-tidy(18) 文章目录 C(Qt)软件调试---静态分析工具clang-tidy(18)1、概述2、clang-tidy基本用法3、目前已有检查项4、Qt Creator中安装clang-tidy5、Qt Creator中使用clang-tidy6、Clang-Tidy配置…...

2401llvm,clang的重构引擎
Clang的重构引擎 展示如何使用重构API中的各种原语来实现不同的重构. LibTooling库提供了几个在开发重构操作时,使用的其他API. 可用重构引擎来实现,用编辑器或IDE中的选择启动的本地重构.可结合AST匹配器和重构引擎,以实现不适合源选择和/或必须查询某些指定节点的AST的重构…...

【C语言深度剖析——第四节(关键字4)】《C语言深度解剖》+蛋哥分析+个人理解
追求本质,不断进步 本文由睡觉待开机原创,转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言,共同进步! 这里写目录标题 一、空间的申请1.变量定义1.1变量定义的概念:1.2变…...

鸿蒙开发系列教程(五)--ArkTS语言:组件开发
1、基础组件 组件API文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/84_u58f0_u660e_u5f0f_u5f00_u53d1_u8303_u5f0f_uff09-0000001427744776-V2 查看组件API 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 容…...

Java:正则表达式讲解加举例,简洁易懂
正则表达式定义: 由一些特定的字符组成,代表的是一个规则。 作用:1.校验数据是否合法。2.可以在一段文本中查找满足要求的内容。 先自己写一个方法去校验qq号,比较与正则表达式的区别: 正则表达式的代码暂时可以不…...

2.机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解
2️⃣机器学习-K最近邻(k-Nearest Neighbor,KNN)分类算法原理讲解 个人简介一算法概述二算法思想2.1 KNN的优缺点 三实例演示3.1电影分类3.2使用KNN算法预测 鸢(yuan)尾花 的种类3.3 预测年收入是否大于50K美元 个人简介 🏘️&…...

WordPress顶部管理工具栏怎么添加一二级自定义菜单?
默认情况下,WordPress前端和后台页面顶部都有一个“管理工具栏”,左侧一般就是站点名称、评论、新建,右侧就是您好,用户名称和头像。那么我们是否可以在这个管理工具栏中添加一些一二级自定义菜单呢? 其实,…...