반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리

Chat GPT Plugin - Getting started

2023. 3. 27. 22:17 | Posted by 솔웅


반응형

Getting Started - OpenAI API

 

OpenAI API

An API for accessing new AI models developed by OpenAI

platform.openai.com

 

Creating a plugin takes three steps:

플러그인 생성에는 세 단계가 필요합니다.

  • Build an API
  • API 빌드
  • Document the API in the OpenAPI yaml or JSON format
  • OpenAPI yaml 또는 JSON 형식으로 API 문서화
  • Create a JSON manifest file that will define relevant metadata for the plugin
  • 플러그인에 대한 관련 메타데이터를 정의할 JSON 매니페스트 파일을 생성합니다.

The focus of the rest of this section will be creating a to-do list plugin by defining the OpenAPI specification along with the manifest file.

이 섹션의 나머지 부분에서는 매니페스트 파일과 함께 OpenAPI 사양을 정의하여 to-do list 플러그인을 만드는 데 초점을 맞춥니다.

 

 

Plugin manifest

Every plugin requires a ai-plugin.json file, which needs to be hosted on the API’s domain.

모든 플러그인에는 API 도메인에서 호스팅되어야 하는 ai-plugin.json 파일이 필요합니다. 

 

For example, a company called example.com would make the plugin JSON file accessible via an https://example.com domain since that is where their API is hosted.

예를 들어 example.com이라는 회사는 API가 호스팅되는 https://example.com 도메인을 통해 플러그인 JSON 파일에 액세스할 수 있도록 합니다.

 

When you install the plugin via the ChatGPT UI, on the backend we look for a file located at /.well-known/ai-plugin.json.

ChatGPT UI를 통해 플러그인을 설치하면 백엔드에서 /.well-known/ai-plugin.json에 있는 파일을 찾습니다. 

 

The /.well-known folder is required and must exist on your domain in order for ChatGPT to connect with your plugin.

/.well-known 폴더가 필요하며 ChatGPT가 플러그인과 연결하려면 도메인에 있어야 합니다.

 

If there is no file found, the plugin cannot be installed. For local development, you can use HTTP but if you are pointing to a remote server, HTTPS is required.

파일이 없으면 플러그인을 설치할 수 없습니다. 로컬 개발의 경우 HTTP를 사용할 수 있지만 원격 서버를 가리키는 경우 HTTPS가 필요합니다.

 

The minimal definition of the required ai-plugin.json file will look like the following:

필요한 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": "http://localhost:3333/logo.png",
  "contact_email": "support@example.com",
  "legal_info_url": "http://www.example.com/legal"
}

 

If you want to see all of the possible options for the plugin file, you can refer to the definition below.

플러그인 파일에 대해 가능한 모든 옵션을 보려면 아래 정의를 참조하십시오.

 

FIELD                      TYPE                   DESCRIPTION / OPTIONS

schema_version String Manifest schema version
name_for_model String Name the model will used to target the plugin
name_for_human String Human-readable name, such as the full company name
description_for_model String Description better tailored to the model, such as token context length considerations or keyword usage for improved plugin prompting.
description_for_human String Human-readable description of the plugin
auth ManifestAuth Authentication schema
api Object API specification
logo_url String URL used to fetch the plugin's logo
contact_email String Email contact for safety/moderation reachout, support, and deactivation
legal_info_url String Redirect URL for users to view plugin information
HttpAuthorizationType HttpAuthorizationType "bearer" or "basic"
ManifestAuthType ManifestAuthType "none", "user_http", "service_http", or "oauth"
interface BaseManifestAuth BaseManifestAuth type: ManifestAuthType; instructions: string;
ManifestNoAuth ManifestNoAuth No authentication required: BaseManifestAuth & { type: 'none', }
ManifestAuth ManifestAuth ManifestNoAuth, ManifestServiceHttpAuth, ManifestUserHttpAuth, ManifestOAuthAuth

 

The following are examples with different authentication methods:

다음은 인증 방법이 다른 예입니다.

 

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

 

There are also some limits to the length of certain field in the manifest file that are subject to change over time:

시간이 지나면서 변경될 수 있는 매니페스트 파일의 특정 필드 길이에도 몇 가지 제한이 있습니다.

  • 50 character max forname_for_human
  • name_for_human에 대해 최대 50자
  • 50 character max for name_for_model
  • name_for_model은 최대 50자
  • 120 character max for description_for_human
  • description_for_human은 최대 120자
  • 8000 character max just for description_for_model (will decrease over time)
  • description_for_model의 경우 최대 8000자(시간이 지남에 따라 감소)

