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 artificial 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 then select Skills.
  3. A description of this image follows.
    Description of the illustration
  4. Click main menu icon again to collapse the side menu.
  5. Click the + New Skill button.

  6. a screenshot of the New Skill button.

    The Create Skill dialog appears.

  7. 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.
  8. Optionally, fill in a one-sentence description (e.g., Skill for ordering from Pizza King)
  9. For the other fields, leave the default values. Note that the Dialog Mode is Visual. Later on in this tutorial, you're going to create a dialog flow, the definition of the skill-user conversation, using the declarative approach of the Visual Flow Designer.

    A description of this image follows.
    Description of the illustration

  10. Click Create.

    The designer will then open on the Intents Description of sample-arch-image.png follows 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).

    A description of this image follows.
    Description of the illustration

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. The order pizza intent is a regular intent, which means that it's mapped to a specific flow that will likely involve one or more exchanges between the user and skill. The cancel pizza and file complaint intents are answer intents, meaning that users who express these intents will get a simple static answer. You are implementing these intents as answer intents in the interest of time. You would not typically implement intents that are related to a process like filing a complaint as answer intents, which are often used for returning answers to FAQs.

Create the Order Pizza Intent

  1. 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.
  6. A description of the illustration follows.
    Description of the illustration
  7. In the Utterances to Add field, paste the examples. Then click Create.

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

Description of the illustration follows.
Description of the illustration

Create the Cancel Pizza Intent

The next two intents are not for a transactional intents like OrderPizza. They are instead answer intents: they return a single answer in response to the resolved user input. Though you typically use answer intents for FAQs, here we'll use them for Cancel Pizza and File Complaint so that we can demonstrate a multi-intent skill in action without first having to implement flows for all of the intents.

  1. Click the + Add Intent button (located at the top left of the page).
  2. Next to the Conversation Name field, click the Edit button, and enter Cancel Pizza.
  3. In the Name field, type CancelPizza.
  4. Click the Edit button in the Answer field. Enter I am sorry to hear this. Let me take your cancellation request.
  5. A description of this illustration follows.
    Description of the illustration
  6. 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
  7. In the Utterances to Add field, select Advanced input mode (if needed), then paste the examples.
  8. 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, enter FileComplaint.
  4. Click the Edit button in the Answer field. Enter I am sorry to hear this. Let me take your complaint details.
  5. Select and copy all of the example phrases 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
  6. In the Utterances to Add field, paste the examples and then click Create.

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

A description of this illustration follows.
Description of the illustration

Note:

If you're stuck, you can import the intents and utterances using PizzaKing-Intents.csv. To import this CSV, click More (located next to +Add Intent), choose Import intents, and then browse to, and select, the PizzaKing-Intents.csv file.

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 the skill to interpret user input based on the utterances that you just added, you need to train to build the intent model.

  1. On the right side of the page, locate and click the Train.
  2. Description of sample-arch-image.png follows
  3. Select Trainer Tm and then click Submit.
    A description of this image follows
    Description of the illustration
    Wait for the training to completeThis is an image of the no training needed icon.. It might take a few minutes.
  4. A description of this illustration follows.
    Description of the illustration

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 link 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 with its Quick Test page open.

  2. A description of the image follows.
    Description of the illustration
  3. In the Language field of the dialog, select English.
  4. In the Utterance field, type I want to order pizza. Then click the Test button (located at the bottom right of the tester) and look at the test results.
  5. A description of the image follows.
    Description of the illustration
  6. Click Reset (located at the bottom right of the tester).
  7. Now scroll back to the top of the dialog, enter I feel like eating some pizza in the Utterance field, and then click Test.

    This should also resolve to the OrderPizza intent. Click Reset.

  8. Now try Cancel my order.

    This should resolve to the CancelPizza intent. Click Reset.

  9. And now try Dude, bring me pizza and see what that resolves to.
  10. Type You are expensive and you still don't deliver on time in the Utterance field and click Test.
    A description of the illustration follows.
    Description of the illustration

    In all likelihood, the FileComplaint intent did not receive the highest score. In the above screenshot, CancelPizza "won". 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.

  11. To remedy this, you're going to add this utterance to the FileComplaint intent:

    Note:

    In these examples, you might get slightly different confidence scores than the ones 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). In real world scenarios, you would be adding a minimum of 80 to 100 utterances per intent.
  12. Retrain the skill with Trainer Tm.
  13. 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.
  14. 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. In cases where the test input doesn't resolve to intents as well as it should, you'll want to augment the intent's utterances to improve the training model.

