.NET でのプロンプト エンジニアリング
この記事では、プロンプト エンジニアリングの重要な概念について説明します。 多くの AI モデルはプロンプトベースです。つまり、ユーザーによる入力テキスト ("プロンプト") に対して、予測アルゴリズムによって生成された応答 ("補完") で応答します。 多くの場合、新しいモデルは、チャット形式の補完と共に、ロール (システム、ユーザー、アシスタント) に基づいたメッセージや会話を保存するチャット履歴をサポートしています。
プロンプトを操作する
プロンプトがユーザー入力で、補完がモデル出力であるテキスト生成の例を考えてみましょう:
プロンプト: "最も在任期間の短い大統領は"
補完: "Pedro Lascurain."
補完は正しいように見えたとしても、アプリの目的が米国史の学生を支援することだとするとどうでしょうか。 ペドロ・ラスクラインの 45 分という任期はあらゆる大統領の中で最も短期ですが、彼が務めたのはメキシコ大統領でした。 米国史の学生が探しているのは、おそらく "ウィリアム・ヘンリー・ハリソン" です。 明らかに、このアプリは意図するユーザーにとってより役立つものでしょう。
モデルがより良い補完を生成できるように、プロンプト エンジニアリングによって "指示"、"例"、"キュー" を指定してプロンプトにコンテキストを追加します。
多くの場合、テキスト生成をサポートするモデルでは、特定の形式は必要ありませんが、指示の内容と例が明確になるようにプロンプトを整理する必要があります。 チャット ベースのアプリをサポートするモデルでは、補完を整理するために 3 つのロール (チャットを制御するシステム ロール、ユーザーによる入力を表すユーザー ロール、ユーザーに応答するためのアシスタント ロール) が使用されます。 プロンプトをロールごとのメッセージに分割します。
- システム メッセージは、アシスタントに関するモデルの指示を提供します。 プロンプトに含めることができるシステム メッセージは 1 つだけであり、最初のメッセージである必要があります。
- "ユーザー メッセージ" にはユーザーからのプロンプトが含まれており、プロンプトの例または履歴を示します。また、アシスタントへの指示が含まれます。 チャット補完の例には、少なくとも 1 つのユーザー メッセージが必要です。
- "アシスタント メッセージ" は、補完の例または履歴を示します。また、前のユーザー メッセージへの応答を含める必要があります。 アシスタント メッセージは必要ありませんが、含める場合は、例を形成するためにユーザー メッセージとペアにする必要があります。
指示を使用して補完を改善する
指示は、応答方法をモデルに指示するテキストです。 指示には、ディレクティブまたは命令型を指定できます:
- ディレクティブはモデルに動作方法を指示しますが、単純なコマンドではありません。改善されたアクターのキャラクター設定を次のように考えます: "あなたは米国の歴史を学ぶの学生を支援するので、他の国について特に尋ねない限り、米国について話してください。"
- 命令型は、モデルが従う明確なコマンドです。 "タガログ語に翻訳してください:"
ディレクティブは、命令よりも自由度が高く、柔軟です。
- 1 つの指示に複数のディレクティブを組み合わせることができます。
- 指示は通常、例と共に使用する場合に適しています。 ただし、命令型は明確なコマンドであるため、モデルはそれらを理解するための例を必要としません (ただし、応答のフォーマット方法をモデルに示すための例を使用することもできます)。 ディレクティブはモデルに何をすべきかを正確に伝えないので、各例はモデルの動作を改善するのに役立ちます。
- 通常は、一連のディレクティブを使用して実行できる一連のディレクティブに難しい指示を分割することをお勧めします。 また、詳細な調整を簡単に行えるように、各ステップの結果を出力するようにモデルに指示する必要があります。 指示を自分自身でステップに分解することはできますが、モデルに指示して各ステップの結果を出力させる方が簡単です。 このアプローチは、思考の連鎖プロンプトと呼ばれます。
プライマリおよびサポート コンテンツによるコンテキストの追加
コンテンツを指定して、指示にコンテキストを追加できます。
プライマリ コンテンツは、モデルが指示で処理するテキストです。 指示に伴うアクションに関係なく、モデルはプライマリ コンテンツに対して実行して補完を生成します。
コンテンツのサポートは、指示で参照するテキストですが、これは指示のターゲットではありません。 このモデルでは、サポート コンテンツを使用して指示を補完します。つまり、サポート コンテンツは、通常、何らかの構造 (見出しや列ラベルなど) として補完にも表示されます。
指示コンテンツと共にラベルを使用して、モデルが指示で使用する方法を理解するのに役立ちます。 精度についてあまり心配しないでください。ラベルは、単語の形式や大文字と小文字などを処理するため、指示と正確に一致する必要はありません。
リストを作成するのに、次のような指示を使用するとします: "米国大統領の達成した成果を要約してください"。 モデルは、任意の数の方法で整理および順序付けできます。 しかし、特定のカテゴリ一式で成果をグループ化するためのリストが欲しい場合はどうでしょう。 サポート コンテンツを使用して、その情報を指示に追加します。
モデルがカテゴリ別にグループ化されるように指示を調整し、それらのカテゴリを指定するサポート コンテンツを追加します:
prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: 'George Washington
- First president of the United States.
- First president to have been a military veteran.
- First president to be elected to a second term in office.
- Received votes from every presidential elector in an election.
- Filled the entire body of the United States federal judges; including the Supreme Court.
- First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ...' ///Text truncated
""";
モデルを導くために例を使用する
例として、ユーザー入力とモデル出力のサンプルを提供して、モデルの応答方法を示すテキストを示します。 モデルでは、例を使用して、補完に含める内容を推測します。 例は、エンジニアリングされたプロンプトの指示の前または後のいずれかになりますが、2 つを混在させるべきではありません。
例はプロンプトで始まり、必要に応じて補完を含めることができます。 例の補完には、逐語的な応答を含める必要はありません。フォーマットされた単語、順序指定されていないリストの最初の行頭文字、または各補完の開始方法を示すような内容が含まれている場合があります。
例は、逐語的な補完が含まれているかどうかに基づいて、ゼロショットの学習または数ショットの学習として分類されます。
- ゼロショットの学習の例には、逐語的な完了のないプロンプトが含まれます。 このアプローチでは、データ出力例を示すことなく、モデルの応答をテストします。 ゼロショット プロンプトには、モデルが補完として "1" を含めて順序付きリストを出力する必要があることを示すなど、キューを含む補完を含めることができます。
- 数ショットの学習例には、逐語的な補完を含む複数のプロンプトのペアが含まれます。 数ショットの学習では、既存の知識を追加することで、モデルの動作を変更できます。
キューを理解する
キューは、目的の構造または出力形式を伝えるテキストです。 指示と同様に、キューはユーザーによる入力であるかのようにモデルによって処理されません。 例のように、キューには何をすべきかを伝える代わりに、必要なモデルが表示されます。 必要な数のキューを追加できるので、反復処理して目的の結果を取得できます。 キューは指示または例と共に使用され、プロンプトの最後に表示されます。
たとえば、カテゴリ別に大統領の成果の一覧を生成するようにモデルに指示し、使用するカテゴリをモデルに伝えるサポート コンテンツを使用するとします。 モデルで、カテゴリのすべてのキャップを含む入れ子になったリストを作成し、各カテゴリの各大統領の成果を、名前で始まる 1 行にリストし、大統領を時系列で示します。 指示とサポート コンテンツの後に、次の 3 つのヒントを追加して、リストを構造化およびフォーマットする方法をモデルに示します。
prompt = """
Instructions: Summarize US Presidential accomplishments, grouped by category.
Categories: Domestic Policy, US Economy, Foreign Affairs, Space Exploration.
Accomplishments: George Washington
First president of the United States.
First president to have been a military veteran.
First president to be elected to a second term in office.
First president to receive votes from every presidential elector in an election.
First president to fill the entire body of the United States federal judges; including the Supreme Court.
First president to be declared an honorary citizen of a foreign country, and an honorary citizen of France.
John Adams ... /// Text truncated
DOMESTIC POLICY
- George Washington:
- John Adams:
""";
- DOMESTIC POLICY では、カテゴリを含む各グループをすべてのキャップで開始するモデルが表示されます。
- - George Washington: では、各セクションを開始するモデルが表示され、George Washington の成果が 1 行に一覧表示されます。
- - John Adams: では残りの大統領を時系列で一覧表示する必要があるモデルを示します。
.NET を使用したプロンプトの例
.NET には、さまざまな AI モデルとプロンプトやチャットを行うさまざまなツールが用意されています。 セマンティック カーネルを使用すると、さまざまな AI モデルやサービス、さらには他の SDK (公式の OpenAI .NET ライブラリなど) に接続できます。 セマンティック カーネルには、さまざまなロールのプロンプトを作成し、チャット履歴を維持するツールや、他の多くの機能があります。
次のコード例について考えてみます。
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
// Create a kernel with OpenAI chat completion
#pragma warning disable SKEXP0010
Kernel kernel = Kernel.CreateBuilder()
.AddOpenAIChatCompletion(
modelId: "phi3:mini",
endpoint: new Uri("http://localhost:11434"),
apiKey: "")
.Build();
var aiChatService = kernel.GetRequiredService<IChatCompletionService>();
var chatHistory = new ChatHistory();
chatHistory.Add(
new ChatMessageContent(AuthorRole.System, "You are a helpful AI Assistant."));
while (true)
{
// Get user prompt and add to chat history
Console.WriteLine("Your prompt:");
chatHistory.Add(new ChatMessageContent(AuthorRole.User, Console.ReadLine()));
// Stream the AI response and add to chat history
Console.WriteLine("AI Response:");
var response = "";
await foreach (var item in
aiChatService.GetStreamingChatMessageContentsAsync(chatHistory))
{
Console.Write(item.Content);
response += item.Content;
}
chatHistory.Add(new ChatMessageContent(AuthorRole.Assistant, response));
Console.WriteLine();
}
上のコードは、次の概念の例を示しています。
- AI モデルにプロンプトを入力して作成者のロールに基づいた補完を得るチャット履歴サービスを作成します。
AuthorRole.System
メッセージを使用して AI を構成します。AuthorRole.User
のコンテキストでさまざまなプロンプトを使用できるように、ユーザーによる入力を受け付けます。- AI からの補完を非同期にストリーミングして、動的なチャット エクスペリエンスを提供します。
プロンプト エンジニアリング手法を拡張する
さらに高度なプロンプト エンジニアリング手法を使用してプロンプトの能力を高めることもできます。詳細については、それらに関する記事で説明されています。
- LLM には、プロンプトに収めることができるテキストの量を制限するトークン入力制限があります。 特定のテキストを表すために必要なトークンの数を減らすには、埋め込みとベクトル データベース ソリューションを使用します。
- LLM は、自分でトレーニングしない限り、データに対してトレーニングされません。これはコストがかかり、時間がかかる可能性があります。 トレーニングを行わずに LLM でデータを使用できるようにするには、取得拡張生成 (RAG) を使用します。
関連するコンテンツ
.NET