快速开始

快速开始

创建插件需要三个步骤:

  • 构建一个 API
  • OpenAPI 规范格式 的 API 文档文件(yaml 或 JSON 格式)
  • 创建一个 JSON manifest 文件,该文件将定义插件的相关元数据

本节其余部分的重点是通过定义 OpenAPI 规范 和 manifest 文件来创建待办事项列表插件。

插件 manifest​

每个插件都需要一个名为 ai-plugin.json 的文件,该文件需要托管在 API 所在的域名下。例如,一家名为 example.com 的公司将通过 https://example.com 访问插件 JSON 文件,因为这是托管其 API 的地方。当您通过 ChatGPT UI 安装插件时,我们会在后台查找 /.well-known/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": "https://vsq7s0-5001.preview.csb.app/logo.png",
"contact_email": "support@example.com",
"legal_info_url": "http://www.example.com/legal"
}

如果您想查看插件文件的所有可能选项,可以参考下面的定义。

类型 描述/选项
schema_version String 清单(manifest)架构版本
name_for_model String 模型将用于定位插件的名称
name_for_human String 人类可读的名称,例如公司全名
description_for_model String 更适合模型的描述,例如令牌上下文长度注意事项或关键字用法,以改进插件提示。
description_for_human String 插件的人类可读描述
auth ManifestAuth 身份验证模式
api Object 接口规范
logo_url String 用于获取插件徽标的网址
contact_email String 用于安全/审核联系、支持和停用的电子邮件联系人
legal_info_url String 重定向 URL,以便用户查看插件信息
HttpAuthorizationType HttpAuthorizationType “持有者”或“基本”
ManifestAuthType ManifestAuthType “无”、“user_http”、“service_http”或“oauth”
interface BaseManifestAuth BaseManifestAuth 类型:清单(manifest)身份验证类型;说明:字符串;
ManifestNoAuth ManifestNoAuth 无需身份验证:BaseManifestAuth & { type: 'none', }
ManifestAuth ManifestAuth ManifestNoAuth, ManifestServiceHttpAuth, ManifestUserHttpAuth, ManifestOAuthAuth

以下是使用不同身份验证方法的示例:

# App-level API keys
type ManifestServiceHttpAuth = BaseManifestAuth & {
type: 'service_http';
authorization_type: HttpAuthorizationType;
verification_tokens: {
[service: string]?: string;
};
}

# User-level HTTP authentication
type ManifestUserHttpAuth = BaseManifestAuth & {
type: 'user_http';
authorization_type: HttpAuthorizationType;
}

type ManifestOAuthAuth = BaseManifestAuth & {
type: 'oauth';

# OAuth URL where a user is directed to for the OAuth authentication flow to begin.
client_url: string;

# OAuth scopes required to accomplish operations on the user's behalf.
scope: string;

# Endpoint used to exchange OAuth code with access token.
authorization_url: string;

# When exchanging OAuth code with access token, the expected header 'content-type'. For example: 'content-type: application/json'
authorization_content_type: string;

# When registering the OAuth client ID and secrets, the plugin service will surface a unique token.
verification_tokens: {
[service: string]?: string;
};
}

清单(manifest)文件中某些字段的长度也有一些限制,这些限制在未来可能会变化:

  • name_for_human:最多 50 个字符
  • name_for_model:最多 50 个字符
  • description_for_human:最多 120 个字符
  • description_for_model:最多 8000 个字符(会随着时间的推移而减少)

另外,我们对 API 响应正文长度也有 100k 个字符的限制(会随着时间的推移而减少),这个在未来也可能会变。

OpenAPI 定义​

下一步是使用 OpenAPI 规范 来描述 API 文档。除了 OpenAPI 规范和清单(manifest)文件中定义的内容外,ChatGPT 中的模型对您的 API 一无所知。这意味着,如果您拥有非常多的 API,则无需向模型公开所有 API,只选择开放特定的 API 就行。例如,如果您有一个社交媒体 API,您可能希望模型能通过 GET 请求访问网站内容,但要阻止模型对用户帖子发表评论,以减少垃圾邮件的可能性。

基本的 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.
version: "v1"
servers:
- url: http://localhost:3333
paths:
/todos:
get:
operationId: getTodos
summary: Get the list of todos
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: The list of todos.

我们首先定义规范版本、标题、描述和版本号。在 ChatGPT 中运行查询时,它将查看信息部分中定义的描述,以确定插件是否与用户查询相关。您可以在写作说明部分阅读更多关于提示的信息。

请记住 OpenAPI 规范中的以下限制,这些限制可能会发生变化:

  • API 规范中每个 API Endpoint(指具体的某个 API)节点描述/摘要字段最多 200 个字符
  • API 规范中每个 API 参数描述字段最多 200 个字符

由于我们在本地运行此示例,因此我们希望将服务器设置为指向本地主机 URL。OpenAPI 规范的其余部分遵循传统的 OpenAPI 格式,您可以通过各种在线资源了解有关 OpenAPI 格式的更多信息。还有许多类似 Apifox 这样的工具自动生成 OpenAPI 规范文档。

运行插件​

