Building a dialog

The dialog component of the Conversation service uses the intents and entities that are identified in the user's input to gather required information and provide a useful response. Your dialog is represented graphically as a tree; create a branch to process each intent that you define.

High-level steps

Plan the responses that you want to make to each possible user input.

If you're a new user of the dialog component, review the overview of dialog concepts and terms before you begin building dialogs.

The dialog component of the Conversation service provides responses to users based on the identified intents and entities. Create a dialog branch for each intent, to gather any required information and make a helpful response. More details are provided in subsequent topics for these high-level steps.

  1. Choose the first intent for which you want to create a dialog branch. Choose an intent that can be processed simply, so that you can become familiar with the tools and concepts.
  2. Determine the response that you want to provide for this intent. Depending on the purpose of your application, you might provide a simple text response that answers a question, or you might tell the application to call a back-end application using the information that you have gathered.
  3. Identify the information that you need to gather to make a helpful response. For example, if you want to answer questions about weather forecasts, you would need to know the location and the date. If you want to enable users to order a pizza, you might need to know the size, the toppings, and so on. In many cases, you will have entities defined to contain these pieces of information.
  4. Define the structure of the context data. Your dialog branch uses context to pass data back and forth with the application, and to retain data from the beginning of the branch until you provide the response.
  5. Build a sequence of dialog nodes that captures the information that you need to enable you to provide a useful response. Think of possible user inputs and identify what additional information you need. For example, if a user asks What is the forecast for Austin?, you would need to ask for the date.
  6. Test your dialog branch as you build it. Enter a variety of inputs to verify that the correct intents and entities are recognized and that you can gather the information that you need.
  7. Choose the next intent to work on and repeat these steps until you have defined a dialog branch for each intent that your application needs to support.

Dialog overview

A dialog uses the intents and entities that have been identified, plus context from the application, to interact with the user and ultimately provide a response.

The response might be the answer to a question such as Where can I get some gas? or the execution of a command, such as turning on the radio. The intent and entity might be enough information to identify the correct response, or the dialog might ask the user for more input that is needed to respond correctly. For example, if a user asks, "Where can I get some food?" you might want to clarify whether they want a restaurant or a grocery store, to dine in or take out, and so on. You can ask for more details in a text response and create one or more child nodes to process the new input.

The dialog is stateless, meaning that it does not retain information from one interchange to the next. Your application is responsible for maintaining any continuing information. However, the application can pass information to the dialog, and the dialog can update the context information and pass it back to the application.

A dialog is made up of nodes, which define steps in the conversation. Dialog nodes are chained together in a tree structure to create an interactive conversation with the end user. Each node includes conditions for the node to be active, as well as an output object that defines the response provided. You can think of the node as an if/then construction: if this condition is true, then return this response. The simplest condition is a single intent, which means that the response is returned if the user's input maps to that intent. Create a dialog branch that corresponds to each intent that you have identified. That branch is used when that intent is recognized.

The tutorial includes a section that guides you through the steps to create some dialog nodes. Follow those steps before you create your own dialog tree.

Dialog terms

Learn these terms to understand how to use the dialog builder to design conversations.

  • node: An element of a dialog that represents a single interaction that is a part of a conversation.
  • condition: Part of the definition of a node, the condition is evaluated against the user's input. If the condition matches the input, the node's response is returned.
  • response: Part of the definition of a node, the response is activated if the node's condition matches the user input. A response can be a simple text response that is returned to the user, or a more advanced process to be run.
  • branch: A sequence of dialog nodes that represents a conversation with a user. A branch is used when the conditions in its base node match a user's input.
  • turn: A single cycle of user input and a response. A dialog branch can have one or many dialog turns.
  • base node: The first node in a dialog branch.
  • child node: A node that is not a base node. The child node is used when a prior node requires more input or processing before returning a final response.
  • peer node: A node that is an alternative to another node; typically one of two or more peer nodes is activated based on its conditions. All base nodes are peers of each other; child nodes can be peers if your conversation requires them. One common use is to process "yes" or "no" responses that the user enters. Also called a sibling node.

Dialog tree evaluation

Tree evaluation is the processing of the user's input against the dialog flow that has been defined in the dialog builder. Dialog trees are evaluated in rounds, and a round always starts on a specific node.

