独自データで OpenAI をカスタマイズ (1 / 2) | eSeGeCe ブログ

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

· 機能

クイック回答: Delphi で OpenAI の回答をご自身のデータに基づかせるには、sgcWebSockets の TsgcHTTP_API_OpenAI コンポーネントを使ってエンベディングを構築します。コンポーネントを配置し、OpenAIOptions.ApiKey を設定してから、_CreateEmbeddings を呼び出して、データの各断片をデータベースに保存するベクトルに変換します。クエリ時には質問をエンベディングし、最も近い保存済みベクトルを見つけて、そのコンテキストを TsgcAIOpenAIChatBot に渡すことで、モデルがご自身のデータに基づいて回答します。

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