Dialogflow
The previous capability made the agent select a random recipe name from the recipe database and recommend this to a user. We now want to allow the user to request a specific recipe by mentioning the name of a recipe. In this case, the conversational agent should be able to understand that a user is mentioning a specific recipe’s name. In other words, our Dialogflow agent needs to be able to recognize all the names of all the recipes in the recipe database.
Recipe entity
The way to do that is by creating an entity for recipes in the Dialogflow agent. For your convenience, we have already provided you with a JSON file that you can use to upload a recipe entity that contains all recipe names (as there are a lot of these names).
Locate the
recipe.json
file in your repository and upload it to your Dialogflow agent.
For more information on entities and how to upload these, please read the Dialogflow: Creating Intents and Entities page.
After you have uploaded the JSON file, you should see a custom entity @recipe listed on the Entities page. Click on the recipe entity. A long list of entries should appear. On the left-hand side, you see the list of all recipe titles in the recipe database. Compare the items in Dialogflow with the recipe names in the recipe_database.pl
file. You should note that these titles or names are exactly the same (to the letter, literally!). This is very important, as even a minor difference in spelling would cause the agent to have problems to match a recipe mentioned by a user (as recognized by Dialogflow) with a recipe name in the recipe database. The list on the left-hand side of the recipe entity in Dialogflow consists of the so-called reference value of each entity entry.
Note also the checkbox Define synonyms that is checked at the top of the page, and hoover over the question mark next to it. By checking this box, all synonyms that are defined for a reference value will be mapped to that reference value by Dialogflow. The list of phrases on the right-hand side consists of the synonyms that are defined for each entry. Adding these synonyms allows for some flexibility on the part of the user who now can also say these (often shorter) synonym phrases instead of the full titles of a recipe. Of course, this is a nice feature, as we can hardly require a user to know the exact titles of recipes in our database. Adding synonyms, however, does require some care, as introducing the same phrase as a synonym for two different reference values will lead to problems. We have, for example, a recipe called artichoke and pine nut pasta (recipe 36), a recipe called pasta frittata (recipe 38), and a recipe called creamy quorn sausage and broccoli pasta (recipe 93) in the recipe database. And, as you can imagine, there are more recipes with pasta in their title in the database. Of course, we cannot add pasta as a synonym for all of these recipes. First, pasta can also be an ingredient and as such appears in many more other recipes. It also does not make sense to abbreviate pasta frittata to pasta as an essential part of the meaning is lost by doing so (check the synonyms for this recipe). Using pine nut pasta as a synonym for artichoke and pine nut pasta, however, might make sense (as you can check by searching the recipe_database.pl
file, there are no other recipes with pine nut pasta in their title). But what kind of synonyms can we introduce for creamy quorn sausage and broccoli pasta? It seems that we can perhaps also use broccoli pasta as a synonym for this recipe. But check the synonyms that are actually provided for this recipe. You will find the most obvious shorthand synonym phrase for the recipe is missing. In other words, there may still be a lot that can be improved here, but putting in the manual work needed for that, however, does not seem to be worth it... Right now, the lesson to be learned here is that making things work perfect in natural language understanding is very difficult if not impossible (at least in some cases).
Recipe request intent
The next thing to do is make the Dialogflow agent respond to user utterances that can be understood as requests for a specific recipe. An obvious example utterance would be “I'd like to make a pasta frittata”. We thus should create a new intent for classifying such utterances as a request for specific recipe and to make sure the mentioned recipe is extracted from the utterance as an entity. The main difference with before thus is to now also add entity recognition to our intent definition. Otherwise, the steps are the same again:
Go to the Dialogflow Console and create a new intent. Call this intent recipeRequest to suggest that utterances asking for a specific recipe are example phrases that should be classified as this intent. The agent assumes that the intent is called recipeRequest and uses this label also already in the
dialog_update.mod2g
file so do not use another label.Add Training Phrases: Add a (large) variety of phrases that users might use when requesting a specific recipe. Example phrases could include, for example, "I'll have the grilled asparagus please", "Can I try the butter chicken", or "I'd like to make goat's cheese toast". When you enter these example phrases as Training phrase, you will see that Dialogflow automatically recognizes the recipe entity and the associated recipe title value in these phrases and marks these phrases.
We recommend that you add quite a few training phrases that vary in shape and form (you should add at least >10, but much more would be much better). That will provide a user with some flexibility of how they can express themselves. By adding only a few very specific phrases, it will be hard for Dialogflow to recognize variants of phrases that a user could use to ask for a specific recipe. It may, however, also be hard for you to come up with all these variants. But as before, you do not need to craft them by hand but should feel free to use any other tool you can think of for creating varied training phrases (e.g., Google, ChatGPT, etc.).As before, don’t forget to make sure the box above the table in the Action and parameters section is filled in with the name of your intent! There is more work to be done here this time, as a
recipeRequest
intent should be recognized only when a recipe title (a recipe entity) can be extracted from the user’s utterance too. In other words, we should make sure the recipe entity is required for this intent. The intent cannot be complete without it. You should already see the recipe entity listed in the section. You should also make sure that the parameter linked to the recipe entity is named recipe too. Finally, you should check the Required checkbox so that your Dialogflow agent knows that when it recognizes therecipeRequest
intent, it also needs to be able to extract a recipe name from the transcription of what the user said.
Don’t forget to press SAVE!
Test that your intent is correctly recognizing user requests by using the microphone button in the Dialogflow test console (you can also enter phrases in the test console by typing). Try various phrases and check whether what you say is classified as your recipe request intent.
Note that just copy-pasting the training phrases you entered for the intent into the test console is not that useful (you will find that Dialogflow will correctly classify these with a confidence score of 1 by inspecting the Diagnostic Info). But you can use these phrases to check that ASR is working by using the microphone button in the test console and talking to the agent.
Prolog and Patterns
Now that we have introduced a new intent for asking for a specific recipe by its name, we can add a new variant of the a50recipeSelect
pattern that we introduced already earlier for the Capability 2: Request a Recommendation. To illustrate it, we repeat the example of the type of pattern that we have in mind:
A: What recipe would you like to cook?
U: I'd like to make an artichoke and pine nut pasta.
A: Artichoke and pine nut pasta is a great choice!
To specify this pattern, it is useful to identify the type of each dialog move that is part of it. Clearly, the second dialog move of the user is the recipeRequest
intent that we just defined above in the Dialogflow section. The first agent move is the same as the first dialog move in our previous a50recipeSelect
pattern variant, a specifyGoal
intent (cf. Capability 2: Request a Recommendation). The third dialog move of the agent is a new type of intent, and we suggest we call this intent recipeChoiceReceipt
. Finally, as before, the agent should insert the pattern a50recipeConfirm
into the agenda of the agent to move the conversation onto the next phase where the user can (dis)confirm that it likes the recipe that has been selected. Recall that you can insert something into the agent's agenda by means of the special insert(PatternID)
action that can be added as a special kind of actor-intent pair in a pattern. Now you should add the variant of the pattern to the patterns.pl
file (as indicated in a comment in that file too).
The new agent intent label recipeChoiceReceipt
that we introduced also needs to be added to the responses.pl
file. To specify a phrase or response the agent can use when performing the intent, you should take into account that the name of the recipe should be part of the response (see the example again: Artichoke and pine nut pasta is a great choice!). As before, defining the response therefore requires a rule to define the text(recipeChoiceReceipt, Txt)
clause. The idea is that the agent first finds the current recipe stored in its conversational memory, retrieves the recipe's name, and finally constructs a response using the template string_concat(PhrasePart1, PhrasePart2, Txt)
where you need to replace the PhrasePart1
and PhrasePart2
arguments.
Visuals
Nothing we ask you to do here for this capability. It’s up to you.
Test it Out
When you finished implementing this capability and you Run your Conversational Agent, you should be able to conduct the following conversational interaction and go through the following dialog moves:
After the Start page, when you click the Start button,
You should see the welcoming page.
The agent starts by greeting you by self-identifying it (moves
greeting
,selfIdentification
).You should be able to greet the agent (
greeting
).You should see the recipe recommendation page.
The agent asks you what kind of recipe you would like (
specifyGoal
).You should be able to say that you want a specific recipe (
recipeRequest
); Ask your agent for a specific recipe you find in the recipe database by name. An example would be “crispy pork spring rolls”.The agent then should acknowledge this choice (
recipeChoiceReceipt
).You should see the recipe confirmation page with the recipe you specified in step 6.
You can also check whether the intent recognition works. In your Dialogflow agent in the Training Tool you should be able to see a conversation listed with a greeting
and recipeRequest
intent. You also should be able to see the SIC server received those intents with transcripts from Dialogflow in the terminal where you started the server.
As we noted already in the Test it Out section for Capability 1: Greet, and Self-Identify, Dialogflow may not be able to recognize what you are saying correctly (ASR failure), and, as a result, the agent may receive a default fallback intent and get stuck because the agent cannot handle these yet (which we will fix when implementing the next Capability 4: Handling Unexpected Intents).
For now (and this will be useful throughout the project), you can also avoid ASR failures by adding and using a chatbox to a page in which you can type a response (instead of using the microphone). We have already provided you with the option to add a chatbox to the footer of pages, but the code is still commented out (check the code for the footer/1
predicate in the html.pl
file.