OpenAI mit deinen eigenen Daten anpassen (1 / 2)

· Funktionen

Wenn wir OpenAI eine Frage stellen, die einen bestimmten Kontext erfordert, zum Beispiel:

Who is my father?

kann OpenAI entweder halluzinieren oder antworten, dass es das nicht weiß.

Damit OpenAI spezifische Fragen beantworten kann, kannst du zusätzliche Kontextinformationen direkt im Prompt mitliefern.

My father lives in Barcelona and is 50 year's old.

Wenn wir OpenAI nun erneut dieselbe Frage stellen, antwortet das Modell unter Berücksichtigung der im Prompt mitgegebenen Kontextinformationen.

Embeddings

OpenAI bietet eine Funktion namens Text-Embeddings, mit der sich die Verwandtschaft von Textzeichenfolgen messen lässt.

Für jeden Textblock, jedes Kapitel oder Thema können wir die Information an den Embedding-Service von OpenAI senden und erhalten dafür die zugehörigen Embedding-Daten zurück (also eine Vektorliste aus Fließkommazahlen). Beispiel einer Anfrage:

TsgcHTTP_API_OpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year's old.');

Und die Antwort von OpenAI sieht in etwa so aus:

{
"data": [
{
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
...
-4.547132266452536e-05,
-0.024047505110502243
],
"index": 0,
"object": "embedding"
}
],
}

Sobald wir die speziellen Daten gesammelt haben, die die verschiedenen Informationen repräsentieren, die unser Chatbot verstehen soll, müssen wir sie an einem sicheren Ort speichern (etwa in einer Vektordatenbank). Dieser Schritt wird nur einmal ausgeführt. Wir erzeugen diese speziellen Daten einmal und aktualisieren sie nur dann, wenn sich die Informationen ändern.

Wenn wir dem Chatbot anschließend eine Frage stellen wollen, wandeln wir die Anfrage zuerst in einen Vektor um, suchen in der zuvor erstellten Datenbank den Vektor, der unserer Anfrage am ähnlichsten ist, und fügen dann den Prompt des ähnlichsten Vektors als Embedding zur Frage hinzu.

Einfaches Beispiel

Erstellen wir ein einfaches Beispiel, das Embeddings und die sgcWebSockets-Bibliothek nutzt. Zunächst beschreiben wir unsere Familie und berechnen für jede Person den Vektor.

oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year''s old.');
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My mather lives in Berlin and is 47 year''s old.');
oOpenAI._CreateEmbeddings('text-embedding-ada-002', 'My sister lives in Seoul and is 28 year''s old.');

Die vorherigen Ergebnisse lassen sich in einer Tabelle ablegen, in der jede Zeile ein Embedding mit dem Prompt und den Vektordaten enthält. 

Prompt Vektor
My father lives in Barcelona and is 50 year's old. [0.000742552,-0.0049907574...]
My mather lives in Berlin and is 47 year's old.[-0.027452856,-0.0023051118...]
My sister lives in Seoul and is 28 year's old.[-0.007873567,-0.014787777...]

Nachdem wir unsere Vektoren gespeichert haben, wandeln wir die Frage, die wir an ChatGPT senden, in einen Vektor um. 

oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
vVectorQuery := oOpenAI._CreateEmbeddings('text-embedding-ada-002', ''Who is my father?''); 

Anschließend suchen wir diesen Vektor in der Datenbank, um zu ermitteln, welcher der Frage am ähnlichsten ist. Hier ein Beispiel als Pseudocode:

// search the most similar vector using Cosine Similarity
vMostSimilarVector := 0;
Database.First;
While not Database.EOF do
begin
  vCosineSimilarity := VectorCosineSimilarity(vVectorQuery, Database.FieldByName('Vector'));
  if vConsineSimilarity > vMostSimilarVector then
  begin
    vMostSimilarVector := vCosineSimilarity;
    vContext := Database.FieldByName('Prompt');
  end;
  Database.Next;
end;

Zum Schluss stellen wir die Frage an ChatGPT und fügen das gefundene Embedding als Kontextinformation hinzu. 

vQuestion := 'Who is my father?';
ChatBot := TsgcAIOpenAIChatBot.Create(nil);
ChatBot.OpenAIOptions.ApiKey := '<your api key>';
ShowMessage(ChatBot.ChatAsUser('Answer the question based on the context below.\n\nContext:\n' + vContext + '\nQuestion:' + vQuestion + '\nAnswer:'));