Note:

You can save test cases in the Utterance Tester to run every time you change the model.

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, select Value list from the Type menu.
  5. Click + Value.
  6. For Value, type small.
  7. For Synonyms, type Personal, then click Enter. Type smallest, and then click Enter again.
  8. Click Create.
  9. A description of this illustration follows.
    Description of the illustration
  10. Following the procedure described in the previous four steps, you are going to add two more values to the PizzaSize entity: one for medium-sized pizza orders, and one for large-sized pizza orders.
    Value Synonym(s)
    medium Middle
    large
    • Big
    • grande
    • biggest
  11. Click Create to complete 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, select Value List from the Type menu
  15. Add separate 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 description of this illustration follows.
    Description of the illustration

Edit Prompts for the Entities

Now let's enter some text to prompt users to enter values that can be matched by these entities.

  1. In the list of entities, select PizzaSize.
  2. Scroll down to the Prompts section.
  3. A description of this illustration follows.
    Description of the illustration
  4. 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? Then click Enter.

    A description of this illustration follows.
    Description of the illustration

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

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.

Create a Composite Bag Entity

In this step, you're going to simplify your development efforts using a composite bag entity, which enables you to manage the three entities that you just created as a consolidated entity. When these entities are controlled by a composite bag, you won't need to create separate references for them when you create the voice of your skill (aka the dialog flow) later on. In addition to unifying your entities, the various composite bag properties enable your skill to match entity values in complex, real-world scenarios that involve erratic user input.

  1. Click + Add Entity.
  2. In the Name field, enter cbePizza.
  3. In the Configuration section, select Composite Bag from the Type menu.
  4. A description of this illustration follows
    Description of the illustration

Add Entities to the Composite Bag

  1. Click cbePizza in the entity list to access its editing page.
  2. To add the entities that are managed by the composite bag, you need to create references for them called bag items. Click + Bag Item.
  3. A description of this illustration follows.
    Description of the illustration
  4. In the Add Bag Item dialog, replace BagItem1 in the Name field with pizzaSize.
  5. Select Entity as the type.
  6. Choose PizzaSize from the Entity Name list.
  7. A description of this illustration follows.
    Description of the illustration
  8. Click Close (located at the upper right).
  9. Repeat these steps to create the Create a bag item for the PizzaTopping entity:
    • Name the item pizzaTopping.
    • Choose PizzaTopping from the Entity Name list.
  10. In addition to enabling users to select the pizza type and size, the skill will also enable them to enter a delivery time. For this, you're going add another entity item to the bag. Unlike the PizzaSize and PizzaType entities that you created from scratch, you're instead going to use the built-in TIME entity, which recognizes various time formats in the user input. To create this item:
    • Click +Bag Item.
    • Enter deliveryTime in the Name field.
    • Select Entity from the Type list.
    • Choose TIME from the Entity Name List.
    • Scroll down the page, then click + Prompt.
    • This is an image of the Add Prompt button.
    • Type When can we deliver that for you (e.g., 4pm)? and then click Enter.
    • A description of this illustration follows.
      Description of the illustration
    • Click Close. When you're done, the Bag Items section of the cbePizza editing page should look like this:
    • A description of this illustration follows.
      Description of the illustration
  11. Click Train.
  12. Select Entity, then click Submit.

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 the composite bag entity 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 cbePizza.
  4. A description of this illustration follows.
    Description of the illustration
  5. Retrain the model with Trainer Tm.

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. Click Reset to clear the input field.
  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.

    The Utterance applies entity labels to the matched terms in the utterance. It also notes that the entities belong to the cbePizza entity.

    A description of the image follows.
    Description of the illustration

    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. The PizzaSize label notes that the "biggest" synonym is matched for the PizzaSize entity. The Time label notes that "noon" is a recognized value.

  5. A description of the illustration follows.
    Description of the illustration

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 a dialog flow for the skill. The dialog flow is a blueprint for the interactions that enable the conversation between the skill and the user. Although you're going to create a single flow in this tutorial, a skill can have multiple flows that support different use cases and functions.

