如何在 C# - CoreBot 中构建 QnA Maker 实例 Class?

How to construct a QnA Maker Instance Class in C# - CoreBot?

我在 运行 我的 Core Bot C# 示例之后得到了一个 System.AggregateException

Startup.cs中我添加了class如下:

     services.AddSingleton<ChitChatRecognizer>();

识别器 Class 看起来像:

    using System.Net.Http;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Bot.Builder;
    using Microsoft.Bot.Builder.AI.QnA;
    using Microsoft.Bot.Schema;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.Logging;

    namespace CoreBot
    {
        public class ChitChatRecognizer : ActivityHandler
        {

            private readonly IConfiguration _configuration;
            private readonly ILogger<ChitChatRecognizer> _logger;
            private readonly IHttpClientFactory _httpClientFactory;

            public ChitChatRecognizer(IConfiguration configuration, ILogger<ChitChatRecognizer> logger, IHttpClientFactory httpClientFactory)
            {
                _configuration = configuration;
                _logger = logger;
                _httpClientFactory = httpClientFactory;
            }

            protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
            {
                var httpClient = _httpClientFactory.CreateClient();

                var qnaMaker = new QnAMaker(new QnAMakerEndpoint
                {
                    KnowledgeBaseId = _configuration["QnAKnowledgebaseId"],
                    EndpointKey = _configuration["QnAEndpointKey"],
                    Host = _configuration["QnAEndpointHostName"]
                },
                null,
                httpClient);

                _logger.LogInformation("Calling QnA Maker");

                var options = new QnAMakerOptions { Top = 1 };

                // The actual call to the QnA Maker service.
                var response = await qnaMaker.GetAnswersAsync(turnContext, options);
                if (response != null && response.Length > 0)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(response[0].Answer), cancellationToken);
                }
                else
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text("No QnA Maker answers were found."), cancellationToken);
                }
            }
        }
    }

我什至还没有使用 Class,但我什至无法在没有错误的情况下启动我的程序。 我该怎么办?

错误代码:

"Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: CoreBot.ChitChatRecognizer Lifetime: Singleton ImplementationType: CoreBot.ChitChatRecognizer': Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'CoreBot.ChitChatRecognizer'.) (Error while validating the service descriptor 'ServiceType: Microsoft.BotBuilderSamples.Dialogs.MainDialog Lifetime: Singleton ImplementationType: Microsoft.BotBuilderSamples.Dialogs.MainDialog': Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'CoreBot.ChitChatRecognizer'.) (Error while validating the service descriptor 'ServiceType: Microsoft.Bot.Builder.IBot Lifetime: Transient ImplementationType: Microsoft.BotBuilderSamples.Bots.DialogAndWelcomeBot`1[Microsoft.BotBuilderSamples.Dialogs.MainDialog]': Unable to resolve service for type 'System.Net.Http.IHttpClientFactory' while attempting to activate 'CoreBot.ChitChatRecognizer'.)"

你的设置很奇怪......你正在制作你的 ChitChatRecognizer,这是一个机器人(它派生自 ActivityHandler),然后 DI 进入对话框或另一个机器人,我想?此外,您似乎想将 QnAMaker(QnA 的识别器)视为单例,但您在 OnMessageActivityAsync 中对其进行了初始化——这意味着除非您的机器人收到一条消息 activity,否则它不会初始化,因此如果您正在尝试初始化其他需要 QnAMaker 的东西,它不会在启动时存在。


无论如何,要回答如何将QnAMaker插入corebot的问题,如果您想将QnAMaker添加为单例,可以在启动时将其添加为单例,然后调用它当您需要调用 QnAMaker 时从您的机器人代码中调用。

将 QnAMaker 添加到 Corebot 示例

Startup.ConfigureServices中:

// Register QnAMaker recognizer
services.AddSingleton<MyQnaMaker>();

MyQnAMaker.cs

namespace Microsoft.BotBuilderSamples
{
    public class MyQnaMaker
    {
        public MyQnaMaker(IConfiguration configuration)
        {
            ChitChatRecognizer = new QnAMaker(new QnAMakerEndpoint
            {
                KnowledgeBaseId = configuration["QnAKnowledgebaseId"],
                EndpointKey = configuration["QnAEndpointKey"],
                Host = configuration["QnAEndpointHostName"]
            });
        }

        public QnAMaker ChitChatRecognizer { get; set; }
    }
}

DialogAndWelcomeBot.cs构造函数

DI QnAMaker 进入机器人

        public DialogAndWelcomeBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, MyQnaMaker myQnAMaker)
            : base(conversationState, userState, dialog, logger, myQnAMaker)

DialogBot.cs

        public DialogBot(ConversationState conversationState, UserState userState, T dialog, ILogger<DialogBot<T>> logger, MyQnaMaker qnaMaker)
        {
            ConversationState = conversationState;
            UserState = userState;
            Dialog = dialog;
            Logger = logger;
            MyQnaMaker = qnaMaker;
        }

...

        protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            Logger.LogInformation("Running dialog with Message Activity.");

            if (turnContext.Activity.Text == "yo")
            {
                await CallQnAMaker(turnContext, cancellationToken);
            } else {
                // Run the Dialog with the new message Activity.
                await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>("DialogState"), cancellationToken);
            }

        }

        private async Task CallQnAMaker(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
        {
            var options = new QnAMakerOptions { Top = 1 };

            // The actual call to the QnA Maker service.
            var response = await MyQnaMaker.ChitChatRecognizer.GetAnswersAsync(turnContext, options);
            if (response != null && response.Length > 0)
            {
                await turnContext.SendActivityAsync(MessageFactory.Text(response[0].Answer), cancellationToken);
            }
            else
            {
                await turnContext.SendActivityAsync(MessageFactory.Text("No QnA Maker answers were found."), cancellationToken);
            }
        }

根据需要向 类 添加更多内容,这只是最低限度。在上面的 DialogBot.cs 中,您可以看到我有触发器调用 QnAMaker,如果用户输入 "yo" 作为消息,用于测试目的。


运行 Corebot


备选方案

或者,您可以 new 在机器人的消息处理程序中创建一个新的 QnAMaker(例如 DialogBot.OnMessageActivityAsync()),类似于示例 11.qnamaker 中的做法,并且取消单例。