📑
Semantic KernelのIChatCompletionで複数の回答を得る
前提
.NET 7
Sementic Kernel 0.15.230609.2-preview
コード例
まずは普通にkernelをインスタンス化してIChatCompletionサービスを取り出す。
IKernel kernel = new KernelBuilder()
.WithLogger(_logger)
.WithAzureChatCompletionService(deploymentName, baseUrl, key)
.Build();
GptChat4 = kernel.GetService<IChatCompletion>();
chatHistory = (OpenAIChatHistory)GptChat4.CreateNewChat();
ここからが従来とちがうところ。
inputはユーザメッセージ
ChatRequestSettingsのプロパティとしてResultsPerPromptが追加となっている。
これは、いくつの回答を生成するかという設定項目である。
chatHistory.AddUserMessage(input);
var setting = new ChatRequestSettings
{
Temperature = 0.8,
MaxTokens = 2000,
FrequencyPenalty = 0.5,
ResultsPerPrompt = 3,
};
List<Task> tasks = new List<Task>();
// いくつ目の回答か管理するための変数
int currentResult = 0;
await foreach (var completionResult in GptChat4.GetStreamingChatCompletionsAsync(chatHistory, setting))
{
tasks.Add(ProcessStreamAsync(completionResult, currentResult++));
}
await Task.WhenAll(tasks.ToArray());
ResultsPerPromptで指定した数だけTaskが生成される
private async Task ProcessStreamAsync(IChatStreamingResult result, int resultNumber)
{
string message = string.Empty;
GeneratedHtmlList.Add(message);
var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseAutoLinks().UseBootstrap().UseDiagrams().UseGridTables().Build();
await foreach (var chatMessage in result.GetStreamingChatMessageAsync())
{
if (chatMessage.Content != null && chatMessage.Content.Length > 0)
{
message += chatMessage.Content;
GeneratedHtmlList[resultNumber] = Markdown.ToHtml(message,pipeline);
NotifyStateChangedList();
}
}
chatHistory.AddAssistantMessage(message);
}
private void NotifyStateChangedList() => OnChangeList?.Invoke();
public event Action? OnChangeList;
GeneratedHtmlListが画面表示用のプロパティになっているのでWebであればこれを参照させOnChangeListでStateHasChangedを呼ぶなどして画面更新をしてあげることにより実装できるだろう。
このような感じで3パターン違う生成結果が得られました。
Discussion