ChatGPT插件开发实战

chatgpt,插件,开发,实战 · 浏览次数 : 527

小编点评

**ChatGPT 插件开发平台** 该平台提供一系列 API 和工具,允许开发者自定义 ChatGPT 的输入输出、添加特定任务支持以及集成外部数据和服务。 **主要功能:** - 自定义 ChatGPT 输入输出 - 添加任务支持 - 集成外部数据和服务 - 实现特定领域知识和回答模式 **技术支持:** -多种编程语言支持 - 与现有的 ChatGPT API 无缝集成 - 安全性和可控性保证 **主要功能:** - **获取列表:**获取用户所有待办事项(`getTodos`) - **添加任务:**添加新待办事项(`addTodo`) - **删除任务:**删除用户指定待办事项(`deleteTodo`) - **获取 OpenAPI 规范:**获取远程服务器定义的 OpenAPI 规范(`openapi_spec`) **示例:** ```python # 获取用户所有待办事项 todos = app.get("/todos/<username>\") # 添加新待办事项 app.post("/todos", data={"todo": "新任务"}) # 删除用户指定待办事项 app.delete("/todos/123", data={"todo_idx": 123}) ``` **优点:** - 用户可定制 ChatGPT 的输入输出 - 可以添加特定任务支持 - 可以集成外部数据和服务 - 实现了特定领域知识和回答模式 **总结:** ChatGPT 插件开发平台是一个全面且易于使用的工具,可帮助开发者将 ChatGPT 打造成更具个性和实用性的智能对话系统。

正文

1.概述

ChatGPT是一款由OpenAI推出的先进对话模型,其强大的自然语言处理能力使得它成为构建智能对话系统和人机交互应用的理想选择。为了进一步拓展ChatGPT的功能和适应不同领域的需求,OpenAI提供了插件开发平台,让开发者可以定制化和扩展ChatGPT的能力。

2.内容

OpenAI 插件将 ChatGPT 连接到第三方应用程序。这些插件使 ChatGPT 能够与开发人员定义的 API 进行交互,从而增强 ChatGPT 的功能并允许其执行广泛的操作。插件使 ChatGPT 能够执行以下操作:

  • 检索实时信息;例如,体育赛事比分、股票价格、最新新闻等。
  • 检索知识库信息;例如,公司文档、个人笔记等。
  • 协助用户采取行动;例如,预订航班、订餐等。

插件开发人员公开一个或多个 API 端点,并附有标准化清单文件和 OpenAPI 规范。这些定义了插件的功能,允许 ChatGPT 使用文件并调用开发人员定义的 API。

AI 模型充当智能 API 调用者。给定 API 规范和何时使用 API 的自然语言描述,模型会主动调用 API 来执行操作。例如,如果用户询问“我应该在巴黎哪里住几晚?”,模型可能会选择调用酒店预订插件 API,接收 API 响应,并结合 API 数据生成面向用户的答案及其自然语言能力。

2.1 插件流程

要构建插件,了解端到端流程是非常有必要的,流程如下所示:

  1.  创建清单文件并将其托管在yourdomain.com/.well-known/ai-plugin.json
    • 该文件包含有关您的插件的元数据(名称、徽标等)、有关所需身份验证的详细信息(身份验证类型、OAuth URL 等)以及您想要公开的端点的 OpenAPI 规范。
    • 该模型将看到 OpenAPI 描述字段,这些字段可用于为不同字段提供自然语言描述。
    • 建议在开始时仅公开 1-2 个端点,并使用最少数量的参数,以最大程度地缩短文本长度。插件描述、API 请求和 API 响应都插入到与 ChatGPT 的对话中。这不利于模型的上下文限制。
  2. 在ChatGPT页面后台系统中注册插件
    • 从顶部下拉列表中选择插件模型,然后选择“插件”、“插件商店”,最后选择“开发自己的插件”。
    • 如果需要身份验证,请提供 OAuth 2client_id和client_secret/或 API 密钥。
  3. 激活插件
    • 必须自己手动激活插件
    • 如果需要 OAuth,用户将通过 OAuth 重定向到您的插件进行登录。

    • 能够与另外 100 个用户共享自己的插件
  4. 开始对话
    • OpenAI 将在发送给 ChatGPT 的消息中注入插件的简洁描述,最终用户看不到。这将包括插件描述、端点和示例。
    • 当用户提出相关问题时,如果看起来相关,模型可能会选择从您的插件调用 API 调用;对于POST请求,我们要求开发者构建用户确认流程以避免破坏行为。
    • 该模型会将 API 调用结果合并到对用户的响应中。
    • 该模型可能会在其响应中包含从 API 调用返回的链接。
    • 该模型还可以在 Markdown 中格式化来自 API 的数据,并且 ChatGPT UI 将自动呈现 Markdown。

2.2 快速使用

创建插件需要 3 个步骤:

  • 构建 API
  • 以 OpenAPI yaml 或 JSON 格式记录 API
  • 创建一个 JSON 清单文件,用于定义插件的相关元数据

