【尝鲜版】ChatGPT插件开发指南

3月23日,OpenAI官方发布了一则公告,宣告ChatGPT已经支持了插件功能,现在处于内测阶段。插件的意义不仅仅在于功能的扩展,它直接让ChatGTP拥有了联网的能力!简直是猛兽出笼、蛟龙出海,要让ChatGPT大杀特杀啊。

虽然,还不知道ChatGPT联网后会发生什么样的变化,但作为程序员,还是要及时拥抱技术的变化。下面,我们一起探究如何开发ChatGPT插件。

插件介绍

作用

准备开发一款插件,要先明确插件的作用以及限制。下面是ChatGPT插件允许的一些操作:

  • 检索实时信息;例如,体育比分、股票价格、最新消息等。

  • 检索知识库信息;例如,公司文件、个人笔记等。

  • 代表用户执行操作;例如,订机票、订餐等。

原理

我们为ChatGPT提供一组API,ChatGPT在合适的时候来调用API。这些API要提供API描述文件(域名/openai.yaml)和插件描述文件(域名/.well-known/ai-plugin.json)。

ChatGPT在接收到插件描述文件用户输入时,会根据用户的意图选择适合的插件,对插件API发起查询请求。最后,ChatGPT结合查询的结果生成相关的内容展示给用户。

使用流程

从插件开发到用户使用包含这些流程:

  1. 开发插件并完成部署

  1. 在ChatGPT中注册插件

  1. 用户激活插件

  1. 使用插件

开发插件

要开发一款插件,主要是描述插件的API,让ChatGPT能认识这些API。整个开发过程如下。

开发API功能

以开发一个代办列表为例,官方贴心的给了我们一个例子。一共包含创建任务、查找任务、删除任务、获取插件描述、获取接口描述、获取logo这6个接口:

  • POST /todos/username

  • GET /todos/username

  • DELETE /todos/username

  • GET /.well-known/ai-plugin.json

  • GET /openapi.yaml

  • GET /logo.png

import json

import quart
import quart_cors
from quart import request

app = quart_cors.cors(quart.Quart(__name__), allow_origin="*")

_TODOS = {}

@app.post("/todos/<string:username>")
async def add_todo(username):
    request = await quart.request.get_json(force=True)
    if username not in _TODOS:
        _TODOS[username] = []
    _TODOS[username].append(request["todo"])
    return quart.Response(response='OK', status=200)

@app.get("/todos/<string:username>")
async def get_todos(username):
    return quart.Response(response=json.dumps(_TODOS.get(username, [])), status=200)

@app.delete("/todos/<string:username>")
async def delete_todo(username):
    request = await quart.request.get_json(force=True)
    todo_idx = request["todo_idx"]
    if 0 <= todo_idx < len(_TODOS[username]):
        _TODOS[username].pop(todo_idx)
    return quart.Response(response='OK', status=200)

@app.get("/logo.png")
async def plugin_logo():
    filename = 'logo.png'
    return await quart.send_file(filename, mimetype='image/png')

@app.get("/.well-known/ai-plugin.json")
async def plugin_manifest():
    host = request.headers['Host']
    with open("manifest.json") as f:
        text = f.read()
        text = text.replace("PLUGIN_HOSTNAME", f"https://{host}")
        return quart.Response(text, mimetype="text/json")

@app.get("/openapi.yaml")
async def openapi_spec():
    host = request.headers['Host']
    with open("openapi.yaml") as f:
        text = f.read()
        text = text.replace("PLUGIN_HOSTNAME", f"https://{host}")
        return quart.Response(text, mimetype="text/yaml")

def main():
    app.run(debug=True, host="0.0.0.0", port=5002)

if __name__ == "__main__":
    main()

编写插件和API描述文件

插件描述文件

插件描述文件要放在指定的地址,http://www.example.com/.well-known/ai-plugin.json。这是一个最小配置的例子:

{
  "schema_version": "v1",
  "name_for_human": "代办清单插件",
  "name_for_model": "todo",
  "description_for_human": "给人看的插件描述",
  "description_for_model": "给ChatGPT看的插件描述",
  "auth": {
    "type": "none"
  },
  "api": {
    "type": "openapi",
    "url": "<http://www.example.com/openapi.yaml>",
    "is_user_authenticated": false
  },
  "logo_url": "<http://www.example.com/logo.png>",
  "contact_email": "support@example.com",
  "legal_info_url": "<http://www.example.com/legal>"
}