Each flow is made up of one or more states, and each state executes a function: rendering a skill response message, authenticating a user, branching the conversation when certain conditions are met, etc. The Visual Flow Designer provides you with templates for each state.

Create the Order Pizza Flow

Now that you have the OrderPizza intent and the pizza variable, you're ready to start building the dialog flow.

  1. Click Add Flow.
  2. This is an image of the Add Flow button.
  3. In the Create Flow dialog, enter intent.reg.order as the name.
  4. For the description, enter Order pizza flow.
  5. Select OrderPizza from the Intent Name list to create a mapping between the OrderPizza intent and this flow. This mapping instructs the Main Flow to execute this flow when user input resolves to the OrderPizza intent. You can also set intent event mappings like this one within the Main Flow.
  6. .
    A description of this image follows.
    Description of the illustration
  7. Click Create.
  8. Click intent.reg.order in the flow list.
  9. A description of this illustration follows.
    Description of the illustration
  10. In the dialog flow editor, hover over the Start node to display its menu Description of sample-arch-image.png follows. Click the menu then click Add start state.
  11. A description of this illustration follows.
    Description of the illustration
  12. In the Add State dialog, choose Send Message, then enter startOrderPizza as the name and Greeting Message as the description. Then click Insert.
    A description of this illustration follows.
    Description of the illustration

    When you're done, the startOrderPizza state should appear in the canvas with its property editor open to the Component page. (If the property editor isn't open, click the startOrderPizza state.) Note that the editor notes that this flow has an error This is an image of the Error icon. that prevents it from being viable. In this case, it's because this component needs a text message.

    A description of this illustration follows.
    Description of the illustration
  13. Paste the following into the Messages field:
    Ok, let's get that order sorted.
    When you're done, the Order Pizza flow should look like this so far.
  14. A description of this illustration follows.
    Description of the illustration
  15. Hover over the startOrderPizza state to access the menu. Then click Add State.
  16. A description of this illustration follows.
    Description of the illustration
  17. In the Add State dialog, choose Resolve Composite Bag.
  18. Name the state resolve_cbePizza.
  19. Enter Pizza menu as then description. Then click Insert.
  20. A description of this illustration follows.
    Description of the illustration

    When you're done, the resolve_cbePizza state should appear in the canvas with its property editor open to the Components page. Note the next transition line that connects it to the startOrderPizza state.

    A description of this illustration follows.
    Description of the illustration
  21. Like the startOrderPizza state, the resove_cbePizza state is flagged with an error because of an undefined property. For this state, the Component page tells you that you can fix this error by adding a variable reference a composite bag entity, which in this case, is the cbePizza entity. To create this variable, click Create.
  22. Because only the intent.reg.order flow uses this variable, choose Flow Scope Variable. The value held by this variable will persist only until the flow executes. If the other flows in this skill needed this variable, then you would create a skill scope variable instead.
  23. Description of illustration follows
    Description of the illustration
  24. For the name, enter pizza.
  25. For the description, enter Resolves the pizza order.
  26. Select Entity as the variable type, then select cbePizza as the entity name.
  27. Click Apply.
  28. Description of illustration follows
    Description of the illustration
  29. Hover over the resolvePizza state to access the menu, then click Add state.
  30. A description of this illustration follows.
    Description of the illustration
  31. Select Send Message.
  32. Name the state displayOrderConfirmation.
  33. Enter Confirmation message as the description. Then click Insert.
    A description of this illustration follows.
    Description of the illustration
  34. In the Component page of the property inspector, enter the message, which uses ApacheFreeMarker expressions to access the values set for the pizza variable:
    Your ${pizza.value.pizzaSize.value} ${pizza.value.pizzaTopping.value} pizza will be delivered at ${pizza.value.deliveryTime.date?long?number_to_time?string('HH:mm')}
    Description of illustration follows
    Description of the illustration

    When you're done, the flow should look like this:

    A description of this illustration follows.
    Description of the illustration

    If you're stuck, you can import a complete version of the skill for your reference.

