Quando fazemos ao OpenAI uma pergunta que requer algum contexto específico, por exemplo:
Who is my father?
O OpenAI pode alucinar ou responder que não sabe.
Para ajudar o OpenAI a responder perguntas específicas, você pode fornecer informações contextuais extras no próprio prompt.
My father lives in Barcelona and is 50 year's old.
Se fizermos a mesma pergunta ao OpenAI novamente, ele responderá incluindo as informações contextuais fornecidas no prompt.
Embeddings
O OpenAI oferece uma capacidade conhecida como text embeddings para medir a similaridade entre strings de texto.Para cada bloco de texto, capítulo ou assunto, podemos enviar essa informação ao serviço de Embedding do OpenAI para receber de volta seus dados de embedding (ou seja, uma lista vetorial de números de ponto flutuante). Exemplo de requisição:
TsgcHTTP_API_OpenAI._CreateEmbeddings('text-embedding-ada-002', 'My father lives in Barcelona and is 50 year's old.');
E a resposta do OpenAI será algo como:
{
"data": [
{
"embedding": [
-0.006929283495992422,
-0.005336422007530928,
...
-4.547132266452536e-05,
-0.024047505110502243
],
"index": 0,
"object": "embedding"
}
],
}
Depois de coletarmos os dados especiais que representam as diferentes informações que queremos que o chatbot entenda, precisamos salvá-los em um lugar seguro (como um banco de dados vetorial). Lembre-se: fazemos isso apenas uma vez. Obtemos esses dados especiais para a informação uma única vez e só os atualizamos se a informação mudar.
Por fim, quando quisermos fazer uma pergunta ao chatbot, primeiro convertemos a consulta em um vetor e com o resultado buscamos no banco de dados criado anteriormente qual vetor é mais similar à nossa consulta; uma vez encontrado, adicionamos o prompt do vetor mais similar à pergunta como embedding.
Exemplo Simples
Vamos criar um exemplo simples para usar embeddings com a biblioteca sgcWebSockets. Primeiro, descreveremos nossa família e calcularemos o vetor para cada membro.
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.');
Os resultados anteriores podem ser armazenados em uma tabela onde cada linha é um embedding com o prompt e os dados do vetor.
| Prompt | Vector |
| 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...] |
Agora que armazenamos nossos vetores, vamos converter a pergunta que enviaremos ao chatgpt em um vetor.
oOpenAI := TsgcHTTP_API_OpenAI.Create(nil);
oOpenAI.OpenAIOptions.ApiKey := '<your api key>';
vVectorQuery := oOpenAI._CreateEmbeddings('text-embedding-ada-002', ''Who is my father?'');
Em seguida, vamos buscar esse vetor no banco de dados para detectar qual é o mais similar à pergunta. Veja abaixo um exemplo de pseudo-código:
// 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;
Por fim, consultamos o chatgpt adicionando o embedding encontrado como informação contextual.
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:'));
