Conversation patterns represent parts of the flow or sequential order of a conversation. In our agent, such patterns are encoded with the Prolog predicate pattern/1
: pattern(Pattern)
where Pattern
is a list that consists of two elements: the name of the pattern as first element, and another list that represents a sequence of dialogue moves (intents). Some of these dialogue moves are performed by a user (and the corresponding intents should be available in the Dialogflow agent). The other dialogue moves are performed by your agent. Dialogue moves of an agent are also intents, but are specified in the MARBEL agent code, not in the Dialogflow agent. With agent dialogue moves, text what the agent will actually say should be provided. These agent responses are encoded using the predicate text/2
: text(IntentName, "Response Text")
.
Since your agent is supposed to be specialized in conducting conversations aimed at recipe recommendation, you should define a specific set of conversation patterns that such an agent can expect to happen in a conversation in which it assists a user with selecting a recipe. But even such conversations may have many variants and it is important to remember that such conversations can be conducted in many different ways. It is your job to account for as many of those variants as possible by means of the patterns that you create.
We shall walk you through the first patterns and responses. You should mainly work in the patterns.pl
and responses.pl
files, where you should place your (new) patterns and responses.
For this section, you will have to collaborate closely with your Dialogflow and Filter Functions Section team members. This is the case because, as explained above, patterns consist of agent and user intents. User intents are defined in the Dialogflow agent that your team members created. It is important that the labels that you use (your naming conventions) are the same! If you do not know what an intent is, it may be helpful to inspect the Dialogflow material and the agent itself. You may also find it useful to inspect the recipe database.
c10 Greeting Patterns
c10 Greeting with No Introduction
To make a pattern you need to use the Prolog predicate ‘pattern(_)’. This predicate only takes one argument, which should take the form of a prolog list.
We shall start by considering how a greeting could go. When the agent does not introduce itself, the most common greeting pattern would look as follows:
Example:
A: hello
U: hi
In this example conversation, we see A(Agent) greets the user and U(User) greets as well. The first thing in our list within our pattern predicate is always the pattern identification code. In the case of greeting, this is c10. After this identification code, the dialogue moves in the pattern are specified consecutively . Such a move is represented as a two-element list, where the first element is the person speaking ('agent' or ‘user’) and the second element is the agent response label or the user’s intent (which should share a name with an intent on Dialogflow, be sure to communicate with your groupmates). Thus for this greeting, we reach the following rule head:
pattern([c10, [agent, greeting], [user, greeting]])
As mentioned before, this greeting should occur if the agent does not know its name. If the agent knows its name it should introduce itself.
Thus the complete rule should specify this condition, which could be done as follows:
pattern([c10, [agent, greeting], [user, greeting]]) :- not(agentName(_)).
c10 Greeting with Introduction
Pattern C10.1: Opening Self-Identification (Agent)
Example:
A: hello
A: I'm _____
U: hi
This pattern will be quite similar to the one above but should include the predicate 'selfIdentification'. Also, note that the agent must have a name in order to self-identify.
c10 responses.pl
In responses.pl you will see the fact text(greeting, ""). Fill in the “” with a response you want your agent to give as a greeting
Next, we need to build the rule for selfIdentification: text(selfIdentification, Txt) :-
This rule should produce a response that is returned as Txt, and should include the agent's name.
c30 General Capability Check
Your user wants to know what your agent does. Create a pattern for this.
Example:
U: what can you do?
A: At the moment I can ….
You should use the intents/predicates 'checkCapability' (for the user) and 'describeCapability' (for the agent).
In responses.pl find text(describeCapability, ""). and fill in the atom with an appropriate response.
c40 Closing
This is the pattern that closes the conversation between the user and agent, a farewell. In this pattern, our agent should do the ‘sessionCloser’ and say ‘farewell’. (or another phrasing of goodbye that fits to the agent persona your team is designing).
In responses.pl, fill in a final remark from your agent about your program in the session closer and add a farewell.
B Patterns for Repair
A good handling of repair is vital to making your agent robust to misunderstanding. There are a few common ways in which misunderstanding occur’s, that need to be addressed by proper repair patterns.
b12 The agent does not understand the user utterance
Example:
U: chicken soup
A: what do you mean?
Your user has just said something odd or not matching the current situation and so your Dialogflow cannot identify the user's intention and goes to a default fallback intent. In this pattern, your agent can try to come to an understanding by asking for a rephrasing with paraphraseRequest. Add a b12 pattern using the defaultFallback and paraphraseRequest intent.
In responses.pl: paraphrase requests are determined depending on the context of the conversation (specified as the pattern that is currently active). Under the paraphrase request section in responses.pl you will see ‘text/3’, which specifies the active pattern, the agent response name, and what the agent should say. Fill all these in.
b13 Out of Context.
The user said something that Dialogflow can identify with the user’s intent, but your agent is not at a stage where that intent is appropriate.
Example:
A: what recipe would you like to cook?
U: goodbye
A: not sure what that means in this context.
Think about what feature in Prolog you could use to symbolize that there is some intent identified, regardless of what particular intent it is. The agent should respond with a ‘contextMismatch’ response.
Fill in all the contextMismatch responses in response.pl. Like the paraphrasing response, it depends on where the user is in your agent’s program.
b14 User Repetition
The user repeats themselves the user says something that is identified and the agent responds with repeatedUserIntent
In responses.pl fill in a response for the repeatedUserIntent.
b42 Appreciation
Example:
U: Thanks
A: You're welcome.
Your user says thank you and shows some ‘appreciation’ and your agent should respond apropriately with an ‘appreciationReceipt’.
Go into responses.pl and fill in the corresponding text fact.
a50recipeSelect: Selecting a Recipe
Example:
A: Let us find a recipe together.
A: what recipe would you like to cook?
U: I'd like to make pasta (or, simply: pasta)
A: pasta is a great choice!
In the a50recipeSelect pattern, the pattern name is not just a50 but a50recipeSelect please note that when building your pattern. In this conversation your agent should specify its goal with the user, make a recipe inquiry, get a recipe request from the user, the agent should respond to the user's choice and then the agent should insert the next pattern in the conversation which is a50recipeConfirm. To do this you should use the responses specifyGoal, recipeInquiry, and recipeChoiceReceipt. The user intent is called recipeRequest. To insert something into the agent’s agenda you can use the insert().
In responses.pl fill in the corresponding responses for specifying goal and recipe inquiry. recipeChoiceReceipt requires a rule. To respond the agent must find the current recipe, access a list of all recipe IDs using the predicate recipeIDs(), check that the current recipe is a member of the list(better safe than sorry), get the recipes name, return a response using string_concat(“Phrase Part 1”, “Phrase Part 2”, Txt).
a50recipeConfirm: Confirming a Recipe
after the user selects a recipe the agent should confirm the user’s choice. On this page, the user would see recipe information via visual support. We foresee three potential situations for this conversation thus we will make three a50recipeConfirm patterns, one for each scenario. The agent uses recipeCheck to ask if the user can look over the recipe information and ask if they want to cook that recipe. The user could confirm, deny, or show appreciation. Look at Dialogflow for the appropriate Intent identification naming. If the user says they don’t want to choose that recipe we need to go back a step. How would one do this?
Note: the name of this pattern is also a50recipeConfirm instead of just a50.
In responses.pl fill in text ( recipeCheck, “”).
a21noMoreFilters
Example:
A: “What other filters would you like to add”
U: “I do not want more filters “
A: “Ok. Here is a list of recipes” / “Sorry the list is too long still to show”
a21noMoreFilters pattern handles a user request to not add more feature requests, preferences, or requirements. When filtering the recipes the user is not shown the list of filtered recipes until there are only 15(or fewer) recipes. It could be though that the user does not wish to filter recipes further. The user would then use the NoMoreFilters intent. The agent can then allow the user to see the list with grantPicture response, or deny the user with pictureNotGranted. If the agent grants the user’s request the pattern should end with the agent updating its memory with [agent, update(['show'='true'])] this triggers the showing of recipes by updating the agent’s memory.
Note: pattern name = a21noMoreFilters
In responses.pl we have to make two rules for grantPicture and pictureNotGranted. An agent can allow the list of recipe pictures to be shown if the list is less than 100 recipes long. An agent cannot grant the recipes if the list is over 99 recipes long. The recipesFiltered predicate provides a list of the filtered recipes. Fill in the two rules with the corresponding conditions.
Pattern a21featureRequest
Pattern A2.10: Open Request Series
Example:
U: A recipe from Japan.
A: Do you want to add another filter?
U: Recipes that use pasta (penne).
A: What recipe would you like to cook? (assuming only <6 left which are displayed on screen)
U: Curry noodle soup.
A: You're welcome!
There will be 4 variants of feature requesting:
A variant for when a user wants to add a specific feature while already checking a recipe and there are recipes that satisfy all feature requests, i.e. the agent can acknowledge that there are recipes left.
A variant for when a user wants to add a specific filter while already checking a recipe but there are no recipes left that satisfy all feature requests.
A variant for when there are recipes that satisfy all feature requests; automatically remove all feature requests that are conflicting with the new request(s).
A variant for the case whereby adding filters there is no recipe left that satisfies all filters.
Unlike previous patterns, this pattern will be in a rule. Thus you only have to fill in the head of the rule. For all feature request pattern variations, the conversation starts with the user adding a filter. The intent is categorized by Dialogflow under the label addFilter. After the user adds a filter you should have the agent use the predicate removeConflicts(Params) to remove the conflicting filters.
Variant 1: a21featureRequest
In variant 1 of a21featureRequest, while already checking a recipe in the confirmation phase, the user wishes to continue filtering or look at other recipes. In this variant we assume some recipes fit the new filter criteria, thus the agent can acknowledge that there are recipes left. The agent should use the acknowledge filter predicate(look for it). In this variant, if the user is at the checking recipe step and wants to look at other recipes then the agent must re-insert a50recipeSelect into its agenda.
Variant 2: a21featureRequest
A variant for when a user wants to add a specific filter while already checking a recipe but there are no recipes left that satisfy all feature requests. Thus after the user adds a filter, the agent removes conflicts and then finds that there are no recipes left and must inform the user that there are no recipes left that fit the user’s criteria using the predefined predicate in responses.pl. The agent should then ask the user to remove a filter with the predicate featureRemovalRequest. Lastly, in this pattern, since there are no recipes left and the user would already be past the a50recipeSelect step the selection should restart. How would one do this?
In responses.pl you have to fill in an appropriate phrase in text( featureRemovalRequest, “”).
Variant 3: a21featureRequest
This variant is for when the user is not checking a recipe and there are recipes left that could be filtered. The pattern itself is the same as variant 1 except instead of inserting the a50recipeSelect into its agenda(it's unnecessary if not one is not in the checking recipe step) the agent should continue its feature inquiry and ask the user for more filters. This is done with the text featureInquiry rules which you must finish in responses.pl. Note the response should be different based on the number of recipes left:
if the list of recipes is smaller than 16 then your bot should show recipes.
if the list is greater than 890(the size of the database) then the recipes has not been filtered yet.
Variant 4: a21featureRequest
The user is in the a50recipeSelect step and they ask for a filter that results in no recipes. This pattern is the exact same as variant 2 except for one exception. What should be left out?
0 Comments