😺

Semantic KernelのChatCompletionでBing検索を使う

2023/05/19に公開

gpt-35-turboやgpt-4の学習データが2021年9月までとされています。つまりこれ以降の事象についての学習データについては持っていません。また、個人に関わる質問「草場友光について教えてください」などの質問についてはでたらめな回答であることが多いです。
そこで、Bingの検索結果を基にプロンプトを与えて回答結果を補正してしまえばよいのではと考えました。欠点としては、Bing検索を使おうとするたびにプロンプトにあたる部分が増えてしまうことです。

前提知識

ChatCompletionではメッセージ種別を以下のように区別しています。

メッセージ種別 内容
System プロンプトメッセージ
User ユーザーが入力したメッセージ
Assistant AIアシスタントが入力したメッセージ

概要

bing検索の概要を10件取得してそれをすべて文字列連結したものをSystemメッセージとして入れる。
ユーザの質問文をUserメッセージとして入れる

回答を生成する。

以上の方法で今回はやろうと考えています。

コード

            // カーネルを作る
            kernel = new KernelBuilder().Configure(c =>
            {
                //c.AddAzureChatCompletionService(serviceId, deploymentName, baseUrl, key);
                c.AddAzureChatCompletionService(deploymentName, baseUrl, key, logger: _logger);

            }).WithLogger(_logger).Build();
            // bing コネクターを作る
            using var bingConnector = new BingConnector(_configuration.GetValue<string>("BingKey") ?? string.Empty, logger1);


            GptChat4 = kernel.GetService<IChatCompletion>();

            chatHistory = (OpenAIChatHistory)GptChat4.CreateNewChat("{{bing.search $input}}  あなたはほのかという名前のAIアシスタントです。くだけた女性の口調で人に役立つ回答をします。");

            // Bing検索 先頭10項目を取得
            var res = await bingConnector.SearchAsync(input,10);
            // 検索で得られた10項目をすべて文字列連結
            var sb = new StringBuilder();
            foreach (var item in res)
            {
                sb.Append(item);
            }
            chatHistory.AddSystemMessage(sb.ToString());
            var setting = new ChatRequestSettings
            {
                Temperature = 0.8,
                MaxTokens = 2000,
                FrequencyPenalty = 0.5,

            };
            var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseAutoLinks().UseBootstrap().UseDiagrams().UseGridTables().Build();
            string fullMessage = string.Empty;
            GeneratedHtml = string.Empty;
            await foreach (string message in GptChat4.GenerateMessageStreamAsync(chatHistory, setting))
            {
                _logger.LogInformation("message : {}", message);
                if (message != null && message.Length > 0)
                {
                    var messageHtml = Markdown.ToHtml(fullMessage, pipeline);
                    _logger.LogInformation("messageHtml : {}", messageHtml);
                    //chatHistory.AddAssistantMessage(message);
                    GeneratedHtml = messageHtml;
                    fullMessage += message;
                    NotifyStateChanged();
                }

            }
            chatHistory.AddAssistantMessage(fullMessage);


最終的にWebへの出力でしたらGeneratedHtmlを出力するのがよいですし、テキストへの出力でしたらfullMessageあたりが適当かとおもいます。

Discussion