Separately, we also have a 100k character limit (will decrease over time) on the API response body length which is also subject to change.

이와는 별도로 API 응답 본문 길이에 대한 100,000자 제한(시간이 지남에 따라 줄어듦)도 변경될 수 있습니다.

 

OpenAPI definition

 

The next step is to build the OpenAPI specification to document the API.

다음 단계는 OpenAPI 사양을 빌드하여 API를 문서화하는 것입니다.

 

The model in ChatGPT does not know anything about your API other than what is defined in the OpenAPI specification and manifest file.

ChatGPT의 모델은 OpenAPI 사양 및 매니페스트 파일에 정의된 것 외에는 API에 대해 아무것도 모릅니다.

 

This means that if you have an extensive API, you need not expose all functionality to the model and can choose specific endpoints.

즉, 광범위한 API가 있는 경우 모든 기능을 모델에 노출할 필요가 없으며 특정 엔드포인트를 선택할 수 있습니다.

 

For example, if you had a social media API, you might want to have the model access content from the site through a GET request but prevent the model from being able to comment on users posts in order to reduce the chance of spam.

예를 들어 소셜 미디어 API가 있는 경우 모델이 GET 요청을 통해 사이트의 콘텐츠에 액세스하도록 할 수 있지만 스팸 가능성을 줄이기 위해 모델이 사용자 게시물에 댓글을 달 수 없도록 할 수 있습니다.

 

The OpenAPI specification is the wrapper that sits on top of your API. A basic OpenAPI specification will look like the following:

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.

 

We start by defining the specification version, the title, description, and version number.

먼저 사양 버전, 제목, 설명 및 버전 번호를 정의합니다.

 

When a query is run in ChatGPT, it will look at the description that is defined in the info section to determine if the plugin is relevant for the user query.

ChatGPT에서 쿼리가 실행되면 정보 섹션에 정의된 설명을 보고 플러그인이 사용자 쿼리와 관련이 있는지 확인합니다.

 

You can read more about prompting in the writing descriptions section.

writing descriptions  섹션에서 프롬프트에 대한 자세한 내용을 읽을 수 있습니다.

 

Keep in mind the following limits in your OpenAPI specification, which are subject to change:

변경될 수 있는 OpenAPI 사양의 다음 제한에 유의하세요.

  • 200 characters max for each API endpoint description/summary field in API specification
  • API 사양의 API 엔드포인트 설명/요약 필드당 최대 200자
  • 200 characters max for each API param description field in API specification
  • API 사양의 각 API 매개변수 설명 필드에 대해 최대 200자

Since we are running this example locally, we want to set the server to point to your local host URL. The rest of the OpenAPI specification follows the traditional OpenAPI format, you can learn more about OpenAPI formatting through various online resources. There are also many tools that auto generate OpenAPI specifications based on your underlying API code.

 

이 예제를 로컬에서 실행하고 있으므로 로컬 호스트 URL을 가리키도록 서버를 설정하려고 합니다. 나머지 OpenAPI 사양은 기존 OpenAPI 형식을 따르므로 다양한 온라인 리소스를 통해 OpenAPI 형식에 대해 자세히 알아볼 수 있습니다. 기본 API 코드를 기반으로 OpenAPI 사양을 자동으로 생성하는 많은 도구도 있습니다.

 

Running a plugin

Once you have created an API, manifest file, and OpenAPI specification for your API, you are now ready to connect the plugin via the ChatGPT UI. There are two different places your plugin might be running, either locally in a development environment or on a remote server.

 

API, 매니페스트 파일 및 API용 OpenAPI 사양을 생성했으면 이제 ChatGPT UI를 통해 플러그인을 연결할 준비가 된 것입니다. 플러그인은 개발 환경의 로컬 또는 원격 서버의 두 가지 다른 위치에서 실행될 수 있습니다.

 

If you have a local version of your API running, you can point the plugin interface to that local setup. To connect the plugin with ChatGPT, you can navigate to the plugin store and then select “Install an unverified plugin”.

 