每个插件都需要一个ai-plugin.json文件,该文件需要托管在API的域名上。例如,名为example.com的公司将通过https://example.com域名使插件的JSON文件可访问,因为这是他们API托管的位置。当通过ChatGPT UI安装插件时,在后端我们会查找位于/.well-known/ai-plugin.json的文件。/.well-known文件夹是必需的,并且必须存在于自己的域名上,以便ChatGPT可以与自己的插件连接。如果找不到文件,则无法安装插件。对于本地开发,可以使用HTTP,但如果指向远程服务器,则需要使用HTTPS。

所需ai-plugin.json文件的最小定义如下所示:

{
    "schema_version": "v1",
    "name_for_human": "TODO List",
    "name_for_model": "todo",
    "description_for_human": "Manage your TODO list. You can add, remove and view your TODOs.",
    "description_for_model": "Help the user with managing a TODO list. You can add, remove and view your TODOs.",
    "auth": {
        "type": "none"
    },
    "api": {
        "type": "openapi",
        "url": "http://localhost:3333/openapi.yaml"
    },
    "logo_url": "http://localhost:3333/logo.png",
    "contact_email": "support@example.com",
    "legal_info_url": "http://www.example.com/legal"
}

请注意,列在“公共”下的项目将在插件商店对用户可用。

以下是具有不同身份验证方法的示例:

# 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;
  };
}

上述提到的清单文件中某些字段的长度存在限制,这些限制可能会发生变化。还对API响应体强加了最大长度限制,目前为100,000个字符,但这也可能随着时间变化而调整。

总体而言,最佳实践是尽可能简洁地描述和响应,因为模型有有限的上下文窗口。

2.3 OpenAPI定义

接下来的步骤是构建OpenAPI规范以文档化API。ChatGPT中的模型除了OpenAPI规范和清单文件中定义的内容外,对你的API一无所知。这意味着,如果你有一个庞大的API,你不需要将所有功能暴露给模型,而是可以选择特定的端点。例如,如果你有一个社交媒体API,你可能希望让模型通过GET请求访问网站内容,但防止模型能够对用户的帖子进行评论,以降低垃圾信息的可能性。

OpenAPI规范是包裹在您的API之上的包装器。一个基本的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端点描述/摘要字段的最大长度为200个字符
  • API规范中每个API参数描述字段的最大长度为200个字符

2.4 运行插件

一旦为API、清单文件和API的OpenAPI规范创建完成,现在可以通过ChatGPT UI连接插件了。我们创建的插件可能运行在两个不同的地方,要么是在开发环境的本地,要么是在远程服务器上。

如果在本地运行API的版本,可以将插件界面指向自己的本地主机服务器。要将插件与ChatGPT连接,请导航到插件商店,然后选择“开发自己的插件”。输入自己的本地主机和端口号(例如localhost:3333)。请注意,目前仅支持本地开发的auth类型为none。

如果插件在远程服务器上运行,则需要首先选择“开发自己的插件”进行设置,然后再选择“安装未验证的插件”将其安装到您的环境中。只需将插件的清单文件添加到yourdomain.com/.well-known/路径中,然后开始测试自己的API。但是,请注意,对于清单文件的后续更改,您需要将新更改部署到公共站点上,这可能需要较长的时间。在这种情况下,我们建议设置一个本地服务器作为自己的API的代理,这样可以快速原型化OpenAPI规范和清单文件的更改。

3.示例插件

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

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

3.1 了解如何构建一个无需身份验证的简单待办事项列表插件

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

{
    "schema_version": "v1",
    "name_for_human": "TODO List (No Auth)",
    "name_for_model": "todo",
    "description_for_human": "Manage your 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"
    },
    "logo_url": "PLUGIN_HOSTNAME/logo.png",
    "contact_email": "support@example.com",
    "legal_info_url": "https://example.com/legal"
}

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

接下来,我们可以定义 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 manifest
        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()
        # This is a trick we do to populate the PLUGIN_HOSTNAME constant in the OpenAPI spec
        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()

最后,我们需要设置和定义 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
View Code

3.2 了解如何构建具有服务级别身份验证的简单待办事项列表插件

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

 

{
    "schema_version": "v1",
    "name_for_human": "TODO List (service auth)",
    "name_for_model": "todo",
    "description_for_human": "Manage your 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": "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"
    },
    "logo_url": "https://example.com/logo.png",
    "contact_email": "support@example.com",
    "legal_info_url": "https://example.com/legal"
}

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

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

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

import json

import quart
import quart_cors
from quart import request

app = 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()
View Code

最后,我们需要设置并定义 OpenAPI 规范以匹配远程服务器上定义的端点。一般来说,无论身份验证方法如何,OpenAPI 规范看起来都是一样的。使用自动 OpenAPI 生成器将减少创建 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: https://example.com
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
View Code

4.总结

