📑

Semantic KernelのIChatCompletionで複数の回答を得る

2023/06/10に公開

前提

.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