Skip to content

🔰 ChatGPT 发布对插件的支持

🕒 Published at:

ChatGPT 发布对插件的支持,告诉 ChatGPT 你可以提供什么在线服务,由它作为“前端”向用户提供

目录

2023 年北京时间 3 月 24 凌晨,OpneAI 在推特上官宣:

image-20230324114533386

指向的链接是: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 文件:

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 列表项的功能。

py
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 规范说明看起来像这样:

yaml
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辅导的读者请与作者联系。作者博客:艺述论