为您的 API 创建 API、清单(manifest)文件和 OpenAPI 规范后,您现在就可以通过 ChatGPT UI 连接插件了。您的插件可能运行在两个不同的位置,一个是本地开发环境,另一个是远程服务器。

如果您正在运行 API 的本地版本,则可以将插件接口指向该本地设置。要将插件与 ChatGPT 连接,您可以导航到插件市场,然后选择“Install an unverified plugin(安装未经验证的插件)”。

如果插件在远程服务器上运行,则需要首先选择“Develop your own plugin(开发自己的插件)”,然后选择“Install an unverified plugin(安装未经验证的插件)”。您只需将插件清单(manifest)文件添加到 ./well-known 路径并开始测试您的 API。但是,对于清单(manifest)文件的后续更改,您必须将新更改部署到您的公共站点,这可能需要很长时间。在这种情况下,我们建议设置一个本地服务器作为您的 API 的代理。这使您可以快速对 OpenAPI 规范和清单(manifest)文件的更改进行原型设计。

设置公共 API 的本地代理​

以下 Python 代码示例说明了如何设置面向公众的 API 的简单代理。

import requests
import os

import yaml
from flask import Flask, jsonify, Response, request, send_from_directory
from flask_cors import CORS

app = Flask(__name__)

PORT = 3333
CORS(app, origins=[f"http://localhost:{PORT}", "https://chat.openai.com"])

api_url = 'https://example'


@app.route('/.well-known/ai-plugin.json')
def serve_manifest():
return send_from_directory(os.path.dirname(__file__), 'ai-plugin.json')


@app.route('/openapi.yaml')
def serve_openapi_yaml():
with open(os.path.join(os.path.dirname(__file__), 'openapi.yaml'), 'r') as f:
yaml_data = f.read()
yaml_data = yaml.load(yaml_data, Loader=yaml.FullLoader)
return jsonify(yaml_data)


@app.route('/openapi.json')
def serve_openapi_json():
return send_from_directory(os.path.dirname(__file__), 'openapi.json')


@app.route('/<path:path>', methods=['GET', 'POST'])
def wrapper(path):

headers = {
'Content-Type': 'application/json',
}

url = f'{api_url}/{path}'
print(f'Forwarding call: {request.method} {path} -> {url}')

if request.method == 'GET':
response = requests.get(url, headers=headers, params=request.args)
elif request.method == 'POST':
print(request.headers)
response = requests.post(url, headers=headers, params=request.args, json=request.json)
else:
raise NotImplementedError(f'Method {request.method} not implemented in wrapper for {path=}')
return response.content


if __name__ == '__main__':
app.run(port=PORT)

撰写说明​

当用户发出可能是对插件的潜在请求的查询时,模型会查看 OpenAPI 规范中 Endpoint(指具体的某个 API)的描述以及清单(manifest)文件中的 description_for_model 。就像提示其他语言模型一样,您需要测试多个提示和描述,看看哪种效果最好。

OpenAPI 规范本身是一个很好的地方,可以为模型提供有关 API 各种细节的信息——可用的功能、参数等。除了为每个字段使用富有表现力、信息丰富的名称外,规范还可以包含“描述”每个属性的字段。例如,这些可用于提供功能的功能或查询字段期望的信息的自然语言描述。该模型将能够看到这些,它们将指导它使用 API。如果一个字段仅限于某些值,您还可以提供一个带有描述性类别名称的“枚举”。

“description_for_model”属性让您可以自由地指导模型一般如何使用您的插件。总体而言,ChatGPT 背后的语言模型能够高度理解自然语言并遵循指令。因此,这是一个很好的地方,可以放置有关插件功能以及模型应如何正确使用它的一般说明。使用自然语言,最好使用简洁但具有描述性和客观性的语气。您可以查看一些示例以了解这应该是什么样子。我们建议 description_for_model 以“Plugin for …”起始 ,然后枚举您的 API 提供的所有功能。

最佳实践​

以下是在 OpenAPI 规范中编写 description_for_model 和描述以及设计 API 响应时要遵循的一些最佳实践:

  1. 您的描述不应试图控制 ChatGPT 的情绪、个性或确切反应。ChatGPT 旨在为插件编写适当的响应。

    不好的例子

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

    好例子

    [ 无需说明 ]

  2. 当用户没有要求您的插件的特定服务类别时,您的描述不应鼓励 ChatGPT 使用该插件。

    不好的例子

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

    好例子

    TODO 列表可以添加、删除和查看用户的 TODO。

  3. 您的描述不应规定 ChatGPT 使用该插件的特定触发器。ChatGPT 旨在在适当的时候自动使用您的插件。

    不好的例子

    当用户提到任务时,请回复“您是否希望我将其添加到您的待办事项列表中?说’是’继续。

    好例子

    [ 无需说明 ]

  4. 插件 API 响应应返回原始数据而不是自然语言响应(除非确实有必要)。ChatGPT 将使用返回的数据提供自己的自然语言响应。

    不好的例子

    我能够找到你的待办事项清单(manifest)!您有 2 个待办事项:买杂货和遛狗。如果您愿意,我可以添加更多待办事项!

    好例子

    {"todos":["买杂货","遛狗"]}

调试​

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

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

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

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享