Before you Begin

This 60-minute hands-on lab is an entry-level exercise for building a skill in Oracle Digital Assistant.

Background

Oracle Digital Assistant is an environment for building digital assistants, which are user interfaces driven by artifical intelligence (AI) that help users accomplish a variety of tasks in natural language conversations. Digital assistants consist of one or more skills, which are individual chatbots that are focused on specific types of tasks.

In this lab, you will create a skill that can be used for interactions with a pizzeria, including ordering pizzas and canceling orders. As part of this process, you will:

  • Define intents, utterances, entities.
  • Design a conversation flow.
  • Validate, debug and test your skill.

What Do You Need?

  • Access to Oracle Digital Assistant.

Create a Skill

In this lab, we're starting from scratch. So the first thing you'll do is create a new skill.

  1. With the Oracle Digital Assistant UI open in your browser, click main menu icon to open the side menu.
  2. Click Development and select Skills.
  3. Click main menu icon again to collapse the side menu.
  4. Click the New Skill button.
    a screenshot of the New Skill button.

    The Create Skill dialog appears.

  5. For Display Name enter Pizza King. If you are working in an environment where others may also be creating the same tutorial, prefix Pizza King with your unique initials.
  6. Optionally, fill in a one-sentence description, e.g. Skill for ordering from Pizza King.
  7. For the other fields, leave the default values.

    a screenshot of the Create Skill dialog. The Display Name is 'Pizza King' and the name is 'PizzaKing'.

  8. Click Create.

    The designer will then open on the Intents page. Here's where we'll begin to express the Pizza King customer use case in terms of the concepts that support Natural Language Processing (NLP).

Create Intents

Oracle Digital Assistant's underlying natural language processing (NLP) engine doesn't inherently know about the business or task that a skill is supposed to assist with. For the skill to understand what it should react to, you need to define intents and examples (utterances) for how a user would request a specific intent.

For the Pizza King example, you will create intents for ordering pizza, cancelling an order, and filing a complaint.

Create the Order Pizza Intent

  1. Scroll back to the top of the page and click the + Intent button.
  2. Next to the Conversation Name field, click the Edit button, and enter Order Pizza.
  3. In the Name field, type OrderPizza.
  4. Select and copy all of the example sentences below to your clipboard:
    • Would you happen to have thin crust options on your Pizzas?
    • Let's order a cheese pizza
    • Would love a large Pepperoni please!
    • I feel like eating some pizza
    • I would like to order a pizza
    • Can I order a Pizza?
    • What's on the menu today?
    • I want pizza
    • Do you server gluten-free pizza?
    • I want to order pizza for lunch
    • Do you have deep dish pizzas available?
    • Order Pizza!

    (You'll notice that it's fine for utterances to have inconsistent punctuation and capitalization.)

  5. In the Examples section, click Advanced input mode.
    Screenshot showing the Examples section of the page. It includes the title ('Examples'), the label 'Utterances to Add' and the clickable text 'Advanced input mode'
  6. In the Utterances to Add field, paste the examples, and then click Create.

Below the Examples section, you should see a table with the utterances that you have added.

Screenshot showing the 'Utterances in Ascending Order' table, with 6 entries starting with 'Can I order a Pizza'. At the bottom of the table are controls for paging to the next set of entries.

Create the Cancel Pizza Intent

  1. Click the + Add Intent button.
  2. Next to the Conversation Name field, click the Edit button, and enter Cancel Pizza.
  3. In the Name field, type CancelPizza.
  4. Select and copy all of the example sentences below to your clipboard:
    • Can i cancel my order?
    • Cancel my order
    • Cancel my Pizza please
    • How do I cancel my order?
    • I don't want my Pizza anymore
    • I really don't want the Pizza anymore
    • I'd like to cancel my order please
    • Its been more than 20 mts. Please cancel my order and issue a refund to my card.
    • Need to cancel my order
    • Please cancel my pizza order
    • Please don't deliver my Pizza
  5. In the Utterances to Add field, past the examples and then click Create.