At the beginning of each conversation, evaluation begins at the top level of dialog nodes. In the UI, this level is represented by the virtual root node labeled Conversation starts. Each time the dialog returns a response and waits for user input, it stores the ID of the node at which the conversation should resume. This node is called the contextual node, and its ID is added to the context.system.dialog_stack property, which contains a JSON array of dialog node IDs that are currently on the dialog stack. The last node on this stack is the contextual node at which evaluation begins in the next round.

The evaluation round works in two stages. In the first stage, the dialog tries to find an answer in the child nodes of the contextual node. That is, it tries to match all the conditions of the child nodes of this contextual node. If the final child node has a condition of "true", meaning that it is to be used if none of its siblings have been matched, then that node's response is processed. Otherwise, if no match is found, the dialog continues to a second stage in which it tries to find an answer to a particular input by matching the top level of dialog nodes. The top level of dialog nodes should contain an anything_else node as the last node, which is hit when no match occurred in the conditions of the top level nodes. Typically, if an anything_else node is defined, the dialog returns an answer to every user input.

The next contextual node to be selected in the dialog depends on whether the last dialog node that was selected has any child nodes. If it does not have children, it is a leaf node. In this case, the next contextual node is set to the Conversation starts virtual root node, and the evaluation in the next round starts from the top level again. If the last selected dialog node has children, it is set as the contextual node for the next round, and the dialog evaluation in the next round starts from the child nodes of this contextual node.

The order of your dialog branches is important. When a user input is received, and the intent and entity have been identified, dialog base nodes are evaluated in the order in which they appear in the UI. The first base node whose condition matches the input is used. To add a new branch in the middle of the current list, select the link on the bottom of the base node in the branch below which you want to add a new branch.

Context variables

The dialog context is the mechanism for passing information between the dialog and your application code.

You can store information by modifying the context part of the dialog node definition in an editor. To open the editor, click the Advanced response icon in the Response section of the edit view of the node. In the editor you can define or modify variables that will persist in the dialog context. You can access the dialog context by typing context.variable_name, where variable_name is the name of the variable on the context you want to access, or you can use the shorthand syntax $variable_name. In the context, you can define any supported JSON types, such as simple string variables, numbers, JSON arrays, or JSON objects. You can use upper- and lower-case alphabetic characters, numeric characters (0-9), and underscores. Here is an example definition of various variables you can define in the context by modifying the context field of the dialog node in the editor:

{
  "context": {
    "my_dessert_string": "ice-cream",
    "toppings_array": ["onion", "olives"],
    "age_number": 18,
    "complex_object": {
      "user_firstname" : "Peter",
      "user_lastname" : "Pan",
      "has_card" : false
    }
  }
}

When the dialog node with this example context is selected to be processed, the dialog context is updated with the values from the context field of the node. If the context already contains some of the variables that are being updated, the update process depends on the variable type. If it is a primitive type, such as a boolean, number, a string or a JSON Array, the variable is simply overwritten. If it is a complex type such as JSON object, a JSON merge procedure is used to update the variable. The merge procedure merges the properties that are already defined in the context with the new properties defined by the context of the dialog node that is being processed. If some existing property is updated, it is overwritten. Consider the following example:

{
  "complex_object": {
    "user_firstname": "Peter",
    "has_card": true
  }
}

The dialog node selected for processing contains the following context:

{
  "complex_object": {
    "user_firstname": "Paul",
    "user_lastname" : "Hill"
  }
}

The result is this context:

{
  "complex_object": {
    "user_firstname": "Paul",
    "user_lastname": "Hill", "has_card": true
  }
}

Creating dialog nodes

A dialog is made up of nodes, which are represented in the UI as boxes. Each node has two parts: a condition and a response.

You can also give each node a name. This makes it easier for you to remember the node's purpose and to locate the node when it is minimized. If you don't enter a name, the condition is used. If you do give names to your dialog nodes, each name must be unique.

The number of dialog nodes you can create in a single service instance depends on your service plan:

Service plan Dialog nodes per service instance
Standard/Premium 100,000
Free 25,000
  • To open the dialog builder and create dialog nodes and branches, choose Dialog in the navigation bar. If Dialog is not visible, use the Menu menu to open the page. When you open the dialog builder for the first time, a first node is created for you. When you define a condition for the first node in your workspace, a node with the Anything else condition is created automatically. This node is used when none of the nodes that you create are selected for use. You can use this node to provide a default response.
  • To add more nodes to your dialog tree, use the Add node link Add node on an existing node.
    • To create a peer node (also called a sibling node), select the link below an existing node. A peer node is an alternative to the existing node; it is checked next if the condition for the existing node is not met.
    • To create a child node, select the link on the side of an existing node. A child node is processed after its parent node.
  • As you create dialog branches, you can minimize the view of the branches that you have already created, in order to simplify the display and help you focus on the new branch. To minimize a branch, select the minimize icon Minimize icon in its base node.

