ChatGPT Plugin 开发颠覆了我们对传统插件开发的认知,外行看热闹,内行看文档。
ChatGPT 插件系统使语言模型在安全,受限的条件下能够与外部工具或服务进行交互。以解决大型语言模型目前面临的挑战(例如:跟上最新事件、访问最新信息以及提供基于证据的参考来增强模型的响应能力)。
插件还使用户能够评估模型输出的可信度并检查其准确性。然而,插件也存在潜在的风险,包括可能导致有害或意外行为。
ChatGPT 插件平台的开发包括几个安全措施和红队演练,以识别潜在的风险并制定安全设计的缓解措施。访问插件的部署正在逐步推出,并鼓励研究人员研究这个领域的安全风险和缓解措施。ChatGPT 插件系统具有广泛的社会影响,并可能产生重大的经济影响。
ChatGPT 插件文档(Alpha)
ChatGPT 插件文档[1],插件目前处于 alpha 阶段,需要申请加入候补名单才能获得访问权限。在 alpha 期间,OpenAI 会与用户和开发人员密切合作,对插件系统进行迭代,API 可能会发生重大变化。
插件简介
OpenAI 插件将 ChatGPT 与第三方应用程序连接起来。这些插件使 ChatGPT 能够与开发人员定义的 API 进行交互,增强 ChatGPT 的功能,使其能够执行各种操作。插件可以让 ChatGPT 做以下事情:
检索实时信息;例如,体育比分、股票价格、最新新闻等。
检索知识库信息;例如,公司文档、个人笔记等。
代表用户执行操作;例如,预订航班、订购食物等。
插件开发者公开一个或多个 API 端点,伴随着一个标准化清单文件和一个 OpenAPI 规范。这些定义了插件的功能,允许 ChatGPT 消耗这些文件并调用开发者定义的 API。
AI 模型作为智能 API 调用者。给定 API 规范和使用 API 的自然语言描述,模型主动调用 API 执行操作。例如,如果用户问“在巴黎住几晚应该住哪里?”,模型可以选择调用酒店预订插件 API,接收 API 响应,并生成结合API数据和自然语言能力的用户可见答案。
插件开发流程
要构建一个插件,理解端到端流程非常重要。
创建一个清单文件并将其托管在 yourdomain.com/.well-known/ai-plugin.json
:
该文件包括有关插件的元数据(名称、标志等)、所需的身份验证详细信息(身份验证类型、OAuth URL等)以及要公开的端点的 OpenAPI 规范
模型将看到 OpenAPI 描述字段,可以用于为不同字段提供自然语言描述。
建议在开始时仅公开 1-2 个端点,最小化参数数量,以最小化文本长度。
插件说明、API 请求和 API 响应都插入到与 ChatGPT 的对话中。这将占用模型的上下文限制。
在 ChatGPT UI[2] 中注册插件
从顶部下拉菜单中选择插件模型,然后选择“插件”、“插件商店”,最后选择“安装未经验证的插件”或“开发自己的插件”。
如果需要身份验证,请提供 OAuth 2 client_id 和 client_secret 或 API 密钥。
用户激活插件
用户必须在 ChatGPT UI 中手动激活插件(ChatGPT 不会默认使用您的插件)。
在 alpha 版期间,插件开发人员将能够与 15 个其他用户共享其插件(当前只有其他开发人员可以安装未经验证的插件)。随着时间的推移,OpenAI 将推出一种方式,可以提交你的插件进行审核,以向 ChatGPT 的所有用户公开。
如果需要身份验证,则用户将通过 OAuth 被重定向到您的插件。您还可以选择在此处创建新帐户。
将来,OpenAI 希望构建功能,帮助用户发现有用和流行的插件。
用户开始对话
OpenAI 将向 ChatGPT 中注入您的插件的紧凑描述,对终端用户不可见。这将包括插件描述、端点和示例。
当用户提出相关问题时,如果似乎相关,模型可能选择从你的插件调用 API。对于 POST 请求,我们要求开发人员构建用户确认流程。
模型会将 API 结果合并到其对用户的响应中。
模型可能会在其响应中包括从API调用返回的链接。这将显示为丰富的预览(使用 OpenGraph 协议[3],在其中我们提取 site_name、title、description、image 和 url 字段)。
目前,OpenAI 将在 Plugin 对话头中发送用户的国家和州信息(例如:如果你在加利福尼亚州,它会显示为 {"openai-subdivision-1-iso-code": "US-CA"}
)。对于更多的数据源,用户需要通过同意屏幕进行选择。这对于购物、餐厅、天气等非常有用。可以在 OpenAI 开发者使用条款[4]中了解更多信息。
插件开发
注意:此教程是根据官网文档总结而来,具体细节可能存在变化。
我们将使用 OpenAI 的插件系统创建一个简单的待办事项列表(to-do list)插件。它使用 Python 开发,并部署在 Replit 上。插件将使用服务级别(认证有 4 种方式:无认证,服务级,用户级和 OAuth,具体可查文档 Plugin authentication[5])的身份验证令牌进行身份验证,并允许用户创建、查看和删除待办事项。我们还需要定义一个 OpenAPI 规范以匹配我们插件中定义的端点。要完成本教程,你需要以下知识储备:
对 Python[6] 有基本的了解
Replit 账户(在 replit.com[7] 免费注册),非必需,你可以自行部署服务器
OpenAI API 密钥(在 openai.com[8] 免费注册,API 收费)
文本编辑器(VSCode[9], Sublime Text[10] 等)或 Replit IDE
开发步骤
Step1
在项目中创建一个名为 manifest.json
的插件清单,并添加以下代码:
{
"schema_version": "v1",
"name_for_human": "TODO Plugin (service http)",
"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": "service_http",
"authorization_type": "bearer",
"verification_tokens": {
"openai": "<YOUR_OPENAI_KEY>"
}
},
"api": {
"type": "openapi",
"url": "https://<YOUR_REPO>.<YOUR_OWNER>.repl.co/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "https://<YOUR_REPO>.<YOUR_OWNER>.repl.co/logo.png",
"contact_email": "<YOUR_EMAIL>",
"legal_info_url": "http://www.example.com/legal"
}复制
<YOUR_OPENAI_KEY>
: API 令牌<YOUR_REPO>
: Replit 应用名称<YOUR_OWNER>
: Replit 用户名<YOUR_EMAIL>
: 邮箱地址
Step2
创建
main.py
文件,实现插件逻辑
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()复制
部署 Replit
上述代码比较啰嗦,如果你想快速部署,可以尝试以下步骤,直接从 lencx/chat-todo-plugin[11] 仓库导入代码到 Replit,即可以运行体验(
manifest.json
中的变量需要替换为自己的)。
打开 Replit,点击
Create Repl
按钮出现弹窗后,点击右上角的
Import from GitHub
按钮在 GitHub URL 中输入
https://github.com/lencx/chat-todo-plugin
,Language 选择Python
然后点击右下角的
Import from GitHub
按钮,等待初始化完成点击
Run
按钮,等待运行完成
服务器运行后,就可以通过使用 ChatGPT 向插件端点发送请求来对其进行测试。如果你顺利走到这一步,那么恭喜你,你已经掌握了 ChatGPT 插件开发!
注意:因为我还未获得开发权限,后续测试可能还会遇到别的问题,所以此系列未完待续...,可以关注
lencx/chat-todo-plugin
项目获取最新动态。
References
ChatGPT 插件文档: https://platform.openai.com/docs/plugins/introduction
[2]ChatGPT UI: https://chat.openai.com/chat
[3]OpenGraph 协议: https://ogp.me/
[4]OpenAI 开发者使用条款: https://openai.com/policies/plugin-terms
[5]Plugin authentication: https://platform.openai.com/docs/plugins/authentication/plugin-authentication
[6]Python: https://www.python.org
[7]replit.com: https://replit.com
[8]openai.com: https://openai.com
[9]VSCode: https://code.visualstudio.com
[10]Sublime Text: https://www.sublimetext.com
[11]lencx/chat-todo-plugin: https://github.com/lencx/chat-todo-plugin