欢迎阅读本系列文章!我将带你一起探索如何利用OpenAI API开发GPT应用。无论你是编程新手还是资深开发者,都能在这里获得灵感和收获。

本文,我们将继续展示聊天API中插件的使用方法,让你能够轻松驾驭这个强大的工具。

插件运行效果

首先给大家展示下插件的运行效果,如下图所示:

可以看到,每次询问GPT,它都会返回指定城市的实时天气信息,这个天气是真实的,不是GPT瞎编的,是GPT通过一个实时天气插件查询到的。

插件运行原理

知己知彼,百战不殆!首先让我们来了解下插件的运行原理。如下图所示:

首先我们在客户端发起一个聊天会话,比如询问GPT:“今天天气怎么样?”

为了使用我们自己的插件,我们还需要告诉GPT有哪些插件可用,目前这需要我们在发起聊天时传递一个支持的插件列表给GPT。

然后GPT收到我们的聊天后,它会根据用户的聊天内容去匹配插件,并在返回的消息中指示命中了哪些插件,这个匹配是根据GPT的语言理解能力做出的。

然后客户端就可以检查命中了哪些插件,并调用执行本地相应的插件方法。插件方法是在本地执行的,这也比较合理,如果放到GPT服务端,GPT不仅要适配各种计算能力,还可能面临巨大的安全风险。

然后客户端将插件的执行结果附加到本次聊天会话中,再次发起聊天请求,GPT收到后,会根据首次聊天请求和插件生成的内容组织本次聊天响应结果,再返回给用户。

这样就完成了一次基于插件的GPT会话。

插件使用示例

基于上面的运行原理,我们来编写一个GPT插件的示例程序。

在这个示例程序中,我将提供一个天气查询的插件,当用户询问GPT今天的天气时,GPT就会命中这个插件,然后插件会调用外部API获取实时的天气情况,最后GPT会使用插件生成的结果组织一段文字回复返回给用户。

编写天气插件

这里我们将使用“心知天气”提供的免费天气查询服务,大家感兴趣的可以去这里注册个账号:https://www.seniverse.com/,注册成功后,需要复制账号的私钥,调用天气接口时会用到。

然后我们就可以编写天气查询插件了,这里直接给出我的代码:

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应用开发:GPT插件开发指南的更多相关文章

  1. Elasticsearch5.5.1插件开发指南

    Elasticsearch5.5.1插件开发指南 原文地址: https://www.elastic.co/guide/en/elasticsearch/plugins/5.5/plugin-auth ...

  2. [置顶] PHP开发实战权威指南-读书总结

    从今年开始,断断续续学习PHP已经有4个月了. 最初,认真学习PHP几天,就弄WordPress搭建了一个个人博客,这也符合技术人的实践理念. 最近,重温PHP开发实战权威指南,做点总结,整理下自己学 ...

  3. 物联网操作系统HelloX开发人员入门指南

    HelloX开发人员入门指南 HelloX是聚焦于物联网领域的操作系统开发项目,能够通过百度搜索"HelloX".获取具体信息. 当前开发团队正在进一步招募中,欢迎您的了解和添加. ...

  4. mac电脑使用,开发环境配置指南

    mac电脑使用,开发环境配置指南 前端工具链,mac下都很好用 用brew来装软件 用brew cask来装应用 Introduction · macOS Setup Guidehttp://sour ...

  5. 【笔记】jQuery插件开发指南

    原文链接:http://www.cnblogs.com/Wayou/p/jquery_plugin_tutorial.html (有部分增删和修改) jQuery插件开发模式 软件开发过程中是需要一定 ...

  6. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

  7. 李洪强iOS开发之-入门指南

    李洪强iOS开发之-入门指南 1零基础小白如何进行iOS系统学习 首先,学习目标要明确:其次,有了目标,要培养兴趣,经常给自己一些正面的反馈,比如对自己的进步进行鼓励,在前期小步快走:再次,学技术最重 ...

  8. PHP开发实战权威指南-读书总结

    从今年开始,断断续续学习PHP已经有4个月了.最初,认真学习PHP几天,就弄WordPress搭建了一个个人博客,这也符合技术人的实践理念. 最近,重温PHP开发实战权威指南,做点总结,整理下自己学习 ...

  9. Go 开发关键技术指南 | 敢问路在何方?(内含超全知识大图)

    作者 | 杨成立(忘篱) 阿里巴巴高级技术专家 Go 开发关键技术指南文章目录: 为什么你要选择 Go? Go 面向失败编程 带着服务器编程金刚经走进 2020 年 敢问路在何方? Go 开发指南大图 ...

  10. Windows下C,C++开发环境搭建指南

    Windows下C,C++开发环境搭建指南 前情提要 基于近一段时间很多网友发邮件反馈,说一些项目编译出现问题,诸如此类的情况. 就觉得很有必要写一篇C,C++开发环境的小指南,统一回复. 1.君欲善 ...