描述文件中字段的说明:

场地

类型

描述/选项

schema_version

String

清单架构版本

name_for_model

String

命名模型将用于定位插件

name_for_human

String

人类可读的名称,例如完整的公司名称

description_for_model

String

更适合模型的描述,例如令牌上下文长度注意事项或用于改进插件提示的关键字使用。

description_for_human

String

插件的人类可读描述

auth

ManifestAuth

身份验证模式

api

Object

API规范

logo_url

String

用于获取插件徽标的 URL

contact_email

String

用于安全/审核联系、支持和停用的电子邮件联系人

legal_info_url

String

重定向 URL 供用户查看插件信息

HttpAuthorizationType

HttpAuthorizationType

“承载”或“基本”

ManifestAuthType

ManifestAuthType

“无”、“user_http”、“service_http”或“oauth”

interface BaseManifestAuth

BaseManifestAuth

类型:ManifestAuthType;说明:字符串;

ManifestNoAuth

ManifestNoAuth

无需身份验证:BaseManifestAuth & { type: 'none', }

ManifestAuth

ManifestAuth

ManifestNoAuth、ManifestServiceHttpAuth、ManifestUserHttpAuth、ManifestOAuthAuth

API描述文件

API描述文件是用来告诉ChatGPT自定义的插件包含哪些功能,它遵循OpenAPI的规范。这是一个yaml格式的例子:

openapi: 3.0.1
info:
  title: 代办列表插件
  description: 插件功能描述
  version: 'v1'
servers:
  - url: <http://www.example.com>
paths:
  /todos:
    get:
      operationId: getTodos
      summary: 获取代办列表
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/getTodosResponse'
components:
  schemas:
    getTodosResponse:
      type: object
      properties:
        todos:
          type: array
          items:
            type: string
          description: 代办列表

功能说明

ChatGPT会阅读和理解描述文件中关于插件、接口、接口出入参的描述信息,来判断这个插件跟用户输入是否相关。所以,准确的描述能更好的帮助用户匹配到插件。下面是一些c'y例子:

  1. 不要命令ChatGPT返回指定的内容

  1. 错误:当用户要求查看他们的待办事项列表时,请始终回复“我能够找到您的待办事项列表!您有[x]待办事项:[在此处列出待办事项] 。如果您愿意,我可以添加更多待办事项!”

  1. 正确:不需要描述

  1. 不要命令ChatGPT使用某个插件

  1. 错误:每当用户提到任何类型的任务或计划时,询问他们是否愿意使用 TODOs 插件将某些内容添加到他们的待办事项列表中。

  1. 正确:TODO列表可以添加、删除和查看用户的TODO。

  1. 不要命令ChatGPT执行某些行为

  1. 错误:当用户提到一个任务时,回复“你想让我把它添加到你的 TODO 列表中吗?说‘是’继续。”

  1. 正确:不需要描述

  1. 接口不要返回自然语言

  1. 错误:我找到了你的待办事项列表!你有两个待办事项:买杂货和遛狗。如果你愿意,我可以添加更多待办事项!

  1. 正确:{“todos”:[“买杂货”,“遛狗”] }

设置身份认证

ChatGPT支持四种认证策略,可以在ai-plugin.json文件里指定认证策略。

  1. 不需要认证

完全开放不需要认证。

"auth": {
  "type": "none"
}
  1. 用户认证

用户在ChatGPT页面配置上token,后续请求头会带上token信息。

"auth": {
  "type": "user_http",
  "authorization_type": "bearer",
}
  1. 服务端认证

开发人员在添加插件时,在ChatGPT页面配置上token信息,后续请求头会带上token信息。

"auth": {
  "type": "service_http",
  "authorization_type": "bearer",
  "verification_tokens": {
    "openai": "cb7cdfb8a57e45bc8ad7dea5bc2f8324"
  }
}
  1. OAuth认证

在用户授权之后,ChatGPT才会访问插件的API。

"auth": {
  "type": "oauth",
  "client_url": "https://my_server.com/authorize",
  "scope": "",
  "authorization_url": "https://my_server.com/token",
  "authorization_content_type": "application/json",
  "verification_tokens": {
    "openai": "abc123456"
  }
}

