演習 - Azure OpenAI サービスを実装する
まず、ごく簡単なサービスである OpenAiService
から始めましょう。 このサービスには、基本的なプロンプトと入力候補をすぐに実装できるように、実装する必要があるメソッドが 2 つだけ含まれています。 Azure Cosmos DB for NoSQL データ サービスは後になるまで実装しないため、デバッグ セッション間でセッションを保持することはまだできません。
この演習では、いくつかの重要な要件があります。
- ユーザーから AI アシスタントに質問を送信し、応答を求めます。
- 一連のプロンプトを AI アシスタントに送信し、会話の要約を求めます。
AI モデルに質問する
まず、システム プロンプト、質問、セッション ID を送信して質問と回答の会話を実装し、AI モデルが現在の会話のコンテキストで回答を提供できるようにします。 プロンプトを解析して応答 (またはこのコンテキストでの完了) を返すために必要なトークンの数を測定してください。
Services/OpenAiService.cs ファイルを開きます。
GetChatCompletionAsync
メソッド内で、既存のプレースホルダー コードをすべて削除します。public async Task<(string completionText, int completionTokens)> GetChatCompletionAsync(string sessionId, string userPrompt) { }
systemMessage
という名前のChatRequestSystemMessage
変数を作成します。 この変数では、User
ロールと、内容に対する_systemPrompt
変数を使用します。ChatRequestSystemMessage systemMessage = new(_systemPrompt);
userMessage
という名前のChatRequestUserMessage
変数を作成します。 この変数の場合、ロールはChatRole.User
である必要があり、メッセージの内容にuserPrompt
コンストラクター パラメーターを使用する必要があります。ChatRequestUserMessage userMessage = new(userPrompt);
options
という名前のChatCompletionsOptions
型の新しい変数を作成します。 2 つのメッセージ変数をMessages
リストに追加し、User
の値をsessionId
コンストラクター パラメーターに設定し、MaxTokens
を4000
に設定して、残りのプロパティを次の推奨値に設定します。ChatCompletionsOptions options = new() { DeploymentName = _modelName, Messages = { systemMessage, userMessage }, User = sessionId, MaxTokens = 4000, Temperature = 0.3f, NucleusSamplingFactor = 0.5f, FrequencyPenalty = 0, PresencePenalty = 0 };
ヒント
gpt-35-turbo モデルのトークンの最大数は 4096 です。 ここでは、作業を簡略化するために単に丸め込みます。
Azure OpenAI クライアント変数 (
_client
) のGetChatCompletionsAsync
メソッドを非同期的に呼び出します。 作成したoptions
変数を渡します。 結果をcompletions
という名前のChatCompletions
型の変数に格納します。ChatCompletions completions = await _client.GetChatCompletionsAsync(options);
ヒント
GetChatCompletionsAsync
メソッドは、Task<Response<ChatCompletions>>
型のオブジェクトを返します。Response<T>
クラスには、T
型への暗黙的な変換が含まれており、アプリケーションのニーズに基づいて型を選択できます。 結果は、応答から完全なメタデータを取得するためのResponse<ChatCompletions>
として、または結果自体の内容のみを考慮する場合は単にChatCompletions
として格納できます。最後に、
GetChatCompletionAsync
メソッドの結果として、文字列としての入力候補の内容、プロンプトに関連付けられたトークンの数、および応答のトークンの数と共にタプルを返します。return ( response: completions.Choices[0].Message.Content, promptTokens: completions.Usage.PromptTokens, responseTokens: completions.Usage.CompletionTokens );
Services/OpenAiService.cs ファイルを保存します。
AI モデルに会話の要約を求める
次に、AI モデルに別のシステム プロンプト、現在の会話、セッション ID を送信して、AI モデルが会話をいくつかの単語で要約できるようにします。
SummarizeAsync
メソッド内で、既存のプレースホルダー コードをすべて削除します。public async Task<string> SummarizeAsync(string sessionId, string conversationText) { }
systemMessage
という名前のChatRequestSystemMessage
変数を作成します。 この変数では、User
ロールと、内容に対する_summarizePrompt
変数を使用します。ChatRequestSystemMessage systemMessage = new(_summarizePrompt);
userMessage
という名前の別のChatRequestUserMessage
変数を作成します。User
ロールをもう一度使用し、メッセージの内容に対してはconversationText
コンストラクター パラメーターを使用します。ChatRequestUserMessage userMessage = new(conversationText);
Messages
リスト内の 2 つのメッセージ変数を使用して、options
という名前のChatCompletionsOptions
変数を作成し、User
をsessionId
コンストラクター パラメーターに設定し、MaxTokens
を200
に設定し、残りのプロパティを次の推奨値に設定します。ChatCompletionsOptions options = new() { DeploymentName = _modelName, Messages = { systemMessage, userMessage }, User = sessionId, MaxTokens = 200, Temperature = 0.0f, NucleusSamplingFactor = 1.0f, FrequencyPenalty = 0, PresencePenalty = 0 };
options
変数をパラメーターとして使って、_client.GetChatCompletionsAsync
を非同期的に呼び出します。 結果をcompletions
という名前のChatCompletions
型の変数に格納します。ChatCompletions completions = await _client.GetChatCompletionsAsync(options);
SummarizeAsync
メソッドの結果として、入力候補の内容を文字列として返します。return completions.Choices[0].Message.Content;
Services/OpenAiService.cs ファイルを保存します。
作業を確認
この時点で、アプリケーションには、アプリケーションをテストできる、十分な Azure OpenAI サービスの実装が必要になります。 まだデータ ストアを実装していないため、会話はデバッグ セッション間で保持されないことに注意してください。
新しいターミナルを開きます。
dotnet watch
を使って、ホット リロードを有効にしてアプリケーションを起動します。dotnet watch run --non-interactive
ヒント
アプリケーションのコードを少し修正する必要がある場合は、ホット リロード機能をここで有効にします。 詳細については、「ASP.NET Core での .NET ホット リロードのサポート」を参照してください。
Visual Studio Code により、Web アプリケーションが実行中の状態で、ツール内の単純なブラウザーが再起動されます。 Web アプリケーションで、新しいチャット セッションを作成し、AI アシスタントに質問します。 AI アシスタントは、モデルによって作成された入力候補を使用して応答するようになりました。 また、トークン UI フィールドに、入力候補とプロンプトごとの実際のトークン使用量が設定されていることにも注意してください。
ターミナルを閉じます。