随机推荐

  1. 解决JPA对查询对象set属性值导致数据更新的问题

    问题描述 1.开启了数据库事务 2.通过EntityManager执行查询,获得返回对象 3.代码业务逻辑处理,其中有对象set属性值的操作 4.没有执行过JPA的save方法或者update语句 5 ...

  2. RocketMQ一直打印RocketmqRemoting closeChannel: close the connection to remote address[] result: true

    交代一下背景: RocketMQ服务端搭建在ECS上面(问题就出在这里) SpringBoot应用根据官网Demo(参考:https://github.com/apache/rocketmq-spri ...

  3. 后端程序员必会的前端知识-05:React

    五. React 1. React 基础 react 是前端三大框架之一 没有 vue 的基础更好,因为两者思想不太一样,不能用 vue 的习惯学习 react 需要有 js 基础,视频 19-58 ...

  4. Oracle重做、归档日志

    日志文件 oracle日志文件分为两种: 重做日志文件(redo),或者称为"在线重做日志" 归档日志文件(arch),或者称为"归档重做日志" 在线重做日志文 ...

  5. IntelliJ IDEA下载安装,以及关联gitee

    https://www.jetbrains.com.cn/ 点击下载 IntelliJ IDEA Ultimate 旗舰版(收费) IntelliJ IDEA Community 社区版(免费) 安装 ...

  6. Shell的概念、shebang、bash的概念

    什么是shell shell的作用是 解释执行用户输入的命令或程序等 用户输入一条命令,shell就解释一条 键盘输入命令,Linux给与响应的方式,称之为交互式 linux的计算机是如何跟用户进行交 ...

  7. SQL 的递归查询

    在一般的业务场景中,特别是针对相关的业务线相关的功能开发时,可能会遇到一些具有层级关系的数据关联结构.比如,一个员工可能属于一个领导管辖,而同时,这个领导也被另一个更高级别的领导管辖--,而本质上这些 ...

  8. shared_ptr 自定义 deleter 删除器

    一些结论 如果 shared_ptr 管理的资源不是 new 分配的内存,才考虑自定义删除器,这也是为什么 make_shared 不支持自定义删除器的原因,因为 make_shared 就是通过 n ...

  9. 伯克利:serverless是下一代计算范式

    摘要:Serverless技术正是云厂商的基于规模经济的一个选择. 引子 刚过去的HC2020,华为面向多样化算力的时代,发布了DC分布式计算的三个开发套件,其中一个是元戎组件.元戎是基于函数计算的分 ...

  10. 连Python都不熟也能跑通AI人脸识别?“隐藏Boss”竟是它!

    摘要:先把AI人脸识别跑起来,然后研究它是如何实现的,整个过程中确实收获不少.所谓先跟着做,再跟着学,实践与理论结合,自己感觉有理解了一些基础概念入个门,在此分享一下自己的捣鼓经验. 1.买台小&qu ...