1. 从0到1开发自己的插件:
1.1 插件描述文件(ai-plugin.json)
一个插件需要一份ai-plugin.json命名的manifest文件,用于描述插件的基本信息
ai-plugin.json 文件总长度建议不超过 1500 字符
种类 | 类型 | 描述/选项 | 是否必填 |
schema_version | String | 插件的版本号,用于开发者标记和使用 | ✅ |
name_for_model | String | 模型将用于定位插件的名称(不允许使用空格,只能使用字母和数字)此字段将作为插件的唯一标识 。描述请带有一定的语义,不要超过20个字符。 |
✅ |
name_for_human | String | 此字段将面向用户查看,是插件对外公开的名字。不超过20个字符。建议编写时按照如下要点顺序: “插件能力->适用场景->使用条件” | ✅ |
description_for_model | String | 面向模型的自然语言描述,请描述插件的核心能力、使用场景等,将用于模型参考解析是否触发插件 ,建议不超过200个字符。 |
✅ |
description_for_human | String | 面向用户介绍插件,建议介绍插件的主要能力,相关限制等。不超过100个字符,前端可完整显示前40 个字符,超出的字符将在用户 hover 时展示。 | ✅ |
auth | ManifestAuth | 用户鉴权相关字段 | ✅ |
api | Object | API规范 |
✅ |
logo_url | String | 用于获取插件标识的URL。建议大小:512 x 512。支持透明背景。必须是图像 ,不允许使用GIF。 |
✅ |
contact_email | String | 安全/审核、支持和停用的电子邮件联系方式 | ✅ |
legal_info_url | String | 用户查看插件信息的重定向URL | ✅ |
HttpAuthorizationType | HttpAuthorizationType | “bearer"或"basic”。默认basic | |
ManifestAuthType | ManifestAuthType | “none”、“user_http”、“service_http"或"oauth” | |
interface BaseManifestAuth | BaseManifestAuth | 类型:ManifestAuthType;说明:字符串 | |
ManifestNoAuth | ManifestNoAuth | 不需要身份验证:BaseManifestAuth和{ type: ‘none’ } | |
ManifestAuth | ManifestAuth | ManifestNoAuth、ManifestServiceHttpAuth、ManifestUserHttpAuth、ManifestOAuthAuth | |
examples | object | “examples”: {“url”: “PLUGIN_HOST/example.yaml” }, 文件url |
举例:
{ "schema_version": "v1", "name_for_human": "单词本_TianJi", "name_for_model": "wordbook_TianJi", "description_for_human": "个性化的英文单词本,可以增加、删除和浏览单词本中的单词,并可以按要求从单词本中随机抽取单词生成句子或段落", "description_for_model": "帮助用户管理单词本,可以增加、删除、浏览单词本,背单词时可以指定随机抽取单词本中若干个单词,生成句子会段落", "auth": { "type": "none" }, "api":{ "type": "openapi", "url": "http://127.0.0.1:8081/.well-known/openapi.yaml" }, "logo_url": "https://ucc.alicdn.com/images/user-upload-01/direct/69935055b23f4362b4747c1e6b5534e0.png", "contact_email": "support@example.com", "legal_info_url": "http://www.example.com/legal" }
插件图像:
只要删除插件再重新提交或者更新配置即可,url是http://127.0.0.1:8081/.well-known/openapi.yaml,只需要填http://127.0.0.1:8081即可,效果:
1.2 服务描述文件(openapi.yaml)
YAML 文件总长度,不可超过 1000个字符 (不包含空格)
APIs定义描述文件需要满足OpenAPI标准,详细见:OpenAPI 规范
OpenAPI 规范 (OAS) 定义了一个标准的、与语言无关的 HTTP API 接口,它允许人类和计算机发现和理解服务的功能,而无需访问源代码、文档或通过网络流量检查。正确定义后,使用者可以使用最少的实现逻辑来理解远程服务并与之交互。
1.2.1 数据类型:
类型 | 格式 | 说明 |
integer | int32 | 有符号 32 位 |
integer | int64 | 有符号 64 位(又名长) |
number | float | 浮点数 |
number | double | 双精度浮点数 |
string | password | 对 UI 的提示,以隐藏输入 |
支持 Markdown 格式
1.2.1 OpenAPI 对象:
字段名称 | 类型 | 描述 |
openapi | string | 必需 此字符串必须是 OpenAPI 文档使用的 OpenAPI 规范的版本号。该字段应由工具用于解释 OpenAPI 文档。这与 API info.version 字符串无关。 |
info | Info 对象 | 必需 提供有关 API 的元数据。元数据可以根据需要由工具使用。 |
jsonSchemaDialect | string | 此 OAS 文档中包含的架构对象中关键字的默认值。这必须采用 URI 的形式。 |
servers | [服务器对象] | 服务器对象数组,用于向目标服务器提供连接信息。如果未提供该属性,或者该属性为空数组,则默认值为 url 值为 的 Server Object。 |
paths | Paths 对象 | API 的可用路径和操作。 |
callbacks | Map[, Path Item 对象 | Reference 对象string] ] | 传入的 Webhook,可以作为此 API 的一部分接收,并且 API 使用者可以选择实现。本部分与该功能密切相关。 |
components | Components 对象 | 用于保存文档的各种架构的元素。 |
security | [安全要求对象] | 可以跨 API 使用哪些安全机制的声明。值列表包括可以使用的替代安全要求对象。单个操作可以覆盖此定义。要使安全性成为可选,可以在数组中包含空的安全要求()。 |
tags | [Tag 对象] | 文档使用的带有其他元数据的标签列表。标签的顺序可用于通过解析工具反映其顺序。未声明的标签可以随机组织,也可以根据工具的逻辑进行组织。列表中的每个标签名称必须是唯一的。 |
externalDocs | 外部文档对象 | 其他外部文档。 |
- info对象
字段名称 | 类型 | 描述 |
title | string | 必需 API 的标题。 |
summary | string | API 的简短摘要。 |
description | string | API 的说明。CommonMark 语法可用于富文本表示。 |
termsOfService | string | API 服务条款的 URL。这必须采用 URL 的形式。 |
contact | Contact 对象 | 公开的 API 的联系信息。 |
license | License 对象 | 公开的 API 的许可证信息。 |
version | string | 必需 OpenAPI 文档的版本(不同于 OpenAPI 规范版本或 API 实现版本) |
示例:
title: Sample Pet Store App summary: A pet store manager. description: This is a sample server for a pet store. termsOfService: https://example.com/terms/ contact: name: API Support url: https://www.example.com/support email: support@example.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html version: 1.0.1
- Paths 对象
request:数量:定义 1-2 个接口 (建议)api_id 不可超过 20 个字符 接口描述 summary 和 description在 description 字段中描述详细的接口介绍,长度不超过 150 个字符 (强制) summary 字段可抽象接口能力,长度不超过 50 个字符 (强制)存在 description,则优先使用 description
response:body中不要返回状态码、错误码 (建议)body仅给和插件结果相关的信息 (比如结果文本) (建议)错误码用http code表示 (建议) - components 对象
参数名称:最多 20 个字符,使用 string 类型 (强制)参数描述:最多 50 个字符,使用 string 类型 (强制)参数数量:参数不超过 5 个 (建议)参数类型:建议使用string, number,boolean;array和包含复杂嵌套的object不建议使用 (建议)
1.3 示例描述文件(example.yaml 可选)
example机制可帮助开发者提供示例,提升插件调用的正确率
为了保障模型触发的效果,每个example.yaml 包含若干示例,文件的长度建议不超过 300 个字符
1.4 开发自己的plugin-server
注意:为了给用户提供更好的体验,插件服务有超时要求:0.5s连接超时,3s读超时,2s读响应头超时,如果插件服务内部处理流程较长,建议采用sse流式方式及时返回,可以参考 5.2 插件为用户显示执行动作。
根据信息中描述的api定义开发自己的服务接口,并在服务中定义自己的插件能力。如下是一个python的示例,您也可以使用其他开发语言进行 server 开发
@app.route() -> Python 中的装饰器
例如:
#!/usr/env python3 # -*- coding: UTF-8 -*- from flask import Flask, request, make_response import json import random app = Flask(__name__) # 创建一个Flask应用程序实例 CORS(app, resources={r"/*": {"origins": "https://yiyan.baidu.com"}}) # 允许跨域请求 wordbook = [] # 初始化一个空的单词本列表 def make_json_response(data, status_code=200): """ 生成 JSON 格式的响应 """ response = make_response(json.dumps(data), status_code) response.headers["Content-Type"] = "application/json" return response @app.route("/add_word", methods=['POST']) async def add_word(): """ 添加一个单词 """ word = request.json.get('word', "") # 从请求中获取要添加的单词 wordbook.append(word) # 将单词添加到单词本列表中 return make_json_response({"message": "单词添加成功"}) # 返回添加成功的消息 @app.route("/delete_word", methods=['DELETE']) async def delete_word(): """ 删除一个单词 """ word = request.json.get('word', "") # 从请求中获取要删除的单词 if word in wordbook: wordbook.remove(word) # 如果单词存在于单词本中,则将其删除 return make_json_response({"message": "单词删除成功"}) # 返回删除成功的消息 @app.route("/get_wordbook") async def get_wordbook(): """ 获得单词本 """ return make_json_response({"wordbook": wordbook}) # 返回当前的单词本列表 @app.route("/generate_sentences", methods=['POST']) async def generate_sentences(): """ 生成句子 """ number = request.get_json()['word_number'] # 从请求中获取要生成句子的单词数量 number = min(number, len(wordbook)) # 确保要生成的单词数量不超过单词本的长度 random_words = random.sample(wordbook, number) # 从单词本中随机选取指定数量的单词 prompt = "利用英文单词(words)生成一个英文段落,要求这个段落不超过100个英文单词且必须全英文," \ "并包含上述英文单词,同时是一个有逻辑的句子" # API返回字段"prompt"有特殊含义:开发者可以通过调试它来调试输出效果 return make_json_response({"words": random_words, "prompt": prompt}) # 返回随机单词列表和提示语句 if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=8081) # 如果是直接运行这个文件,则启动Flask应用,监听8081端口