Create the File Complaint Intent

  1. Click the + Add Intent button.
  2. Next to the Conversation Name field, click the Edit button, and enter File Complaint.
  3. In the Name field, type FileComplaint.
  4. Select and copy all of the example sentences below to your clipboard:
    • I am upset
    • You charged me wrong
    • I want to file a complaint
    • I am not happy with my recent order
    • I have some grief to share
    • I want to speak with a manager
    • Can I raise a complaint
  5. In the Utterances to Add field, past the examples and then click Create.

Your screen should look similar to what is shown in the image below:

a screenshot of the Intents page of the Pizza King skill. The page has entries for the CancelPizza, FileComplaint, and OrderPizza intents.

Note: If you are stuck, you can import the intents and utterances using PizzaKing-Intents.csv.

Train Your Intents

You've now provided the basic ingredients that allow the skill to recognize user input for ordering a pizza, but right now, the skill has no cognition. It can't understand any user input.

To enable it to understand the intents, you need to train it.

  • On the right side of the page, locate and click the Train button (Train bot icon), click Submit, and then wait a few seconds for the training to complete.

Test Your Model

It is not realistic to expect to get the training of your intent model right the first time you do it. Good intent models are created in an iterative cycle of training, testing, retraining, and retesting.

A good intent model is one that has a low ambiguity between the different intents. So let's see how well we’re doing so far.

  1. Click the Test Utterances label that appears near the top of the Intents page.

    screenshot showing the top left of the Intents page. The 'Test Utterances' link appears to the right of the 'Intents' heading on the page.

    The Utterance Tester slides out from the right side of the page.

    screenshot showing the Utterance Tester. On the top of the tester are the label 'Utterance Tester' and buttons for 'Reset', 'Test', and 'Close'. Below that are tabs for 'Quick Test' and 'Go to Test Cases'.

  2. In the Language field of the dialog, select English.
  3. In the Utterance field, type I want to order pizza click the Test button, and look at the test results.

    a screenshot of the Results section of the Utterance Tester dialog. It includes entries for the OrderPizza and CancelPizza intents. For OrderPizza it shows a confidence score of 100%. For CancelPizza it shows 0.00%.

  4. Now scroll back to the top of the dialog, enter I feel like eating some pizza in the Utterance field, and click Test.

    This should also resolve to the OrderPizza intent.

  5. Now try Cancel my order.

    This should resolve to the CancelPizza intent.

  6. And now try Dude, bring me pizza and see what that resolves to.

    a screenshot of the Utterance Tester dialog. It shows the chat message 'Dude, bring me pizza'. Below that is a table with the confidence scores for the OrderPizza (38%) and  FileComplaint (29.7%) intents.

    If you click Show More, an entry for FileComplaint will also appear.

    As you can see, the intent engine is (correctly) most confident that the user wants to create an order, but not by a particularly high margin. Since "Dude, bring me pizza" is a fairly realistic utterance that captures an informal way that someone may interact with the skill, we'll add it to the list of English language utterances for the OrderPizza intent.

  7. Make sure the radio button for Order Pizza is selected.
  8. Click Add to Intent to add it to the list of English utterances for Order Pizza.

    Notes:

    • If the Add to Intent button isn't enabled, make sure that English is selected in the Language dropdown at the top of the dialog.
    • If the Add to Intent button is enabled but it doesn't immediately add the utterance to your intent, you can add the utterance directly in the intent's Utterances to Add field.

  9. Click Train bot icon to retrain the model.
  10. Again enter Dude, bring me pizza in the Utterance field and click Test.

    The confidence score should be much higher for OrderPizza (possibly even 100%).

  11. Type You are expensive and you still don't deliver on time in the Utterance field and click Test.
    a screenshot of the Utterance Tester dialog. It shows the chat message 'You are expensive and you still don't deliver on time'. Below that is a table with the confidence scores for the CancelPizza (73.4%), OrderPizza (71.1%), and FileComplaint (61%) intents.

    In all likelihood, the FileComplaint intent did not receive the highest score. In the above screenshot, CancelPizza "won", though it's also possible that OrderPizza could get the highest score. For us humans it is easy to see that "You are expensive and you still don't deliver on time" is not an order but a complaint. However, a skill first needs to be trained with relevant utterances before it is able to gain the same understanding.

  12. To help remedy this, in the FileComplaint intent row of the dialog, select the radio button (as shown in the screenshot below) and then click the Add to Intent button to add the utterance to the FileComplaint intent.
    a screenshot of the Utterance Tester dialog. It shows the chat message 'You are expensive and you still don't deliver on time'. Below that is a table with the confidence scores for the CancelPizza (73.4%), OrderPizza (71.1%), and FileComplaint (61%) intents. The radio button in the FileComplaint row is selected.

    Note: In these examples, you might get slightly different confidence scores than what are shown here. And in some cases, the matching intents themselves could vary, should the differing confidence scores push those intents above or below the given confidence thresholds. The cause of this variance is the non-deterministic nature of the AI behind the natural language processing and the fact that these skills have a limited number of training utterances (in order to make the tutorial simpler).

  13. Retrain the skill.
  14. Think of two or three more phrases that the system might have problems matching to an intent with high confidence and try them in the Intent tester.

    If you find one that doesn’t match well, select the intent that it should be resolved to and click Add to Intent.

  15. Train the model again and then re-test.

