Using QnA Maker To Easily Create and Consume A Chat Bot

Apr 2

Written by:
4/2/2017 12:40 PM  RssIcon

image

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.

Ai Help Website Links

Programmatically Updating A QnA Maker Service Using the QnA Maker API

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

8 comment(s) so far...


Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

Can we integrate this QnA service to the skype.. just to make the end user feel like bot like experience.

By kiran on   4/3/2017 6:08 AM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

@kiran - After you create a Bot using the Microsoft Bot Framework (docs.botframework.com/en-us/azure-bot-service/templates/qnamaker/#navtitle) you can then call that Bot from Skype.

By Administrator on   4/3/2017 7:03 AM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

Good Day,
I have been a SharePoint developer for years and am new to ASP.NET core MVC development.
I have my bot up and running and I am unable to get the value of the Answer to appear on Index.cshtml.
When I debug I can see the value of answer in (JsonDataResponse):
It seems the issue is that "QnAQueryResult" is never assigned any values?
I am under a deadline at work and hoping you can suggest what might be the fix?

if (msg.IsSuccessStatusCode)
{
var JsonDataResponse =
await msg.Content.ReadAsStringAsync();

QnAQueryResult =
JsonConvert.DeserializeObject(JsonDataResponse);
}
}
return QnAQueryResult;

Thanks

By SPACEOG905 on   6/6/2017 9:37 AM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

@SPACEOG905 - Please download and run my sample code from the Downloads page on this site. Then let me know if the expected value works for you by making a post to the Forums on this site.

By Administrator on   6/6/2017 10:56 AM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

Thanks for the quick response!!!
Question: I am using the project from the Downloads page, downloaded about 4 days ago..
Has that code base changed since then?

By SPACEOG905 on   6/6/2017 11:30 AM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

@SPACEOG905 - You have open the appsettings.json file and supply your own OcpApimSubscriptionKey and KnowledgeBase for the code to work. Let me know if it works for you by making a post to the Forums on this site. The comments section in the Blogs is not useful for addressing issues. Thanks!

By Administrator on   6/6/2017 12:00 PM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

Thanks
I will post to the Forum later this week.
Have a meeting to review today.
BTW, I downloaded the full project which uses the API V 2.0 to manage QnA Knowledge bases...
Everything works except getting an answer back after entering a question.
That part is not that important related to management of Knowledge bases...

For now I will remove the Question and Answer form in Index.cshtml.
Thanks Again for your great work!!!

By SPACEOG905 on   6/6/2017 12:30 PM
Gravatar

Re: Using QnA Maker To Easily Create and Consume A Chat Bot

@SPACEOG905 - If you download the example "Using QnA Maker To Easily Create and Consume A Chat Bot" (from the Downloads page) it will work. That uses the V1 API.

By Administrator on   6/6/2017 12:58 PM