Recursive questions with IBM Watson Conversations

IBM Watson released a new API earlier this year called Conversations which enables developers to build cognitive conversational solutions like chatbots and virtual assistants.

A common scenario when creating a chatbot is the need for clarification questions, for example you are creating a bot that helps users open a bank account. The user might say “I’d like to open a current account”, the bot understands that the user intends to “open account” and the account type is “current account” (AKA checking account in the US). What if the user says “I’d like to open an account”? In this case, in order to help the user, we’d need to know the type of account they want to open.

There are a number of way to approach the collection of the required information in a chatbot. The image below shows an approach of splitting the conversation based on the information provided.

Screen Shot 2016-08-30 at 13.07.41

If the users intent is classified as “Open_Account” and an entity of the type “Account_Type” is found then the first node will fire. If however the intent is classified as “Open_Account” but there is no entity then the second node will fire. This approach will work just fine for these examples but if we have many more pieces of information we require to complete a request, then this approach will be more difficult to maintain.

One of our goals when designing dialogs should be to reduce duplication and provide flexibility to the end-user. Reducing duplication will lower the cost of maintaining solutions, while flexibility in the way users can interact will provide a much better user experience. The following image shows a better way to approach this flow.

Screen Shot 2016-08-30 at 14.31.30

The key to this approach lies in utilising the “continue from” features of the Conversations service so the flow will respond intelligently and intuitively to users.

The first thing to note is the “Continue from…” node at the top of the second column of nodes. This tells the dialog to continue straight from the initial node with the #Open_Account condition to the next level. Note also that the output of the first node is empty, this is required as we don’t want our bot to say anything we just want it to move on and evaluate the second level of conditions. You can check that the node will not output anything by making sure that the output is set to {} in the advanced view as shown below.

Screen Shot 2016-08-30 at 14.07.00

The second thing to note is the second column of nodes. The first node has a condition on “Account_Type”, the second has a dummy condition of “true” (This always evaluates to true). This tells our dialog that if the user input has an account type then go ahead and fire the first node, if not ask the user what type of account they want.

The last thing we add is a new “Continue from”, the last node which is set to “User input”. This tells the dialog that every time we hit this node return the user input and evaluate this stack again (i.e Recursive).

This approach ensures our bot gets the information it needs to continue through the conversation but it also locks the user into the flow. In a future post I will explain techniques for allowing users to break out of the flow which is important when our bot doesn’t understand or when the user wants to talk about something else.

Accessing the synonym mentioned with IBM Watson Conversations

A couple of my clients have asked me how to access the synonym mentioned by a user when working with the IBM Watson Conversation service. Accessing the matching entity is well documented but it wasn’t apparent how to get the actual word or words mentioned by the user that the entity was matched on.

Having asked the question internally and received the answer I thought I would share in lieu of the documentation being updated. The answer is actually in the documentation here but without explanation so my clients and I missed it.

The scenario is pretty common and straight forward, lets say you have an entity called Account_Type with an entry for Bronze with a synonym of Basic. Your dialog flow for opening an account asks the user what type of account they would like to open, to which they say “I’d like to open a basic account please”. At this point your dialog is configured with:

“Okay, I’ll open a @Account_Type for you now.”

1*l9WzyyIDJpvhJdLbBPTFGA
Example of outputting a matched Entity

The result will be a replacement of the @Account_Type placeholder with “Bronze”. This can be confusing for users and communicates a sense of inflexibility that is less than ideal. Instead we can access the synonym mentioned by the user with:

<?entities["Account_Type"][0].literal ?>

We configure our output as:

Okay, I’ll open a <?entities["Account_Type"][0].literal ?> for you now.

1*Epu1qC9hx3i_G4rAoUCDgA
Example of outputting the synonym used

The result will now be that the placeholder is replaced with the word “basic”.