Tag Archives: IBM Watson

Conditional fields using IBM Watson Conversation Slots

I’ve been playing a little more with the Slots feature in IBM Watson Conversations and hit a few issues that at first seemed like they could be a problem. One scenario in particular that took me a while to solve, was how to build conditional logic into a node with Slots.

Let’s say that we are walking the user through a process and in the middle of that process a decision needs to be made based on a value collected earlier in the process. This is a common feature of a workflow, it’s obvious how it is done using multiple nodes but how do we do it in a single node using Slots?

I’m going to stick with the example process (Open Account) I’ve used before and extend the completed workspace from this previous post (Read that post first for background). When you’ve worked through the steps in this post it should look something like this completed workspace.

The diagram below details the workflow we are going to follow to implement our process.


So our process is the same as in previous posts with the addition that if the @Subscription_Type is Annual we’re giving away a free t-shirt and need to collect the size. Our challenge is to be able to complete this process in a single node using slots so that we only ask for @TShirtSize when the @Subscription_Type equals Annual.

To perform this kind of condition slot we need to understand two things about the way slots work.

  1. Using the Slot editor on the slot we can use the JSON editor of the Found/Not Found conditions to update the context
  2. A slot is fulfilled when the context variable in the “save as” field has a value

With these insights in mind our solution will

  1. Update the definition of the @Subscription_Type slot so that it updates context with "TShirtSize": "NA"
  2. Add a slot with the “Check for” condition set to @TShirtSize and the “Save as” field set to TShirtSize

Start by adding an entity called @TShirtSize to the workspace and add values for Small, Medium and Large.

Next, select the #Open_Account node and click the Screen Shot 2017-06-26 at 16.35.27icon for the @SubscriptionType slot to open the editor.

Screen Shot 2017-07-31 at 14.01.09

Find the section that says “When user responds, if @Subscription_Type is…”, select the “Not found” option and add a condition for @Subscription_Type:Monthly.

Screen Shot 2017-07-31 at 12.00.28

Click the Screen Shot 2017-06-26 at 16.36.08 icon, select Open JSON editor and add a statement to set the context variable TShirtSize to “NA”.

Screen Shot 2017-07-31 at 12.03.14

Save the @Subscription_Type slot and add a new slot with a “Check for” value of @TShirtSize, “Save as” value of $TShirtSize and “Would you like a Small, Medium or Large t-shirt?” in the “If not present, ask” field as shown below.

Screen Shot 2017-07-31 at 13.54.36

To finish off our conditional slot we’ll add a conditional response to demonstrate that the final responses can also be tailored to our process and business rules. To do this, open the #Open_Account node, right at the bottom of that node you will see a section for “Then respond with:” which can have conditions attached to responses.

Click the add condition link above the current response and add a condition of $TShirtSize=="NA" then click “Add another response” and enter the text as “Okay, I’ll open your $Account_Type with $Subscription_Type payments and send your $TShirtSize t-shirt right now.”

Screen Shot 2017-07-31 at 14.17.15

Go ahead and test the workspace, in particular try out both Monthly and Annual subscription types to verify conditional t-shirt size question only gets asked when it should.

Using this approach you can build really quite complex decision trees without having to create trees at all, moreover your decision trees will allow users to provide information in a flexible manner, one at a time or all at once.

In my next post on using Slots in IBM Watson I will discuss how to add slots for non Entity conditions and how to deal with numbers where zero (0) is a valid entry.


Using Slots to collect data in IBM Watson Conversations

A new feature was released in IBM Watson Conversations earlier this month called “Slots”. This feature allows the collection of data from users to be configured in a more data driven and succinct manner than was previously possible.

In a previous post, I explained an approach for recursively collecting information that relied on configuring a flow with “Jump To” conditions or “Continue From” as they were called back then.

Using slots is pretty easy once you’ve done it a couple of times and the resulting node structure is very simple even in quite complex use cases. Let’s update my example from previous posts with this new approach.

Download the starter template which contains the basic structure and import it into a Watson Conversations Instance (see here for how to import). The workspace includes a couple of intents (Open and Close Accounts) and two entities (Account and Subscription Type). The basic idea is that we are building an assistant that will help us open an account for which two pieces of information are required.

Once imported use the “Add Node” button at the top of the dialog tab and set the node condition to #Open_Account” as shown below.

IBM Watson Conversation Slots 1

Next click on the customise link at the top of the right hand edit panel just above the #Open_Account condition. In the dialog that opens select the first checkbox to enable the Slots feature, ignore the “Prompt for everything” checkbox for now.

ICM Watson Conversations Slots 2

Clicking “Apply” will result in an update in the right hand edit panel and the addition of the Slot editor. Let’s add our first Slot, type @Account_Type into the “Check for” field of the first row and something like “You can open a Bronze, Silver or Gold account. Which option would you like?” to the “If not present, ask” field. The “save as” field will be defaulted for you and the default is fine for our purposes.

IBM Watson Conversation Slots 3

Next click the “Add slot” link and enter @Subscription_Type into the “Check for” field and something like “Would you like to pay monthly or annually?” into the “If not present, ask” field.

Finally we need to add the response that will be presented to the user when both account type and subscription type have been collected. In the section “Then respond with” add something like “Super. I’ll open your <? $Account_Type ?> account with <? $Subscription_Type ?> billing.”. The placeholders for $Account_Type and $Subscription_Type will be replaced with the values from context, you can see where this context is set by clicking on the cog iconScreen Shot 2017-06-26 at 16.35.27 to the right of the slot, then select the hamburger menu Screen Shot 2017-06-26 at 16.36.08 and select the “Open JSON editor” option.

