2

I have a bot in QnA template in C#(SDK v3). I tried to integrate LUIS to QnA Maker service. But bot is unable to reply back to queries. Bot has BasicQnAMakerDialog.cs and LuisDialog.cs files.

BasicQnAMakerDialog.cs file code -

using System;
using System.Threading;
using System.Threading.Tasks;

using Microsoft.Bot.Builder.Azure;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.CognitiveServices.QnAMaker;
using Microsoft.Bot.Connector;
using System.Linq;

namespace Microsoft.Bot.Sample.QnABot
{
    [Serializable]
    public class RootDialog : QnAMakerDialog
    {
        public async Task StartAsync(IDialogContext context)
        {
            /* Wait until the first message is received from the conversation and call MessageReceviedAsync 
            *  to process that message. */
            context.Wait(this.MessageReceivedAsync);
        }

        public RootDialog() : base(new QnAMakerService(new QnAMakerAttribute(Utils.GetAppSetting("QnAAuthKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "No good match found in KB", 0.3)))
        {
        }

        protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
        {
            var answer = result.Answers.First().Answer;
            Activity reply = ((Activity)context.Activity).CreateReply();
            await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
            await context.PostAsync(reply);
        }

        private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            // When MessageReceivedAsync is called, it's passed an IAwaitable<IMessageActivity>. To get the message,
            // await the result.
            var message = await result;

            var qnaAuthKey = GetSetting("QnAAuthKey");
            var qnaKBId = Utils.GetAppSetting("QnAKnowledgebaseId");
            var endpointHostName = Utils.GetAppSetting("QnAEndpointHostName");

            // QnA Subscription Key and KnowledgeBase Id null verification
            if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
            {
                // Forward to the appropriate Dialog based on whether the endpoint hostname is present
                if (string.IsNullOrEmpty(endpointHostName))
                    await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
                else
                    await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
            }
            else
            {
                await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
            }

        }

        private async Task AfterAnswerAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
        {
            // wait for the next user message
            context.Wait(MessageReceivedAsync);
        }

        public static string GetSetting(string key)
        {
            var value = Utils.GetAppSetting(key);
            if (String.IsNullOrEmpty(value) && key == "QnAAuthKey")
            {
                value = Utils.GetAppSetting("QnASubscriptionKey"); // QnASubscriptionKey for backward compatibility with QnAMaker (Preview)
            }
            return value;
        }
    }

    // Dialog for QnAMaker Preview service
    [Serializable]
    public class BasicQnAMakerPreviewDialog : QnAMakerDialog
    {
        // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
        // Parameters to QnAMakerService are:
        // Required: subscriptionKey, knowledgebaseId, 
        // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
        public BasicQnAMakerPreviewDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "No good match in FAQ.", 0.5)))
        { }
    }

    // Dialog for QnAMaker GA service
    [Serializable]
    public class BasicQnAMakerDialog : QnAMakerDialog
    {
        // Go to https://qnamaker.ai and feed data, train & publish your QnA Knowledgebase.
        // Parameters to QnAMakerService are:
        // Required: qnaAuthKey, knowledgebaseId, endpointHostName
        // Optional: defaultMessage, scoreThreshold[Range 0.0 – 1.0]
        public BasicQnAMakerDialog() : base(new QnAMakerService(new QnAMakerAttribute(RootDialog.GetSetting("QnAAuthKey"), Utils.GetAppSetting("QnAKnowledgebaseId"), "No good match in FAQ.", 0.5, 1, Utils.GetAppSetting("QnAEndpointHostName"))))
        { }

    }  
}

LuisDialog.cs file code -

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Luis;
using Microsoft.Bot.Builder.Luis.Models;
using Microsoft.Bot.Connector;

namespace Microsoft.Bot.Sample.QnABot
{
    [LuisModel("Luis-app-key", "Luis-auth-key")]
    [Serializable]
    public class LuisDialog : LuisDialog<object>
    {
        [LuisIntent("azureBot")]
        public async Task azureBotIntent(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
        {
            //await context.PostAsync("No answer found");
            //context.Wait(MessageReceived);

            var messageToForward = await message as Activity;
            await context.Forward(new RootDialog(), this.AfterQnA, messageToForward, CancellationToken.None);
            //check here if I place this below line.
            //await context.PostAsync("No answer found");

        }

         private async Task AfterQnA(IDialogContext context, IAwaitable<IMessageActivity> result) {
         context.Wait(this.MessageReceived);
         }

    }
}

I changed some part of MessageController.cs file from await Conversation.SendAsync(activity, () => new RootDialog()); to await Conversation.SendAsync(activity, () => new LuisDialog());.

I am not getting any error while building it but bot does not respond to user queries. Any help will be appreciated.

