내 데이터로 OpenAI 커스터마이징하기 (1 / 2)

· 기능

OpenAI에 특정한 맥락이 필요한 질문을 할 때, 예를 들면 이런 식이에요.

Who is my father?

OpenAI는 환각을 일으키거나 모른다고 답할 수 있어요.

OpenAI가 특정한 질문에 답하도록 도우려면 프롬프트 자체에 추가 맥락 정보를 제공할 수 있어요.

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

같은 질문을 다시 openAI에 던지면 OpenAI는 제공된 맥락 정보가 담긴 프롬프트를 바탕으로 답변하게 돼요.

Embeddings

OpenAI는 텍스트 문자열 간의 관련성을 측정하기 위해 text embeddings라는 기능을 제공해요.

모든 텍스트 블록, 장 또는 주제에 대해 해당 정보를 OpenAI의 Embedding 서비스에 보내면 그 embedding 데이터(즉, 부동 소수점 숫자로 이루어진 벡터 리스트)를 돌려받을 수 있어요. 요청 예시는 다음과 같아요.

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

그리고 openAI로부터의 응답은 대략 이런 모습이에요.

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

챗봇이 이해해야 하는 다양한 정보 조각을 표현하는 특별한 데이터를 수집했다면, 이를 안전한 곳(예: 벡터 데이터베이스)에 저장해야 해요. 참고로 이 단계는 한 번만 수행하면 돼요. 정보에 대한 이 특별한 데이터를 한 번 얻고, 정보가 변경될 때만 업데이트해요.

마지막으로 챗봇에게 질문을 하고 싶을 때는 먼저 질의를 벡터로 변환하고, 그 결과를 이용해 이전에 만들어 둔 데이터베이스에서 우리의 질의와 가장 유사한 벡터를 찾아요. 찾은 후에는 가장 유사한 벡터의 프롬프트를 질문에 embedding으로 추가해요.

간단한 예제

embeddings와 sgcWebSockets 라이브러리를 사용하는 간단한 예제를 만들어 볼게요. 먼저 우리 가족을 묘사하고 각각의 벡터를 계산해요.

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.');

위 결과는 각 행이 프롬프트와 벡터 데이터로 이루어진 embedding인 테이블에 저장할 수 있어요. 

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...]

이제 벡터를 저장했으니, chatgpt에 보낼 질문을 벡터로 변환할 거예요. 

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

그런 다음 이 벡터를 데이터베이스에서 검색해 질문과 가장 유사한 것을 찾아요. 아래에 의사 코드 예제가 있어요.

// 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;

마지막으로 찾은 embedding을 맥락 정보로 추가하여 chatgpt에 질문해요. 

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:'));