Determining Intent Using Dialogs

What did you say?

Bots give you the ability to allow users to interact with your app through communication. As a result, figuring out what the user is trying to say, or their intent, is core to all bots you write. There are numerous ways to do this, including regular expressions and external recognizers such as LUIS.

For purposes of this blog post, we’re going to focus our attention on regular expressions. This will give us the ability to focus on design and dialogs without having to worry about training an external service. Don’t worry, though, we’ll absolutely see how to use LUIS, just not in this post.

Dialogs

In Bot Framework, a dialog is the core component to interacting with a user. A dialog is a set of back and forth messages between your bot and the user. In this back and forth you’ll figure out what the user is trying to accomplish, and collect the necessary information to complete the operation on their behalf.

Every dialog you create will have a match. The match will kick off the set of questions you’ll ask the user, and start the user down the process of fulfilling their request.

As mentioned above, there are two ways to “match” or determine the user’s intent, regular expressions or LUIS. Regular expressions are perfect for bots that respond to explicit commands such as create, stop or load. They’re also a great way to offer the user help.

Design Note

One big thing to keep in mind when designing a bot is no natural language processor is perfect. When people create their first bot, the most common mistake is to allow the user to type almost anything. The challenge is this is almost guaranteed to frustrate the user, and lead to more complex code trying to detect the user’s intent, only to misunderstand a higher percentage of statements.

Generally speaking, you want to guide the user as much as possible, and encourage them to issue terse commands. Not only will this make it easier for your bot to understand what the user is trying to tell it, it actually makes it easier for the user.

Think about a mobile phone, which is one of the most common bot clients. Typing on a small keyboard is a challenge at best, and the user isn’t going to type “I would like to find the profile GeekTrainer” or the like. By using terse commands and utterances, you’ll not only increase the percentage of statements you understand without clarification, you’ll make it easier for the user to interact with your bot. That’s a win/win.

In turn, make it easy for your user to understand what commands are available. By guiding the user through a set of questions, in an almost wizard-like pattern, you’ll increase the chances of success.

Creating dialogs

To determine the user’s intent by using regular expressions or other external recognizers, you use the IntentDialog. IntentDialog effectively has a set of events exposed via matches which allow you to execute at least one function in response to the detected event.

Let’s say you wanted to respond to the user’s command of “load”, and send a message in response. You could create a dialog by using the following code:

1
2
3
4
5
// snippet
let dialog = new builder.IntentDialog()
.matches(/load/i, (session) => {
session.send('Load message detected.');
});

matches takes two parameters - a regular expression which will be used to match the message sent by the user, and the function (or array of functions) to be called should there be a match. The function, or event handler if you will, takes three parameters, session, which we saw previously, args, which contains any additional information sent to the function, and next, which can be used to call the next function should we provide more than one in an array. For the moment, the only one that’s important, and the only one we’ve used thus far, is session.

To use this with a bot, you’ll create it and add the dialog like we did previously, only adding in the dialog object rather than a function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// text.js
// full code
const builder = require('botbuilder');
const connector = new builder.ConsoleConnector();
const bot = new builder.UniversalBot(connector);
const dialog = new builder.IntentDialog()
.matches(/load/i, (session) => {
session.send('Load message detected.');
});
bot.dialog('/', dialog);
connector.listen();

If you run the code, and send the word load, you’ll notice it sends the expected message.

1
2
3
node text.js
load
// output: Load message detected

Handling default

Over time you’ll add more intents. However, as we mentioned earlier, we want to make sure we are able to give the user a bit of guidance, especially if they send a message that we don’t understand at all. Dialogs support this through onDefault. onDefault, as you might suspect, executes as the default message when no matches are found. onDefault works just like any other handler, accepting one or more functions to execute in response to the user’s intent.

1
2
3
4
5
6
7
8
9
10
11
// existing code
const dialog = new builder.IntentDialog()
.matches(/load/i, (session) => {
session.send('Load message detected.');
})
.onDefault((session) => {
session.endConversation(`Hi there! I'm a GitHub bot. I can load user profile information if you send the command **load**.`);
});
// existing code

You’ll notice you don’t give onDefault a name because it’s of course also a name. You’ll also notice we used session.endConversation to send the message. endConversation ends the conversation, and the next message starts from the very top. In the case of our help message this is the perfect behavior. We’ve given the user the list of everything they can do. The next message they send, in theory anyway, will be one of those commands, and we’ll want to process it. The easiest way to handle it is to use the existing infrastructure we just created.

If you test the bot you just created, you should see the following:

1
2
3
node text.js
Hello
// output: Hi there! I'm a GitHub bot. I can load user profile information if you send the command load.

Summary

When creating a bot, the first thing you’ll do is determine what the user’s intent is; what are they trying to accomplish? This is done in a standard app by the user clicking on a button. Obviously, there are no buttons. When you get down to the basics, a bot is a text based application. Dialogs can make it easier to determine the user’s intent.