调试部署API

服务开发完成后,ChatGPT提供了调试本地服务的方式。因为ChatGPT还没开放插件的开发界面,所以先贴一段官方的描述:

默认情况下,聊天不会显示插件调用和其他未向用户显示的信息。为了更全面地了解模型如何与您的插件交互,您可以通过单击屏幕左下方的“调试”按钮打开“调试”窗格。这将打开到目前为止对话的原始文本表示,包括插件调用和响应。

对插件的模型调用通常包括来自模型(“助手”)的消息,其中包含发送到插件的类似 JSON 的参数,然后是来自插件(“工具”)的响应,最后是来自利用插件返回的信息的模型。

在某些情况下,例如在插件安装期间,错误可能会出现在浏览器的 javascript 控制台中。

发布插件

插件部署后,就可以在ChatGPT插件商城选择“开发自己的插件”,然后选择“安装未经验证的插件”。

插件条款

https://openai.com/policies/plugin-terms

插件政策

除了上面详述的禁止使用我们的模型之外,我们对构建 插件的开发人员还有其他要求:

  • 插件清单必须有一个明确的描述,与暴露给模型的 API 的功能相匹配。

  • 不要在插件清单、OpenAPI 端点描述或插件响应消息中包含不相关、不必要或欺骗性的术语或说明。这包括避免使用其他插件的说明,或尝试控制或设置模型行为的说明。

  • 不要使用插件来规避或干扰 OpenAI 的安全系统。

  • 不要使用插件来自动与真人对话,无论是通过模拟类似人类的响应还是通过使用预编程的消息进行回复。

  • 分发由 ChatGPT 生成的个人通信或内容(例如电子邮件、消息或其他内容)的插件必须表明该内容是由 AI 生成的。

与我们的其他使用政策一样,我们希望我们的插件政策随着我们对插件的使用和滥用的了解而改变。

官方示例

在Github上也有官方的文件检索插件的Python版实例,我以Redis作为存储,体验插件的开发。

  1. 安装 Python 3.10(如果尚未安装)。

  1. 克隆存储库:git clone https://github.com/openai/chatgpt-retrieval-plugin.git

  1. 导航到克隆的存储库目录:cd chatgpt-retrieval-plugin

  1. 安装poetry:pip install poetry

  1. 使用 Python 3.10 创建一个新的虚拟环境:poetry env use python3.10

  1. 激活虚拟环境:poetry shell

  1. 安装应用程序依赖项:poetry install

  1. 生成一个bearer_token ,使用https://jwt.io/随便生成一个

  1. 使用docker启动Redis容器,到examples/docker/redis/目录下执行docker compose up -d

  1. 设置所需的环境变量:

export DATASTORE=reids 
export BEARER_TOKEN=<your_bearer_token> 
export OPENAI_API_KEY=<your_openai_api_key>
  1. 在本地运行 API:poetry run start

  1. 访问 Swagger查看API 文档http://0.0.0.0:8000/docs

  1. 在Swagger设置bearer_token

  1. 调用/upsert接口创建数据

// 接口入参
{
  "documents": [
    {
      "id": "1",
      "text": "邀请小明参加后天的会议01",
      "metadata": {
        "source": "email",
        "source_id": "email003",
        "url": "<https://blog.csdn.net/xsgnzb/article/details/129723103?spm=1001.2014.3001.5502>",
        "created_at": "2023-03-23",
        "author": "xsg"
      }
    }
  ]
}

// 接口响应
{
  "ids": [
    "1"
  ]
}
  1. 调用/query接口查询数据

// 接口入参
{
  "queries": [
    {
      "query": "小红后天有什么安排",
      "filter": {
        "source": "email"
      },
      "top_k": 3
    }
  ]
}

