4/2/2017 Webmaster

Using QnA Maker To Easily Create and Consume A Chat Bot


image

** Note this is outdated – See new information here: https://docs.microsoft.com/en-us/azure/cognitive-services/QnAMaker/how-to/migrate-knowledge-base

Using the QnA Maker website, you can quickly create a Chat Bot based on your existing Frequently Asked Questions (and answers) known as a FAQ.

Note: Also see: Programmatically Updating A QnA Maker Service Using the QnA Maker API.

image

To use it, sign in and select Create new service.

image

The Creating a QnA service page allows you to enter a name for your service and the web page URL that contains your FAQ (you can also enter the questions and answers manually or you can upload a file with your questions and answers).

image

The site will import the FAQ

image

… and then display it in a FAQ database.

You can edit the content of the database on this screen.

image

The test screen allows you to chat with the Bot who responds by retrieving the appropriate answer from the FAQ database.

This screen allows you to train the Bot by indicating what answer the Bot should give to a particular question, or by supplying a new answer.

image

When you have completed training, click the Save and retrain button.

Finally, click the Publish button.

image

You will see a confirmation screen.

Click Publish again.

image

You will then be presented with the information needed to consume the Bot.

image

Note, you can always get back to these values by selecting My services, selecting the service, then Settings.

Consume The Service

image

You can create a Microsoft Bot Framework application to consume your Bot. QnA Maker is available as a template on Azure Bot Service.

However, you can also call the QnA Maker service directly, without using the Microsoft Bot Framework, for full control over the user experience.

Create An ASP.NET Core Application

image

If you do not have it, you can download the free Visual Studio 2017 Community Edition from:

https://www.visualstudio.com/downloads/download-visual-studio-vs

image

In Visual Studio, select File, then New, then Project.

image

Create a ASP.NET Core Web Application project.

 

image

Select Web Application.

image

If we log into the QnA Maker website and select My Services, and click on the View Code link next to our service…

image

… we can retrieve the KnowledgeBase number and the Ocp-Apim-Subscription-Key.

image

Back in Visual Studio, open the appsettings.json file and add these settings using the following format:

 

{
  "CustomSettings": {
    "OcpApimSubscriptionKey": "{{ Your OcpApimSubscriptionKey }}",
    "KnowledgeBase": "{{ Your KnowledgeBase }}"
  },

 

image

Create a Models folder and add two classes using the following code:

 

CustomSettings.cs:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace QNABot.Models
{
    // This allows us to retrieve custom settings 
    // from appsettings.json
    public class CustomSettings
    {
        public string OcpApimSubscriptionKey { get; set; }
        public string KnowledgeBase { get; set; }
    }
}

 

 

QnAQuery.cs:

 

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace QNABot.Models
{
    // This class is used to hold data when
    // communicating with the QnA Service
    public class QnAQuery
    {
        [JsonProperty(PropertyName = "question")]
        public string Question { get; set; }
        [JsonProperty(PropertyName = "answer")]
        public string Answer { get; set; }
        [JsonProperty(PropertyName = "score")]
        public double Score { get; set; }
    }
}

image

Add the following code to the ConfigureServices method in the Startup.cs file:

 

    // Get the CustomSettings from appsettings.json
    // allow them to be passed to any class using dependency injection
    services.Configure<Models.CustomSettings>(
        Configuration.GetSection("CustomSettings"));

 

The Controller

image

Open the HomeController.cs file and add the follow using statements:

 

using QNABot.Models;
using Newtonsoft.Json;
using Microsoft.Extensions.Options;
using System.Net.Http;
using System.Text;

 

Add the following code to the class (to retrieve the values from appsettings.json):

 

        // Global values to hold the custom settings
        private static string _OcpApimSubscriptionKey;
        private static string _KnowledgeBase;
        // Get the CustomSettings using dependency injection
        public HomeController(
            IOptions<CustomSettings> CustomSettings)
        {
            // Set the custom values
            _OcpApimSubscriptionKey = CustomSettings.Value.OcpApimSubscriptionKey;
            _KnowledgeBase = CustomSettings.Value.KnowledgeBase;
        }

 

Replace the existing Index method with the following method to retrieve a question and pass back a response (answer):

 

        public async Task<ActionResult> Index(string searchString)
        {
            QnAQuery objQnAResult = new QnAQuery();
            try
            {
                if (searchString != null)
                {
                    objQnAResult = await QueryQnABot(searchString);
                }
                return View(objQnAResult);
            }
            catch (Exception ex)
            {
                ModelState.AddModelError(string.Empty, "Error: " + ex);
                return View(objQnAResult);
            }
        }

 

Add the following method to implement the required QueryQnABot method:

 

       private static async Task<QnAQuery> QueryQnABot(string Query)
        {
            QnAQuery QnAQueryResult = new QnAQuery();
            using (System.Net.Http.HttpClient client =
                new System.Net.Http.HttpClient())
            {
                string RequestURI = String.Format("{0}{1}{2}{3}{4}",
                    @"https://westus.api.cognitive.microsoft.com/",
                    @"qnamaker/v1.0/",
                    @"knowledgebases/",
                    _KnowledgeBase,
                    @"/generateAnswer");
                var httpContent =
                    new StringContent($"{{\"question\": \"{Query}\"}}",
                    Encoding.UTF8, "application/json");
                httpContent.Headers.Add(
                    "Ocp-Apim-Subscription-Key", _OcpApimSubscriptionKey);
                System.Net.Http.HttpResponseMessage msg =
                    await client.PostAsync(RequestURI, httpContent);
                if (msg.IsSuccessStatusCode)
                {
                    var JsonDataResponse =
                        await msg.Content.ReadAsStringAsync();
                    QnAQueryResult =
                        JsonConvert.DeserializeObject<QnAQuery>(JsonDataResponse);
                }
            }
            return QnAQueryResult;
        }

 

The View

image

 

Open the Views/Home/Index.cshtml file and replace all the code with the following code:

 

@model QNABot.Models.QnAQuery
@{
    ViewData["Title"] = "Home Page";
}
<div class="form-horizontal">
    <br />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    @using (Html.BeginForm())
    {
        <div class="form-group">
            @Html.LabelFor(model => model.Question,
           htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.TextBox("SearchString", "",
               new { style = "width: 800px;" }) <input type="submit" value="Submit" />
            </div>
        </div>
    }
    <div class="form-group">
        @Html.LabelFor(model => model.Answer,
       htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DisplayFor(model => model.Answer,
           new { htmlAttributes = new { @class = "form-control" } })
        </div>
    </div>
</div>

 

image

Run the application.

image

You can now enter questions that will be answered by entries in the FAQ database.


Links

QnA Maker Application Website

Create your first QnA bot using botframework’s QnA Maker

QnA Maker Dialog for Bot Framework – Gary Pretty
Adding rich attachments to your QnAMaker bot responses – Gary Pretty

Download

You can download the code from the Download page

An unhandled error has occurred. Reload 🗙