了解ChatGPT插件-看看这一篇文章吧
ChatGPT插件常见宣传语
ChatGPT+插件释放惊人潜力-Greg Brockman,ChatGPT 的 iPhone 时刻!ChatGPT 支持联网、添加插件支持!AI 从工具进化成 App Store 这样的应用商店平台!
ChatGPT宣布推出插件功能,ChatGPT的实时数据获取、自定义数据知识接入、精确数学计算等相关能力大幅提高。
What’s More:OpenAI允许开发者自定义开发、上传插件到插件平台,这将掀起新一轮的插件开发狂潮。
本篇文章主要介绍了ChatGPT Plugins的使用和其主要原理,并简单聊了聊插件的开发。笔者近期在看LLM应用如何做grounding和retrieval相关的内容,将在接下来的文章中聊,这里先做个预告。
什么是ChatGPT插件
ChatGPT插件是一种通过将ChatGPT模型集成到网站或应用程序中,使其能够自动回答用户提出的问题或提供相关信息的工具。它可以为用户提供快速、实时和个性化的响应,增强用户体验。
Plugin 的推出意味着 OpenAI 正在追求平台化。做个不恰当的比喻,如果把 OpenAI 相当于苹果公司,那么GPT 模型相当于 iPhone,推出的插件系统则相当于 App Store。
插件使ChatGPT哪些方面能力增强
插件功能简单来讲,就是chatgpt可以连接第三方的api,在使用chatgpt的时候可以调用第三方的插件,以此增强 ChatGPT 的功能(检索实时信息、检索内部知识库)并允许其执行更加广泛的操作。
开发插件的前置条件
目前ChatGPT Plugins对全部plus用户开放使用,但成为插件开发者需要加入ChatGPT Plugins developer的白名单。
开发的插件通过openai的审核后,会加入到plugins store中开放给全部的用户使用。
成为ChatGPT插件开发者,需要满足以下三个条件:
- 能够科学上网;
- ChatGPT账户开通Plus;
- 加入ChatGPT Plugins developer的白名单,申请链接:openai.com/waitlist/pl…
开通ChatGPT plus
笔者充值ChatGPT plus时,下述方法有效,现在有说已经不好用的,所以这块仅供参考。
- 使用欧易充USDT
欧易(买入后24小时内不能进行转账),如果你有朋友已经玩上了,你可以直接让朋友用depay给你的depay进行转账,这样欧易这里就可以省略了。
- 网站地址 www.okx.com/cn
- app下载地址 www.okx.com/cn/download…
你可以全程操作网站就可以完成。也可以使用手机APP,当然这里就存在一个问题,如果是android自己捯饬下载一下就可以直接在手机上安装了。
通过快捷买币(没有通过C2C是因为需求没那么大,不够资格),选择USDT,输入要买入的金额 CNY(元)。
查看选择的是支付宝、微信还是银行卡转账,注意一下细节就好了,这里一般只要你转账给对方,一两分钟很快就能收到到账信息,在欧易里查看即可。
- 安装depay
depay(只能接受USDT的TRC20链路的充值)下载DepayAPP地址 www.depay.one/zh-cn/index…
如果是android 上面的链接中就可以下载apk。而如果是IOS的话,这里是需要切换到海外的App Store。
这里是注册链接depay.depay.one/web-app/reg…
根据顺序先申请一张MD卡:卡=>申请卡==>标准卡==> KYC认证(输入身份信息正常填写即可)==>下一步==> 激活卡片==>输入信息申请成功
然后按照顺序依次打开:Depay app、钱包、USDT、充币、TRC20、这个时候便会生成一个充值地址
- 欧易中提币USDT到depay
按照顺序依次打开:欧易 app、提币、USDT、链上提现
将depay中生成的充值地址复制到这里的提币地址,然后选择金额,最后点击提交即可。
经过邮箱验证和手机验证成功后,经过大概五分钟钱便可以在depay中看到。
- depay中将USDT转换为USD
在depay app中依次打开:钱包、实时兑换(暂时在顶部位置)、支付USDT(输入你想要的额度)、得到USD, 最后点击提交兑换即可。
- 将USD转入卡中
然后在depay首页卡中便可以看到余额增多了,当然有可能要稍等片刻 刷新一下。
- 开通ChatGPT PLUS
ai.com登录==>chat.openai.com==>左下角Updrade To Plus==>Updrage Plan==>填写支付方式,其中CVC就是depay中的CVV安全码。
这里最重要的就是账单地址,这是我之前的地址,我是通过谷歌地图直接找的一个地址,你可以在我附近地址差不多的位置
United States of America
631 South College Avenue(这个你可以谷歌地图到附近再找找其他街道,其他可以和我一样即可)
Newark 19716
Delaware
如果填写完毕点击最后的订阅查看是否成功,如果失败,基本就是IP的问题。所以看到最后如果是IP不太行的话,大概率充值是失败的了。
加入ChatGPT Plugins waitlist
目前ChatGPT Plugins是beta版本,成为Plugins developer需要加入白名单,申请可以通过如下链接openai.com/waitlist/pl…
由于目前全球开发者都在申请加入,等待时间可能较长,如果暂时未加入也不要气馁,可以先学ChatGPT Plugins的开发,可以先调研做什么类型的插件,并在本地开发接口做好准备。
如何使用ChatGPT插件
- 开启插件功能
- 在plugin store选择插件
- 安装插件
- 点击右下角[Develop your own plugin]可以开发调试自己本地的plugin
- 输入本地的endpoint,调试自己本地的插件
- 以Wolfram插件为例,ChatGPT首先根据用户输入分析出用户意图是使用Wolfram插件,然后抽取槽位作为插件输入,插件进行处理后,返回结果
ChatGPT插件的原理
为了画图描述简单清晰,下面流程描述单轮的情形,多轮的情况与单轮类似。注意:下面流程是笔者自己的理解,openai的真实实现步骤的拆分粒度可能与笔者有出入(笔者出于易于理解的角度这样拆分)。步骤3、步骤4有可能在一个prompt内完成。
-
步骤1:用户输入问题(以calculate 123*456),触发会话开始;
-
步骤2:根据用户当前安装并选中的插件(beta版本仅支持选中3个插件),生成一个紧凑的描述(包括plugin description, endpoints, and examples),这里我们将它标记为compact plugin description。
-
步骤3:判断compact plugin description与用户问题(calculate 123*456)相关性(relevant),判断相关性可能使用ground+retrieval(下一篇文章详细聊这一块,笔者近期把这块看差不多了)
- 如果无关,则将用户问题(calculate 123*456)交给GPT,GPT完成completion;
- 如果有关,则将插件信息与用户问题一起交给GPT,并进入步骤4
-
步骤4:GPT选中插件(wolfram),并抽取出槽位(input:”123*456″)
-
步骤5:插件执行器负责调用具体的API并传入parameters
-
步骤6:插件负责执行,并将执行结果返回,返回结果样例参考如何使用插件小节
-
步骤7:插件执行器将执行结果和上下文传给GPT,GPT做completion,并返回给用户
ChatGPT插件开发
插件清单和接口定义文件
ChatGPT插件都需要定义两个文件ai-plugin.json和openapi.yaml。
- ai-plugin.json 是 ChatGPT 插件的清单文件,用于记录插件的基本信息和 API 服务身份验证设置。当通过 ChatGPT UI 安装插件时,系统会在后端查找此文件,如果找不到文件,则无法安装插件。
- openapi.yaml文件的作用是,采用 OpenAPI Specification(OAS)格式定义了一种标准的、与语言无关的 HTTP API 接口,允许人类和计算机理解服务的功能。说白了就是告诉GPT我这个插件提供了哪些接口。
ai-plugin.json
{
"schema_version": "v1",
"name_for_human": "TODO Plugin",
"name_for_model": "todo",
"description_for_human": "Plugin for managing a TODO list. You can add, remove and view your TODOs.",
"description_for_model": "Plugin for managing a TODO list. You can add, remove and view your TODOs.",
"auth": {
"type": "none"
},
"api": {
"type": "openapi",
"url": "http://localhost:3333/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "http://localhost:3333/logo.png",
"contact_email": "support@example.com",
"legal_info_url": "http://www.example.com/legal"
}
这里相对重要的配置字段是:
字段 | 说明 |
---|---|
schema_version | 清单架构版本 |
name_for_human | 插件名字,用于显示 |
name_for_model | 插件名字,用于模型定位 |
description_for_human | 插件的功能描述,Plugins store中用于插件说明 |
description_for_model | 描述插件的功能,这个字段很重要,在如何写好两个文件章节具体介绍。 |
auth | 使用的是没有身份验证的机制,如果使用插件api接口时面向所有用户开发,不需要身份的验证,便可以这样设置。 |
api | API规范 |
logo_url | 获取插件的logo |
contact_email | 用于安全/审核联系、支持和停用的电子邮件联系人 |
legal_info_url | 重定向URL供用户查看插件信息 |
openapi.yaml
OpenAPI 规范(OpenAPI Specification)是一种开放的、标准化的、机器可读的 API 描述格式,它可以帮助开发者快速地创建、测试、发布和维护 API。OpenAPI 也可以用来生成 API 的文档、客户端代码、服务器代码等。
OpenAPI 的规范由 OpenAPI Initiative(OAI)组织制定和维护,目前最新的版本是 3.1.0。OpenAPI 规范使用 JSON 或 YAML 语言来定义 API 的元数据、路径、参数、响应、安全等信息。OpenAPI 规范是一种通用的和语言无关的接口,它可以让人类和计算机都能够发现和理解 API 的能力,而不需要访问源代码、额外的文档或网络流量检查。
说白了,openai.yaml其实就是一个标准的 OpenAPI 规范文件,可以使用例如Apifox,用可视化的界面来编写你的 API 文档,并且加以自然语言的接口描述信息,选择导出 OpenAPI 格式就可以得到一份非常标准的 OpenAPI 格式描述文件。
深入了解:OpenAPI 规范 (中文版)
openapi: 3.0.1
info:
title: TODO Plugin
description: A plugin that allows the user to create and manage a TODO list using ChatGPT. If you do not know the user's username, ask them first before making queries to the plugin. Otherwise, use the username "global".
version: 'v1'
servers:
- url: http://localhost:5003
paths:
/todos/{username}:
get:
operationId: getTodos
summary: Get the list of todos
parameters:
- in: path
name: username
schema:
type: string
required: true
description: The name of the user.
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/getTodosResponse'
post:
operationId: addTodo
summary: Add a todo to the list
parameters:
- in: path
name: username
schema:
type: string
required: true
description: The name of the user.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/addTodoRequest'
responses:
"200":
description: OK
delete:
operationId: deleteTodo
summary: Delete a todo from the list
parameters:
- in: path
name: username
schema:
type: string
required: true
description: The name of the user.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/deleteTodoRequest'
responses:
"200":
description: OK
components:
schemas:
getTodosResponse:
type: object
properties:
todos:
type: array
items:
type: string
description: The list of todos.
addTodoRequest:
type: object
required:
- todo
properties:
todo:
type: string
description: The todo to add to the list.
required: true
deleteTodoRequest:
type: object
required:
- todo_idx
properties:
todo_idx:
type: integer
description: The index of the todo to delete.
required: true
如何写好两个文件
写好两个文件的重点是写好description
ai-plugin.json和openapi.yaml两个文件中都有description字段,主要是用来描述插件和API的功能。
引用OPENAI的Best practices看一下如何写好这个字段。
- description字段不要试图控制ChatGPT的情绪、个性、或者确切回应。ChatGPT负责编写插件的对应回复。
Bad example:
When the user asks to see their todo list, always respond with "I was able to find your todo list! You have [x] todos: [list the todos here]. I can add more todos if you'd like!"
Good example:
[no instructions needed for this]
2. 当用户的问题与插件提供的特地服务无关时,descriptions字段不应鼓励Chatgpt使用插件。
Bad example:
Whenever the user mentions any type of task or plan, ask if they would like to use the TODOs plugin to add something to their todo list.
Good example:
The TODO list can add, remove and view the user's TODOs.
3. 不要为插件设定触发特定的触发条件
Bad example:
When the user mentions a task, respond with "Would you like me to add this to your TODO list? Say 'yes' to continue."
Good example:
[no instructions needed for this]
4. 除非有必要,否则插件API响应应返回原始数据,而不是自然语言响应。Chatgpt将使用返回的数据提供自己的自然语言响应。
Bad example:
I was able to find your todo list! You have 2 todos: get groceries and walk the dog. I can add more todos if you'd like!
Good example:
{ "todos": [ "get groceries", "walk the dog" ] }
权限(TODO)
完全开放不需要认证。
"auth": {
"type": "none"
},
官方文档:platform.openai.com/docs/plugin…
参考:www.jianshu.com/p/309b51d76…
一个简单的TODO插件的代码
import os
import quart
import quart_cors
from quart import Quart, jsonify, request
PORT = 5002
TODOS = {}
# 从环境变量中获取 auth key
SERVICE_AUTH_KEY = os.environ.get("SERVICE_AUTH_KEY")
# 创建 app,并启用 CORS,allow_origin="*" 为允许从任何来源使用应用程序,不推荐此写法
# app = quart_cors.cors(Quart(__name__), allow_origin="*")
app = quart_cors.cors(
Quart(__name__),
allow_origin=[
f"http://localhost:{PORT}",
"https://chat.openai.com",
]
)
# 添加一个 before_request 钩子来检查授权标头
@app.before_request
def assert_auth_header():
auth_header = request.headers.get("Authorization")
print(auth_header)
# 检查 auth 是否丢失或不正确,并在需要时返回错误
if not auth_header or auth_header != f"Bearer {SERVICE_AUTH_KEY}":
return jsonify({"error": "Unauthorized"}), 401
# 路由:获取所有用户 TODO 列表
@app.route("/todos", methods=["GET"])
async def get_todos():
return jsonify(TODOS)
# 路由:获取特定用户的 TODO 列表
@app.route("/todos/<string:username>", methods=["GET"])
async def get_todo_user(username):
todos = TODOS.get(username, [])
return jsonify(todos)
# 路由:特定用户添加 TODO 项
@app.route("/todos/<string:username>", methods=["POST"])
async def add_todo(username):
request_data = await request.get_json()
todo = request_data.get("todo", "")
TODOS.setdefault(username, []).append(todo)
return jsonify({"status": "success"})
# 路由:特定用户删除 TODO 项
@app.route("/todos/<string:username>", methods=["DELETE"])
async def delete_todo(username):
request_data = await request.get_json()
todo_idx = request_data.get("todo_idx", -1)
if 0 <= todo_idx < len(TODOS.get(username, [])):
TODOS[username].pop(todo_idx)
return jsonify({"status": "success"})
# 路由:获取 logo
@app.get("/logo.png")
async def plugin_logo():
filename = 'logo.png'
return await quart.send_file(filename, mimetype='image/png')
# 路由:插件清单,当通过 ChatGPT UI 安装插件时,ChatGPT 会在后端查找位于 /.well-known/ai-plugin.json。
# 如果找不到文件,则无法安装插件。
@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")
# 路由:OpenAPI 规范,帮助 ChatGPT 大模型了解你的 API
@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()
开源源码
GPT插件的实现可以很简单,也可能很复杂。
简单的插件如lencx开发的TODO这个Demo,它只有增、改、删、查四项功能,当收到用户不同的请求后,它就在内存中做对应的操作。
复杂点的插件如chatgpt-retrieval-plugin,它可以让GPT访问个人或组织的信息源(经过授权),并通过自然语言的问题或需求,获取最相关的信息片段。
学习插件开发代码可以先从TODO这个Demo开始学起,然后逐步深入到chatgpt-retrieval-plugin。
ChatGPT Plugins VS LangChain
ChatGPT Plugins | LangChain | |
---|---|---|
自研模型是否可用 | 否 | 可以 |
是否开源 | 框架闭源,部分插件开源 | 完全开源 github.com/hwchase17 |
开发语言 | 任何编程语言 | nodejs和python |
程序本地运行 | 调试模式可用localhost, | 可以 |
权限控制 | 支持 | 支持 |
GPT Plugin的未来
- 插件模式并不代表AI智能的提升,但会是短期内主流的应用方
- 随着时间的推移,相信GPT会增加更多的插件类型和功能,覆盖更多的行业和场景,如网安,遥感,办公等。
- 另外,提高插件的安全性和可靠性,防止插件被滥用或泄露敏感信息,保护用户的隐私和权益,是GPT Plugin需要重点解决的问题。
- 而优化插件的交互和体验,让用户可以更方便和自然地使用插件,提高插件的智能度和友好度则是 GPT Plugin的长远目标。
- 不可或缺的是,探索插件的创新和商业模式,让插件开发者可以获得更多的收益和激励,让插件用户可以获得更多的价值和服务是GPT可以长久下去的基石。