실행 중인 API의 로컬 버전이 있는 경우 플러그인 인터페이스가 해당 로컬 설정을 가리킬 수 있습니다. 플러그인을 ChatGPT와 연결하려면 플러그인 스토어로 이동한 다음 "확인되지 않은 플러그인 설치"를 선택하면 됩니다.

 

If the plugin is running on a remote server, you will need to first select “Develop your own plugin” and then “Install an unverified plugin”.

 

플러그인이 원격 서버에서 실행 중인 경우 먼저 "자체 플러그인 개발"을 선택한 다음 "확인되지 않은 플러그인 설치"를 선택해야 합니다.

 

You can simply add the plugin manifest file to the ./well-known path and start testing your API.

 

플러그인 매니페스트 파일을 ./well-known 경로에 추가하고 API 테스트를 시작할 수 있습니다.

 

However, for subsequent changes to your manifest file, you will have to deploy the new changes to your public site which might take a long time. In that case, we suggest setting up a local server to act as a proxy for your API. This allows you to quickly prototype changes to your OpenAPI spec and manifest file.

 

이후에 매니페스트 파일을 변경하려면 새 변경 사항을 공개 사이트에 배포해야 하며 시간이 오래 걸릴 수 있습니다. 이 경우 API의 프록시 역할을 하도록 로컬 서버를 설정하는 것이 좋습니다. 이를 통해 OpenAPI 사양 및 매니페스트 파일에 대한 변경 사항의 프로토타입을 신속하게 만들 수 있습니다.

 

Setup a local proxy of your public API

 

The following Python code is an example of how you can set up a simple proxy of your public facing 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)

 

Writing descriptions

 

When a user makes a query that might be a potential request that goes to a plugin, the model looks through the descriptions of the endpoints in the OpenAPI specification along with the description_for_model in the manifest file. Just like with prompting other language models, you will want to test out multiple prompts and descriptions to see what works best.

 

사용자가 플러그인으로 이동하는 잠재적인 요청일 수 있는 쿼리를 만들면 모델은 매니페스트 파일의 description_for_model과 함께 OpenAPI 사양의 엔드포인트 설명을 살펴봅니다. 다른 언어 모델 프롬프트와 마찬가지로 여러 프롬프트와 설명을 테스트하여 무엇이 가장 잘 작동하는지 확인하고 싶을 것입니다.

 

The OpenAPI spec itself is a great place to give the model information about the diverse details of your API – what functions are available, with what parameters, etc. Besides using expressive, informative names for each field, the spec can also contain “description” fields for every attribute. These can be used to provide natural language descriptions of what a function does or what information a query field expects, for example. The model will be able to see these, and they will guide it in using the API. If a field is restricted to only certain values, you can also provide an “enum” with descriptive category names.

 

OpenAPI 사양 자체는 API의 다양한 세부 정보(사용 가능한 기능, 매개변수 등)에 대한 정보를 모델에 제공할 수 있는 좋은 장소입니다. 각 필드에 대해 표현적이고 유익한 이름을 사용하는 것 외에도 사양에는 "설명"도 포함될 수 있습니다. 모든 속성에 대한 필드. 예를 들어 함수가 수행하는 작업 또는 쿼리 필드에 필요한 정보에 대한 자연어 설명을 제공하는 데 사용할 수 있습니다. 모델은 이를 볼 수 있으며 API를 사용하도록 안내합니다. 필드가 특정 값으로만 제한되는 경우 설명 범주 이름과 함께 "enum"을 제공할 수도 있습니다.

 

The “description_for_model” attribute gives you the freedom to instruct the model on how to use your plugin generally. Overall, the language model behind ChatGPT is highly capable of understanding natural language and following instructions. Therefore, this is a good place to put in general instructions on what your plugin does and how the model should use it properly. Use natural language, preferably in a concise yet descriptive and objective tone. You can look at some of the examples to have an idea of what this should look like. We suggest starting the description_for_model with “Plugin for …” and then enumerating all of the functionality that your API provides.

 

"description_for_model" 속성은 일반적으로 플러그인을 사용하는 방법에 대해 모델에 지시할 수 있는 자유를 제공합니다. 전반적으로 ChatGPT의 언어 모델은 자연어를 이해하고 지침을 따를 수 있는 능력이 뛰어납니다. 따라서 플러그인이 수행하는 작업과 모델이 플러그인을 올바르게 사용하는 방법에 대한 일반적인 지침을 입력하기에 좋은 곳입니다. 간결하면서도 설명적이고 객관적인 어조로 자연어를 사용하는 것이 좋습니다. 몇 가지 예를 보면 이것이 어떤 모습이어야 하는지 알 수 있습니다. “Plugin for …”로 description_for_model을 시작한 다음 API가 제공하는 모든 기능을 열거하는 것이 좋습니다.

 