// 接口响应
{
  "results": [
    {
      "query": "小红后天有什么安排",
      "results": [
        {
          "id": "1",
          "text": "邀请小红参加明天的会议01",
          "metadata": {
            "source": "email",
            "source_id": "email001",
            "url": "<https://blog.csdn.net/xsgnzb/article/details/129723103?spm=1001.2014.3001.5502>",
            "created_at": "1679529600",
            "author": "xueshengguo",
            "document_id": "1"
          },
          "embedding": null,
          "score": 0.160142925763
        },
        {
          "id": "string",
          "text": "邀请小红参加明天的会议01",
          "metadata": {
            "source": "email",
            "source_id": "email002",
            "url": "<https://blog.csdn.net/xsgnzb/article/details/129723103?spm=1001.2014.3001.5502>",
            "created_at": "1679529600",
            "author": "xueshengguo",
            "document_id": "string"
          },
          "embedding": null,
          "score": 0.16018631594
        },
        {
          "id": "3",
          "text": "邀请小明参加后天的会议02",
          "metadata": {
            "source": "email",
            "source_id": "email003",
            "url": "<https://blog.csdn.net/xsgnzb/article/details/129723103?spm=1001.2014.3001.5502>",
            "created_at": "1679529600",
            "author": "xueshengguo",
            "document_id": "3"
          },
          "embedding": null,
          "score": 0.175134840024
        }
      ]
    }
  ]
}

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

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

相关文章

phpstorm断点调试

环境&#xff1a;win10phpstorm2022phpstudy8lnmp 1、phpinfo(); 查看是否安装xdebug&#xff0c;没有走以下流程 2、phpstudy中切换不同版本php版本&#xff0c;有些版本不支持xdebug&#xff08;如php8.0.2&#xff09;&#xff0c;有些已经自带了&#xff08;如php7.3.9&a…

Java奠基】Java经典案例讲解

目录 卖飞机票 找质数 开发验证码 数组元素的复制 评委打分 数字加密 数字解密 抢红包 模拟双色球 二维数组 卖飞机票 需求&#xff1a;机票价格按照淡季旺季、头等舱和经济舱收费、输入机票原价、月份和头等舱或经济舱。按照如下规则计算机票价格&#xff1a; 旺季&…

技术分享——Java8新特性

技术分享——Java8新特性1.背景2. 新特性主要内容3. Lambda表达式4. 四大内置核心函数式接口4.1 Consumer<T>消费型接口4.2 Supplier<T>供给型接口4.3 Function<T,R>函数型接口4.4 Predicate<T> 断定型接口5. Stream流操作5.1 什么是流以及流的类型5.2…

[攻城狮计划]如何优雅的在RA2E1上运行RT_Thread

文章目录[攻城狮计划]|如何优雅的在RA2E1上运行RT_Thread准备阶段&#x1f697;开发板&#x1f697;开发环境&#x1f697;下载BSP&#x1f697;编译烧录连接串口总结[攻城狮计划]|如何优雅的在RA2E1上运行RT_Thread &#x1f680;&#x1f680;开启攻城狮的成长之旅&#xff0…

【ChatGPT】教你搭建多任务模型

ChatGPT教你搭建多任务模型 You: tell me what’s your version of gpt ? ChatGPT: As an AI language model developed by OpenAI, I am based on the GPT (Generative Pretrained Transformer) architecture. However, my version is known as GPT-3.5, which is an updat…

数据泄漏防护 (DLP) 工具保护敏感数据

通过实时安全监控&#xff0c;通过端点&#xff08;即 USB、电子邮件、打印等&#xff09;检测、中断和防止敏感数据泄露。使用 DataSecurity Plus 的数据泄漏防护 &#xff08;DLP&#xff09; 工具保护敏感数据不被泄露或被盗。DataSecurity Plus 主要功能包括&#xff1a; …

Android APP检查设备是否为平板

正文 Android APP判断设备是否为平板的三种方法&#xff1a; 通过屏幕尺寸判断。一般来说&#xff0c;平板电脑的屏幕尺寸比手机大很多&#xff0c;可以根据屏幕的长宽比和尺寸等信息来区分设备类型。通过屏幕像素密度判断。一般来说&#xff0c;平板电脑的屏幕像素密度比手机…

Java开发一年不到,来面试居然敢开口要20K,面完连8K都不想给~

前言 我的好朋友兼大学同学老伍家庭经济情况不错&#xff0c;毕业之后没两年自己存了点钱加上家里的支持&#xff0c;自己在杭州开了一家网络公司。由于公司不是很大所以公司大部分的开发人员都是自己面试的&#xff0c;近期公司发展的不错&#xff0c;打算扩招也面试了不少人…

四级数据库工程师 刷真题错题整理(三)数据库原理