  • I would revert your change that you made to see if that fixes your issue. If this does not fix your issue then go to the QnA Maker portal, and make sure that your app is [published](https://learn.microsoft.com/en-us/azure/cognitive-services/qnamaker/quickstarts/create-publish-knowledge-base#publish-the-knowledge-base). Then visit the LUIS portal for your [region](https://learn.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-regions#luis-authoring-regions) and do the same. Once you are sure that everything is published, double check your keys and URLs. – Matt Stannett Jun 21 '19 at 09:52
  • When I reverted my change from `await Conversation.SendAsync(activity, () => new LuisDialog());` to `await Conversation.SendAsync(activity, () => new RootDialog());`, I am getting error `couldn't send retry` and reply `Sorry, my bot code is having an issue`. But with previously changes, I did not get this error. I checked, my KB and LUIS app id published and all keys are correct. – Kailash Kumawat Jun 21 '19 at 10:57
  • 1
    It sounds like your bot is encountering and exception then returning a preset message to the user. If you search for “Sorry my bot code is having an issue” to find where it is used, I imagine it will be in some default error handling code. You should put a breakpoint on the line where this message is displayed and you should be able to inspect the exception that is being thrown and from there fix the issue. – Matt Stannett Jun 21 '19 at 20:24
  • 1
    How did you go @kailash-kumawat? – Matt Stannett Jun 22 '19 at 20:26
  • I tried for this error but could not get any help. Can check part of my code which handles replies of user queries from QnA maker service and tell me, is it fine or something wrong there only? [Here](https://imgur.com/EMgpYdW) is screenshot for my problem of `No response`. – Kailash Kumawat Jun 23 '19 at 12:43
  • In `LuisDialog.cs` file, when I use `await context.PostAsync("No answer found");` below the line - `await context.Forward(new RootDialog(), this.AfterQnA, messageToForward, CancellationToken.None);`, bot replies - `No answer found` as per command. So I think I am missing some line of code which post reply of user queries from QnA but I am unable to find what I am missing. Can you check that? @MattStannett – Kailash Kumawat Jun 24 '19 at 06:06
  • I am not familiar with SDK v3 sorry, it has also been replaced by v4. I would suggest using [this sample code](https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/14.nlp-with-dispatch) which has the framework setup for LUIS and QnA Maker. There is step by step guide of how to get this configured [here](https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-tutorial-dispatch?view=azure-bot-service-4.0&tabs=cs). Once you have got it configured you can replace the LUIS and QnA Maker ids in the `appsettings.json` file with your own. – Matt Stannett Jun 24 '19 at 08:11
  • I need two knowledge bases in my bot. In SDK v4, I am not familiar about how to use two KBs and `Dispatch` tool also not working for me. It is giving error `'dispatch' is not recognized as an internal or external command,operable program or batch file.` even though I have installed it using `npm install -g botdispatch`. Is this command also for C#?@MattStannett – Kailash Kumawat Jun 24 '19 at 12:26
  • Try opening a new command prompt as administrator then running the dispatch install command. Once the install command has completed you should be able to run ‘dispatch -v’ to check the version and verify that it installed. – Matt Stannett Jun 24 '19 at 19:03
  • It worked. Thanks. But still I need help with code in SDK-v3 because my bot in that version only. I will try new bots in SDK-v4. – Kailash Kumawat Jun 25 '19 at 06:35
  • If you can't help me regarding this then can you tell me how to use two KBs in a C# bot with luis(SDK-v4)? @MattStannett – Kailash Kumawat Jun 25 '19 at 07:37
  • Yep, to use 2 KBs in C# both with Luis you can download [this sample](https://github.com/Microsoft/BotBuilder-Samples/tree/master/samples/csharp_dotnetcore/14.nlp-with-dispatch) and follow the official guide [here](https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-tutorial-dispatch?view=azure-bot-service-4.0&tabs=cs). – Matt Stannett Jun 25 '19 at 09:47

0 Answers0