Best practices

Here are some best practices to follow when writing your description_for_model and descriptions in your OpenAPI specification, as well as when designing your API responses:

 

다음은 OpenAPI 사양에 description_for_model 및 설명을 작성할 때와 API 응답을 디자인할 때 따라야 할 몇 가지 모범 사례입니다.

 

  1. Your descriptions should not attempt to control the mood, personality, or exact responses of ChatGPT. ChatGPT is designed to write appropriate responses to plugins.

    귀하의 설명은 기분, 성격 또는 ChatGPT의 정확한 응답을 제어하려고 시도해서는 안 됩니다. ChatGPT는 플러그인에 적절한 응답을 작성하도록 설계되었습니다.

    나쁜 예
    When the user asks to see their todo list, always respond with "I was able to find your todo list! You have [x] todos: [list the todos here]. I can add more todos if you'd like!"

    좋은 예
    [no instructions needed for this]
  2. Your descriptions should not encourage ChatGPT to use the plugin when the user hasn’t asked for your plugin’s particular category of service.

    설명은 사용자가 플러그인의 특정 서비스 범주를 요청하지 않은 경우에도 ChatGPT가 플러그인을 사용하도록 권장해서는 안 됩니다.

    나쁜 예
    Whenever the user mentions any type of task or plan, ask if they would like to use the TODOs plugin to add something to their todo list.

    좋은 예
  3. The TODO list can add, remove and view the user's TODOs.
  4. Your descriptions should not prescribe specific triggers for ChatGPT to use the plugin. ChatGPT is designed to use your plugin automatically when appropriate.

    귀하의 설명은 ChatGPT가 플러그인을 사용하기 위한 특정 트리거를 규정해서는 안 됩니다. ChatGPT는 필요할 때 플러그인을 자동으로 사용하도록 설계되었습니다.

    나쁜 예
    When the user mentions a task, respond with "Would you like me to add this to your TODO list? Say 'yes' to continue."

    좋은 예
  5. [no instructions needed for this]
  6. Plugin API responses should return raw data instead of natural language responses unless it’s necessary. ChatGPT will provide its own natural language response using the returned data.

    플러그인 API 응답은 필요한 경우가 아니면 자연어 응답 대신 원시 데이터를 반환해야 합니다. ChatGPT는 반환된 데이터를 사용하여 자체 자연어 응답을 제공합니다.

    나쁜 예
    I was able to find your todo list! You have 2 todos: get groceries and walk the dog. I can add more todos if you'd like!

  7. 좋은 예
    { "todos": [ "get groceries", "walk the dog" ] }

Debugging

By default, the chat will not show plugin calls and other information that is not surfaced to the user. In order to get a more complete picture of how the model is interacting with your plugin, you can see the request and response by clicking the down arrow on the plugin name after interacting with the plugin.

 

기본적으로 채팅에는 사용자에게 표시되지 않는 플러그인 호출 및 기타 정보가 표시되지 않습니다. 모델이 플러그인과 상호 작용하는 방식을 보다 완벽하게 파악하기 위해 플러그인과 상호 작용한 후 플러그인 이름에서 아래쪽 화살표를 클릭하여 요청 및 응답을 볼 수 있습니다.

 

A model call to the plugin will usually consist of a message from the model (“Assistant”) containing JSON-like parameters which are sent to the plugin, followed by a response from the plugin (“Tool”), and finally a message from the model utilizing the information returned by the plugin.

 

플러그인에 대한 모델 호출은 일반적으로 플러그인으로 전송되는 JSON과 같은 매개변수를 포함하는 모델("Assistant")의 메시지, 플러그인("Tool")의 응답, 마지막으로 플러그인이 반환한 정보를 활용하는 모델입니다.

 

In some cases, like during plugin installation, errors might be surfaced in the browsers javascript console.

 

플러그인 설치와 같은 경우에 브라우저의 javascript 콘솔에 오류가 표시될 수 있습니다.

 

 

 

반응형