Defining conditions

The condition portion of a dialog node determines whether that node is used in the conversation. You can use any combination of intents, entities, context variables, and special conditions in the condition portion of a node.

Valid expressions in conditions are written in the Spring Expression (SpEL) language. For more information, see Spring Expression Language (SpEL) language.

  • The simplest condition is a single intent, which means that the node is used if the user's input maps to that intent. To check the presence of a particular intent in a condition, enter the name of the intent, preceded by a number sign, for example, #weather.

  • When you create a node, and you edit the condition, you might find that you need to define an intent that you do not yet have. You can choose to create the intent while editing the condition. Then, when you go to the Intents panel, the new intent appears in the list. Be sure to add some examples so that the intent can be recognized.

  • To check for a particular value for an entity, add the entity name, preceded by @, followed by a colon and the value, for example, @appliance:heat. Be sure to use a value and not a synonym.

    You might want to define a node that is used whenever any value is found for a particular entity. You can state this condition as @entity_name. This condition is satisfied if any value or synonym for the named entity is recognized in the user input. Be sure to create a peer node to handle the case where no value is recognized.

    As an alternative to the @appliance:(air conditioner) format, you can use @appliance == 'air conditioner'. When you use == you are evaluating only the value of the first detected @appliance entity only. Using @appliance:(air conditioner) gets expanded to entity['appliance'].contains('air conditioner'), which matches whenever there is at least one @appliance entity of value 'air conditioner' detected in the user input.

  • To use a context variable in your condition, use the format $variable_name:value or $variable_name == 'value'. The value of the condition might have been set by the application, or in the response portion of a previous dialog node.

  • The following special conditions are available:

    • welcome: This condition is evaluated as true during the first dialog turn (when the conversation starts), only if the initial request from the application does not contain any user input. It is evaluated as false in all subsequent dialog turns. Typically, a node with this condition is used to greet the user, for example, to display a message such as "Welcome to our Pizza ordering app."
    • conversation_start: Like welcome, this condition is evaluated as true during the first dialog turn, but unlike welcome, it is true whether or not the initial request from the application contains user input. You can use a node with the welcome condition, a node with the conversation_start condition, or both, depending on the design of your application. A node with the conversation_start condition can be used to initialize context variables or perform other tasks at the beginning of the dialog.
    • anything_else: You can use this condition at the end of a dialog, to be processed when the user input does not match any other dialog nodes.
    • irrelevant: This condition will evaluate to true if the user’s input is determined to be irrelevant by the Conversation service.
    • true: This condition is always evaluated to true. You can use it at the end of a list of nodes or responses to catch any responses that did not match any of the previous conditions.
    • false: This condition is always evaluated to false. You might use this at the top of a branch that is under development, to prevent it from being used, or as the condition for a node that provides a common function and is used only as the target of a Jump to action.

Note: When you check the value of a numeric variable, such as an entity or a context variable, make sure that the variable has a value. If a variable does not have a value, it is treated as having value 0 in a numeric comparison. If you check the value of a variable in a condition such as @price < 100, and the @price entity has a null value, perhaps because it has never been set, the condition is evaluated as true. To prevent the checking of null variables, use a condition such as @price AND @price < 100. This condition verifies that a value was found for @price and the value is less than 100. If @price has no value, this condition is evaluated as false.

  • You can combine any of these types of condition in a single node.

    For example, you might check whether the intent #turn_off is present AND the value of the @appliance entity is heat. That node would be used, and its response returned, only if the user's input includes both the #turn_on intent and the heat value for the @appliance entity.

    To change the connector from and to or, select the and, and select or from the drop-down list.

  • You might want to combine nodes in order to use a combination of conditions. For example, when you recognize an intent, you might want to use another node to see whether an entity has been recognized. You do not need another user input before you look for the entity value. To combine conditions like this, you can use a Jump to action. In this case, no response is made to the user. Instead, the dialog is continued at another node that you choose.

    Tip: The process that is described here can be used and will work, but you can now provide multiple responses, each with its own condition, from a single node. See Multiple responses, described below.

    1. Create your first node with the initial condition (in this case, an intent) but do not specify a response.
    2. Create a child node that processes the second part of the condition (in this case, an entity).
    3. Return to the first node and from the edit view choose Jump to icon Jump to.
    4. Then choose the condition portion of the child node as the point from which to continue.

    You can see an example of this in the dialog portion of the Tutorial. The technique combines the #turn_on intent and the processing of entity values, and eliminates the user input that is ordinarily required between a dialog node and a child node.

