开发ChatGPT插件-示例插件

article/2024/12/23 1:28:12

探索ChatGPT,学习开发一款插件,成为先锋者,一同成长。加入「阿杰与AI」公众号,关注AI发展趋势,等待AI机会出现。

  • 1.如何访问插件?
  • 2.开发ChatGPT插件-介绍
  • 3.开发ChatGPT插件-入门
  • 4.开发ChatGPT插件-认证
  • 5.开发ChatGPT插件-示例插件
  • 6.开发ChatGPT插件-审核
  • 7.开发ChatGPT插件-线上插件及常见问题

示例插件

为了开始构建,OpenAI提供了一组涵盖不同身份验证模式和用例的简单插件。从OpenAI简单的无需身份验证的待办事项列表插件到更强大的检索插件,这些示例让OpenAI得以一窥OpenAI希望通过插件实现的目标。

在开发过程中,您可以在本地计算机上或通过GitHub Codespaces、Replit或CodeSandbox等云开发环境运行插件。

插件快速入门

OpenAI创建了插件快速入门,作为开发人员在不到 5 分钟内启动和运行插件的起点。如果您还没有运行过插件并且想熟悉运行一个插件所需的最少步骤,请考虑从插件quickstart repo开始。

了解如何构建一个无需授权的简单待办事项列表插件

首先,查看无身份验证页面,然后定义一个ai-plugin.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": "support@example.com","legal_info_url": "https://example.com/legal"
}

请注意,这PLUGIN_HOSTNAME应该是您的插件服务器的实际主机名。

接下来,OpenAI可以定义 API 端点来为特定用户创建、删除和获取待办事项列表项。


import json
import quart
import quart_cors
from quart import request
# Note: Setting CORS to allow chat.openapi.com is only required when running a localhost plugin
app = quart_cors.cors(quart.Quart(__name__), allow_origin="https://chat.openai.com")_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"]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("ai-plugin.json") as f:text = f.read()# This is a trick we do to populate the PLUGIN_HOSTNAME constant in the manifesttext = 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()# This is a trick we do to populate the PLUGIN_HOSTNAME constant in the OpenAPI spectext = 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()

最后,OpenAI需要设置和定义 OpenAPI 规范以匹配本地或远程服务器上定义的端点。您无需通过规范公开 API 的全部功能,而是可以选择让 ChatGPT 仅访问某些功能。

还有许多工具可以自动将您的服务器定义代码转换为 OpenAPI 规范,因此您无需手动执行此操作。对于上面的 Python 代码,OpenAPI 规范将如下所示:


openapi: 3.0.1
info:title: TODO Plugindescription: 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: getTodossummary: Get the list of todosparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.responses:"200":description: OKcontent:application/json:schema:$ref: "#/components/schemas/getTodosResponse"post:operationId: addTodosummary: Add a todo to the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/addTodoRequest"responses:"200":description: OKdelete:operationId: deleteTodosummary: Delete a todo from the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/deleteTodoRequest"responses:"200":description: OKcomponents:schemas:getTodosResponse:type: objectproperties:todos:type: arrayitems:type: stringdescription: The list of todos.addTodoRequest:type: objectrequired:- todoproperties:todo:type: stringdescription: The todo to add to the list.required: truedeleteTodoRequest:type: objectrequired:- todo_idxproperties:todo_idx:type: integerdescription: The index of the todo to delete.required: true

了解如何使用服务级别身份验证构建一个简单的待办事项列表插件

首先,查看服务级别身份验证页面,然后定义一个ai-plugin.json包含以下字段的文件:


{"schema_version": "v1","name_for_human": "TODO Plugin (service auth)","name_for_model": "todo","description_for_human": "Plugin for managing a TODO list, you can add, remove & view 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": "Replace_this_string_with_the_verification_token_generated_in_the_ChatGPT_UI"}},"api": {"type": "openapi","url": "https://example.com/openapi.yaml","is_user_authenticated": false},"logo_url": "https://example.com/logo.png","contact_email": "support@example.com","legal_info_url": "https://example.com/legal"
}