Screen Shot 2017-06-26 at 16.36.17

The resulting flow should handle the possible variations of user input in a single dialog node rather than the 5 nodes we needed in my previous example. Try out the following variants:

  • I’d like to open and account
  • I’d like to open a bronze account
  • I’d like to open an account and pay monthly
  • I’d like to open a bronze account and pay monthly

Assuming our changes went well the above sentences will work and guide the user toward the endpoint regardless of what information they provide in the first utterance. The completed #Open_Account node should look like the below image, if you have any problems I have included a completed workspace that can be imported to double check against your own.

ICM Watson Conversations Slots 4

Although only a basic example I hope you can see just how powerful a feature Slots are within IBM Watson Conversations service. Extending this approach to 5, 6 or 7 pieces of information would be quick and easy to maintain, my only word or warning is that collecting a lot of information will quickly become a arduous task for users and is better handled with traditional forms.


Pattern for gathering information in IBM Watson Conversations

UPDATE: The approach detailed in the post is now out of date for many use cases, please see the update post Using Slots to collect data in IBM Watson Conversations.

In a previous post, I shared some thoughts and an approach to Recursive questions with IBM Watson’s Conversation service. The post detailed how we can collect a piece of information from users in a way that allows for that information to be provided in the initial utterance or as a response to a question from our bots.

In this post, I will extend this example and demonstrate a pattern to collect multiple pieces of information while maintaining flexibility and eliminating duplication. You can download the workspace source code from my Github account.

What are we trying to do?

The scenario is that we are creating a bot for a cloud service provider which will enable users to open a new account. Our Acme SaaS company provides three account types (Bronze, Silver and Gold) and two subscription types (Monthly and Annual). We have two entities for Account_Type and Subscription_Type and an intent for Open_Account.

I find it helpful when designing processes to be serviced by bots to map these out logically, I like to do this as follows:

Intent Entities Resolution
Open_Account Account_Type
Subscription Type
Account Opened

Creating the above mapping, particularly for complex use cases will help you identify where intents can be merged. If you get two intents with different Entity conditions but the same resolution you should merge the intents and disambiguate on the Entity values.

The above mapping identifies that we need to know the Account Type and Subscription Type before we can fulfil the request and open an account. The following diagram shows the strategy we are going to implement to fulfil our open account request.

The important thing to note from above is that we can describe the collection of the information in a recursive loop. Within the loop if a required entity is provided we save it to context, if additional entities are required we prompt for those and repeat. Once all requirements are satisfied we can fulfil the users request.

How do we do that?

To achieve this, with the dialog features of the Watson Conversation service, we will use a combination of @Entity and $Context conditions and the “continue_from” features in a single level within the dialog. Let’s take a look at the first few nodes.

screen-shot-2016-11-18-at-14-17-40Our first node matches on the intent for Open_Account and uses a “continue_ from” to go immediately to the check for @Account_Type. This node will fire if the user’s input includes a valid @Account_Type and uses it a “continue_from” to go immediately to the next entity check.

Looking at the advanced tab of @Account_Type or $account_type node, we can see that it returns no output and sets the account_type variable on the context object. We will use that context variable later to fulfil the request but also to make sure we don’t ask the user for the info twice.

  "output": {},
  "context": {
    "account_type": "<? @Account_Type ?>"

Moving down the node stack at this level we do the same for Subscription_Type which if it’s present we will again use the “continue_from” and move on to check each context variable.

screen-shot-2016-11-18-at-17-55-05Our next few nodes have conditions that check if a context variable doesn’t exist and if not, prompts for the user to provide the entity. Once we have checked for $account_type and $subscription_type our final node fulfils the request (or at least says that it will).

Context variable checks and fulfilment node

Notice the use of <? $account_type ?> in the output of the last node, this inserts the values of the information collected into the response to the user.

Before wrapping up I’d like to point out one more thing you can’t see in the image above, but the nodes with conditions on the context variables (e.g. !$account_type) have complex output that uses a feature called sequential selection policy. Let’s take a look at the advanced json first then I’ll explain what it does.

  "output": {
    "text": {
      "values": [
        "I can help you open an account...Which option would you like?",
        "Sorry I didn't understand that...Gold account?"
      "selection_policy": "sequential"

When this node fires (i.e. when the $account_type variable is not set) it will output the first item in the values array “I can help you open an account…”. If the user fails to enter a valid @Account_Type then it will output the second item in the values array “Sorry I didn’t understand…”. With this approach you can re-prompt the user without having to introduce new nodes.

What does it all mean?

To conclude I want to point out the ways that we can interact with the Open_Account flow. If I were to ask “I’d like to open an account”, the bot would ask “what type of account?”.  If I then say “bronze” the bot will ask “monthly or annual payments?”. If I then say “monthly” the bot will fitful the request. However I could also say “I’d like to open a bronze account” in which case the bot will just ask “monthly or annual payments?”. If I say “I’d like to open a Bronze account with monthly billing” the bot will simply fitful the request.

Using this pattern we can allow the user to provide all, some or none of the information we require in the initial request. With a few nodes and one level of evaluation we can collect the information we need and even re-prompt the user where required.

As a reminder you can download the workspace I used to test this pattern on my Github account. Just download it and use the import feature in the conversation tooling to see a working example for yourself.

Recursive questions with IBM Watson Conversations

UPDATE: The approach detailed in the post is now out of date for many use cases, please see the update post Using Slots to collect data in 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 synonyms 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.”


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.


Example of outputting the synonym used

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