Defining a response

In a response, you can perform any combination of these functions: update the dialog context; provide a text response to the user; and change the flow of the dialog by using a Jump to action. The three options are always processed in this order, regardless of the order in which you specify them.

If you want to provide a text response, and you do not need to update the context or change the flow, simply enter the response text in the Response portion of the node. If you want to change the flow, use a Jump to action, described below. If you want to update the context, follow these steps.

  1. Select the Advanced response icon to open a JSON editor in the response portion of the node.

  2. Enter the change that you want to make to the context, if any.

    To store the entire string that was input by the user, use input.text:

    {
      "context": {
        "repeat": "<?input.text?>"
      }
    }
    

    To store the value of an entity in a context variable, use this syntax:

    {
      "context": {
        "place": "@place"
      }
    }
    

    To update an array in the dialog context, see Updating arrays.

  3. Enter the text that you want to return to the user, if any.

    To define output as a simple string, use this format to update value of the output.text property.

    {
      "output": {
        "text": "Hello $user"
      }
    }
    

    To define output as a JSON array, use this format:

    {
      "output": {
        "text": ["Hello there.", "How are you?"]
      }
    }
    

    To define output as a complex structured JSON object, use this format:

    {
      "output": {
        "text":{
          "values":["Hello.","Hi."],
          "selection_policy":"random",
          "append":false
        }
      }
    }
    

    If the text field of the output is a complex JSON object that contains a values attribute, selection_policy attribute, and an optional append attribute, an advanced mechanism processes this output.

    • values: A JSON array of strings that holds multiple versions of output text this dialog node can return. Which node is selected depends on the attribute selection_policy.

    • selection_policy: The following values are valid:

      • random: The system randomly selects output text from the values array and does not repeat them consecutively. For example, consider output.text that contains three values. For the first three times, a random value is selected but not repeated another time. After all the output values are given, the system randomly selects another value and repeats the process.

        {
          "output":{
            "text":{
              "values":["Hello.","Hi."],
              "selection_policy":"random"
            }
          }
        }
        

        The system processes this output.text property in this order:

        • The first time the node is hit the system randomly selects and delivers Hi. as the response.
        • The second time the node is hit the system selects and delivers Hello. as the response and resets the counter.
        • The third time the node is hit the system selects and delivers Hello. as the response.
      • sequential: The system delivers the first output text the first time the dialog node is hit, the second output text the second time the node is hit, and so on.

        {
          "output":{
            "text":{
              "values":["Hello.", "Hi."],
              "selection_policy":"sequential"
            }
          }
        }
        

        The system processes this output.text property in this order:

        • The first time the node is hit the system selects and delivers Hello. as the response.
        • The second time the node is hit the system selects and delivers Hi. as the response.
        • The third time the node is hit the system selects and delivers Hello. as the response.
    • append: When the attribute append is set to false, the output collected in previously executed dialog nodes is overwritten by the text value in this particular node.

      {
        "output":{
          "text":{
            "values": ["Hello."],
            "append":false
          }
        }
      }
      

      In this case, all other output text is overwritten by this output text.

      The default behavior assumes selection_policy = random and append = true. When the values array contains more than one item, then the output text is randomly selected from its elements.

Jump to actions

When you want to change the flow of a dialog, use a Jump to action. This action tells the system which dialog node to go to next. Common uses are to bypass asking for user input when going to child nodes and to route the flow to a common dialog node from multiple locations in the tree. If you want to change the flow of the dialog by using a Jump to action, the target node must be created before you do so. To add a Jump to action to a node, choose the Jump to icon Jump to icon.

Select a dialog node that the Jump to action targets and set whether the action targets the response or the condition of the selected dialog node or user input.

  • Response: If the statement targets the response part of the selected dialog node, it is run immediately. That is, the system does not evaluate the condition part of the selected dialog node and runs the response part of the selected dialog node immediately.