Notes on What You Just Did

In this section:

  • You created a variable that references the composite bag entity and a state for resolving this composite bag entity. If you hadn't created the composite bag entity, you would have needed to create separate variables for pizza size, pizza topping, and delivery time that would, in turn, require separate states in the dialog flow.
  • When you created the dialog flow, you mapped it to the OrderPizza intent so that it's executed whenever user input gets resolved to the OrderPizza intent at or above the confidence level.
  • By creating the resolve_cbePizza state, you learned how to leverage a composite bag to create a compact flow. Finally, for the output message in the displayOrderConfirmation state, you added an Apache FreeMarker expression that accessed the values set for the skill-level pizza variable through the skill. property.

Test Your Skill

In this section, you'll test out the intent.reg.order flow, but also test out the conversation flows that are handled automatically: the FileComplaint and CancelPizza answer intents and unresolvedIntent.

Test the Order Pizza Flow

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

    You should see a menu of pizza sizes:

    A description of the illustration follows.
    Description of the illustration

  4. Click the Intent/Q&A view to see how the utterance resolves to the OrderPizza intent.
  5. Click the Conversation view.
    This is an image of the Conversation tab in the Skill Tester.

    Note the dialog flow traversal that routes the request from the Main Flow to the intent.reg.order flow.

  6. Description of illustration follows
    Description of the illustration
  7. Back in the tester, select an option (e.g., small) from the menu.

    A prompt for the pizza topping should appear.

  8. A description of the image follows.
    Description of the illustration
  9. Continue the conversation by selecting a topping (e.g., Veggie).

    A prompt for delivery time should appear.

  10. Enter a delivery time, such as 7:30 p.m.

    You should receive an order confirmation that summarizes the order. In the Conversation Tester, note the dialog flow traversal that routes the request from the Main Flow to the intent.reg.order flow.

    A description of this image follows.
    Description of the illustration
  11. Note that the state traversal rendered in the Conversation view includes the displayOrderConfirmation state. Click Reset.
  12. Description of the illustration follows
    Description of the illustration
  13. Now try entering Dude, can you get me the biggest hot and spicy pizza you can make at noon.

    This time, you should receive the confirmation message immediately.

    A description of this illustration follows.
    Description of the illustration

  14. Within the Conversation tab of the tester, scroll down to take a look at the Variables 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.

  15. A description of this image follows.
    Description of the illustration
  16. Finally, enter I want to order a veggie pizza at 8:00pm.

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

  17. Select a pizza size.

    Your order should then be completed.

Test the Answer Intents

In testing the order pizza intent, you saw how utterance was resolved to the OrderPizza intent, which you mapped to the intent.reg.order flow. Now, you're going to test out the FileComplaint and CancelPizza answer intents which are handled automatically. You'll also test out unresolvedIntent, the flow for handling the user input that can't be resolved to any of the intents that you defined.

  1. In the Utterance field, enter I want to cancel my order.

    The skill should respond with a message regarding pizza cancelation. Because the Main flow alone handles this intent (and the other answer intents that you'll be testing in the section), only the Main flow gets rendered in the Conversation view.

    Description of the illustration follows
    Description of the illustration

    And, in the Intent/Q&A view, you should see that the CancelPizza intent is matched.

  2. A description of the illustration follows.
    Description of the illustration
  3. Click Reset
  4. In the Utterance field, enter I want to speak to your manager and then press Enter.
    A description of the image follows.
    Description of the illustration

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

  5. Now let's try a more random utterance.

    Click Reset.
  6. In the Utterance field, enter Can you get me a radio taxi now?
    A description of this image follows.
    Description of the illustration

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

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

Learn More