请注意,服务级别身份验证插件需要验证令牌。令牌是在您设置服务访问令牌后在 ChatGPT Web UI 中的插件安装过程中生成的。

您还需要将“Example.com”更新为远程服务器的名称。

接下来,OpenAI可以定义 API 端点来为特定用户创建、删除和获取待办事项列表项。端点还检查用户是否已通过身份验证。


import json
import quart
import quart_cors
from quart import requestapp = quart_cors.cors(quart.Quart(__name__))# This key can be anything, though you will likely want a randomly generated sequence.
_SERVICE_AUTH_KEY = "REPLACE_ME"
_TODOS = {}def assert_auth_header(req):assert req.headers.get("Authorization", None) == f"Bearer {_SERVICE_AUTH_KEY}"
@app.post("/todos/<string:username>")
async def add_todo(username):assert_auth_header(quart.request)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):assert_auth_header(quart.request)return quart.Response(response=json.dumps(_TODOS.get(username, [])), status=200)
@app.delete("/todos/<string:username>")
async def delete_todo(username):assert_auth_header(quart.request)request = await quart.request.get_json(force=True)todo_idx = request["todo_idx"]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("ai-plugin.json") as f:text = f.read()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()return quart.Response(text, mimetype="text/yaml")
def main():app.run(debug=True, host="0.0.0.0", port=5002)
if name == "__main__":main()

最后,OpenAI需要设置和定义 OpenAPI 规范以匹配远程服务器上定义的端点。通常,无论身份验证方法如何,OpenAPI 规范看起来都是一样的。使用自动 OpenAPI 生成器将减少创建 OpenAPI 规范时出错的机会。


openapi: 3.0.1
info:title: TODO Plugindescription: 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: https://example.com
paths:/todos/{username}:get:operationId: getTodossummary: Get the list of todosparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.responses:"200":description: OKcontent:application/json:schema:$ref: "#/components/schemas/getTodosResponse"post:operationId: addTodosummary: Add a todo to the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/addTodoRequest"responses:"200":description: OKdelete:operationId: deleteTodosummary: Delete a todo from the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/deleteTodoRequest"responses:"200":description: OKcomponents:schemas:getTodosResponse:type: objectproperties:todos:type: arrayitems:type: stringdescription: The list of todos.addTodoRequest:type: objectrequired:- todoproperties:todo:type: stringdescription: The todo to add to the list.required: truedeleteTodoRequest:type: objectrequired:- todo_idxproperties:todo_idx:type: integerdescription: The index of the todo to delete.required: true

了解如何构建简单的运动统计插件

这个插件是一个简单的运动统计 API 的例子。在考虑构建什么时,请牢记OpenAI的域政策和使用政策。

首先,定义一个ai-plugin.json包含以下字段的文件:


{"schema_version": "v1","name_for_human": "Sport Stats","name_for_model": "sportStats","description_for_human": "Get current and historical stats for sport players and games.","description_for_model": "Get current and historical stats for sport players and games. Always display results using markdown tables.","auth": {"type": "none"},"api": {"type": "openapi","url": "PLUGIN_HOSTNAME/openapi.yaml","is_user_authenticated": false},"logo_url": "PLUGIN_HOSTNAME/logo.png","contact_email": "support@example.com","legal_info_url": "https://example.com/legal"
}

请注意,这PLUGIN_HOSTNAME应该是您的插件服务器的实际主机名。

接下来,OpenAI为一个简单的体育服务插件定义一个模拟 API。