Notes on What You Just Did

In this part of the tutorial, you have tested the quality of your intent training with the goal being to ensure a high level of confidence when resolving intents.

In a real skill project, you would always need to go back to the intent testing with user-provided entries you find in the conversation logs. If, using that test input, your intents are not matched the way they should be, you need to add them as example utterances to proper intents and then retrain the model.

Note: The Utterance Tester also enables you to import tests based on a log of a previous set of tests. This is useful for re-running a set of tests iteratively as you fine-tune your intents.

Create Entities

Now it's time to add entities, which detect information in the user input that can help the intent fulfill a user request. For the Pizza King business, such information could be pizza size, pizza toppings, and delivery time. For example, the user input "I'd like to order a small meaty pizza at 9:00 pm" contains all three of these information types.

We'll create custom entities for size and topping and later use a built-in entity for time. While we're at it, we'll add some synonyms (including some common misspellings) that optimize the entity's ability to tag words from sloppy user input.

Create Entities for Pizza Size and Pizza Topping

  1. In the left navigation for the designer, select the Entities icon.
  2. Click + Add Entity to create a new entity.
  3. In the Name field, change the value to PizzaSize.
  4. In the Configuration section, in the Type dropdown, select Value list.
  5. Click + Value.
  6. For Value, type Small.
  7. For Synonyms, type Personal, press Enter, type smallest, and press Enter again.
  8. Click Create.
  9. Following the pattern in the previous four steps, add the value Medium and the synomym middle.
  10. Following the same pattern, add the value Large and the synomyms Big, grande, and biggest.
  11. Click Create to complete creation of the entity.
  12. Click + Add Entity to create another entity.
  13. In the Name field, change the value to PizzaTopping.
  14. In the Configuration section, in the Type dropdown, select Value list.
  15. Add values for Meaty, Veggie, Hot and Spicy, and American Hot.
  16. Click Create.
  17. PizzaSize and PizzaToppings should appear in the list of entities, as shown in this image:

    a screenshot of the Entities page for Pizza King. In the left side of the page are entries for the PizzaSize and PizzaTopping entities. The PizzaSize entries is selected. On the right side of the page, values (and their synonyms are shown for Small, Medium, and Large.

Edit Prompts for the Entities

Now let's enter some text that the dialog flow can use to prompt for these entities.

  1. In the list of entities, select PizzaSize.
  2. Scroll down to the Prompts section.
  3. In the row for the default prompt ("Please enter PizzaSize"), click Edit icon, replace the text with Which size would you like for your pizza?, and press Enter.

    a screenshot of the Prompts section of an entities page. There is a table with one prompt with the text 'Which size would you like for your pizza?' To the right of that entry are Edit and Delete icons.

  4. In the list of entities, select PizzaTopping.
  5. Scroll down to the Prompts section.
  6. In the row for the default prompt ("Please enter PizzaTopping"), click Edit icon, replace the text with What type of pizza would you like?, and press Enter.

Later on in the tutorial, you'll notice that the skill will use these prompts when it needs to ask the user for pizza size and pizza topping.

Associate the Entities with OrderPizza Intent

For an entity to be recognized when parsing the user input message, it needs to be associated with the appropriate intents. In this case, we need to associate our entities with the OrderPizza intent.

  1. In the left navigation for the designer, select the Intents icon.
  2. Select the OrderPizza intent.
  3. Click the Add Entity dropdown (in the upper right side of the page), type pizza in the Filter Field, and select PizzaSize.
  4. Click the Add Entity dropdown again, type pizza in the Filter Field, and select PizzaTopping.
  5. Click the Add Entity dropdown again, type time in the Filter Field, and select TIME.

    (TIME is a built-in entity that we'll use to help the skill process input for pizza delivery time.)

    The entity list associated with the OrderPizza intent should look like what is shown in the image below (though the order may be different):

    a screenshot of the Intent Entities section of the page for Pizza King. The listed entities are PizzaSize, PizzaTopping, and TIME.
  6. Retrain the model by clicking Train bot icon.

Test the Entities

The Utterance Tester feature enables you to test whether the skill identifies entity values in user input.

  1. In the left navigation for the designer, select the Intents icon.
  2. Click the Test Utterances link.
  3. In the Utterance field of the dialog, type I want to order a small hot and spicy pizza at 7:30 pm and click Test.

    You should see a table showing entities and the values extracted from the input.

    a screenshot of the Utterance Tester dialog. It shows the chat message 'I want to order a small hot and spicy pizza at 7:30 pm'. Below that is a list of entities and their extracted values, including PizzaSize (Small), PizzaTopping (Hot and Spicy), TIME - date (1619551800000), TIME - hourFormat (PM), TIME - hrs (7), and TIME - mins (30).

    Note: You may need to scroll up in the dialog to see the entities.

    Since the entities are recognized in the user input, the skill doesn’t have to ask the user for that information later in the flow.

    Now let's try another one.

  4. In the Utterance field, now type I want to order the biggest meaty pizza at noon and click Test.

    The result should look like what is shown below and thus prove that the PizzaSize entity shows the right value for the synonym "biggest". Also "noon" is properly interpreted as 12:00 p.m.

    a screenshot of the Utterance Tester dialog. It shows the chat message 'I want to order the biggest meaty pizza at noon'. Below that is a list of entities and their extracted values including: PizzaSize (Large), PizzaTopping (Meaty), TIME - date (1619524800000), TIME - hourFormat (PM), TIME - hrs (12), and TIME - mins (0).

Notes on What You Just Did

In this part of the tutorial, you have created custom entities for the Pizza King OrderPizza intent, associated the entities with the intent, and tested the entity recognition in the embedded skill tester.

Similar to the PizzaOrder intent, you would typically need to create and associate entities for the other intents as well. In the interest of time, this tutorial only focuses on the PizzaOrder intent.

Design the Dialog Flow

With the NLP model created, you are ready to build the dialog flow for the skill. The dialog flow is a conversation blueprint that defines interactions users may have with the skill. Each interaction is defined as a state. Each state references a component, which renders a skill response, receives user input, sets and resets variables, resolves user intents, or authenticates users.

Declare Context Variables for the Flow

Our first step is to create the basic flow outline, including context variables and states to handle the user's initial input.

Context variables are the skill's temporary memory. They can be referenced throughout the dialog flow. We'll add context variables to hold values returned by the intent engine, entity values, and the value for the pizza order message.

  1. In the left navigation for the designer, click the Flows icon to open the dialog flow editor.
  2. Delete all of the lines between the variables and the states elements.
  3. Delete all of the lines below the states element.

    That should leave you the following remaining code:

    a screenshot of the dialog flow editor showing lines 2 (name) 3 (a comment), 4 (context), 5 ( variables), and 7 (states) .
  4. In the line under variables:, add these five context variables:
        iResult: "nlpresult"
        pizzaSize: "PizzaSize"
        pizzaTopping: "PizzaTopping"
        deliveryTime: "TIME"
        pizzaOrderMsg: "string"

    Important: Make sure that they are indented two spaces more than the variables: (four spaces total). If the indentation isn’t exact, metadata validation will fail.

    This is what the flow should now look like:

    a screenshot of the dialog flow editor showing lines 2 (name) 3 (a comment), 4 (context), 5 ( variables), 6-10 (the added variables), and 1a (states) .

    Now we're ready to add some states.

Add a State to Determine User Intent

First we'll add the System.Intent component. This component evaluates user input to determine the user intent, extracts all of the entities, and then triggers a subsequent state.

  1. Click + Add Component to open the gallery of component templates.
  2. Select the Language category and then select the Intent component.
    a screenshot of the Language section of the component gallery. It includes items for Detect Language, Intent, Intent with Q&A, Match entity, and others. Intent is selected. In the right panel, there is code for the component. In the bottom, there is an Insert Component button.
  3. Click Insert Component.
  4. In the newly added state, set the value of the variable property to "iResult" (including the quotation marks).

    This means that iResult will be the variable to which the NLP engine saves the intent resolution and entity extraction results to.

  5. Delete the following properties (and their corresponding comments):
    • botName
    • botVersion
    • sourceVariable
    • autoNumberPostbackActions
    • footerText
    • daIntercept
  6. Replace the final three lines (starting with transitions:) with the following code:
        transitions:
          actions:
            OrderPizza: "startOrderPizza"
            CancelPizza: "cancelPizza"
            FileComplaint: "fileComplaint"
            unresolvedIntent: "startUnresolved"
    								

Add Initial States for Each Intent

Next, you need to create the dialog flow states that each possible outcome navigates to. To save you some time, the states are provided in a text document for you to copy and paste.

  1. Open states.txt.
  2. Copy the file's contents and paste them at the bottom of the dialog flow.

    Make sure that the indentation is preserved in the pasted content.

  3. Verify the correctness of your edits by clicking the Validate button on the top of the page.

Troubleshooting Errors in the Dialog Flow

If you don't see a success message, then most likely you misspelled a property name or did not follow the required two-space indenting increments. In this case, scroll through the dialog flow until you see an error icon icon in the left margin. Mouse over the icon to display the tooltip with a description of the problem.

In addition, you can click the Findings icon (Findings icon), which appears on the top of the page. It opens the Validation Findings window, which provides additional information about validation issues. You close the Validation Findings window by clicking Findings icon again.

If you have gotten into a jam and can’t get anything to work, open the your-first-dialog-flow.txt and replace the content in your dialog flow with the content from the file.

Tune Intent Resolution

Before moving further, let's take a look at some settings that are useful for fine-tuning intent resolution.

  • Confidence Threshold: The skill uses this property to steer the conversation by the confidence level of the resolved intent. Set the minimum confidence level required to match an intent. When the level falls below this minimum value, the component triggers its unresolvedIntent action.
  • Confidence Win Margin: When a skill can’t determine a specific intent, it displays a list of possible intents and prompts the user to choose one. This property helps the skill determine what intents should be in the list. Set the maximum level to use for the delta between the respective confidence levels for the top intents. The list includes the intents that are greater than or equal to this delta and exceed the value set for the Confidence Threshold.

Let's update the Confidence Threshold property:

  1. In the left navigation for the skill, click the Settings icon and select the Configuration tab.
  2. Set the Confidence Threshold property to 0.6 (meaning 60%).
  3. Note that the Confidence Win Margin property is set to 0.1 (meaning 10%).
    a screenshot of the Settings page. There are tabs for General, Configuration, Digital Assistant, Events, and Q&A Routing Config. Configuration is selected. 5 properties are displayed, including Confidence Threshold (set to 0.6) and Confidence Win Margin (set to 0.1)

Test the Basic Flow

Before doing any further development, let's test the basic flow to make sure it responds correctly to initial user input.

  1. Open the skill tester by clicking (the Skill Tester icon) in the bottom of the skill's left navigation bar.
  2. In the Utterance field, type I want to order a pizza and then press Enter.

    You should see a response from the skill saying that it is starting your order process:

  3. Click the Intent/Q&A tab to view intent resolution.

    You should see that it shows a match for the OrderPizza intent.

    A screenshot of the tester. It shows user input of 'I want to order a pizza' and the skill's response of 'Hello. Starting your order process'. In the Intent Matches section, it shows a match for OrderPizza, with a result of 100%
  4. Click Reset.
  5. In the Utterance field, type I want to cancel my order and then press Enter.

    The skill should respond with a message regarding pizza cancelation. And, in the Intent Matches panel, you should see that the CancelPizza intent is matched.

    A screenshot of the tester. It shows the exchange from the previous screenshot plus new input of 'I want to cancel my order' and the skill's response of 'I am sorry to hear this. Let me take your cancellation request'. In the Intent Matches section, it shows a match for CancelPizza, with a result of 100%

    Now let's try something more ambiguous.

  6. Click Reset
  7. In the Utterance field, type Your delivery is too late, either cancel the order or file a complaint right now and then press Enter.
    A screenshot of the tester. It shows user input of 'Your delivery is too late, either cancel the order or file a complaint right now' and the skill's response of 'Do you want to', followed by clickable options for CancelPizza and FileComplaint. In the Intent Matches section, it shows intent scores for CancelPizza (about 79%), and FileComplaint (about 72%), and OrderPizza (about 3%)

    As you can see, both CancelPizza and FileComplaint exceeded the confidence threshold of 60%. CancelPizza has a higher score than FileComplaint. However, since CancelPizza's score exceeds that of FileComplaint by less than the confidence win margin that we set earlier (10%), the skill presents a dialog so that the user can select what she really wants.

  8. Click File Complaint.

    The skill should respond with the message "I am sorry to hear this. Let me take your complaint details.".

    Now let's try a more random utterance.

  9. Click Reset.
  10. In the Utterance field, type Can you get me a radio taxi now?
    A screenshot of the tester. It shows user input of 'Can you get me a radio taxi now?' and the skill's response of 'I am sorry I could not understand, let me connect you to someone who can help'. In the Intent Matches section, it shows intent scores for OrderPizza, CancelPizza, and FileComplaint that are all under 50%

    As you can see, the confidence threshold level falls below this minimum value of 60% in this case, so the component triggers its unresolvedIntent action.

Build the Pizza Order Conversation Flow

Now that we have verified that the basic intent model is working, the next step is to implement conversation flows for each intent. In the interest of time, we'll do this just for the PizzaOrder intent.

We'll complete the pizza order process by fetching the pizza size, topping, and delivery time, and then printing an order summary.

Complete the startOrderPizza State

So far, the startOrderPizza state is only set up to acknowledge that the user wants to order a pizza. Let's update it so that it can start processing a pizza order.

  1. In the dialog flow, navigate to the startOrderPizza state.
  2. Change the text property's value to "OK, let's get that order sorted".
  3. Change the keepTurn value to true.
  4. Change the processUserMessage value to false.
  5. Delete the line return: "done".
  6. Replace the deleted line with
          next: "setPizzaSize"

    This is what the state should look like:

    A screenshot of the dialog flow editor showing the startOrderPizza state after the previous steps have been completed.

Set Pizza Size

You'll notice that the previous state ends with a transition to "setPizzaSize". That refers to a state for prompting for pizza size that we'll add here.

  1. Set your cursor on the line after the next: "setPizzaSize" line. (It is important that you set it at the very beginning of the line so that the code that you paste has the proper indentation.)
  2. Paste the following code:
      setPizzaSize:
        component: "System.CommonResponse"
        properties:
          processUserMessage: true
          variable: "pizzaSize"
          nlpResultVariable:  "iResult"     
          useFullEntityMatches: true      
          metadata: 
            responseItems:         
            - type: "text"  
              #text: "Please select a size"
              text: "${system.entityToResolve.value.prompt}"       
              actions:
              - label: "${enumValue.value!enumValue.originalString}"
                type: "postback"
                iteratorVariable: "system.entityToResolve.value.enumValues"
                payload:
                  variables:
                    pizzaSize: "${enumValue.value!enumValue.originalString}"
        transitions:
          next: "setPizzaTopping"
    

    There's a lot of code here that you probably are not used to yet. In short, it uses a System.CommonResponse component to display the pizza sizes from which a user can select. Once the user selects a pizza size, the flow transitions to the setPizzaTopping state, which we'll define in the next step.

Set Pizza Topping

  1. Insert a new line after the end of the state that you just pasted and set your cursor at the very beginning of the line.
  2. Paste the following code (also based on the System.CommonResponse component) to create the setPizzaTopping state:
      setPizzaTopping:
        component: "System.CommonResponse"
        properties:
          processUserMessage: true
          variable: "pizzaTopping"
          nlpResultVariable:  "iResult"     
          useFullEntityMatches: true      
          metadata: 
            responseItems:         
            - type: "text"  
              #text: "Please select a topping"
              text: "${system.entityToResolve.value.prompt}"       
              actions:
              - label: "${enumValue.value!enumValue.originalString}"
                type: "postback"
                iteratorVariable: "system.entityToResolve.value.enumValues"
                payload:
                  variables:
                    pizzaTopping: "${enumValue.value!enumValue.originalString}"
        transitions:
          next: "setPizzaDeliveryTime"
    

    You'll notice that this component has a transition to setPizzaDeliveryTime. We'll define that state in the next step.

Set Pizza Delivery Time

  1. Insert a new line after the end of the state that you just pasted and set your cursor at the beginning of the line.
  2. Paste the following code to create the setPizzaDeliveryTime state:
      setPizzaDeliveryTime:
        component: "System.CommonResponse"
        properties:
          processUserMessage: true
          variable: "deliveryTime"
          maxPrompts: 3
          nlpResultVariable:  "iResult"     
          useFullEntityMatches: true      
          metadata: 
            responseItems:         
            - type: "text"  
              text: "At what time can we deliver that for you (e.g. 4 pm)?"
        transitions:
          actions:
            cancel: "maxError"
          next: "setPizzaOrderMessage"
    

Set Pizza Order Message

Now we'll create the setPizzaOrderMessage state to construct a message that we'll then display using the displayOrderConfirmation state.

For the setPizzaOrderMessage state, we'll use a component template and adjust the code for our purposes.

  1. Click a screenshot of the Add Component button.
  2. Select the Variables category.
  3. Select the Set variable template.
  4. From the Insert After dropdown, select setPizzaDeliveryTime.
  5. Clear the Include template comments checkbox.
  6. Click Insert Component.
  7. Change the state name of the newly added component from setVariable to setPizzaOrderMessage.
  8. Edit the state to look like the following:
      setPizzaOrderMessage:
        component: "System.SetVariable"
        properties:
          variable: "pizzaOrderMsg"
          value: 
          - "Thank you for ordering from Pizza King!"
          - "OK, so we are getting you the following items:"
          - "A ${pizzaSize.value.value} ${pizzaTopping.value.value} pizza at ${deliveryTime.value.date?long?number_to_time?string('HH:mm')}."
        transitions:
          next: "displayOrderConfirmation"
    

Display Order Confirmation

  1. Insert a new line after the setPizzaOrderMessage state.
  2. At the beginning of the new line, paste the following code to create the displayOrderConfirmation state:
      displayOrderConfirmation:
        component: "System.CommonResponse"
        properties:
          processUserMessage: false
          metadata: 
            responseItems:         
            - type: "text"  
              separateBubbles: false
              text: "${pizzaOrderMsg}"  
              iteratorVariable: "pizzaOrderMsg"
        transitions: 
          return: "done"
    

Validate the Dialog Flow

  • Click the Validate button on the top of the page, and then fix any errors that are revealed.

    If you have errors that you can't resolve, you can copy and paste the code from complete-dialog-flow.txt.

Note: At this stage, the Validation Findings will likely display a number of items that are marked by the Info icon. These items are suggestions for best practices, which will be of interest to you as you become more experienced in skill development. However, for purposes of completing this tutorial, you can ignore these suggestions.

Test Your Skill

Now that all of the skill's pieces are in place, let's test its behavior.

  1. Open the skill tester by clicking the Skill Tester icon at the top of the page.
  2. Click Reset.
  3. In the Utterance field, type I want to order pizza and then press Enter.

    You should see a menu of pizza sizes:

    A screenshot of the tester showing the input 'I want to order pizza', followed by the response: 'OK, let's get that order sorted. What size would you like for your pizza?' and then a menu with options for Small, Medium, and Large.
  4. In the pizza size menu, select an option, e.g. Small.

    A prompt for the pizza topping should appear.

  5. Select a topping e.g. Veggie.

    A prompt for delivery time should appear.

  6. Enter a delivery time, e.g. 7:30 p.m.

    You should receive an order confirmation. Here's a screenshot of what the whole conversation might look like.

    A screenshot of the tester showing the conversation, starting with the prompt 'Which size would you like for your pizza?', followed by the response 'Small'. After that is the question 'What type of pizza would you like', followed by the response 'Veggie.' After that is the question 'At what time can we deliver that for you (e.g. 4 pm)?', followed by the response '7:30 p.m.'. After that is the confirmation: 'Thank you for ordering from Pizza King! OK, so we are getting you the following items: A Small Veggie pizza at 19:30.
  7. Click Reset.
  8. Now try entering Dude, can you get me the biggest hot and spicy pizza you can make at noon and pressing Enter.

    This time, you should be immediately presented with the results of the order.

    A screenshot of the tester showing the input 'Dude, can you get me the biggest hot and spicy pizza you can make at noon', followed by the response 'Thank you for ordering from Pizza King! OK, so we are getting you the following items: A Large Hot and Spicy pizza at 12:00.

  9. Within the Conversation tab of the tester, scroll down to take a look at the Variable section to see the entity values that were extracted from your input.

    You can expand the nodes for each entity to see details of the entity values that were extracted.

    A screenshot of the Variables section of the tester. It shows nodes for pizzaSize and pizzaTopping. Under each node are leaves for various properties such as originalString and value and their values ('hot and spicy' and 'Hot and Spicy', respectively).

  10. Finally, enter I want to order a veggie pizza at 8:00pm and press Enter.

    This time the topping menu and the delivery time should be skipped, but the pizza size list should be displayed.

  11. Select a pizza size.

    Your order should then be completed.

Congratulations! You have created your first skill and learned key aspects of defining intents, defining entities, designing the conversation flow, and using the tester to evaluate intent resolution and the conversation flow.

Learn More