copyright | lastupdated | subcollection | ||
---|---|---|---|---|
|
2019-05-10 |
assistant |
{:shortdesc: .shortdesc} {:new_window: target="_blank"} {:deprecated: .deprecated} {:important: .important} {:note: .note} {:tip: .tip} {:pre: .pre} {:codeblock: .codeblock} {:screen: .screen} {:javascript: .ph data-hd-programlang='javascript'} {:java: .ph data-hd-programlang='java'} {:python: .ph data-hd-programlang='python'} {:swift: .ph data-hd-programlang='swift'} {:gif: data-image-type='gif'}
{: #tutorial}
In this tutorial, you will use the {{site.data.keyword.conversationshort}} service to create a dialog for an assistant that helps users with inquiries about a fictitious restaurant called Truck Stop Gourmand. {: shortdesc}
{: #tutorial-objectives}
By the time you finish the tutorial, you will understand how to:
- Plan a dialog
- Define custom intents
- Add dialog nodes that can handle your intents
- Add entities to make your responses more specific
- Add a pattern entity, and use it in the dialog to find patterns in user input
- Set and reference context variables
{: #tutorial-duration}
This tutorial will take approximately 2 to 3 hours to complete.
{: #tutorial-prereqs}
Before you begin, complete the Getting Started tutorial.
You will use the dialog skill that you created, and add nodes to the simple dialog that you built as part of the getting started exercise.
{: #tutorial-plan}
You are building an assistant for a restaurant named Truck Stop Gourmand that has one location and a thriving cake-baking business. You want the simple assistant to answer user questions about the restaurant, its menu, and to cancel customer cake orders. Therefore, you need to create intents that handle inquiries related to the following subjects:
- Restaurant information
- Menu details
- Order cancellations
You'll start by creating intents that represent these subjects, and then build a dialog that responds to user questions about them.
{: #tutorial-add-about-intent}
Add an intent that recognizes when customers ask for details about the restaurant itself. An intent is the purpose or goal expressed in user input. The #General_About_You
intent that is provided with the General content catalog serves a similar function, but its user examples are designed to focus on queries about the assistant as opposed to the business that is using the assistant to help its customers. So, you will add your own intent.
{: #tutorial-add-about-restaurant}
-
From the Intents tab, click Create intent.
-
Enter
about_restaurant
in the Intent name field, and then click Create intent. -
Add the following user examples:
Tell me about the restaurant i want to know about you who are the restaurant owners and what is their philosophy? What's your story? Where do you source your produce from? Who is your head chef and what is the chef's background? How many locations do you have? do you cater or host functions on site? Do you deliver? Are you open for breakfast?
{: screen}
-
Click the Close icon to finish adding the
#about_restaurant
intent.
You added an intent and provided examples of utterances that real users might enter to trigger this intent.
{: #tutorial-trigger-about-intent}
Add a dialog node that recognizes when the user input maps to the intent that you created in the previous step, meaning its condition checks whether your assistant recognized the #about_restaurant
intent from the user input.
-
Click the Dialog tab.
-
Find the
#General_Greetings
node in the dialog tree.You will add a node that checks for questions about the restaurant below this initial greeting node to reflect the flow you might expect to encounter in a normal conversation. For example,
Hello.
thenTell me about yourself.
-
Click the More icon on the
#General_Greetings
node, and then select Add node below. -
Start to type
#about_restaurant
into the If assistant recognizes field of this node. Then select the#about_restaurant
option. -
Add the following text as the response.
To copy the text, click the copy icon that is associated with the text block :
```
Truck Stop Gourmand is the brain child of Gloria and Fred Smith. What started out as a food truck in 2004 has expanded into a thriving restaurant. We now have one brick and mortar restaurant in downtown Portland. The bigger kitchen brought with it new chefs, but each one is faithful to the philosophy that made the Smith food truck so popular to begin with: deliver fresh, local produce in inventive and delicious ways. Join us for lunch or dinner seven days a week. Or order a cake from our bakery.
```
{: codeblock}
-
Let's add an image to the response also.
Click Add response type. Select Image from the drop-down list. In the Image source field, add
https://www.ibmlearningcenter.com/wp-content/uploads/2018/02/IBM-Learning-Center-Food4.jpg
. -
Move the image response type up, so it is displayed in the response before the text is displayed. Click the Move up arrow to reorder the two response types.
{: #tutorial-test-about-intent}
Test the intent by checking whether user utterances that are similar to, but not exactly the same as, the examples you added to the training data have successfully trained your assistant to recognize input with an #about_restaurant
intent.
-
Enter,
I want to learn more about your restaurant.
Your assistant indicates that the
#about_restaurant
intent is recognized, and returns a response with the image and text that you specified for the dialog node.
Congratulations! You have added a custom intent, and a dialog node that knows how to handle it.
The #about_restaurant
intent is designed to recognize a variety of general questions about the restaurant. You added a single node to capture such questions. The response is long, but it is a single statement that can potentially answer questions about all of the following topics:
- The restaurant owners
- The restaurant history
- The philosophy
- The number of sites
- The days of operation
- The meals served
- The fact that the restaurant bakes cakes to order
For general, low-hanging fruit types of questions, a single, general answer is suitable.
{: #tutorial-menu}
A key question from potential restaurant customers is about the menu. The Truck Stop Gourmand restaurant changes the menu daily. In addition to its standard menu, it has vegetarian and cake shop menus. When a user asks about the menu, the dialog needs to find out which menu to share, and then provide a hyperlink to the menu that is kept up to date daily on the restaurant's website. You never want to hard-code information into a dialog node if that information changes regularly.
{: #tutorial-add-menu-intent}
-
Click the Intents tab.
-
Click Create intent.
-
Enter
menu
in the Intent name field, and then click Create intent. -
Add the following user examples:
I want to see a menu What do you have for food? Are there any specials today? where can i find out about your cuisine? What dishes do you have? What are the choices for appetizers? do you serve desserts? What is the price range of your meals? How much does a typical dish cost? tell me the entree choices Do you offer a prix fixe option?
{: screen}
{: #tutorial-trigger-menu-intent}
Add a dialog node that recognizes when the user input maps to the intent that you created in the previous step, meaning its condition checks whether your assistant recognized the #menu
intent from the user input.
-
Click the Dialog tab.
-
Find the
#about_restaurant
node in the dialog tree.You will add a node that checks for questions about the menu below this node.
-
Click the More icon on the
#about_restaurant
node, and then select Add node below. -
Start to type
#menu
into the If assistant recognizes field of this node. Then select the#menu
option. -
Add the following text as the response:
In keeping with our commitment to giving you only fresh local ingredients, our menu changes daily to accommodate the produce we pick up in the morning. You can find today's menu on our website.
-
Add an option response type that provides a list of options for the user to choose from. In this case, the list of options includes the different versions of the menu that are available.
Click Add response type. Select Option from the drop-down list.
-
In the Title field, add Which menu do you want to see?
-
Click Add option.
-
In the List label field, add
Standard
. The text you add as the label is displayed in the response to the user as a selectable option. -
In the Value field, add
standard menu
. The text you specify as the value is what gets sent to your assistant as new user input when a user chooses this option from the list, and clicks it. -
Repeat the previous two steps to add label and value information for the remaining menu types:
Option response type details List label Value Vegetarian vegetarian menu Cake shop cake shop menu
{: #tutorial-add-menu-entity}
To recognize the different types of menus that customers indicate they want to see, you will add a @menu
entity. Entities represent a class of object or a data type that is relevant to a user's purpose. By checking for the presence of specific entities in the user input, you can add more responses, each one tailored to address a distinct user request. In this case, you will add a @menu
entity that can distinguish among different menu types.
-
Click the Entities tab.
-
Click Create entity.
-
Enter
menu
into the entity name field. -
Click Create entity.
-
Add
standard
to the Value name field, and then addstandard menu
to the Synonyms field, and press Enter. -
Add the following additional synonyms:
- bill of fare
- cuisine
- carte du jour
-
Click Add value to add the
@menu:standard
value. -
Add
vegetarian
to the Value name field, and then addvegetarian menu
to the Synonyms field, and press Enter. -
Click Show recommendations, and then click the checkbox for vegan diet.
-
Click Add selected.
-
Click the empty Add synonym field, and then add these additional synonyms:
- vegan
- plants-only
-
Click Add value to add the
@menu:vegetarian
value. -
Add
cake
to the Value name field, and then addcake menu
to the Synonyms field, and press Enter. -
Add the following additional synonyms:
- cake shop menu
- dessert menu
- bakery offerings
-
Click Add value to add the
@menu:cake
value.
{: #tutorial-trigger-menu-entity}
In this step, you will add child nodes to the dialog node that checks for the #menu
intent. Each child node will show a different response depending on the @menu
entity type the user chooses from the options list.
-
Click the Dialog tab.
-
Find the
#menu
node in the dialog tree.You will add a child node to handle each menu type option that you added to the
#menu
node. -
Click the More icon on the
#menu
node, and then select Add child node. -
Start to type
@menu:standard
into the If assistant recognizes field of this node. Then select the@menu:standard
option. -
Add the following message in the response text field,
To see our menu, go to the <a href="https://www.example.com/menu.html" target="blank">menu</a> page on our website.
-
Click the More icon on the
@menu:standard
node, and then select Add node below. -
Start to type
@menu:vegetarian
into the If assistant recognizes field of this node. Then select the@menu:vegetarian
option. -
Add the following message in the response text field,
To see our vegetarian menu, go to the <a href="https://www.example.com/vegetarian-menu.html" target="blank">vegetarian menu</a> page on our website.
-
Click the More icon on the
@menu:vegetarian
node, and then select Add node below. -
Start to type
@menu:cake
into the If assistant recognizes field of this node. Then select the@menu:cake
option. -
Add the following message in the response text field,
To see our cake shop menu, go to the <a href="https://www.example.com/menu.html" target="blank">cake shop menu</a> page on our website.
-
The standard menu is likely to be requested most often, so move it to the bottom of the child nodes list. Placing it last can help prevent it from being triggered accidentally when someone asks for a specialty menu instead the standard menu.
Click the More icon on the
@menu:standard
node, and then select Move. -
Select the
@menu:cake
node, and then choose Below node.
You have added nodes that recognize user requests for menu details. Your response informs the user that there are three types of menus available, and asks them to choose one. When the user chooses a menu type, a response is displayed that provides a hypertext link to a web page with the requested menu details.
{: #tutorial-test-menu-options-intent}
Test the dialog nodes that you added to recognize menu questions.
-
Enter,
What type of food do you serve?
Your assistant indicates that the
#menu
intent is recognized, and displays the list of menu options for the user to choose from. -
Click the
Cake shop
option.Your assistant recognizes the
#menu
intent and@menu:cake
entity reference, and displays the response,To see our cake shop menu, go to the cake shop page on our website.
-
Click the cake shop hyperlink in the response.
A new web browser page opens and displays the example.com website.
-
Close the example.com web page.
Well done. You have succesfully added an intent and entity that can recognize user requests for menu details, and can direct users to the appropriate menu.
The #menu
intent represents a common, key need of potential restaurant customers. Due to its importance and popularity, you added a more complex section to the dialog to address it well.
{: #tutorial-manage-orders}
Customers place orders in person, over the phone, or by using the order form on the website. After the order is placed, users can cancel the order through the virtual assistant. First, define an entity that can recognize order numbers. Then, add an intent that recognizes when users want to cancel a cake order.
{: tutorial-add-pattern-entity}
You want the assistant to recognize order numbers, so you will create a pattern entity to recognize the unique format that the restaurant uses to identify its orders. The syntax of order numbers used by the restaurant's bakery is 2 upper-case letters followed by 5 numbers. For example, YR34663
. Add an entity that can recognize this character pattern.
-
Click the Entities tab.
-
Click Create entity.
-
Enter
order_number
into the entity name field. -
Click Create entity.
-
Add
order_syntax
to the Value name field, and then click the down arrow next to Synonyms to change the type to Patterns. -
Add the following regular expression to the Pattern field:
[A-Z]{2}\d{5}
-
Click Add value.
-
Click the Close icon to finish adding the
@order_number
entity.
{: #tutorial-cancel-order-intent}
-
Click the Intents tab.
-
Click Create intent.
-
Enter
cancel_order
in the Intent name field, and then click Create intent. -
Add the following user examples:
I want to cancel my cake order I need to cancel an order I just placed Can I cancel my cake order? I'd like to cancel my order There's been a change. I need to cancel my bakery order. please cancel the birthday cake order I placed last week The party theme changed; we don't need a cake anymore that order i placed, i need to cancel it.
{: screen}
-
Click the Close icon to finish adding the
#cancel_order
intent.
{: #tutorial-yes-intent}
Before you perform an action on the user's behalf, you must get confirmation that you are taking the proper action. Add a #yes intent to the dialog that can recognize when a user agrees with what your assistant is proposing.
-
Click the Intents tab.
-
Click Create intent.
-
Enter
yes
in the Intent name field, and then click Create intent. -
Add the following user examples:
Yes Correct Please do. You've got it right. Please do that. that is correct. That's right yeah Yup Yes, I'd like to go ahead with that.
{: screen}
{: #tutorial-cancel-order-dialog}
Now, add a dialog node that can handle requests to cancel a cake order.
-
Click the Dialog tab.
-
Find the
#menu
node. Click the More icon on the#menu
node, and then select Add node below. -
Start to type
#cancel_order
into the If assistant recognizes field of this node. Then select the#cancel_order
option. -
Add the following message in the response text field:
If the pickup time is more than 48 hours from now, you can cancel your order.
{: codeblock}
Before you can actually cancel the order, you need to know the order number. The user might specify the order number in the original request. So, to avoid asking for the order number again, check for a number with the order number pattern in the original input. To do so, define a context variable that would save the order number if it is specified.
-
You define a context variable in the context editor. From the response section of the node, click the More icon, and then select Open context editor.
-
Enter the following context variable name and value pair:
Order number context variable details Variable Value $ordernumber The context variable value (
<? @order_number.literal ?>
) is a SpEL expression that captures the number that the user specifies that matches the pattern defined by the @order_number pattern entity. It saves it to the$ordernumber
variable. -
Now, add child nodes that either ask for the order number or get confirmation from the user that she wants to cancel an order with the detected order number.
-
Click the More icon on the
#cancel_order
node, and then select Add child node. -
Add a label to the node to distinguish it from other child nodes you will be adding. In the name field, add
Ask for order number
. Typetrue
into the If assistant recognizes field of this node. -
Add the following message in the response text field:
What is the order number?
{: codeblock}
-
Now, add another child node that informs the user that you are canceling the order.
-
Click the More icon on the
Ask for order number
node, and then select Add child node. -
Type
@order_number
into the If assistant recognizes field of this node. -
Open the context editor. Click the More icon, and select Open context editor.
-
Enter the following context variable name and value pair:
Order number context variable details Variable Value $ordernumber The context variable value (
<? @order_number.literal ?>
) is a SpEL expression that captures the number that the user specifies that matches the pattern defined by the @order_number pattern entity. It saves it to the$ordernumber
variable. -
Add the following message in the response text field:
Ok. The order $ordernumber is canceled. We hope we get the opportunity to bake a cake for you sometime soon.
{: codeblock}
-
Add another node to capture the case where a user provides a number, but it is not a valid order number. Click the More icon on the
@order_number
node, and then select Add node below. -
Type
true
into the If assistant recognizes field of this node. -
Add the following message in the response text field:
I need the order number to cancel the order for you. If you don't know the order number, please call us at 958-234-3456 to cancel over the phone.
{: codeblock}
-
Add a node below the initial order cancellation request node that responds in the case where the user provides the order number in the initial request, so you don't have to ask for it again. Click the More icon on the
#cancel_order
node, and then select Add child node. -
Add a label to the node to distinguish it from other child nodes. In the name field, add
Number provided
. Type@order_number
into the If assistant recognizes field of this node. -
Add the following message in the response text field:
Just to confirm, you want to cancel order $ordernumber?
{: codeblock}
-
You must add child nodes that check for the user's response to your confirmation question.
-
Click the More icon on the
Number provided
node, and then select Add child node. -
Type
#yes
into the If assistant recognizes field of this node. -
Add the following message in the response text field:
Ok. The order $ordernumber is canceled. We hope we get the opportunity to bake a cake for you sometime soon.
{: codeblock}
-
Click the More icon on the
#yes
node, and then select Add node below. -
Type
true
into the If assistant recognizes field of this node.Do not add a response. Instead, you will redirect users to the branch that asks for the order number details that you created earlier.
-
In the And finally section, choose Jump to.
-
Select the Ask for order number node's condition.
-
Move the Number provided node above the Ask for order number node. Click the More icon on the
Number provided
node, and then select Move. Select the Ask for order number node, and then click Above node. -
Force the conversation to evaluate the child nodes under the
#cancel_order
node at run time. Click to open the#cancel_order
node in the edit view, and then, in theAnd finally
section, selectSkip user input
.
{: #tutorial-test-cancel-order}
Test whether your assistant can recognize character patterns that match the pattern used for product order numbers in user input.
-
Enter,
i want to cancel my order number TW12345.
Your assistant recognizes both the
#cancel_order
intent and the@order_number
entity. It responds with,If the pickup time is more than 48 hours from now, you can cancel your order. Just to confirm, you want to cancel order TW12345?
-
Enter,
Yes
.Your assistant recognizes the
#yes
intent and responds with,Ok. The order TW12345 is canceled. We hope we get the opportunity to bake a cake for you sometime soon.
Now, try it when you don't know the order number.
-
Click Clear in the "Try it out" pane to start over. Enter,
I want to cancel my order.
Your assistant recognizes the
#cancel_order
intent, and responds with,If the pickup time is more than 48 hours from now, you can cancel your order. What is the order number?
-
Enter,
I don't know.
Your assistant responds with,
I need the order number to cancel the order for you. If you don't know the order number, please call us at 958-234-3456 to cancel over the phone.
{: #tutorial-clarify-order-number format}
If you do more testing, you might find that the dialog isn't very helpful in scenarios where the user does not remember the order number format. The user might include only the numbers or the letters too, but forget that they are meant to be uppercase. So, it would be a nice touch to give them a hint in such cases, right? If you want to be kind, add another node to the dialog tree that checks for numbers in the user input.
-
Find the
@order_number
node that is a child of the Ask order number node. -
Click the More icon on the
@order_number
node, and then select Add node below. -
In the condition field, add
input.text.find('\d')
, which is a SpEL expression that says if you find one or more numbers in the user input, trigger this response. -
In the text response field, add the following response:
The correct format for our order numbers is AAnnnnn. The A's represents 2 uppercase letters, and the n's represent 5 numbers. Do you have an order number in that format?
{: codeblock}
-
Click the More icon on the
input.text.find('\d')
node, and then select Add child node. -
Type
true
into the If assistant recognizes field of this node. -
Enable conditional responses by clicking Customize, scrolling down, and then switching the Multiple responses toggle to On.
-
Click Apply.
-
In the newly-added If assistant recognizes field, type
@order_number
, and in the Respond with field, type:Ok. The order $ordernumber is canceled. We hope we get the opportunity to bake a cake for you sometime soon.
{: codeblock}
-
Click Add response.
-
In the If assistant recognizes field, type
true
, and in the Respond with field, type:I need the order number to cancel the order for you. If you don't know the order number, please call us at 958-234-3456 to cancel over the phone.
{: codeblock}
Now, when you test, you can provide a set of number or a mix of numbers and text as input, and the dialog reminds you of the correct order number format. You have successfully tested your dialog, found a weakness in it, and corrected it.
Another way you can address this type of scenario is to add a node with slots. See the Adding a node with slots to a dialog tutorial to learn more about using slots. {:tip}
{: #tutorial-get-username}
If the user shows interest in the bot itself, you want the virtual assistant to recognize that curiosity and engage with the user in a more personal way. You might remember the #General_About_You
intent, which is provided with the General content catalog, that we considered using earlier, before you added your own custom #about_restaurant
intent. It is built to recognize just such questions from the user. Add a node that conditions on this intent. In your response, you can ask for the user's name and save it to a $username variable that you can use elsewhere in the dialog, if available.
First, you need to make sure your assistant will recognize a name if the user provides one. To do so, enable the @sys-person
entity, which is designed to recognize common first and last names (in English).
{: #tutorial-add-person-entity}
Your assistant provides a number of system entities, which are common entities that you can use for any application.
-
Click the Entities tab, and then click System entities.
-
Find the
@sys-person
entity toggle, and then switch it On.
{: #tutorial-add-about-you-node}
Now, add a dialog node that can recognize the user's interest in the bot, and respond.
-
Click the Dialog tab.
-
Find the
Welcome
node in the dialog tree. -
Click the More icon on the
Welcome
node, and then select Add node below. -
Start to type
#General_About_You
into the If assistant recognizes field of this node. Then select the#General_About_You
option. -
Add the following message in the response text field:
I am a virtual assistant that is designed to answer your questions about the Truck Stop Gourmand restaurant. What's your name?
{: codeblock}
-
Click the More icon on the
#General_About_You
node, and then select Add child node. -
Start to type
@sys-person
into the If assistant recognizes field of this node. Then select the@sys-person
option. -
Add the following message in the response text field:
Hello, <? @sys-person.literal ?>! It's lovely to meet you. How can I help you today?
{: codeblock}
-
To capture the name that the user provides, add a context variable to the node. Click the More icon, and select Open context editor.
-
Enter the following context variable name and value pair:
User name context variable details Variable Value $username The context variable value (
<? @sys-person.literal ?>
) is a SpEL expression that captures the user name as it is specified by the user, and then saves it to the$username
context variable. -
Click the More icon on the
@sys-person
node, and then select Add node below.You will add a node to capture user responses that do not include a name. If the user chooses not to share it, you want the bot to keep the conversation going anyhow.
-
Type
true
into the If assistant recognizes field of this node. -
Add the following message in the response text field:
How can I help you today?
{: codeblock}
If, at run time, the user triggers this node and provides a name, then you will know the user's name. If you know it, you should use it! Add conditional responses to the greeting dialog node you added previously to include a conditional response that uses the user name, if it is known.
{: #tutorial-add-username-to-greeting}
If you know the user's name, you should include it in your greeting message. To do so, add conditional responses, and include a variation of the greeting that includes the user's name.
-
Find the
#General_Greetings
node in the dialog tree, and click to open it in the edit view. -
Click Customize, scroll down, and then switch the Multiple responses toggle to On.
-
Click Apply.
-
Click Add response.
-
In the If assistant recognizes field, type
$username
, and in the Respond with field, add a new response:Good day to you, $username!
{: codeblock}
-
Click the up arrow for response number 2 to move it so it is listed before response number 1 (
Good day to you!
).
{: #tutorial-test-personalize}
Test whether your assistant can recognize and save a user's name, and then refer to the user by it later.
-
Click Clear to restart the conversation session.
-
Enter,
Who are you?
Your assistant recognizes the
#General_About_You
intent. Its response ends with the question,What's your name?
-
Enter,
I am Jane Doe.
Your assistant recognizes
Jane Doe
as an@sys-person
entity mention. It comments on your name, and then asks how it can help you. -
Enter,
Hello.
Your assistant recognizes the
#General_Greetings
intent and says,Good day to you, Jane Doe!
It uses the conditional response that includes the user's name because the$username
context variable contains a value at the time that the greeting node is triggered.
You can add a conditional response that conditions on and includes the user's name for any other responses where personalization would add value to the conversation.
{: #tutorial-integrate-assistant}
Now that you have built a more sophisticated version of the assistant, return to the public web page that you deployed as part of the previous tutorial, and then test the new capabilities you added.
-
Open the assistant.
-
From the Integrations area, click Preview Link.
-
Click the URL that is displayed on the page.
The page opens in a new tab.
-
Repeat a few of the test utterances that you submited to the "Try it out" pane to see how the assistant behaves in a real integration.
Unlike when you send test utterances to your assistant from the "Try it out" pane, standard usage charges apply to API calls that result from utterances that are submited to the chat widget. {: note}
{: #tutorial-deploy}
Now that you have built and tested your dialog skill, you can share it with customers. Deploy your skill by first connecting it to an assistant, and then deploying the assistant. There are several ways you can do this. See Adding integrations for more details.