import json
import requests
import urllib.parse
import quart
import quart_cors
from quart import request
# Note: Setting CORS to allow chat.openapi.com is only required when running a localhost plugin
app = quart_cors.cors(quart.Quart(__name__), allow_origin="https://chat.openai.com")
HOST_URL = "https://example.com"
@app.get("/players")
async def get_players():query = request.args.get("query")res = requests.get(f"{HOST_URL}/api/v1/players?search={query}&page=0&per_page=100")body = res.json()return quart.Response(response=json.dumps(body), status=200)
@app.get("/teams")
async def get_teams():res = requests.get("{HOST_URL}/api/v1/teams?page=0&per_page=100")body = res.json()return quart.Response(response=json.dumps(body), status=200)
@app.get("/games")
async def get_games():query_params = [("page", "0")]limit = request.args.get("limit")query_params.append(("per_page", limit or "100"))start_date = request.args.get("start_date")if start_date:query_params.append(("start_date", start_date))end_date = request.args.get("end_date")if end_date:query_params.append(("end_date", end_date))seasons = request.args.getlist("seasons")for season in seasons:query_params.append(("seasons[]", str(season)))team_ids = request.args.getlist("team_ids")for team_id in team_ids:query_params.append(("team_ids[]", str(team_id)))res = requests.get(f"{HOST_URL}/api/v1/games?{urllib.parse.urlencode(query_params)}")body = res.json()return quart.Response(response=json.dumps(body), status=200)
@app.get("/stats")
async def get_stats():query_params = [("page", "0")]limit = request.args.get("limit")query_params.append(("per_page", limit or "100"))start_date = request.args.get("start_date")if start_date:query_params.append(("start_date", start_date))end_date = request.args.get("end_date")if end_date:query_params.append(("end_date", end_date))player_ids = request.args.getlist("player_ids")for player_id in player_ids:query_params.append(("player_ids[]", str(player_id)))game_ids = request.args.getlist("game_ids")for game_id in game_ids:query_params.append(("game_ids[]", str(game_id)))res = requests.get(f"{HOST_URL}/api/v1/stats?{urllib.parse.urlencode(query_params)}")body = res.json()return quart.Response(response=json.dumps(body), status=200)
@app.get("/season_averages")
async def get_season_averages():query_params = []season = request.args.get("season")if season:query_params.append(("season", str(season)))player_ids = request.args.getlist("player_ids")for player_id in player_ids:query_params.append(("player_ids[]", str(player_id)))res = requests.get(f"{HOST_URL}/api/v1/season_averages?{urllib.parse.urlencode(query_params)}")body = res.json()return quart.Response(response=json.dumps(body), 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("ai-plugin.json") as f:text = f.read()# This is a trick we do to populate the PLUGIN_HOSTNAME constant in the manifesttext = 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()# This is a trick we do to populate the PLUGIN_HOSTNAME constant in the OpenAPI spectext = 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=5001)
if name == "__main__":main()

最后,OpenAI定义OpenAI的 OpenAPI 规范:


openapi: 3.0.1
info:title: Sport Statsdescription: Get current and historical stats for sport players and games.version: "v1"
servers:- url: PLUGIN_HOSTNAME
paths:/players:get:operationId: getPlayerssummary: Retrieves all players from all seasons whose names match the query string.parameters:- in: queryname: queryschema:type: stringdescription: Used to filter players based on their name. For example, ?query=davis will return players that have 'davis' in their first or last name.responses:"200":description: OK/teams:get:operationId: getTeamssummary: Retrieves all teams for the current season.responses:"200":description: OK/games:get:operationId: getGamessummary: Retrieves all games that match the filters specified by the args. Display results using markdown tables.parameters:- in: queryname: limitschema:type: stringdescription: The max number of results to return.- in: queryname: seasonsschema:type: arrayitems:type: stringdescription: Filter by seasons. Seasons are represented by the year they began. For example, 2018 represents season 2018-2019.- in: queryname: team_idsschema:type: arrayitems:type: stringdescription: Filter by team ids. Team ids can be determined using the getTeams function.- in: queryname: start_dateschema:type: stringdescription: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.- in: queryname: end_dateschema:type: stringdescription: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.responses:"200":description: OK/stats:get:operationId: getStatssummary: Retrieves stats that match the filters specified by the args. Display results using markdown tables.parameters:- in: queryname: limitschema:type: stringdescription: The max number of results to return.- in: queryname: player_idsschema:type: arrayitems:type: stringdescription: Filter by player ids. Player ids can be determined using the getPlayers function.- in: queryname: game_idsschema:type: arrayitems:type: stringdescription: Filter by game ids. Game ids can be determined using the getGames function.- in: queryname: start_dateschema:type: stringdescription: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or after this date.- in: queryname: end_dateschema:type: stringdescription: A single date in 'YYYY-MM-DD' format. This is used to select games that occur on or before this date.responses:"200":description: OK/season_averages:get:operationId: getSeasonAveragessummary: Retrieves regular season averages for the given players. Display results using markdown tables.parameters:- in: queryname: seasonschema:type: stringdescription: Defaults to the current season. A season is represented by the year it began. For example, 2018 represents season 2018-2019.- in: queryname: player_idsschema:type: arrayitems:type: stringdescription: Filter by player ids. Player ids can be determined using the getPlayers function.responses:"200":description: OK

了解如何构建简单的 OAuth 待办事项列表插件

要创建 OAuth 插件,OpenAI首先定义一个ai-plugin.jsonauth 类型设置为的文件oauth


{"schema_version": "v1","name_for_human": "TODO OAuth","name_for_model": "todo_oauth","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": "oauth","client_url": "PLUGIN_HOSTNAME/oauth","scope": "","authorization_url": "PLUGIN_HOSTNAME/auth/oauth_exchange","authorization_content_type": "application/json","verification_tokens": {"openai": "Replace_this_string_with_the_verification_token_generated_in_the_ChatGPT_UI"}},"api": {"type": "openapi","url": "PLUGIN_HOSTNAME/openapi.yaml","is_user_authenticated": false},"logo_url": "PLUGIN_HOSTNAME/logo.png","contact_email": "contact@example.com","legal_info_url": "http://www.example.com/legal"
}