Targeting the response is useful for chaining several dialog nodes together. The response part of the selected dialog node is processed as if the condition of this dialog node is true. If the selected dialog node has another Jump to action, that action is run immediately, too.

  • Condition: If the statement targets the condition part of the selected dialog node, the service checks first whether the condition of the targeted node evaluates to true.
    • If the condition evaluates to true, the system processes this node immediately by updating the context with the dialog node context and the output with the dialog node output.
    • If the condition does not evaluate to true, the system continues the evaluation process of a condition of the next sibling node of the target dialog node and so on, until it finds a dialog node with a condition that evaluates to true.
    • If the system processes all the siblings and no condition evaluates to true, the basic fallback strategy is used, and the dialog evaluates the nodes at the top level too.
    • Note: the processing of Jump to actions changed with the February 3, 2017 release. Previously, if you jumped to the condition of a node, and neither that node nor any of its peer nodes had a condition that was evaluated as true, the system would jump to the root-level node and look for a node whose condition matched the input. In some situations this processing created a loop, which prevented the dialog from progressing. Under the new process, if neither the target node nor its peers is evaluated as true, the dialog turn is ended. Any response that has been generated is returned to the user, and an error message is returned to the application: Goto failed from node DIALOG_NODE_ID. Did not match the condition of the target node and any of the conditions of its subsequent siblings. The next user input is handled at the root level of the dialog. This update might change the behavior of your dialog, if you have Jump to actions that target nodes whose conditions are false. If you wish to restore the old processing model, simply add a final peer node with a condition of true and in the response use a Jump to action that targets the condition of the first node at the root level of your dialog tree.

Targeting the condition is useful for chaining the conditions of dialog nodes. For example, you might want to first check whether the input contains an intent, such as #turn_on, and if it does, you might want to check whether the input contains entities, such as @lights, @radio, or @wipers.

Chaining conditions helps to structure larger dialog trees.

Targeting user input requires a next user input before it is processed. This kind of targeting is helpful when you want to reroute the dialog tree evaluation to a particular part of the dialog tree for the next user input. When this statement is encountered by the system, the system returns an actual response, and in the next dialog round the system continues to evaluate from the dialog node that is targeted by this Jump to statement. It tries to match the condition first and the conditions of the siblings next. If no match is found, the evaluation continues at the top level of the tree.

Multiple responses

A single dialog node can provide several different responses. Each of the responses can be triggered by a different condition. This approach enables you to simplify your dialog tree.

The node still has a main condition, which is the condition for using the node and processing the conditions and responses that it contains. Let's look at an example.

In this simple example, we return to the cognitive car concept; we'll process the #turn_on intent and provide different outputs depending on the entity that we detect. We could use multiple dialog nodes to accomplish this, but we're going to do it in a single node. The main condition for the node is #turn_on, which means that the user has asked us to turn on an appliance in the car. To keep things simple, we'll focus on requests to turn on the heat or the air conditioning. Here are the steps we follow:

  1. Click the node to open the editing view.
  2. Let's give our node a name and call it Turn on. Naming a node makes it easier to remember its purpose and to find the node when it is minimized.
  3. Under "Triggered by", enter #turn_on as the condition for the node.
  4. Under "Fulfill with a response", select to add a condition, and enter @appliance:ac to check whether the user asked to turn on the air conditioning.
  5. Enter a response: A bit too warm? OK, turning on the @appliance. By using the entity name, we repeat the same value that the user entered. Here is our node so far, in the edit view: Turn_on node with first response
  6. Select Create another response. For the condition, enter @appliance:heat.
  7. For the response, enter Chilly, eh? Turning on the heat.
  8. Again, select Create another response. For this third entry, we don't need to check the appliance. If it's not AC or heat, we're not interested right now; we can come back and add other appliances later. For the condition, enter true. This causes the accompanying response to be used whenever this part of the node is reached. In fact, you could leave this condition blank; the conditions for individual responses within a node default to true. But it's a good idea to add the true condition to make the purpose clear.
  9. For the response, enter Please try again.
  10. Close the edit view of the node.

Now let's look at our node. It shows the number of responses that are defined (3), and it shows the three conditions and responses: Completed Turn_on node

This single node now provides the function that would have required four separate nodes if we hadn't used the multiple-response capability.

Tips:

  • The conditions within a node are evaluated in order, just as nodes are. Be sure that your conditions and responses are listed in the correct order. If you need to change the order, select a condition and move it up or down in the list using the arrows that appear.
  • If you want to update the context, you must do so in each individual response. There is not a common response section.
  • The Jump to action is processed after a response is selected and delivered. If you add a Jump to action, it is run after any response that is returned from the node.

