Use QnA Maker to answer questions

Note

This topic is for the latest release of the SDK (v4). You can find content for the older version of the SDK (v3) here.

You can use QnA Maker service to add question and answer support to your bot. One of the basic requirements in creating your own QnA Maker service is to seed it with questions and answers. In many cases, the questions and answers already exist in content like FAQs or other documentation. Other times you would like to customize your answers to questions in a more natural, conversational way.

In this topic we will create a knowledge base and use it in a bot.

Prerequisites

Create a QnA Maker service and publish a knowledge base

  1. First, you'll need to create a QnA Maker service.
  2. Next, you'll create a knowledge base using the smartLightFAQ.tsv file located in the CognitiveModels folder of the project. The steps to create, train, and publish your QnA Maker knowledge base are listed in the QnA Maker documentation. As you follow these steps, name your KB qna, and use the smartLightFAQ.tsv file to populate your KB.

Note. This article may also be used to access your own user developed QnA Maker knowledgebase.

Obtain values to connect your bot to the knowledge base

  1. In the QnA Maker site, select your knowledge base.
  2. With your knowledge base open, select the Settings. Record the value shown for service name. This value is useful for finding your knowledgebase of interest when using the QnA Maker portal interface. It is not used to connect your bot app to this knowledgebase.
  3. Scroll down to find Deployment details record the following values:
    • POST /knowledgebases/<Your_Knowledge_Base_Id>/getAnswers
    • Host: <Your_Hostname>/qnamaker
    • Authorization: EndpointKey <Your_Endpoint_Key>

These three values provide the information necessary for your app to connect to your QnA Maker knowledgebase via your Azure QnA service.

Update the .bot file

First, add the information required to access your knowledge base including hostname, endpoint key and knowledge base Id (kbId) into the qnamaker.bot. These are the values you saved from the Settings of your knowledge base in QnA Maker.

Note. If you are adding access to a QnA Maker knowledgebase into an existing bot application, be sure to add a "type": "qna" section like the one shown below into your .bot file. The "name" value within this section provides the key required to access this information from within your app.

{
  "name": "qnamaker",
  "services": [
    {
      "type": "endpoint",
      "name": "development",
      "endpoint": "http://localhost:3978/api/messages",
      "appId": "",
      "appPassword": "",
      "id": "25"    
    },
    {
      "type": "qna",
      "name": "QnABot",
      "kbId": "<Your_Knowledge_Base_Id>",
      "subscriptionKey": "",
      "endpointKey": "<Your_Endpoint_Key>",
      "hostname": "<Your_Hostname>",
      "id": "117"
    }
  ],
  "padlock": "",
   "version": "2.0"
}

Be sure that the Microsoft.Bot.Builder.AI.QnA NuGet package is installed for your project.

Next, we initialize a new instance of the BotServices class in BotServices.cs, which grabs the above information from your .bot file. The external service is configured using the BotConfiguration class.

using Microsoft.Bot.Builder.AI.QnA;
using Microsoft.Bot.Configuration;
public BotServices(BotConfiguration botConfiguration)
{
    foreach (var service in botConfiguration.Services)
    {
        switch (service.Type)
        {
            case ServiceTypes.QnA:
                {
                    // Create a QnA Maker that is initialized and suitable for passing
                    // into the IBot-derived class (QnABot).
                    var qna = service as QnAMakerService;

                    // ...

                    var qnaEndpoint = new QnAMakerEndpoint()
                    {
                        KnowledgeBaseId = qna.KbId,
                        EndpointKey = qna.EndpointKey,
                        Host = qna.Hostname,
                    };

                    var qnaMaker = new QnAMaker(qnaEndpoint);
                    QnAServices.Add(qna.Name, qnaMaker);
                    break;
                }
        }
    }
}

Then in QnABot.cs, we give the bot this QnAMaker instance. If you are accessing your own knowledge base, change the welcome message shown below to provide useful initial instructions for your users. This class is also where the static variable QnAMakerKey is defined. This points to the section within your .bot file containing the connection information to access your QnA Maker knowledgebase.

public class QnABot : IBot
{
    public static readonly string QnAMakerKey = "QnABot";

    private const string WelcomeText = @"This bot will introduce you to QnA Maker.
                                         Ask a question to get started.";
    private readonly BotServices _services;

    public QnABot(BotServices services)
    {
        _services = services ?? throw new System.ArgumentNullException(nameof(services));
        if (!_services.QnAServices.ContainsKey(QnAMakerKey))
        {
            throw new System.ArgumentException(
                $"Invalid configuration. Please check your '.bot' file for a QnA service named '{QnAMakerKey}'.");
        }
    }
}

Calling QnA Maker from your bot

When your bot needs an answer from QnAMaker, call GetAnswersAsync() from your bot code to get the appropriate answer based on the current context. If you are accessing your own knowledge base, change the no answers message below to provide useful instructions for your users.

// Check QnA Maker model
var response = await _services.QnAServices[QnAMakerKey].GetAnswersAsync(turnContext);
if (response != null && response.Length > 0)
{
    await turnContext.SendActivityAsync(response[0].Answer, cancellationToken: cancellationToken);
}
else
{
    var msg = @"No QnA Maker answers were found. This example uses a QnA Maker Knowledge Base that focuses on smart light bulbs.
                To see QnA Maker in action, ask the bot questions like 'Why won't it turn on?' or 'I need help'.";
    await turnContext.SendActivityAsync(msg, cancellationToken: cancellationToken);
}

    /// ...

Test the bot

Run the sample locally on your machine. If you need instructions, refer to the readme file for C# or JS sample.

In the emulator, send message to the bot as shown below.

test qna sample

Next steps

QnA Maker can be combined with other Cognitive Services, to make your bot even more powerful. The Dispatch tool provides a way to combine QnA with Language Understanding (LUIS) in your bot.