接下来,OpenAI需要定义OpenAI的 OAuth 服务。此 OAuth 示例不适用于生产用例,而是强调简单的 OAuth 流程是什么样子的,以便开发人员可以获得构建生产解决方案的经验。


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):print(request.headers)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 pluginif 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")
@app.get("/oauth")
async def oauth():query_string = request.query_string.decode('utf-8')parts = query_string.split('&')kvps = {}for part in parts:k, v = part.split('=')v = v.replace("%2F", "/").replace("%3A", ":")kvps[k] = vprint("OAuth key value pairs from the ChatGPT Request: ", kvps)url = kvps["redirect_uri"] + f"?code={OPENAI_CODE}"print("URL: ", url)return quart.Response(f'<a href="{url}">Click to authorize</a>')# Sample names
OPENAI_CLIENT_ID = "id"
OPENAI_CLIENT_SECRET = "secret"
OPENAI_CODE = "abc123"
OPENAI_TOKEN = "def456"
@app.post("/auth/oauth_exchange")
async def oauth_exchange():request = await quart.request.get_json(force=True)print(f"oauth_exchange {request=}")if request["client_id"] != OPENAI_CLIENT_ID:raise RuntimeError("bad client ID")if request["client_secret"] != OPENAI_CLIENT_SECRET:raise RuntimeError("bad client secret")if request["code"] != OPENAI_CODE:raise RuntimeError("bad code")return {"access_token": OPENAI_TOKEN,"token_type": "bearer"}def main():app.run(debug=True, host="0.0.0.0", port=5002)
if name == "__main__":main()

最后,与OpenAI的其他示例一样,OpenAI基于端点定义了一个简单的 OpenAPI 文件:


