ChatGPT 发布对插件的支持,告诉 ChatGPT 你可以提供什么在线服务,由它作为“前端”向用户提供
目录
2023 年北京时间 3 月 24 凌晨,OpneAI 在推特上官宣:
指向的链接是:https://openai.com/blog/chatgpt-plugins
你可以立即申请加入等待列表:https://openai.com/waitlist/plugins
或阅读开发插件的文档:https://platform.openai.com/docs/plugins/introduction
插件可以干什么事?
- 检索实时信息,例如体育比分、股票价格、最新消息等;
- 检索知识库信息,例如公司文档、个人笔记等;
- 代表用户执行操作,例如预订航班、订购食物等。
总而言之,可以充许你通过 ChatGPT 向你的同事或用户提供你能提供的在线服务。
举个例子:
如果用户在线问 ChatGPT:我应该在巴黎的哪里住几晚?
ChatGPT 模型可以选择调用酒店“预订插件 API”,接收 API 响应,并将 API 返回的数据组合起来,基于其自然语言处理能力,向用户返回人类友好的答案。
这里提到了 API,那么什么是 API?
什么是 API?
API 代表应用程序编程接口,它是一组用于构建和集成应用程序软件的定义和协议。
你可以把 API 理解为餐馆的服务员,举个例子,假如我们去一家饭馆,桌面上摆着一份菜单,后厨能提供菜单上的菜式。服务员是我们与后厨沟通的桥梁,你告诉服务员你选的菜,然后他再将菜带回到你的餐桌上。在这接口调用中,相当于服务员带着你的 request 去告诉 system,然后将 response 带回给你。
至此,全世界都可以开放自己系统的 API,然后提供给 ChatGPT 调用,而 ChatGPT 作为“前端”,向用户提供在线服务。
插件的宣布,宣告着智能革命的开始,从此 ChatGPT 可以访问在线服务和知识内容了。以各大平台仅存的优势就真的只剩下数据了。
如何申请?
你可以在这里申请加入等待列表:https://openai.com/waitlist/plugins
如何开发ChatGPT Plugins(插件)?
创建 ChatGPT 插件需要三个步骤:
- 构建 API 代码,这是插件服务的核心;
- 接口文档化,遵照 OpenAPI 规范,以 yaml 或 JSON 格式描述 API,告诉 ChatGPT 你的接口如何调用;
- 创建一个 JSON 清单文件,该文件将定义插件的相关元数据,位于/.well-known/ai-plugin.json,它有指定的结构及字段名称,告诉 ChatGPT 你的插件是干什么用的。
具体步骤,以官方构建一个简单的待办事项列表插件为例说明一下:
第 1 步
首先,使用以下字段定义一个 manifest.json 文件:
{
"schema_version": "v1",
"name_for_human": "TODO Plugin (no auth)",
"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": "PLUGIN_HOSTNAME/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "PLUGIN_HOSTNAME/logo.png",
"contact_email": "dummy@email.com",
"legal_info_url": "http://www.example.com/legal"
}
{
"schema_version": "v1",
"name_for_human": "TODO Plugin (no auth)",
"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": "PLUGIN_HOSTNAME/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "PLUGIN_HOSTNAME/logo.png",
"contact_email": "dummy@email.com",
"legal_info_url": "http://www.example.com/legal"
}
该文件将在/.well-known/ai-plugin.json 这个位置提供。
第 2 步
接下来,我们可以定义几个简单的 Python 接口,为特定用户提供创建、删除和获取 todo 列表项的功能。
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"]
# fail silently, it's a simple plugin
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()
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"]
# fail silently, it's a simple plugin
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()
这是一个在内存中实现简单的增删改查功能的 Py 示例。它同时做为 Web Server 程序还提供了 ChatGPT 需要的 ai-plugin.json 和 openapi.yaml。
第 3 步
最后,我们需要设置和定义 OpenAPI 规范,以匹配本地或远程服务器上定义的接口。您不需要通过规范公开 API 的全部功能,而是可以选择性地让 ChatGPT 只访问某些功能。
有不少工具可以自动将服务器定义代码转换为 OpenAPI 规范,因此您不需要手动执行此操作。对于上面的 Python 代码,它的 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: PLUGIN_HOSTNAME
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
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: PLUGIN_HOSTNAME
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
这是 openapi.yaml 文件的内容,它将告诉 ChatGPT,如何调用接口。
这里提代了 OpenAI 规范,可能有读者不了解,那么什么是 OpenAI 规范?
什么是 OpenAI 规范?
OpenAPI 规范(OAS),是定义一个标准的、与具体编程语言无关的 RESTful API 的规范。
OpenAPI 规范使得人类和计算机都能在“不接触任何程序源代码和文档、不监控网络通信”的情况下理解一个在线服务的作用。
遵循该规范的好处是什么?
如果您遵循 OpenAPI 规范来定义您的 API,那么您就可以用文档生成工具来展示您的 API,用代码生成工具来自动生成其它编程语言的服务器端和客户端代码,用自动测试工具进行测试等等。
简而言之,通过该规范,我们即可以由接口程序代码生成规范,也可以由规范生成其它后端语言实现的接口程序代码。
这里有一个份关于 OpenAI 规范的中文文档,可以考虑:https://openapi.apifox.cn/
如何由 OpenAI 规范文件生成代码?
可以使用 openapi-generator-cli。
它的工具仓库地址是:https://github.com/openapitools/openapi-generator-cli
第 1 步,安装工具
npm install @openapitools/openapi-generator-cli -g
npm install @openapitools/openapi-generator-cli -g
第 2 步,由规范生成代码
下面是一个使用 OpenAPI Generator 生成 Python 服务端代码的示例。
$ openapi-generator generate -i /path/to/openapi.yaml -g python-flask -o /output/directory
$ openapi-generator generate -i /path/to/openapi.yaml -g python-flask -o /output/directory
其中,/path/to/openapi.yaml 是 OpenAPI 规范文件的路径,-g 指定使用的生成器(这里是 python-flask),-o 指定输出目录。
小结
1946年电子计算机被发明出来的时候,当时没有多少人意识到它将发挥多大作用,我们现在知道的信息革命其实是我们后来总结的。今天开始的智能革命,其实具有同样的特征,如果说ChatGPT的发布还不能让你感到震撼的话,那么今天它发布的ChatGPT Plugins,应该能够引起你足够的重视了。一个联网的智能机器人,无穷的数据+无穷的算力,谁也不知道将产生怎样的结果。智能革命已经到来,AI或许不会取代的人,但会使用AI的人,一定会把不会使用AI的人取代。
你对ChatGPT了解多少,开始试用了吗?如果你是一名程序员,开始研究它的API文档了吗?
新人从0到1编程自学经典《微信小游戏开发》全套书籍已经在京东、当当上架,需要签名版及1v1辅导的读者请与作者联系。作者博客:艺述论。