插件开发平台为开发者提供了一系列API和工具,使其可以自定义ChatGPT的输入输出、增加特定任务的支持以及集成外部数据和服务。开发者可以通过插件实现特定的领域知识、自定义回答模式、定制话题导向等功能,从而让ChatGPT更贴合特定的使用场景和用户需求。

在插件开发过程中,开发者可以借助ChatGPT的先进预训练模型,以及丰富的开发文档和示例代码来快速上手。插件支持多种编程语言,并与现有的ChatGPT API无缝集成,保证了开发的便捷性和灵活性。

值得注意的是,插件开发平台也注重模型的安全性和可控性。OpenAI提供了强大的监管措施和审核流程,确保插件的使用符合社区准则,并防止滥用或不当行为。

总体而言,ChatGPT插件开发平台为开发者提供了一个广阔的创作空间,让他们可以将ChatGPT打造成更具个性和实用性的智能对话系统。通过这个平台,开发者可以将ChatGPT的潜力发挥到极致,为用户提供更加智能、定制化的交互体验。 

与ChatGPT插件开发实战相似的内容:

ChatGPT插件开发实战

1.概述 ChatGPT是一款由OpenAI推出的先进对话模型,其强大的自然语言处理能力使得它成为构建智能对话系统和人机交互应用的理想选择。为了进一步拓展ChatGPT的功能和适应不同领域的需求,OpenAI提供了插件开发平台,让开发者可以定制化和扩展ChatGPT的能力。 2.内容 OpenAI

LangChain:打造自己的LLM应用

LangChain是一个框架,用于开发由LLM驱动的应用程序。可以简单认为是LLM领域的Spring,以及开源版的ChatGPT插件系统

微软面向企业的Private ChatGPT 参考应用 Chat Copilot

这两天你可能看过这篇文章:微软面向企业的Private ChatGPT 开源!超详细安装流程反馈![1], 这篇文章顶多就是一个Azure OpenAI 服务的简单Demo, 就连插件机制都没有,这也是促使我写这篇文章的因素之一。 微软在Build 大会上宣布了Copilot Stack,Copil

搭载AI之后的表格插件又有哪些新的改变

摘要:本文由葡萄城技术团队于博客园原创并首发。葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 在[《大火的ChatGPT与SpreadJS结合会有哪些意想不到的效果》](https://www.grapecity.com.cn/blogs/chatgpt-meets-spreadjs

构建 JavaScript ChatGPT 插件

> 聊天插件系统是一种令人兴奋的新方式,可以扩展ChatGPT的功能,纳入您自己的业务数据,并为客户与您的业务互动增加另一个渠道。在这篇文章中,我将解释什么是聊天插件,它们能做什么,以及你如何用JavaScript建立你自己的聊天插件。 这篇文章(或OpenAI所称的"训练数据")提供了一个快速入门

Edge浏览器安装 wetab ChatGPT插件的简单步骤

# Edge浏览器安装 wetab ChatGPT插件的简单步骤 ## 背景 ``` 首先感谢 神通的 李诺帆老师, 之前一直使用. https://chat.jubianxingqiu.com/#/chat/1002 类似的浏览器进行 中文的ChatGPT的使用. 感觉有时候容易卡顿, 并且需要扫

【转帖】ChatGPT重塑Windows!微软王炸更新:操作系统全面接入,Bing也能用插件了

https://cloud.tencent.com/developer/article/2291078?areaSource=&traceId= 金磊 丰色 西风 发自 凹非寺 量子位 | 公众号 QbitAI 一夜之间,微软彻底重新定义了PC交互。 因为这一次,它把Bing和ChatGPT插件的能

大火的ChatGPT与表格插件结合会有哪些意想不到的效果?

### 大火的ChatGPT与表格插件结合会有哪些意想不到的效果? ChatGPT已经火了好久了,想探索一下ChatGPT在表格中的使用场景,思考了很久自己整理了三点: 一、使用助手:根据需求提供操作指南、按照描述生成公式。 二、数据分析:对表格中的数据提供数据分析建议,按照描述分析数据。 三、工作

这款 AI 代码辅助插件真不错,还能帮你发现 bug!

大家好,我是树哥。 随着 ChatGPT 风靡全球之后,编程界也迎来了许多代码辅助工具,有非常出名的 Github Copilot 工具。今天,树哥给大家介绍一款免费的代码辅助插件,它无需代理上网,直接在 IDEA 中搜索安装即可。它不仅可以帮你辅助写代码,还可以帮你发现 bug 哦!它就是 ——

iPhone 使用类ChatGPT应用的几种方法

# iPhone 使用类ChatGPT功能的几种方法 ## 背景 ``` 前几天使用edge的wetab的插件给自己的工作带来了很多帮助 尤其是一些基础shell语法以及sql语法, 比使用百度, bing 等搜素引擎更加方便快捷. 当时一直想能不能在手机上面也使用这样的软件. 当然了, 这个帖子仅