独自データで OpenAI をカスタマイズ (1 / 2)

· 機能

OpenAI に特定の文脈を要する質問、たとえば次のような質問をしたとします。

Who is my father?

OpenAI はハルシネーションを起こすか、知らないと回答する場合があります。

OpenAI が特定の質問に回答できるよう支援するには、プロンプト自体に追加の文脈情報を提供できます。

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

同じ質問を再度 OpenAI にすると、提供された文脈情報を含むプロンプトを踏まえて OpenAI が回答します。

エンベディング

OpenAI は、テキスト文字列の関連性を測定するための テキストエンベディング (text embeddings) と呼ばれる機能を提供しています。

テキスト、章、トピックごとに、その情報を OpenAI のエンベディングサービスに送信し、エンベディングデータ (浮動小数点数のベクトルリスト) を受け取ることができます。リクエストの例:

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"
}
],
}

チャットボットに理解させたい情報を表す特別なデータを収集したら、安全な場所 (ベクトルデータベースなど) に保存する必要があります。このステップは一度だけ実行することに注意してください。情報に対する特別なデータは一度取得し、情報が変わった場合にのみ更新します。

最後に、チャットボットに質問する際は、まずクエリをベクトルに変換し、その結果を使って事前に作成したデータベースの中から、クエリに最も類似するベクトルを検索します。見つかったら、最も類似するベクトルのプロンプトをエンベディングとして質問に追加します。

シンプルな例

エンベディングと 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.');

上記の結果は、各行がエンベディング (プロンプトとベクトルデータ) であるテーブルに保存できます。 

プロンプト ベクトル
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;

最後に、見つかったエンベディングを文脈情報として追加して 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:'));