Azure Cognitives Services - How to build a simple contextual Bot

27 maart 2019

As announced in my previous blog post I will be writing a series on some of the Azure Cognitive Services. Today I will start off with a topic that will be the foundation for the upcoming services that will be connected to it. "NLP", natural language processing, is the technique of understanding context and can be used with one of Azure's services. Of course, we'll also need something to interact with this service, hence the introduction of the Microsoft Bot Framework.

In this blog I will demonstrate:

  • How to create a LUIS app via Azure
  • How to create a simple Bot using the Microsoft Bot Framework (MBF)

Source code: https://github.com/RutgerKnijnenburg/TostiBot

Demo: http://tostibot.azurewebsites.net/

What and why is a tosti?

A quick introduction to LUIS

Microsoft offers a service called LUIS (Language Understanding Intelligent Service) that can not only comprehend what you are trying to say (with trained models) but it can also extract parameters from your context. LUIS works with a few key elements that together create a pretty advanced NLP-service. This service is available at www.luis.ai. Here you can create new apps and maintain your current ones. However, we're going to initiate a new LUIS APP using Azure in this blog.

The key elements are utterances, entities, and intents. This is easily explained in an example sentence:

"I would like to order a pepperoni pizza (Entity -> Pizza.Type)" Intent: OrderPizza

"Where can I find a tosti company?" Intent: FindTostiCompany

"Can you tell me the route to the National Museum(Entity -> Location)?" Intent: GetRoute

An "intent" is the context of what someone is trying to say/do.

An "utterance" is an example of input that LUIS can categorize in a specific intent.

An "entity" is a parameter in the context that specifies something.

With phrase lists it is possible to add synonyms to commonly used keywords in your utterances. This can help you train a model quicker and reduces the amount of repetitive utterances.

An example of a filled in phrase list in LUIS.ai

Create a simple Bot

One of many ways NLP can be used is via a Bot. Microsoft really improved their Microsoft Bot Framework last year. Version 4 has been published and I must say, it's better than ever.

Create a new Bot App in Azure by: "Create a resource" -> "AI + Machine Learning" -> "Web App Bot".

Again fill in all input fields. Be sure to set the pricing tier to F0 for development purposes. 10.000 messages are more than enough to get going. Azure Storage is necessary for logging. Insights can be really (really!!!) useful when debugging the production code.

Navigating to the selected resource group four new resources have been added (Web App Bot, App Service, Insights and Storage). Selecting the Web App Bot will show the Web App dashboard at which the Web Bot is configured. It is possible to already talk to the bot, as it just created a LUIS App for you.


Create a LUIS App

Creating a LUIS service in Azure

NOTE: This step is optional. A LUIS Service resource is only necessary if you use all of the free quotas of the LUIS starters key that is enabled on creation.

Create a resource -> AI + Machine Learning -> Language understanding.

In the Azure environment navigate to "Create a Resource" -> "AI + Machine Learning" -> "Language Understanding".

In the newly opened window choose F0 (you will get 10K calls free per month), location and select a location and resource group.

Once the form has been submitted it may take a moment for Azure to complete the request. Once it's done head on down to the selected resource group. Here you will find a new resource of type "Cognitive Services".

Maintain and develop the LUIS model

Navigate to www.luis.ai.

Now it's time to add some content to the LUIS service. Create some intents, add some utterances and set some entities. Don't forget to train your model once you're happy with the content. It's good practice not to add that many utterances to each intent. And an intent should always be demarcated. An intent should never do two things, neither should the same utterance be in more than 1 intent. Entities can be used in any intent of course. When LUIS is initiated after creation it already defines four intents. These can be used as fallback intents and to get started.

Now it's time to train the LUIS service by pressing test. Entering different ways of saying the same thing can really help the LUIS app categorize unique utterances. Utterances of which the service is not sure of can be found in "Review endpoint utterances" once the app has been published and used. This is a good way to maintain the service and see how users are using the NLP service.

In the TostiBot LUIS App I'm using a hierarchy entity. A tosti has some key elements like topping, bread type, duration and so forth. It's a good idea to break down these entities in smaller dimensions. This allows me, for example, to extract entities like Ingredients. Meat or Ingredients.Bread.

An example of a hierarchy entity in LUIS.ai

Develop the Bot

Alright. It's time to get devving. Testing the bot in the web chat option already kind of gave it away. There is a fully functioning code behind this newly created bot. Browsing to the Build page it's possible to download the source code of the bot. This includes a publish profile for easy publish access.

To download the source code head to the bot's dashboard an select Download bot source code.

It's possible to emulate conversations using the Bot Framework Emulator (V4). See the documentation for more details. A quick scan through the code tells us a few things.

  • Each intent is basically a "dialog" in code
  • Each dialog that needs to be used should be added to a stack (Dialogs.Add(new GreetingDialog(_greetingStateAccessor, loggerFactory));
  • Each dialog that requires data transfer (parameters, info etc) should have a StateAccessor (Sounds like the React way to do it)
  • OnTurnAsync in the BasicBot.cs is used for switching to the right dialogs

I believe it's good practice to use an UpdateStateAccessor for each StateAccessor to extract LUIS Entities and store it in a state. In terms of High Cohesion Low Coupling, it's better to do this in a controller than pass all LUIS objects to a dialog.

Take a look at the source code of Tosti Bot. This source code includes the default greeting dialog which prompts user input. It also shows an example of how to use Adaptive Cards and carousel images.

I hope you enjoyed this first blog of the Tostibot adventure. Next up: QnA Maker.

Be sure to follow @Mavention on Twitter to get updates on more interesting Blogs.

Submit a comment