OpenAI'nin ChatGPT'sinin son derece akıllı olduğuna şüphe yok; avukatlık sınavını geçmiş, doktor benzeri bilgiye sahip ve bazı testler IQ'sunun 155 olduğunu gösteriyor . Ancak cehaleti kabul etmek yerine bilgiyi uydurma eğilimindedir. Bu eğilim, bilgi birikiminin 2021'de sona ereceği gerçeğiyle birleştiğinde, GPT API'yi kullanarak özel ürünler oluşturma konusunda zorluklar ortaya çıkarıyor.
Bu engelleri nasıl aşabiliriz? GPT-3 gibi bir modele yeni bilgileri nasıl aktarabiliriz? Amacım Python, OpenAI API ve sözcük yerleştirmeleri kullanan bir soru yanıtlayan bot oluşturarak bu soruları yanıtlamak.
Bildiğiniz gibi Semaphore CI/CD'de YAML ile biçimlendirilmiş bir istemden sürekli entegrasyon ardışık düzenleri oluşturan bir bot oluşturmayı düşünüyorum.
İşte botun çalışırken bir örneği:
Çalışan programın ekran görüntüsü. Ekranda python query.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub"
yürütülür ve program, istenen eylemi gerçekleştiren bir CI işlem hattına karşılık gelen YAML'yi yazdırır.
DocsGPT , My AskAI ve Libraria gibi projelerin ruhuna uygun olarak, GPT-3 modelini Semaphore ve ardışık düzen yapılandırma dosyalarının nasıl oluşturulacağı hakkında "öğretmeyi" planlıyorum. Bunu mevcut belgelerden yararlanarak başaracağım.
Bot oluşturma konusunda önceden bilgi sahibi olduğumu varsaymayacağım ve gereksinimlerinize uyarlayabilmeniz için temiz kodu koruyacağım.
Bu öğreticiyi takip etmek için bir bot kodlama deneyimine veya sinir ağları bilgisine ihtiyacınız yoktur. Ancak ihtiyacınız olacak:
ChatGPT veya daha doğrusu GPT-3 ve GPT-4, onları destekleyen Büyük Dil Modelleri (LLM), Eylül 2021 civarında sonlanma tarihi olan devasa bir veri kümesi üzerinde eğitildi.
Aslında GPT-3 bu tarihin ötesindeki olaylar hakkında çok az şey biliyor. Bunu basit bir istemle doğrulayabiliriz:
ChatGPT, 2022'de Dünya Kupasını kimin kazandığını bilmiyor.
Bazı OpenAI modelleri ince ayardan geçebilirken, ilgilenilenler gibi daha gelişmiş modeller bunu yapamaz; onların eğitim verilerini artıramayız.
GPT-3'ten eğitim verilerinin ötesinde nasıl yanıt alabiliriz? Yöntemlerden biri metni anlama yeteneklerinden yararlanmayı içerir; Bilgi istemini ilgili bağlamla zenginleştirerek muhtemelen doğru cevabı elde edebiliriz.
Aşağıdaki örnekte, FIFA'nın resmi sitesinden bağlamı aktarıyorum ve yanıtlar önemli ölçüde farklılık gösteriyor:
Sağlanan bağlamla ChatGPT doğru yanıt verebilir.
Yeterince ilgili bağlam verildiğinde modelin herhangi bir soruya yanıt verebileceği sonucunu çıkarabiliriz. Soru hala ortada: Keyfi bir istemle neyin alakalı olduğunu nasıl bilebiliriz? Bu sorunu çözmek için kelime yerleştirmelerin ne olduğunu araştırmamız gerekiyor.
Dil modelleri bağlamında gömme, kelimeleri, cümleleri veya tüm belgeleri vektörler veya sayı listeleri olarak temsil etmenin bir yoludur.
Gömmeleri hesaplamak için word2vec veya text-embedding-ada-002 gibi bir sinir ağına ihtiyacımız olacak. Bu ağlar çok büyük miktarda metin üzerinde eğitilmiştir ve eğitim verilerinde belirli kalıpların görünme sıklığını analiz ederek kelimeler arasındaki ilişkileri bulabilirler.
Diyelim ki elimizde şu kelimeler var:
Her kelimenin vektörlerini hesaplamak için bu yerleştirme ağlarından birini kullandığımızı hayal edin. Örneğin:
Kelime | Vektör | Bağlam |
---|---|---|
Kedi | [0,1, 0,2, 0,3, 0,4, 0,5] | Hayvanlar, nesneler, küçük şeyler |
Köpek | [0,6, 0,7, 0,8, 0,9, 1,0] | Hayvanlar, nesneler, büyük şeyler |
Top | [0,2, 0,4, 0,6, 0,8, 1,0] | Nesneler, oyuncaklar, küçük şeyler |
Ev | [0,3, 0,6, 0,9, 1,2, 1,5] | Binalar, evler, büyük şeyler |
Her kelimenin vektörlerini aldıktan sonra bunları metnin anlamını temsil etmek için kullanabiliriz. Örneğin, "Kedi topu kovaladı" cümlesi şu şekilde gösterilebilir: [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]. Bu vektör bir nesneyi kovalayan bir hayvanla ilgili bir cümleyi temsil ediyor.
Kelime gömmeleri, benzer anlamlara sahip kelime veya cümlelerin birbirine yakın olduğu çok boyutlu alanlar olarak görselleştirilebilir. Herhangi bir girdi metnine benzer anlamlar bulmak için vektörler arasındaki "mesafeyi" hesaplayabiliriz.
Gömmelerin vektör uzayları olarak 3 boyutlu gösterimi. Gerçekte bu uzayların yüzlerce ya da binlerce boyutu olabilir. Kaynak: Yapay Zekanın Çok Amaçlı Aracıyla Tanışın: Vektör Yerleştirmeleri
Tüm bunların ardındaki gerçek matematik bu makalenin kapsamı dışındadır. Bununla birlikte, önemli çıkarım , vektör işlemlerinin matematiği kullanarak anlamı değiştirmemize veya belirlememize olanak sağlamasıdır . “Kraliçe” kelimesini temsil eden vektörü alın, “kadın” vektörünü bundan çıkarın ve “erkek” vektörünü ekleyin. Sonuç “kral”ın yakınında bir vektör olmalıdır. “Oğul”u eklersek “prens”e yakın bir yere gelmeliyiz.
Şu ana kadar kelimeleri girdi, sayıları da çıktı olarak alan sinir ağlarının yerleştirilmesini tartıştık. Ancak birçok modern ağ, kelimeleri işlemekten jetonları işlemeye geçti.
Belirteç , model tarafından işlenebilen en küçük metin birimidir. Belirteçler sözcükler, karakterler, noktalama işaretleri, semboller veya sözcük parçaları olabilir.
Metni belirteçlere dönüştürmek ve her birini bir sayıyla temsil etmek için Bayt Çifti Kodlama (BPE) kullanan OpenAI çevrimiçi belirteç oluşturucuyu deneyerek kelimelerin nasıl belirteçlere dönüştürüldüğünü görebiliriz:
Belirteçler ve kelimeler arasında genellikle 1'e 1 ilişki vardır. Çoğu jeton, kelimeyi ve baştaki boşluğu içerir. Bununla birlikte, "embed" ve "ding" olmak üzere iki jetondan oluşan "gömme" veya dört jetondan oluşan "yetenekler" gibi özel durumlar da vardır. "Jeton Kimlikleri"ne tıklarsanız modelin her bir jetonun sayısal temsilini görebilirsiniz.
Artık yerleştirmelerin ne olduğunu anladığımıza göre bir sonraki soru şu: Daha akıllı bir bot oluşturmamıza nasıl yardımcı olabilirler?
Öncelikle GPT-3 API'sini doğrudan kullandığımızda ne olacağına bakalım. Kullanıcı bir istem gönderir ve model, yeteneğinin en iyisine yanıt verir.
Ancak denkleme bağlam eklediğimizde işler değişiyor. Örneğin, bağlamı sağladıktan sonra ChatGPT'ye Dünya Kupası'nın galibi hakkında soru sorduğumda büyük fark yarattı.
Yani daha akıllı bir bot oluşturma planı şu şekildedir:
Çoğu projede olduğu gibi veritabanını tasarlayarak başlayalım.
Bağlam veritabanımız orijinal belgeleri ve bunların ilgili vektörlerini içermelidir. Prensip olarak bu görev için her tür veritabanını kullanabiliriz ancak vektör veritabanı bu iş için en uygun araçtır.
Vektör veritabanları, yüksek boyutlu vektör verilerini depolamak ve almak için tasarlanmış özel veritabanlarıdır. Arama için SQL gibi bir sorgu dili kullanmak yerine bir vektör sağlıyoruz ve en yakın N komşuyu talep ediyoruz.
Vektörleri oluşturmak için OpenAI'nin text-embedding-ada-002'sini kullanacağız çünkü bu, sundukları en hızlı ve en uygun maliyetli modeldir. Model, giriş metnini belirteçlere dönüştürür ve aralarındaki ilişkileri öğrenmek için Transformer olarak bilinen bir dikkat mekanizmasını kullanır. Bu sinir ağının çıktısı metnin anlamını temsil eden vektörlerdir.
Bir bağlam veritabanı oluşturmak için şunları yapacağım:
Öncelikle OpenAI API anahtarıyla bir ortam dosyasını başlatmalıyım. API anahtarı özel olduğundan ve hesabınıza bağlı olduğundan bu dosya hiçbir zaman sürüm kontrolüne alınmamalıdır.
export OPENAI_API_KEY=YOUR_API_KEY
Daha sonra Python uygulamam için bir virtualenv oluşturacağım:
$ virtualenv venv $ source venv/bin/activate $ source .env
Ve OpenAI paketini yükleyin:
```bash $ pip install openai numpy
"Docker Container" dizisinin yerleştirmesini hesaplamayı deneyelim. Bunu Python REPL'de veya Python betiği olarak çalıştırabilirsiniz:
$ 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 } }
Gördüğünüz gibi, OpenAI'nin modeli 1536 öğe içeren bir embedding
listesiyle yanıt veriyor - metin yerleştirme-ada-002'nin vektör boyutu.
Açık kaynaklı Chroma gibi seçilebilecek birden fazla vektör veritabanı motoru olmasına rağmen, Pinecone'u seçtim çünkü bu, ücretsiz katmana sahip yönetilen bir veritabanı, bu da işleri kolaylaştırıyor. Başlangıç planları ihtiyaç duyacağım tüm verileri fazlasıyla karşılayabilecek kapasitede.
Pinecone hesabımı oluşturup API anahtarımı ve ortamımı aldıktan sonra her iki değeri de .env
dosyama ekliyorum.
Artık .env
benim Pinecone ve OpenAI sırlarımı içermeli.
export OPENAI_API_KEY=YOUR_API_KEY # Pinecone secrets export PINECONE_API_KEY=YOUR_API_KEY export PINECONE_ENVIRONMENT=YOUR_PINECONE_DATACENTER
Daha sonra Python için Pinecone istemcisini kuruyorum:
$ pip install pinecone-client
Bir veritabanını başlatmam gerekiyor; db_create.py
betiğinin içeriği şunlardır:
# 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']} )
Komut dosyasının veritabanını oluşturması birkaç dakika sürebilir.
$ python db_create.py
Daha sonra tiktoken paketini kuracağım. Kaynak belgelerin kaç jetona sahip olduğunu hesaplamak için kullanacağım. Bu önemlidir çünkü yerleştirme modeli yalnızca 8191 jetona kadar işleyebilir.
$ pip install tiktoken
Paketleri kurarken güzel görünümlü bir ilerleme çubuğu oluşturmak için tqdm
de kuralım.
$ pip install tqdm
Şimdi belgeleri veritabanına yüklemem gerekiyor. Bunun betiğine index_docs.py
adı verilecek. Gerekli modülleri içe aktararak ve bazı sabitleri tanımlayarak başlayalım:
# 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
Daha sonra jetonları saymak için bir fonksiyona ihtiyacımız olacak. OpenAI sayfasında bir jeton sayacı örneği var:
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
Son olarak orijinal belgeyi kullanılabilir örneklere dönüştürmek için bazı filtreleme işlevlerine ihtiyacım olacak. Belgelerdeki örneklerin çoğu kod sınırları arasındadır, bu nedenle tüm YAML kodunu her dosyadan çıkaracağım:
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
Fonksiyonlarla işim bitti. Daha sonra bu, dosyaları belleğe yükleyecek ve örnekleri çıkaracaktır:
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}]" })
Bu noktada tüm YAML'lerin new_data
listesinde saklanması gerekir. Son adım, yerleştirmeleri Çam Kozalağı'na yüklemektir.
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)
Referans olarak index_docs.py dosyasının tamamını demo deposunda bulabilirsiniz.
Veritabanı kurulumunu tamamlamak için indeks betiğini çalıştıralım:
$ git clone https://github.com/semaphoreci/docs.git /tmp/docs $ source .env $ python index_docs.py /tmp/docs
Çam kozalağı kontrol paneli veritabanındaki vektörleri göstermelidir.
Veritabanını, komut dosyası olarak veya doğrudan Python REPL'de çalıştırabileceğiniz aşağıdaki kodla sorgulayabiliriz:
$ 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': []}
Gördüğünüz gibi ilk eşleşme, Docker görüntüsünü çeken ve çalıştıran Semafor hattının YAML'sidir. "Docker Konteynerleri" arama dizemizle alakalı olduğundan bu iyi bir başlangıç.
Veriler elimizde ve onu nasıl sorgulayacağımızı biliyoruz. Bunu botta çalıştıralım.
İstemi işlemeye yönelik adımlar şunlardır:
Her zamanki gibi, botun ana betiği complete.py
dosyasında bazı sabitleri tanımlayarak başlayacağım:
# 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)
Daha sonra, OpenAI örneklerinde gösterildiği gibi jetonları saymak için işlevler ekleyeceğim. İlk işlev bir dizedeki belirteçleri sayarken, ikincisi mesajlardaki belirteçleri sayar. Mesajları birazdan detaylı olarak göreceğiz. Şimdilik konuşmanın durumunu hafızada tutan bir yapı olduğunu söyleyelim.
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
Aşağıdaki işlev, GPT-3 için zenginleştirilmiş bir bilgi istemi döndürmek üzere orijinal bilgi istemini ve bağlam dizelerini alır:
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
işlevi istemi API ile uyumlu bir biçimde biçimlendirir:
def get_message(role: str, content: str) -> dict: """Generate a message for OpenAI API completion.""" return {"role": role, "content": content}
Modelin nasıl tepki vereceğini etkileyen üç tür rol vardır:
Şimdi ilgi çekici kısım için. get_context
işlevi istemi alır, veritabanını sorgular ve şu koşullardan biri karşılanana kadar bir bağlam dizesi oluşturur:
context_tokens_per_query
alanını aşıyor.match_min_score
altında olan eşleşmeler dikkate alınmaz. 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
Bir sonraki ve son işlev olan complete
, API isteğini OpenAI'ye gönderir ve modelin yanıtını döndürür.
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()
Bu kadar; şimdi sadece komut satırı argümanlarıyla ilgilenmem ve fonksiyonları doğru sırayla çağırmam gerekiyor:
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))
Komut dosyasını çalıştırmanın ve nasıl çalıştığını görmenin zamanı geldi:
$ python complete.py "Create a CI pipeline that builds and uploads a Docker image to Docker Hub"
Sonuç:
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'"
Bu ilk iyi sonuçtur. Model, sözdizimini sunduğumuz bağlam örneklerinden çıkarmıştır.
Mütevazı bir hedefle başladığımı unutmayın: YAML işlem hatlarını yazacak bir asistan yaratmak. Vektör veritabanımdaki daha zengin içerik sayesinde botu, Semaphore (veya herhangi bir ürün) hakkındaki her soruyu yanıtlayacak şekilde genelleştirebilirim; dokümanları /tmp
içine kopyalamayı unutmayın.
İyi yanıtlar almanın anahtarı - şaşırtıcı olmayan bir şekilde - kaliteli bağlamdır. Her belgenin yalnızca vektör veri tabanına yüklenmesinin iyi sonuçlar vermesi pek mümkün değildir. Bağlam veritabanı düzenlenmeli, açıklayıcı meta verilerle etiketlenmeli ve kısa ve öz olmalıdır. Aksi takdirde, istemdeki belirteç kotasını alakasız bağlamla doldurma riskiyle karşı karşıya kalırız.
Yani, bir bakıma, ihtiyaçlarımızı karşılayacak şekilde botun ince ayarını yapmak bir sanat ve çok sayıda deneme yanılma içeriyor. Benzerlik puanını ayarlayarak bağlam sınırıyla denemeler yapabilir, düşük kaliteli içeriği kaldırabilir, özetleyebilir ve alakasız bağlamı filtreleyebiliriz.
Botumun ChatGPT gibi gerçek sohbetler yapmamıza izin vermediğini fark etmiş olabilirsiniz. Bir soru soruyoruz ve bir cevap alıyoruz.
Botu tam teşekküllü bir chatbot'a dönüştürmek prensipte çok zor değil. Her API isteğinde modele verilen önceki yanıtları yeniden göndererek konuşmayı sürdürebiliriz. Önceki GPT-3 yanıtları "asistan" rolü altında geri gönderilir. Örneğin:
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))
Ne yazık ki, bu uygulama oldukça ilkeldir. Her etkileşimde belirteç sayısı arttığından, genişletilmiş konuşmaları desteklemeyecektir. Çok yakında GPT-3 için 4096 jeton sınırına ulaşacağız ve bu da daha fazla diyaloğu önleyecek.
Bu nedenle, isteği belirteç sınırları dahilinde tutmanın bir yolunu bulmalıyız. Birkaç strateji takip ediyor:
Botun yanıtlarını geliştirmek, kelime yerleştirmeler ve iyi bir bağlam veri tabanı ile mümkündür. Bunu başarmak için kaliteli belgelere ihtiyacımız var. Görünüşte konuyu kavrayabilen bir bot geliştirmede önemli miktarda deneme yanılma söz konusudur.
Kelime yerleştirmelerin ve büyük dil modellerinin bu derinlemesine incelenmesinin, gereksinimlerinize göre özelleştirilmiş daha güçlü bir bot oluşturmanıza yardımcı olacağını umuyorum.
Mutlu bina!
Burada da yayınlandı.