Adding variety

If your users return to your bot frequently, they might be bored to hear the same greetings and responses every time. You can add variations to your responses so that your bot can respond to the same condition in different ways. You can add variations whether you are using one response or multiple responses in a node.

Let's add some variations to the responses that you just created.

  1. Select the node that you named Turn on to open the editing view. Find the first response that you added.
  2. Select Add a variation to your response.
  3. Enter another response to be used with the same condition, such as Cooling you off with the air conditioner.
  4. Repeat the previous step to add several variations if you wish.
  5. Add some variations to the responses for turning on the heat.

By default, responses are rotated sequentially, as if they were chosen from an ordered list. If you prefer that responses be returned randomly, select Set to random.

Updating arrays

If your dialog context data contains an array of values, you can update the array by appending values, removing a value, or replacing all the values.

Choose one of these actions to update the array. In each case, we see the array before the action, the action, and the array after the action has been applied.

  • Append: To add values to the end of an array, use the append method.

    For this Dialog runtime context:

    {
      "context": {
        "toppings_array": ["onion", "olives"]
      }
    }
    

    Make this update:

    {
      "context": {
        "toppings_array": "<? $toppings_array.append('ketchup', 'tomatoes') ?>"
      }
    }
    

    Result:

    {
      "context": {
        "toppings_array": ["onion", "olives", "ketchup", "tomatoes"]
      }
    }
    
  • Remove: To remove an element, use the remove method and specify its value or position in the array.

    • Remove by value removes an element from an array by its value.

      For this Dialog runtime context:

      {
        "context": {
          "toppings_array": ["onion", "olives"]
        }
      }
      

      Make this update:

      {
        "context": {
          "toppings_array": "<? $toppings_array.removeValue('onion') ?>"
        }
      }
      

      Result:

      {
        "context": {
          "toppings_array": ["olives"]
        }
      }
      
      • Remove by position: Removing an element from an array by its index position:

        For this Dialog runtime context:

      {
        "context": {
          "toppings_array": ["onion", "olives"]
        }
      }
      

      Make this update:

      {
        "context": {
          "toppings_array": "<? $toppings_array.remove(0) ?>"
        }
      }
      

      Result:

      {
        "context": {
          "toppings_array": ["olives"]
        }
      }
      
  • Overwrite: To overwrite the values in an array, simply set the array to the new values:

    For this Dialog runtime context:

    {
      "context": {
        "toppings_array": ["onion", "olives"]
      }
    }
    

    Make this update:

    {
      "context": {
        "toppings_array": ["ketchup", "tomatoes"]
      }
    }
    

    Result:

    {
      "context": {
        "toppings_array": ["ketchup", "tomatoes"]
      }
    }
    

Moving a dialog node

Each node that you create can be moved elsewhere in the dialog tree.

You might want to move a previously created node to another area of the flow, to change the conversation. You can move nodes to become siblings or peers in another branch.

  1. On the node you want to move, select the the Move icon Move icon.
  2. Select where you want to move this node. Two icons appear on the destination node. You can choose to place the node that you are moving as a peer to this node, or as a child of it.
  3. Choose one of the icons. Depending on which you choose, the source node is moved to appear as a peer or a sibling of the target node and is used in that branch during a conversation.

Testing your dialog

As you make changes to your dialog, you can test it at any time to see how it responds to input.

  1. From the Dialog tab, click the Ask Watson icon.

  2. In the chat pane, type some text and then press Enter.

    Tip: Make sure the system has finished training on your most recent changes before you start to test the dialog. If the system is still training, a message appears at the top of the chat pane:

    Screen capture of training message

  3. Check the response to see if the dialog correctly interpreted your input and chose the right response.

    The chat window indicates what intents and entities were recognized in the input:

    Screen capture of test dialog output

    In the dialog editor pane, the currently active node is highlighted:

    Screen capture of highlighted node

As you continue to interact with the dialog, you can see how the conversation flows through the dialog.

If you determine that the wrong intents or entities are being recognized, you might need to modify your intent or entity definitions. If the right intents and entities are being recognized, but the wrong nodes are being triggered in your dialog, make sure your conditions are written correctly.

More information

For information about the expression language used by dialog, plus methods, system entities, and other useful details, see the Reference section.