OpenAI의 ChatGPT가 예외적으로 지능적이라는 것은 의심의 여지가 없습니다. 변호사의 변호사 테스트를 통과했으며 의사와 유사한 지식을 보유하고 있으며 일부 테스트에서는 IQ가 155로 기록되었습니다 . 그러나 무지를 인정하기보다는 정보를 조작 하는 경향이 있습니다. 이러한 경향은 2021년에 해당 지식이 중단된다는 사실과 결합되어 GPT API를 사용하여 전문 제품을 구축하는 데 어려움을 초래합니다.
우리는 이러한 장애물을 어떻게 극복할 수 있습니까? GPT-3와 같은 모델에 새로운 지식을 어떻게 전달할 수 있습니까? 나의 목표는 Python, OpenAI API 및 단어 임베딩을 사용하는 질문 답변 봇을 구성하여 이러한 질문을 해결하는 것입니다.
저는 프롬프트에서 지속적인 통합 파이프라인을 생성하는 봇을 만들려고 합니다. 이 파이프라인은 아시다시피 Semaphore CI/CD에서 YAML로 형식화됩니다 .
다음은 실제 봇의 예입니다.
실행 중인 프로그램의 스크린샷. 화면에서 python query.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub"
명령이 실행되고, 프로그램은 요청된 작업을 수행하는 CI 파이프라인에 해당하는 YAML을 인쇄합니다.
DocsGPT , My AskAI 및 Libraria 와 같은 프로젝트의 정신으로 세마포어 및 파이프라인 구성 파일 생성 방법에 대해 GPT-3 모델을 "교육"할 계획입니다. 나는 기존 문서를 활용하여 이를 달성할 것입니다.
나는 봇 구축에 대한 사전 지식을 가정하지 않고 귀하의 요구 사항에 맞게 조정할 수 있도록 깨끗한 코드를 유지 관리할 것입니다.
이 튜토리얼을 따르기 위해 봇 코딩 경험이나 신경망 지식이 필요하지 않습니다. 그러나 다음이 필요합니다.
ChatGPT, 더 정확하게는 이를 지원하는 LLM(대형 언어 모델)인 GPT-3 및 GPT-4는 마감 날짜가 2021년 9월경인 대규모 데이터 세트에서 훈련되었습니다.
본질적으로 GPT-3는 해당 날짜 이후의 사건에 대해 거의 알지 못합니다. 간단한 프롬프트를 통해 이를 확인할 수 있습니다:
ChatGPT는 2022년 월드컵에서 누가 우승했는지 모릅니다.
일부 OpenAI 모델은 미세 조정을 거칠 수 있지만 관심 있는 모델과 같은 고급 모델은 그럴 수 없습니다. 훈련 데이터를 늘릴 수는 없습니다.
훈련 데이터 외에 GPT-3에서 어떻게 답변을 얻을 수 있습니까? 한 가지 방법은 텍스트 이해 능력을 활용하는 것입니다. 관련 맥락으로 프롬프트를 강화함으로써 정답을 얻을 수 있을 것입니다.
아래 예에서는 FIFA 공식 사이트 의 컨텍스트를 제공하는데 응답이 크게 다릅니다.
제공된 컨텍스트를 사용하면 ChatGPT가 정확하게 응답할 수 있습니다.
충분한 관련 컨텍스트가 제공되면 모델이 모든 프롬프트에 응답할 수 있다고 추론할 수 있습니다. 문제는 여전히 남아 있습니다. 임의의 프롬프트가 주어지면 관련 내용을 어떻게 알 수 있습니까? 이 문제를 해결하려면 단어 임베딩이 무엇인지 살펴봐야 합니다.
언어 모델의 맥락에서 임베딩은 단어, 문장 또는 전체 문서를 벡터 또는 숫자 목록으로 표현하는 방법입니다.
임베딩을 계산하려면 word2vec 또는 text-embedding-ada-002 와 같은 신경망이 필요합니다. 이러한 네트워크는 방대한 양의 텍스트에 대해 훈련되었으며 훈련 데이터에 특정 패턴이 나타나는 빈도를 분석하여 단어 간의 관계를 찾을 수 있습니다.
다음과 같은 단어가 있다고 가정해 보겠습니다.
각 단어에 대한 벡터를 계산하기 위해 이러한 임베딩 네트워크 중 하나를 사용한다고 상상해 보세요. 예를 들어:
단어 | 벡터 | 문맥 |
---|---|---|
고양이 | [0.1, 0.2, 0.3, 0.4, 0.5] | 동물, 물건, 작은 것 |
개 | [0.6, 0.7, 0.8, 0.9, 1.0] | 동물, 물건, 큰 것 |
공 | [0.2, 0.4, 0.6, 0.8, 1.0] | 물건, 장난감, 작은 물건 |
집 | [0.3, 0.6, 0.9, 1.2, 1.5] | 건물, 집, 큰 물건 |
각 단어에 대한 벡터가 있으면 이를 사용하여 텍스트의 의미를 나타낼 수 있습니다. 예를 들어, “고양이가 공을 쫓았다”라는 문장은 벡터 [0.1, 0.2, 0.3, 0.4, 0.5] + [0.2, 0.4, 0.6, 0.8, 1.0] = [0.3, 0.6, 0.9, 1.2 로 표현될 수 있습니다. , 1.5]. 이 벡터는 물체를 쫓는 동물에 대한 문장을 나타냅니다.
단어 임베딩은 비슷한 의미를 가진 단어나 문장이 서로 가까이 있는 다차원 공간으로 시각화될 수 있습니다. 벡터 사이의 "거리"를 계산하여 입력 텍스트에 대한 유사한 의미를 찾을 수 있습니다.
임베딩을 벡터 공간으로 3D 표현합니다. 실제로 이러한 공간은 수백 또는 수천 개의 차원을 가질 수 있습니다. 출처: AI의 Multitool을 만나보세요: 벡터 임베딩
이 모든 것 뒤에 숨은 실제 수학은 이 기사의 범위를 벗어납니다. 그러나 중요한 점 은 벡터 연산을 통해 수학을 사용하여 의미를 조작하거나 결정할 수 있다는 것입니다. "queen"이라는 단어를 나타내는 벡터에서 "woman" 벡터를 빼고 "man" 벡터를 추가합니다. 결과는 "king" 근처의 벡터여야 합니다. '아들'을 추가하면 '왕자'에 가까운 위치에 도달해야 합니다.
지금까지 단어를 입력으로, 숫자를 출력으로 사용하는 신경망 내장에 대해 논의했습니다. 그러나 많은 현대 네트워크는 단어 처리에서 토큰 처리로 전환했습니다.
토큰은 모델에서 처리할 수 있는 가장 작은 텍스트 단위입니다. 토큰은 단어, 문자, 구두점, 기호 또는 단어의 일부일 수 있습니다.
BPE( 바이트 쌍 인코딩 )를 사용하여 텍스트를 토큰으로 변환하고 각 토큰을 숫자로 표시하는 OpenAI 온라인 토크나이저를 실험하여 단어가 토큰으로 변환되는 방식을 확인할 수 있습니다.
토큰과 단어 사이에는 1:1 관계가 있는 경우가 많습니다. 대부분의 토큰에는 단어와 선행 공백이 포함됩니다. 그러나 두 개의 토큰으로 구성된 "임베딩", "임베딩" 및 "딩" 또는 4개의 토큰으로 구성된 "기능"과 같은 특별한 경우가 있습니다. "토큰 ID"를 클릭하면 각 토큰에 대한 모델의 숫자 표현을 볼 수 있습니다.
이제 임베딩이 무엇인지 이해했으므로 다음 질문은 임베딩이 어떻게 더 똑똑한 봇을 구축하는 데 도움이 될 수 있는가입니다.
먼저 GPT-3 API를 직접 사용할 때 어떤 일이 발생하는지 살펴보겠습니다. 사용자가 프롬프트를 표시하면 모델은 최선을 다해 응답합니다.
그러나 방정식에 맥락을 추가하면 상황이 달라집니다. 예를 들어, 맥락을 제공한 후 ChatGPT에 월드컵 우승팀에 대해 물었을 때 큰 변화가 있었습니다.
따라서 더욱 스마트한 봇을 구축하기 위한 계획은 다음과 같습니다.
대부분의 프로젝트처럼 데이터베이스를 설계하는 것부터 시작해 보겠습니다.
당사의 컨텍스트 데이터베이스에는 원본 문서와 해당 벡터가 포함되어야 합니다. 원칙적으로 이 작업에는 모든 유형의 데이터베이스를 사용할 수 있지만 벡터 데이터베이스가 작업에 가장 적합한 도구입니다.
벡터 데이터베이스는 고차원 벡터 데이터를 저장하고 검색하도록 설계된 특수 데이터베이스입니다. 검색을 위해 SQL과 같은 쿼리 언어를 사용하는 대신 벡터를 제공하고 N개의 가장 가까운 이웃을 요청합니다.
벡터를 생성하기 위해 OpenAI가 제공하는 가장 빠르고 비용 효율적인 모델인 text-embedding-ada-002를 사용합니다. 모델은 입력 텍스트를 토큰으로 변환하고 Transformer 라는 주의 메커니즘을 사용하여 관계를 학습합니다. 이 신경망의 출력은 텍스트의 의미를 나타내는 벡터입니다.
컨텍스트 데이터베이스를 생성하려면 다음을 수행합니다.
먼저 OpenAI API 키를 사용하여 환경 파일을 초기화해야 합니다. API 키는 비공개이며 귀하의 계정에 연결되어 있으므로 이 파일을 버전 관리에 커밋해서는 안 됩니다.
export OPENAI_API_KEY=YOUR_API_KEY
다음으로 Python 애플리케이션용 virtualenv를 생성하겠습니다.
$ virtualenv venv $ source venv/bin/activate $ source .env
OpenAI 패키지를 설치합니다.
```bash $ pip install openai numpy
문자열 "Docker Container"에 대한 임베딩을 계산해 보겠습니다. Python REPL에서 또는 Python 스크립트로 실행할 수 있습니다.
$ python >>> import openai >>> embeddings = openai.Embedding.create(input="Docker Containers", engine="text-embedding-ada-002") >>> embeddings JSON: { "data": [ { "embedding": [ -0.00530336843803525, 0.0013223182177171111, ... 1533 more items ..., -0.015645816922187805 ], "index": 0, "object": "embedding" } ], "model": "text-embedding-ada-002-v2", "object": "list", "usage": { "prompt_tokens": 2, "total_tokens": 2 } }
보시다시피 OpenAI의 모델은 1536개 항목(text-embedding-ada-002의 벡터 크기)이 포함된 embedding
목록으로 응답합니다.
오픈 소스인 Chroma 처럼 선택할 수 있는 벡터 데이터베이스 엔진이 여러 개 있지만 저는 무료 계층이 포함된 관리형 데이터베이스로 작업이 더 간단해지기 때문에 Pinecone을 선택했습니다. 그들의 스타터 플랜은 나에게 필요한 모든 데이터를 처리할 수 있는 능력을 갖추고 있습니다.
Pinecone 계정을 생성하고 API 키와 환경을 검색한 후 두 값을 모두 .env
파일에 추가합니다.
이제 .env
Pinecone 및 OpenAI 비밀이 포함되어야 합니다.
export OPENAI_API_KEY=YOUR_API_KEY # Pinecone secrets export PINECONE_API_KEY=YOUR_API_KEY export PINECONE_ENVIRONMENT=YOUR_PINECONE_DATACENTER
그런 다음 Python용 Pinecone 클라이언트를 설치합니다.
$ pip install pinecone-client
데이터베이스를 초기화해야 합니다. db_create.py
스크립트의 내용은 다음과 같습니다.
# db_create.py import pinecone import openai import os index_name = "semaphore" embed_model = "text-embedding-ada-002" api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, environment=env) embedding = openai.Embedding.create( input=[ "Sample document text goes here", "there will be several phrases in each batch" ], engine=embed_model ) if index_name not in pinecone.list_indexes(): print("Creating pinecone index: " + index_name) pinecone.create_index( index_name, dimension=len(embedding['data'][0]['embedding']), metric='cosine', metadata_config={'indexed': ['source', 'id']} )
스크립트가 데이터베이스를 생성하는 데 몇 분 정도 걸릴 수 있습니다.
$ python db_create.py
다음으로 tiktoken 패키지를 설치하겠습니다. 이를 사용하여 소스 문서에 있는 토큰 수를 계산하겠습니다. 임베딩 모델은 최대 8191개의 토큰만 처리할 수 있기 때문에 이는 중요합니다.
$ pip install tiktoken
패키지를 설치하는 동안 tqdm
도 설치하여 멋진 진행률 표시줄을 생성해 보겠습니다.
$ pip install tqdm
이제 문서를 데이터베이스에 업로드해야 합니다. 이에 대한 스크립트는 index_docs.py
라고 합니다. 필요한 모듈을 가져오고 몇 가지 상수를 정의하는 것부터 시작해 보겠습니다.
# index_docs.py # Pinecone db name and upload batch size index_name = 'semaphore' upsert_batch_size = 20 # OpenAI embedding and tokenizer models embed_model = "text-embedding-ada-002" encoding_model = "cl100k_base" max_tokens_model = 8191
다음으로 토큰을 계산하는 함수가 필요합니다. OpenAI 페이지에는 토큰 카운터 예제가 있습니다.
import tiktoken def num_tokens_from_string(string: str) -> int: """Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_model) num_tokens = len(encoding.encode(string)) return num_tokens
마지막으로 원본 문서를 사용 가능한 예제로 변환하려면 몇 가지 필터링 기능이 필요합니다. 문서의 대부분의 예는 코드 펜스 사이에 있으므로 모든 파일에서 모든 YAML 코드를 추출하겠습니다.
import re def extract_yaml(text: str) -> str: """Returns list with all the YAML code blocks found in text.""" matches = [m.group(1) for m in re.finditer("```yaml([\w\W]*?)```", text)] return matches
이제 기능이 끝났습니다. 다음으로 메모리에 파일을 로드하고 예제를 추출합니다.
from tqdm import tqdm import sys import os import pathlib repo_path = sys.argv[1] repo_path = os.path.abspath(repo_path) repo = pathlib.Path(repo_path) markdown_files = list(repo.glob("**/*.md")) + list( repo.glob("**/*.mdx") ) print(f"Extracting YAML from Markdown files in {repo_path}") new_data = [] for i in tqdm(range(0, len(markdown_files))): markdown_file = markdown_files[i] with open(markdown_file, "r") as f: relative_path = markdown_file.relative_to(repo_path) text = str(f.read()) if text == '': continue yamls = extract_yaml(text) j = 0 for y in yamls: j = j+1 new_data.append({ "source": str(relative_path), "text": y, "id": f"github.com/semaphore/docs/{relative_path}[{j}]" })
이 시점에서 모든 YAML은 new_data
목록에 저장되어야 합니다. 마지막 단계는 임베딩을 Pinecone에 업로드하는 것입니다.
import pinecone import openai api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, enviroment=env) index = pinecone.Index(index_name) print(f"Creating embeddings and uploading vectors to database") for i in tqdm(range(0, len(new_data), upsert_batch_size)): i_end = min(len(new_data), i+upsert_batch_size) meta_batch = new_data[i:i_end] ids_batch = [x['id'] for x in meta_batch] texts = [x['text'] for x in meta_batch] embedding = openai.Embedding.create(input=texts, engine=embed_model) embeds = [record['embedding'] for record in embedding['data']] # clean metadata before upserting meta_batch = [{ 'id': x['id'], 'text': x['text'], 'source': x['source'] } for x in meta_batch] to_upsert = list(zip(ids_batch, embeds, meta_batch)) index.upsert(vectors=to_upsert)
참고로 데모 저장소에서 전체 index_docs.py 파일을 찾을 수 있습니다.
데이터베이스 설정을 완료하기 위해 인덱스 스크립트를 실행해 보겠습니다.
$ git clone https://github.com/semaphoreci/docs.git /tmp/docs $ source .env $ python index_docs.py /tmp/docs
Pinecone 대시보드에는 데이터베이스의 벡터가 표시되어야 합니다.
스크립트로 실행하거나 Python REPL에서 직접 실행할 수 있는 다음 코드를 사용하여 데이터베이스를 쿼리할 수 있습니다.
$ python >>> import os >>> import pinecone >>> import openai # Compute embeddings for string "Docker Container" >>> embeddings = openai.Embedding.create(input="Docker Containers", engine="text-embedding-ada-002") # Connect to database >>> index_name = "semaphore" >>> api_key = os.getenv("PINECONE_API_KEY") >>> env = os.getenv("PINECONE_ENVIRONMENT") >>> pinecone.init(api_key=api_key, environment=env) >>> index = pinecone.Index(index_name) # Query database >>> matches = index.query(embeddings['data'][0]['embedding'], top_k=1, include_metadata=True) >>> matches['matches'][0] {'id': 'github.com/semaphore/docs/docs/ci-cd-environment/docker-authentication.md[3]', 'metadata': {'id': 'github.com/semaphore/docs/docs/ci-cd-environment/docker-authentication.md[3]', 'source': 'docs/ci-cd-environment/docker-authentication.md', 'text': '\n' '# .semaphore/semaphore.yml\n' 'version: v1.0\n' 'name: Using a Docker image\n' 'agent:\n' ' machine:\n' ' type: e1-standard-2\n' ' os_image: ubuntu1804\n' '\n' 'blocks:\n' ' - name: Run container from Docker Hub\n' ' task:\n' ' jobs:\n' ' - name: Authenticate docker pull\n' ' commands:\n' ' - checkout\n' ' - echo $DOCKERHUB_PASSWORD | docker login ' '--username "$DOCKERHUB_USERNAME" --password-stdin\n' ' - docker pull /\n' ' - docker images\n' ' - docker run /\n' ' secrets:\n' ' - name: docker-hub\n'}, 'score': 0.796259582, 'values': []}
보시다시피 첫 번째 일치 항목은 Docker 이미지를 가져와 실행하는 세마포어 파이프라인에 대한 YAML입니다. "Docker Containers" 검색 문자열과 관련이 있으므로 좋은 시작입니다.
우리는 데이터를 갖고 있으며 이를 쿼리하는 방법을 알고 있습니다. 봇에서 작동하도록 합시다.
프롬프트 처리 단계는 다음과 같습니다.
평소와 같이 봇의 기본 스크립트 complete.py
에 몇 가지 상수를 정의하는 것부터 시작하겠습니다.
# complete.py # Pinecone database name, number of matched to retrieve # cutoff similarity score, and how much tokens as context index_name = 'semaphore' context_cap_per_query = 30 match_min_score = 0.75 context_tokens_per_query = 3000 # OpenAI LLM model parameters chat_engine_model = "gpt-3.5-turbo" max_tokens_model = 4096 temperature = 0.2 embed_model = "text-embedding-ada-002" encoding_model_messages = "gpt-3.5-turbo-0301" encoding_model_strings = "cl100k_base" import pinecone import os # Connect with Pinecone db and index api_key = os.getenv("PINECONE_API_KEY") env = os.getenv("PINECONE_ENVIRONMENT") pinecone.init(api_key=api_key, environment=env) index = pinecone.Index(index_name)
다음으로 OpenAI 예제 에 표시된 대로 토큰을 계산하는 함수를 추가하겠습니다. 첫 번째 함수는 문자열의 토큰 수를 계산하고, 두 번째 함수는 메시지의 토큰 수를 계산합니다. 잠시 후 메시지를 자세히 살펴보겠습니다. 지금은 대화의 상태를 기억에 유지하는 구조라고만 하자.
import tiktoken def num_tokens_from_string(string: str) -> int: """Returns the number of tokens in a text string.""" encoding = tiktoken.get_encoding(encoding_model_strings) num_tokens = len(encoding.encode(string)) return num_tokens def num_tokens_from_messages(messages): """Returns the number of tokens used by a list of messages. Compatible with model """ try: encoding = tiktoken.encoding_for_model(encoding_model_messages) except KeyError: encoding = tiktoken.get_encoding(encoding_model_strings) num_tokens = 0 for message in messages: num_tokens += 4 # every message follows {role/name}\n{content}\n for key, value in message.items(): num_tokens += len(encoding.encode(value)) if key == "name": # if there's a name, the role is omitted num_tokens += -1 # role is always required and always 1 token num_tokens += 2 # every reply is primed with assistant return num_tokens
다음 함수는 원본 프롬프트와 컨텍스트 문자열을 사용하여 GPT-3에 대한 강화된 프롬프트를 반환합니다.
def get_prompt(query: str, context: str) -> str: """Return the prompt with query and context.""" return ( f"Create the continuous integration pipeline YAML code to fullfil the requested task.\n" + f"Below you will find some context that may help. Ignore it if it seems irrelevant.\n\n" + f"Context:\n{context}" + f"\n\nTask: {query}\n\nYAML Code:" )
get_message
함수는 API와 호환되는 형식으로 프롬프트 형식을 지정합니다.
def get_message(role: str, content: str) -> dict: """Generate a message for OpenAI API completion.""" return {"role": role, "content": content}
모델이 반응하는 방식에 영향을 미치는 역할에는 세 가지 유형이 있습니다.
이제 매력적인 부분입니다. get_context
함수는 프롬프트를 사용하여 데이터베이스를 쿼리하고 다음 조건 중 하나가 충족될 때까지 컨텍스트 문자열을 생성합니다.
context_tokens_per_query
초과합니다.match_min_score
미만의 유사성 점수가 있는 일치 항목은 무시됩니다. import openai def get_context(query: str, max_tokens: int) -> list: """Generate message for OpenAI model. Add context until hitting `context_token_limit` limit. Returns prompt string.""" embeddings = openai.Embedding.create( input=[query], engine=embed_model ) # search the database vectors = embeddings['data'][0]['embedding'] embeddings = index.query(vectors, top_k=context_cap_per_query, include_metadata=True) matches = embeddings['matches'] # filter and aggregate context usable_context = "" context_count = 0 for i in range(0, len(matches)): source = matches[i]['metadata']['source'] if matches[i]['score'] < match_min_score: # skip context with low similarity score continue context = matches[i]['metadata']['text'] token_count = num_tokens_from_string(usable_context + '\n---\n' + context) if token_count < context_tokens_per_query: usable_context = usable_context + '\n---\n' + context context_count = context_count + 1 print(f"Found {context_count} contexts for your query") return usable_context
다음이자 마지막 함수인 complete
OpenAI에 API 요청을 보내고 모델의 응답을 반환합니다.
def complete(messages): """Query the OpenAI model. Returns the first answer. """ res = openai.ChatCompletion.create( model=chat_engine_model, messages=messages, temperature=temperature ) return res.choices[0].message.content.strip()
그게 다야; 이제 명령줄 인수만 처리하고 올바른 순서로 함수를 호출하면 됩니다.
import sys query = sys.argv[1] context = get_context(query, context_tokens_per_query) prompt = get_prompt(query, context) # initialize messages list to send to OpenAI API messages = [] messages.append(get_message('user', prompt)) messages.append(get_message('system', 'You are a helpful assistant that writes YAML code for Semaphore continuous integration pipelines and explains them. Return YAML code inside code fences.')) if num_tokens_from_messages(messages) >= max_tokens_model: raise Exception('Model token size limit reached') print("Working on your query... ") answer = complete(messages) print("Answer:\n") print(answer) messages.append(get_message('assistant', answer))
이제 스크립트를 실행하고 결과가 어떻게 되는지 살펴보겠습니다.
$ python complete.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub"
결과는 다음과 같습니다.
version: v1.0 name: Docker Build and Push agent: machine: type: e1-standard-2 os_image: ubuntu1804 blocks: - name: "Build and Push Docker Image" task: jobs: - name: "Docker Build and Push" commands: - checkout - docker build -t /: . - echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin - docker push /: promotions: - name: Deploy to production pipeline_file: deploy-production.yml auto_promote: when: "result = 'passed' and branch = 'master'"
이것이 첫 번째 좋은 결과입니다. 모델은 우리가 제공한 컨텍스트 예제에서 구문을 추론했습니다.
제가 YAML 파이프라인을 작성하기 위한 도우미를 만드는 작은 목표로 시작했다는 것을 기억하세요. 내 벡터 데이터베이스에 더 풍부한 콘텐츠가 있으면 봇을 일반화하여 세마포어(또는 모든 제품 - 문서를 /tmp
?에 복제한 것을 기억하시나요?)에 대한 모든 질문에 답할 수 있습니다.
좋은 답변을 얻는 열쇠는 당연히 품질 컨텍스트입니다. 단순히 모든 문서를 벡터 데이터베이스에 업로드하는 것만으로는 좋은 결과를 얻을 수 없습니다. 컨텍스트 데이터베이스는 선별되고, 설명적인 메타데이터로 태그가 지정되고, 간결해야 합니다. 그렇지 않으면 관련 없는 컨텍스트로 프롬프트의 토큰 할당량을 채울 위험이 있습니다.
따라서 어떤 의미에서 우리의 요구 사항을 충족하도록 봇을 미세 조정하는 데는 기술과 많은 시행착오가 필요합니다. 유사성 점수를 조정하여 컨텍스트 제한을 실험하고, 품질이 낮은 콘텐츠를 제거하고, 요약하고, 관련 없는 컨텍스트를 필터링할 수 있습니다.
내 봇을 사용하면 ChatGPT와 같은 실제 대화가 가능하지 않다는 점을 눈치채셨을 것입니다. 우리는 하나의 질문을 하고 하나의 답을 얻습니다.
봇을 완전한 기능을 갖춘 챗봇으로 전환하는 것은 원칙적으로 그리 어렵지 않습니다. 각 API 요청과 함께 모델에 이전 응답을 다시 보내 대화를 유지할 수 있습니다. 이전 GPT-3 답변은 '보조' 역할로 다시 전송됩니다. 예를 들어:
messages = [] while True: query = input('Type your prompt:\n') context = get_context(query, context_tokens_per_query) prompt = get_prompt(query, context) messages.append(get_message('user', prompt)) messages.append(get_message('system', 'You are a helpful assistant that writes YAML code for Semaphore continuous integration pipelines and explains them. Return YAML code inside code fences.')) if num_tokens_from_messages(messages) >= max_tokens_model: raise Exception('Model token size limit reached') print("Working on your query... ") answer = complete(messages) print("Answer:\n") print(answer) # remove system message and append model's answer messages.pop() messages.append(get_message('assistant', answer))
불행하게도 이 구현은 다소 초보적입니다. 각 상호작용마다 토큰 수가 증가하므로 확장된 대화는 지원되지 않습니다. 머지않아 GPT-3의 4096개 토큰 제한에 도달하여 더 이상의 대화가 불가능해질 것입니다.
따라서 요청을 토큰 제한 내에서 유지하는 방법을 찾아야 합니다. 몇 가지 전략은 다음과 같습니다.
단어 임베딩과 좋은 컨텍스트 데이터베이스를 사용하면 봇의 응답을 향상시킬 수 있습니다. 이를 달성하려면 양질의 문서가 필요합니다. 주제를 파악하고 있는 것처럼 보이는 봇을 개발하는 데에는 상당한 양의 시행착오가 있습니다.
단어 임베딩 및 대규모 언어 모델에 대한 심층적인 탐색이 귀하의 요구 사항에 맞게 맞춤화된 더욱 강력한 봇을 구축하는 데 도움이 되기를 바랍니다.
행복한 건물!
여기에도 게시되었습니다.