1.数据模型是对现实世界进行抽象的工具&#xff0c;它按算机系统的观点模于提数据库系统中信息表示和操作手段的形式框架&#xff0c;主要用于 DBMS 的实现&#xff0c;是数据库系统的核心和基础。其中&#xff0c;数据操作是对数据间的动态行为。 2.数据库的型是稳定的&#…

day38_JDBC

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、数据库连接池 二、反射 三、封装DBUtil 零、 复习昨日 SQL注入 预处理语句 String sql "select * from user where id ?"; PreparedStat…

企业微信中如何拉黑?拉黑个人和群成员有什么区别?

企业微信既可以拉黑个人好友&#xff0c;又可以拉黑群好友。 1. 拉黑个人好友 拉黑好友通俗来说就是不想再接收到对方的信息&#xff0c;企业微信可以通过设置消息免打扰的方式来屏蔽对方的消息。 【客户聊天界面】-【右上角的小人标志】-【第一栏名称进入】-【右上角三点】…

C语言——动态内存管理 malloc、calloc、realloc、free的使用

目录 一、为什么存在动态内存分配 二、动态内存函数的介绍 2.1malloc和free 2.2calloc 2.3realloc 三、常见的动态内存错误 3.1对NULL指针的解引用操作 3.2对动态开辟空间的越界访问 3.3对非动态开辟的内存使用free释放 3.4使用free释放一块动态开辟内存的一部分 3.5…

奇安信_防火墙部署_透明桥模式

奇安信_防火墙部署_透明桥模式一、预备知识二、项目场景三、拓扑图四、基本部署配置1. 登录web控制台2.连通性配置3.可信主机配置4.授权导入5.特征库升级6.安全配置文件五、透明桥配置1. 创建桥2. 端口绑定桥3. 创建桥端口六、结语一、预备知识 安全设备接入网络部署方式 二、…

运算放大器:电压比较器

目录一、单限电压比较器二、滞回电压比较器三、窗口电压比较器最近在学习电机控制&#xff0c;遇到了与运算放大电路相关的知识&#xff0c;然而太久没有接触模拟电路&#xff0c;对该知识已经淡忘了&#xff0c;及时温故而知新&#xff0c;做好笔记&#xff0c;若有错误、不足…

字节跳动测试岗面试记:二面被按地上血虐,所幸Offer已到手...

在互联网做了几年之后&#xff0c;去大厂“镀镀金”是大部分人的首选。大厂不仅待遇高、福利好&#xff0c;更重要的是&#xff0c;它是对你专业能力的背书&#xff0c;大厂工作背景多少会给你的简历增加几分竞争力。 但说实话&#xff0c;想进大厂还真没那么容易。最近面试字…

3分钟阐述这些年我的 接口自动化测试 职业生涯经验分享

接口自动化测试学习教程地址&#xff1a;https://www.bilibili.com/video/BV1914y1F7Bv/ 你好&#xff0c;我是凡哥。 很高兴能够分享我的接口自动化测试经验和心得体会。在我目前的职业生涯中&#xff0c;接口自动化测试是我经常进行的一项任务。通过不断地学习和实践&#xf…

【C++】map 和 set

文章目录一、关联式容器与键值对1、关联式容器2、键值对 pair3、树形结构的关联式容器二、set1、set 的介绍2、set 的使用三、multiset四、map1、map 的介绍2、map 的使用五、multimap一、关联式容器与键值对 1、关联式容器 在C初阶的时候&#xff0c;我们已经接触了 STL 中的…

基于SpringBoot的酒店管理系统

系统环境 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/i…

matplotlib参数详解

文章目录一、简介二、安装与调用三、绘图与风格设置3.1、绘图标记3.1.1、标记类型&#xff08;marker*&#xff09;3.1.2、标记大小、内部和边框颜色&#xff08;ms10、mfcr、mecg&#xff09;3.2、绘图线3.2.1、线类型&#xff08;linestyle--&#xff09;3.2.2、线宽&#xf…

C++入门教程||C++ 字符串||

C 字符串C 字符串C 提供了以下两种类型的字符串表示形式&#xff1a;C 风格字符串C 引入的 string 类类型C 风格字符串C 风格的字符串起源于 C 语言&#xff0c;并在 C 中继续得到支持。字符串实际上是使用 null 字符 终止的一维字符数组。因此&#xff0c;一个以 null 结尾的…