Gdy zadajemy OpenAI pytanie, które wymaga konkretnego kontekstu, na przykład:
Who is my father?
OpenAI może albo halucynować, albo odpowiedzieć, że nie wie.
Aby pomóc OpenAI odpowiadać na konkretne pytania, możesz dodać dodatkowe informacje kontekstowe w samym promptcie.
My father lives in Barcelona and is 50 year's old.
Jeśli zadamy OpenAI ponownie to samo pytanie, OpenAI odpowie, uwzględniając prompt zawierający informacje kontekstowe.
Embeddings
OpenAI udostępnia funkcję znaną jako text embeddings, która pozwala mierzyć powiązanie ciągów tekstowych.Dla każdego bloku tekstu, rozdziału lub tematu możemy wysłać tę informację do usługi Embedding OpenAI i otrzymać w odpowiedzi jej dane embeddingu (tj. wektorową listę liczb zmiennoprzecinkowych). Przykład zapytania:
TsgcHTTP_API_OpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year's old.');
A odpowiedź z openAI będzie wyglądać mniej więcej tak:
{
"data": [
{
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
...
-4.547132266452536e-05,
-0.024047505110502243
],
"index": 0,
"object": "embedding"
}
],
}
Gdy już zbierzemy specjalne dane reprezentujące różne fragmenty informacji, które chcemy, aby nasz chatbot rozumiał, musimy je zapisać w bezpiecznym miejscu (na przykład w bazie wektorowej). Pamiętaj, ten krok wykonujemy tylko raz. Pobieramy te specjalne dane dla informacji jednorazowo, a aktualizujemy je tylko wtedy, gdy informacje się zmienią.
Wreszcie, gdy chcemy zadać pytanie chatbotowi, najpierw konwertujemy zapytanie na wektor i z otrzymanym wynikiem przeszukujemy wcześniej utworzoną bazę danych, aby znaleźć wektor najbardziej podobny do naszego zapytania; po znalezieniu dołączamy prompt najbardziej podobnego wektora do pytania jako embedding.
Prosty przykład
Stwórzmy prosty przykład używający embeddingów i biblioteki sgcWebSockets. Najpierw opiszemy naszą rodzinę i obliczymy wektor dla każdej osoby.
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.');
Poprzednie wyniki można zapisać w tabeli, w której każdy wiersz to embedding zawierający prompt i dane wektora.
| Prompt | Wektor |
| 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...] |
Teraz, gdy zapisaliśmy nasze wektory, przekonwertujemy pytanie, które wyślemy do chatgpt, na wektor
oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
vVectorQuery := oOpenAI._CreateEmbeddings('text-embedding-ada-002', ''Who is my father?'');
Następnie wyszukamy ten wektor w bazie danych, aby określić, który jest najbardziej podobny do pytania. Poniżej przykład w pseudokodzie:
// 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;
Wreszcie zadajemy pytanie chatgpt, dodając znaleziony embedding jako informację kontekstową.
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:'));