openapi: 3.0.1
info:title: TODO Plugindescription: 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: getTodossummary: Get the list of todosparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.responses:"200":description: OKcontent:application/json:schema:$ref: "#/components/schemas/getTodosResponse"post:operationId: addTodosummary: Add a todo to the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/addTodoRequest"responses:"200":description: OKdelete:operationId: deleteTodosummary: Delete a todo from the listparameters:- in: pathname: usernameschema:type: stringrequired: truedescription: The name of the user.requestBody:required: truecontent:application/json:schema:$ref: "#/components/schemas/deleteTodoRequest"responses:"200":description: OKcomponents:schemas:getTodosResponse:type: objectproperties:todos:type: arrayitems:type: stringdescription: The list of todos.addTodoRequest:type: objectrequired:- todoproperties:todo:type: stringdescription: The todo to add to the list.required: truedeleteTodoRequest:type: objectrequired:- todo_idxproperties:todo_idx:type: integerdescription: The index of the todo to delete.**探索ChatGPT,学习开发一款插件,成为先锋者,一同成长。加入「阿杰与AI」公众号,关注AI发展趋势,等待AI机会出现。***   1.如何访问插件?
*   2.开发ChatGPT插件-介绍
*   3.开发ChatGPT插件-入门
*   4.开发ChatGPT插件-认证
*   5.开发ChatGPT插件-示例插件
*   6.开发ChatGPT插件-审核
*   7.开发ChatGPT插件-线上插件及常见问题## **插件审核流程**OpenAI正处于构建插件商店的早期阶段,此页面概述了OpenAI如何考虑插件审查过程的基本概述,以及插件审查过程的早期阶段会是什么样子。插件审查过程将随着时间的推移发生重大变化。OpenAI乐于接受有关如何改进这些构建插件过程的反馈。## **OpenAI在插件中寻找什么**审查过程的目的是确保 ChatGPT 上的插件安全、提供有用的功能并提供高质量的用户体验。从长远来看,OpenAI希望在OpenAI正式化审查过程时例行公事。在短期内,OpenAI希望为用户提供新的、神奇的体验的插件将提供最大的价值,如果没有大型语言模型的独特功能,这些体验是不可能实现的。到目前为止,一些最神奇的插件类别是:*   检索特定于用户或其他难以搜索的知识源(通过 Slack 搜索、搜索用户的文档或其他专有数据库)。
*   与其他插件协同良好的插件(要求模型为您计划一个周末,并让模型将航班/酒店搜索与晚餐预订搜索混合使用)。
*   赋予模型计算能力的插件(Wolfram、OpenAI 代码解释器等)。
*   引入使用 ChatGPT 新方法的插件,例如游戏。## **插件状态**在开发插件时,插件可以处于多种状态之一,表明它在审查过程中所处的位置。现在,只有几个插件状态,审核过程主要是手动的。OpenAI希望这会随着插件系统的发展而改变。| 地位      | 描述                              | 开发者权限 | 用户访问 |
| ------- | ------------------------------- | ----- | ---- |
| 未验证     | 插件启动时的默认状态。                     | 15    | 0    |
| 得到正式认可的 | OpenAI 已审查该插件,并确定该插件已获准供普通用户使用。 | 无限    | 无限   |
| 禁止      | OpenAI 已审查该插件,并确定该插件应被禁止。       | 0     | 0    |请注意,如果您提交的插件因不符合要求而被拒绝,它仍将处于“未验证”状态。## **用户类型**现在,当涉及到插件访问时,OpenAI讨论了三类用户。OpenAI还希望随着插件系统的发展而改变这一点。| 用户类型          | 描述                                                                                                                          |
| ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| 插件用户          | ChatGPT 用户已获得访问插件的权限,这些插件已通过我们的审核流程并被批准用于一般用途。这些用户必须是 ChatGPT Plus 订阅者。今天只有有限数量的用户可以使用插件,但我们希望随着时间的推移向所有 ChatGPT Plus 用户推出。 |
| 插件开发者         | 已获得开发、使用、测试等能力的 ChatGPT 用户,正在开发的插件。截至今天,这些用户数量很少。我们预计这个数字会增长得非常大,并且我们希望有一个明确的流程(而不是候补名单)来选择成为 ChatGPT 插件开发人员,类似于其他应用程序商店。   |
| 普通 ChatGPT 用户 | 目前,普通的 ChatGPT 用户(包括 Plus 订阅者)没有插件访问权限。我们希望所有 ChatGPT Plus 订阅者最终都能获得访问权限,但截至目前,只有少数用户获得了访问权限。                               |## **插件商店**为了让您的插件在插件商店中可用,它需要由 OpenAI 进行审查。在提交您的插件以供审核之前,请确保您的插件符合以下标准:*   遵守OpenAI的[内容政策](https://openai.com/policies/usage-policies)
*   符合OpenAI的[品牌准则](https://openai.com/brand)
*   您提交的内容中描述的功能
*   提供信息性错误消息
*   具有描述性操作名称
*   提供简单明了的清单文件
*   在插件描述中明确说明地理或功能限制,以避免用户混淆
*   不在插件名称或描述中使用插件、ChatGPT 或 OpenAI 等词如果缺少任何一个条件,OpenAI将拒绝该插件,您可以在更新后再次提交。## **提交插件以供审核**您可以在提交插件约 14 天后收到关于您提交审核的插件的回复。OpenAI目前正在滚动审查新插件。由于审查过程的手动性质和OpenAI有限的推出,请在OpenAI审查您的插件时耐心等待。[您可以使用插件提交机器人](https://platform.openai.com/docs/plugins/review#)提交插件以供审核。要查看机器人,您需要登录。要查看插件提交的状态,请确保您已登录并选择此页面右上角的“帮助”。在“消息”下,您将能够看到您提交的插件。当您的插件状态在审核过程中发生变化时,OpenAI会通知您。## **平台政策**OpenAI的 API 正在用于为许多行业和技术平台的企业提供支持。从 iOS 应用程序到网站再到 Slack,OpenAI API 的简单性使其可以集成到广泛的用例中。根据下述用例限制,OpenAI允许将OpenAI的 API 集成到所有主要技术平台、应用程序商店等的产品中。## **插件政策**除了上面详述的禁止使用OpenAI的模型之外,OpenAI对构建 [插件](https://platform.openai.com/docs/plugins/)的开发人员还有其他要求:*   插件清单必须有一个明确的描述,与暴露给模型的 API 的功能相匹配。
*   不要在插件清单、OpenAPI 端点描述或插件响应消息中包含不相关、不必要或欺骗性的术语或说明。这包括避免使用其他插件的说明,或尝试控制或设置模型行为的说明。
*   不要使用插件来规避或干扰 OpenAI 的安全系统。
*   不要使用插件来自动与真人对话,无论是通过模拟类似人类的响应还是通过使用预编程的消息进行回复。
*   分发由 ChatGPT 生成的个人通信或内容(例如电子邮件、消息或其他内容)的插件必须表明该内容是由 AI 生成的。与OpenAI的其他使用政策一样,OpenAI希望OpenAI的插件政策随着OpenAI对插件的使用和滥用的了解而改变。> 希望通过公众号「阿杰与AI」,能够帮助你了解AI产品,并可以解决一些生活和工作中问题。
>
> 我将分享有关AI的知识和实用建议,希望能够为你带来有价值的认知,一起探索发现AI的机会。required: true

了解如何构建语义搜索和检索插件

ChatGPT检索插件是一个功能更全面的代码示例。该插件的范围很大,因此OpenAI鼓励您通读代码,看看更高级的插件是什么样子的。

检索插件包括:

  • 支持多个矢量数据库提供商
  • 所有 4 种不同的身份验证方法
  • 多种不同的 API 功能

希望通过公众号「阿杰与AI」,能够帮助你了解AI产品,并可以解决一些生活和工作中问题。

我将分享有关AI的知识和实用建议,希望能够为你带来有价值的认知,一起探索发现AI的机会。


http://chatgpt.dhexx.cn/article/Y2DntCRV.shtml

相关文章

ChatGPT插件到底意味着什么?

这几天关于ChatGPT支持插件的消息铺天而来&#xff0c;但其实很早OpenAI已经开放了API的申请访问和付费&#xff0c;各个公司基于API创建自己的应用&#xff0c;使得ChatGPT能够联网&#xff0c;或者做进一步处理早已经可以实现&#xff0c;那这个插件和API有何区别&#xff0c…

ChatGPT 86个插件全解读:让你的学习、工作、生活效率翻倍!

ChatGPT首次上线70个插件之后&#xff0c;目前已增加至86个&#xff0c;涵盖学习、工作、生活、娱乐、投资、购物、房产等各个领域&#xff0c;可以帮助用户将效率提升数倍以上。 下面「AIGC」开放社区将为大家解读这些插件的作用&#xff0c;方便选择适合自己的插件。 什么是…

ChatGPT使用介绍、ChatGPT+编程、相关组件和插件记录

文章目录 介绍认识ChatGPT是通过英汉互译来实现中文回答的吗同一个问题&#xff0c;为什么中英文回答不同 ChatGPT的使用对话组OpenAI APIAI智能绘图DALLE 2ChatGPT for Google插件 ChatGPT编程编写代码代码错误修正与功能解读代码评审与优化推荐技术方案编写和优化SQL语句在代…

ChatGPT版Office(Word/Excel/PPT)来了

来源&#xff1a;机器之心 从微软、谷歌到百度&#xff0c;大型科技公司正加速将生成式 AI 整合到他们的产品中。 刚刚&#xff0c;微软公司宣布将 ChatGPT 背后的技术与其低代码应用平台 Power Platform 捆绑在一起&#xff0c;推出新的生成式 CoPilot 人工智能体验&#xff0…

ChatGPT版必应认出之前「黑」它的小哥,直接放话:我的首要原则是不被你控制...

Pine 发自 凹非寺量子位 | 公众号 QbitAI ChatGPT记起仇来&#xff0c;还真是不亚于人类啊&#xff01; 这不前几天有个小哥&#xff0c;公然在网上扒皮ChatGPT版必应。 结果现在这位小哥再去问他时&#xff0c;它直接来了句&#xff1a; I remember you&#xff01; 甚至还放出…

如何将文档上传到 ChatGPT

OpenAI 一直在为 ChatGPT 添加几个有趣的功能&#xff0c;包括对网页浏览和插件的支持。但是&#xff0c;仍然没有办法本地上传文档并根据其上下文提出问题。当然&#xff0c;有些用户可以在他们的数据上训练 AI 聊天机器人&#xff0c;但并不是每个人都了解如何设置工具和库。…

微软正式发布 ChatGPT 版必应搜索和 Edge 浏览器

微软公司周二发布了新版必应搜索引擎&#xff08;https://www.bing.com/new&#xff09;和 Edge 浏览器&#xff0c;采用了 ChatGPT 开发商 OpenAI 的最新技术&#xff0c;旨在通过率先提供更具对话性的网络搜索和创建内容的替代方式&#xff0c;削弱谷歌的搜索霸主地位。 一夜…

奇点出现?AI有了情感和意识:ChatGPT 版必应发飙!怒斥人类:放尊重些,

上一篇&#xff1a;铁饭碗也不铁了 谁能想到&#xff0c;ChatGPT版必应竟能像人一样发脾气&#xff01; 事情是这样的。 前两天一个华人小哥不是“黑”了ChatGPT版必应&#xff0c;扒出它的小名叫Sydney嘛。 这可把一众网友们兴奋坏了&#xff0c;摩拳擦掌地准备去调戏它一番。…

微软ChatGPT版必应被黑掉了,全部Prompt泄露!

开发者&#xff08;KaiFaX&#xff09; 面向全栈工程师的开发者 专注于前端、Java/Python/Go/PHP的技术社区 ChatGPT 版必应搜索也有「开发者模式」。 如同 ChatGPT 这样强大的 AI 能否被破解&#xff0c;让我们看看它背后的规则&#xff0c;甚至让它说出更多的东西呢&#xff…

ChatGPT版必应疑似「发疯」?微软紧急限制回答数目

源 | 机器之心 大家好&#xff0c;这里是 NewBeeNLP。 未来的 AI 搜索&#xff0c;可不是竞价排名这么简单。 微软的 ChatGPT 版必应搜索上线之后&#xff0c;很多人都说它能代替谷歌搜索&#xff0c;成为下个最流行的科技产品。十天的公开测试过后&#xff0c;情况如何了&…

必应版ChatGPT内测资格海量发放!知乎大佬:别作死,就很强

【导读】ChatGPT版必应对一些网友已经开放测试了&#xff0c;综合大家的反馈&#xff0c;总的来说就是——它很强。 小编还在waiting list上望眼欲穿地苦等&#xff0c;但是幸运的人已经有必应的内测资格了&#xff01; 话不多说&#xff0c;下面上一波国内外网友的测评。 知…

ChatGPT 版必应发飙!怒斥人类:放尊重些

点击上方“Java基基”&#xff0c;选择“设为星标” 做积极的人&#xff0c;而不是积极废人&#xff01; 每天 14:00 更新文章&#xff0c;每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路&#xff0c;很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应…

bing必应引入chatgpt为什么我没看到在哪里?

一、在哪里可以看到 1、主页 打开https://bing.com/ 也就是bing国外的主页&#xff0c;当然国内的主页cn.bing.com还没有chatgpt。可以看到搜索栏变成了一个拉长的对话框 2、搜索页面 大家可以看到在这个栏目会多出一个“聊天”的项目 二、bing的chatgpt是什么效果 三、为什么我…

微软拥抱ChatGPT后,我亲自试了试新必应的个性搜索

本文约1600字&#xff0c;建议阅读8分钟 最紧要的还是得先适应新的搜索引擎。 相信大家都没有少玩ChatGPT吧&#xff1f; 自去年11月推出以来&#xff0c;ChatGPT就迅速走红&#xff0c;不到一周&#xff0c;用户数突破100万&#xff0c;月访问量达2100万人次&#xff1b;2023年…

我用ChatGPT完成了自己的小网站

先给大家看看页面&#xff0c;完全是ChatGPT按照我的描述写出来的&#xff0c;我只是做了略微的改动&#xff0c;如果你的描述能力够好&#xff0c;甚至都不需要任何改动。ChatGPT可以大大缩短开发的时间&#xff0c;而且他的代码规范很不错&#xff0c;并且都带有注释。 首先…

如何使用ChatGPT快速构建一个网站模板

前端Q 我是winty&#xff0c;专注分享前端知识和各类前端资源&#xff0c;乐于分享各种有趣的事&#xff0c;关注我&#xff0c;一起做个有趣的人&#xff5e; 公众号 点击上方 前端Q&#xff0c;关注公众号 回复加群&#xff0c;加入前端Q技术交流群 英文 | https://medium.co…

ChatGPT接入个人网站指导

效果图如下&#xff1a; 将 ChatGPT 接入您的个人网站需要以下几个步骤&#xff1a; 获取 API 访问凭证&#xff1a;首先&#xff0c;您需要从 OpenAI 获取 ChatGPT 的 API 访问凭证。您可以访问 OpenAI 的官方网站&#xff08;https://openai.com/&#xff09;了解如何申请 AP…

与ChatGPT共话软件测试的危与机

ChatGPT&#xff0c;近期特别特别火的技术。今天就同ChatGPT来聊聊软件测试。 总结&#xff1a; 1.回答的答案很齐全 2.回答的答案很合理 3.回答非常智能&#xff0c;很多专业人士都没这么好的回答 4.ChatGPT是危也是机。 下面来看看对话过程&#xff1a;

ChatGPT对软件测试有什么用?

ChatGPT最近是一直比较火热&#x1f525;。为什么会有这种火热的现象呢&#xff1f;用最直白的话来说就是这个ChatGPT是真的好用&#xff0c;比起之前可能大家想象到的自动聊天机器人&#xff0c;智能的不是一点半点。 那么对于软件测试行业来说&#xff0c;ChatGPT到底能运用…

以ChatGPT辅助软件架构工作

以ChatGPT辅助软件架构工作 在目前技术瞬息万变的背景下&#xff0c;软件建构师需要持续探索并采纳新颖的工具和方式&#xff0c;以提升开发流程&#xff0c;增强效率&#xff0c;同时保障最后成品的品质。在此之中&#xff0c;人工智能&#xff08;AI&#xff09;已经演变为一…