如何从 LUIS Intent 调用 Dialog Class

How to call Dialog Class From a LUIS Intent

我正在使用 Bot Framework V4 调度模型来调用 LUIS 和 QnA 服务。 我可以在得分最高的意图中调用代码 class.

但是,我找不到从中调用外部对话框的方法。我该怎么做?

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

    namespace Microsoft.BotBuilderSamples
    {
        public class DispatchBot : ActivityHandler
        {
            private ILogger<DispatchBot> _logger;
            private IBotServices _botServices;

            public DispatchBot(IBotServices botServices, ILogger<DispatchBot> logger)
            {
                _logger = logger;
                _botServices = botServices;
            }

            protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
            {
                // First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
                var recognizerResult = await _botServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);

                // Top intent tell us which cognitive service to use.
                var topIntent = recognizerResult.GetTopScoringIntent();

                // Next, we call the dispatcher with the top intent.
                await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
            }

            protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
            {
                const string WelcomeText = "Type a greeting, or a question about the weather to get started.";

                foreach (var member in membersAdded)
                {
                    if (member.Id != turnContext.Activity.Recipient.Id)
                    {
                        await turnContext.SendActivityAsync(MessageFactory.Text($"Welcome to Dispatch bot {member.Name}. {WelcomeText}"), cancellationToken);
                    }
                }
            }

            private async Task DispatchToTopIntentAsync(ITurnContext<IMessageActivity> turnContext, string intent, RecognizerResult recognizerResult, CancellationToken cancellationToken)
            {
                switch (intent)
                {
                    case "l_HomeAutomation":
                        //WANT TO CALL THE EXTERNAL DIALOG CLASS FROM HERE
                        //await ProcessHomeAutomationAsync(turnContext, recognizerResult.Properties["luisResult"] as LuisResult, cancellationToken);
                        break;
                    case "l_Weather":
                        await ProcessWeatherAsync(turnContext, recognizerResult.Properties["luisResult"] as LuisResult, cancellationToken);
                        break;
                    case "q_sample-qna":
                        await ProcessSampleQnAAsync(turnContext, cancellationToken);
                        break;
                    default:
                        _logger.LogInformation($"Dispatch unrecognized intent: {intent}.");
                        await turnContext.SendActivityAsync(MessageFactory.Text($"Dispatch unrecognized intent: {intent}."), cancellationToken);
                        break;
                }
            }

            private async Task ProcessHomeAutomationAsync(ITurnContext<IMessageActivity> turnContext, LuisResult luisResult, CancellationToken cancellationToken)
            {
                _logger.LogInformation("ProcessHomeAutomationAsync");

                // Retrieve LUIS result for Process Automation.
                var result = luisResult.ConnectedServiceResult;
                var topIntent = result.TopScoringIntent.Intent; 

                await turnContext.SendActivityAsync(MessageFactory.Text($"HomeAutomation top intent {topIntent}."), cancellationToken);
                await turnContext.SendActivityAsync(MessageFactory.Text($"HomeAutomation intents detected:\n\n{string.Join("\n\n", result.Intents.Select(i => i.Intent))}"), cancellationToken);
                if (luisResult.Entities.Count > 0)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text($"HomeAutomation entities were found in the message:\n\n{string.Join("\n\n", result.Entities.Select(i => i.Entity))}"), cancellationToken);
                }
            }

            private async Task ProcessWeatherAsync(ITurnContext<IMessageActivity> turnContext, LuisResult luisResult, CancellationToken cancellationToken)
            {
                _logger.LogInformation("ProcessWeatherAsync");

                // Retrieve LUIS results for Weather.
                var result = luisResult.ConnectedServiceResult;
                var topIntent = result.TopScoringIntent.Intent;
                await turnContext.SendActivityAsync(MessageFactory.Text($"ProcessWeather top intent {topIntent}."), cancellationToken);
                await turnContext.SendActivityAsync(MessageFactory.Text($"ProcessWeather Intents detected::\n\n{string.Join("\n\n", result.Intents.Select(i => i.Intent))}"), cancellationToken);
                if (luisResult.Entities.Count > 0)
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text($"ProcessWeather entities were found in the message:\n\n{string.Join("\n\n", result.Entities.Select(i => i.Entity))}"), cancellationToken);
                }
            }

            private async Task ProcessSampleQnAAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
            {
                _logger.LogInformation("ProcessSampleQnAAsync");

                var results = await _botServices.SampleQnA.GetAnswersAsync(turnContext);
                if (results.Any())
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text(results.First().Answer), cancellationToken);
                }
                else
                {
                    await turnContext.SendActivityAsync(MessageFactory.Text("Sorry, could not find an answer in the Q and A system."), cancellationToken);
                }
            }
        }
    }

您需要在 DispatchBot 中初始化所需对话框的实例,然后像这样调用它们: await this.weatherDialog.RunAsync(turnContext, dialogStateAccessor, cancellationToken)

这里是some sample code。它与您的设计略有不同,因为我将意图检测委托给父对话框,然后从那里进行逻辑分支(以保持机器人 class 逻辑简单),但如何调用对话框是相同的。

根据以下讨论更新: 如果您使用的是多轮对话,我建议您遵循我的代码中的模式。否则你将不得不自己处理对话并继续,祝你好运。