Search code examples
c#botframeworkazure-cognitive-servicesazure-qna-maker

Ranked results based on the input in QnAMaker


Using Bot Framework SDK v-3 I was able to get the list of matching questions based on a keyword as suggested action/cards like this- Suggested actions cards in QnAMaker Dialog

image

Now, I am using the pre-release version SDK v-4 which uses the concepts of middle ware. So I did something like this in Startup.cs-

services.AddBot<QnABot>(options =>
            {
                options.CredentialProvider = new ConfigurationCredentialProvider(Configuration);

                var endpoint = new QnAMakerEndpoint
                {
                    KnowledgeBaseId = kbId,
                    // Get the Host from the HTTP request example at https://www.qnamaker.ai
                    // For GA services: https://<Service-Name>.azurewebsites.net/qnamaker
                    // For Preview services: https://westus.api.cognitive.microsoft.com/qnamaker/v2.0           
                    Host = hostURL,
                    EndpointKey = endpointKey
                };
                var qnaOptions = new QnAMakerMiddlewareOptions();
                qnaOptions.Top = 5;
            options.Middleware.Add(new QnAMakerMiddleware(endpoint, qnaOptions));
            });

I am only getting the first matching question's answer as the output in the chat window but not the matching questions as suggested action cards for the user to choose from. I used to have a separate dialog inherited from QnAMakerDialog in SDK v-3 along with the overridden function to manage my conversation flow. I am not sure how to manage that now within the middle ware as all I got from the documentation was this- QnAMaker with bot framework SDK v-4 Any help with this please?


Solution

  • I found same question is reported in this github issue: "Ability to get ranked results based on the input does not work", and as JonathanFingold suggested, we can use QnA maker service in bot code, and then send different response activity to user based on the number of matched questions returned from QnA maker service.

    Besides, if you’d like to make the several choices displayed like in Bot Framework SDK v3, you can dynamically generate a hero card to display the suggested options. You can refer to the following sample code to display suggested options using hero card.

    var results = await QnA.GetAnswers(text);
    
    switch (results.Length)
    {
        case 0:
            await context.SendActivity($"I have no topics in the FAQ for '{text}'.");
            await context.SendActivity("Ask me a question.");
            break;
        case 1:
            await context.SendActivity(results[0].Answer);
            break;
    default:
    
            //var options = MessageFactory.SuggestedActions(
            //    results.Select(r => r.Questions[0]).ToList(), "Did you mean:");
            //options.SuggestedActions.Actions.Add(None);
    
    
            //show options using HeroCard
            var options = results.Select(r => r.Questions[0]).ToList();
    
            var herocard = new HeroCard();
            herocard.Text = "Did you mean:";
    
            List<CardAction> buttons = new List<CardAction>();
    
            foreach (var item in options)
            {
                buttons.Add(new CardAction()
                {
                    Type = ActionTypes.ImBack,
                    Title = item.ToString(),
                    Value = item.ToString()
                });
            }
    
            buttons.Add(new CardAction()
            {
                Type = ActionTypes.ImBack,
                Title = "None of the above.",
                Value = "None of the above."
            });
    
            herocard.Buttons = buttons;
    
            var response = context.Activity.CreateReply();
            response.Attachments = new List<Attachment>() { herocard.ToAttachment() };
            await context.SendActivity(response);
            break;
    }
    

    Test result:

    enter image description here