Completion(入力候補)の API を使って1回だけ質問する場合はAIの答えを表示するだけで終了するのですが、チャットのようにAIとの会話を進める場合には、チャットの内容を保存しなければなりません。何故、保存しないとダメか?ってのは書籍に書いたので、ここでは、ChatHistory を使えば、AIとの会話を保存できます、とだけ言っておきます。いや、やっていることは、List に追加しているだけなんですが。
Microsoft.SemanticKernel パッケージを追加する
<ItemGroup>
<PackageReference Include="Microsoft.SemanticKernel" Version="1.14.1" />
</ItemGroup>
kernel を作る
using Azure.AI.OpenAI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.OpenAI;
var builder = Kernel.CreateBuilder();
builder.AddAzureOpenAIChatCompletion(
"test-x",
"https://sample-moonmile-openai.openai.azure.com/",
Environment.GetEnvironmentVariable("AZURE_OPENAI_API_KEY") ?? "");
var kernel = builder.Build();
ChatHistory を作る
Console.WriteLine("チャットの例");
// チャットの履歴をためておく
var history = new ChatHistory();
var chatCompletionService = kernel.GetRequiredService<IChatCompletionService>();
GetRequiredService メソッドを使って ChatCompletionService のインスタンスを持ってこないといけないのが微妙なところですが、まあこれで動きます。
You(自分)のメッセージ入力はコンソールで、GetChatMessageContentAsync を使い API を呼び出します。会話履歴は hisotry にため込んでいるので、これも一緒に渡します。
while ( true ) {
Console.Write("You: ");
var prompt = Console.In.ReadLine();
if ( string.IsNullOrEmpty(prompt) )
{
break;
}
// ユーザーの入力を履歴に追加
history.AddUserMessage(prompt);
var response = await chatCompletionService.GetChatMessageContentAsync(
history,
kernel: kernel);
// 応答を取得
string combinedResponse = response.Items.OfType<TextContent>().FirstOrDefault()?.Text ?? "";
Console.WriteLine("AI: " + combinedResponse);
// AIの応答を履歴に追加
history.AddAssistantMessage(combinedResponse);
}
AI の応答がちょっとややこしいのですが、レスポンスの先頭の要素だけ持ってきて(パラメータによって、複数の回答を得ることができるので)、これを画面に表示します。
AIの回答も履歴に追加して、次の入力を待ちます。
実行してみる
中央林間から東京駅までの道のりを尋ねたものです。

最初にシステムメッセージを履歴に加えておけば、口調や応答の長さなどの調節ができます。
AI の回答を見ながら、結局タクシーで行くという結論を出すわけですが、この試行錯誤は入力候補のような1回だけのプロンプトでは到達できません。このようにチャットを使い複数回 AI とやりとりすることが重要になります。