Dialogflow - Can 1 follow-up intent has more than 1 parent - dialogflow-es

Can Follow-up intent has more than 1 parent?
For example, my program will be like
from(A)
if(A.response == yes){
go_to_intent(B)
go_to_intent(C) //A-->B-->C
}
else
go_to_intent_(C) //A-->C
which can be seen that both B and A are the possible parents of C.
So how to set C as the follow-up intent of both A and B?

In short - no. You're not supposed to "go to" Intents - Intents represent user inputs under different conditions.
So Using your example, the user has said or done something that matches Intent A. As a response, your agent asks a question.
If they answer "yes", then it should match Intent B.
If not, then it will match Intent C.
Now... what you do in your webhook fulfillment in Intents A, B, and C is a completely different story. You're allowed to call the same functions for B and C and just return different messages from each.
Intents aren't about what your agent does - it is about what your user does.
Update
Based on your example in the comments, I want to repeat - don't think of Intents as what your agent is saying, think of it as what the user is saying or doing.
Based on this, I would rephrase your Intents this way:
When the user starts the action, this triggers Intent A. In the handler for Intent A:
Set the context "ask-city"
Send the message "Do you want to provide the city?"
When the context "ask-city" is active, and the user says "yes", trigger Intent B. In the handler for Intent B:
Clear the context "ask-city"
Set the context "prompt-city"
Send the message "What city?"
When the context "ask-city" is active, the user may also just reply with the city, so trigger Intent B1. In the handler for Intent B1:
Clear the context "ask-city"
Save the city information
Set the context "prompt-gender"
Send the message "What is your gender?"
When the context "ask-city" is active, the user may reply "no", so trigger Intent C. In the handler for Intent C:
Clear the context "ask-city"
Save that there is no city information
Set the context "prompt-gender"
Send the message "What is your gender?"
When the context "prompt-city" is active, and the user says a city name, trigger Intent C1. In the handler for Intent C1:
Clear the context "prompt-city"
Save the city information
Set the context "prompt-gender"
Send the message "What is your gender?"
You notice that Intents B1, C, and C1 all have very similar, but not identical, fulfillments. So in your webhook, they can all essentially call the same (or similar) code. But you notice that they're triggered under slightly different conditions, so each one needs a different Dialogflow Intent.
I added Intent B1 because this may very well be how the user responds to you. In a conversational UI, we're not presenting them with a phone menu - they can respond as if they were responding to another human asking the same question.
Also keep in mind that there may be other Intents that you want to build that are handled differently in each state. For example, when the "ask-city" context is valid, if the user says something besides "yes", "no", or a city, you may want to clarify what you're asking.
Also note that none of these are, technically, Followup Intents. Followup Intents are just some visual coating around Contexts. You never need to use a Followup Intent - they just make some, very specific, things better organized. In your case - they also cause problems. If all you accept in a followup is "yes" and "no", then the user saying other things aren't allowed and you end up with a much more stilted conversation. The important part about each case isn't if they're followups or not - they're the ability to set an output context and that Intents will only be triggered on those contexts being specified as input contexts.

Related

Dialogflow: How can I repeat a previous intent

I have an intent with slot-filling, after all parameters are set my agent then prompts the user to confirm that the parameters are correct. If the user answers "no", a follow up intent is triggered, but I don't know how to make it so this repeats the previous intent allowing the user to correct the information.
Add a follow-up intent with yes and another follow-up intent with no values.
Then in the follow-up no values, check the user input and then again call the main intent.
Remember that Intents represent what the user says or does and not what you do with that information. So there is no way to force "repeating" the previous Intent, since the user may choose to do something else.
What you can do is
Clear out the various Input Contexts, except for an Input Context that your original Intent is valid.
Re-prompt in a way that they would answer it so the original Intent would be triggered.

DialogFlow name in context, prevent resetting conversation flow every time a new name is spoken

I have a conversation tree set up in DialogFlow, starts with a welcome intent and has a few follow-up intents, goes three levels deep.
The conversation begins with the user saying hi or similar, to which the bot replies with a greeting and prompts for the user's name, the user then provides the name, the bot follows up with 'Hi [name], nice to meet you' and asks a question. Then depending on the answer (custom follow-up intents) the conversation goes on.
The name is remembered and used in the follow-up intents, but at any point in the conversation flow if the user says a different name for some reason (or something that is recognized as a name), the bot resets to the 'awaiting_name' intent and says 'Hi [new name], nice to meet you'.
How can I prevent this from happening?
This is due the the LifeSpanCount that you are setting to each intent. Reduce it to 1 or 2 as required so to make it inactive after 2 counts.
Also, you can add follow-up intents to handle the "no-match" situation, defining whether to repeat the intent or do something else when a user speaks something out of context.

How to prevent user from hopping to another intent in the middle of the conversation?

Let say I have 2 basic intents i.e Set Appointment and Cancel Appointment.
Each of the intents has its own follow up questions and so on. When the user is in the follow up chain for the intent, Set Appointment, I want to prevent the user from hopping to another intent if he/she says "cancel appointment for abc"
Since both intents have empty input contexts so they can be called from the Google Assistant's invocation i.e Tell XYZ App to set appointment for...., it seems that this allows the user to be able to hop between intent mid conversation.
How do I limit this behavior? Or is there some kind design best practices here?
First of all, remember that Intents represent what the user says, not what you're doing with that the user says.
Second, remember that users can change the course of the conversation at any time. So it makes sense that if they start adding an appointment, that they might want to cancel that appointment.
The best approach is that, if they try to cancel in the middle of making an appointment, you decide how you want to handle this change in conversation. And then just reply that way. You may choose to change tracks. Or you may choose to say something like "let's add this new appointment first, and then we can cancel the old one". With this scheme:
You have one Intent that matches "set the appointment for 10am"
In your handler:
If you aren't taking any action, you'd start prompting them for additional appointment setting info, or whatever.
If you are already setting an appointment, prompt them if they want to change the time to 10am
If you're cancelling an appointment, tell them that you'll talk about canceling the old one when you're done with the new one.
I tend to go with this approach in most (tho not all) cases. It lets me code the logic and lets me determine the best way to reply based on the entire state.
Another approach that you can use is to create an Intent with the Input Context that matches your current contextual line of questioning that matches the phrases from the Intent you don't want to match. (This might even be reasonable as part of a negative training phrase for a context-specific Fallback Intent.) Context matches are handled before context-free matches. So under this scheme you would have:
An Intent, without input context, that matches "set the appointment for 10am". The handler for this Intent would set the "set" context and start prompting for additional info.
An Intent, with your "set" input context, that matches "set the appointment for 10am". This could do something like re-start the prompting, or just change the time they're requesting.
An Intent, with your "cancel" input context, that matches "set the appointment for 10am". This handler would let them know that you'll ask about cancelling older appointments at the end.
Which method you use depends on how you're handling other state management in your code.

how do I trigger an intent using DialogFlow?

I have a conversation with dialogflow to select a favourite type of drink and then depending on the category of drink there are follow up questions (ie follow up intents).
Under the intent tab I have the following intents:
Default Welcome Intent
Favourite drink Intent
Coffee Intent
follow up
Soft Drink Intent
follow up
Juice Intent
follow up
I use the training phrase in the Favourite Drink Intent and ask:
"What is your favourite drink?"
And store the response in an entity #drink.
But I don't know how then to trigger the intent "soft drink", "juice" or "coffee" intents depending on the users response. If I was writing code I'd use a switch statement or if/else but that prob doesn't apply here.
I wasn't sure if I had to use the fulfillment inline editor or I could just do that from within the Intent UI.
Thanks
In general - think of Intents as capturing what the user could be saying. Although Intents also have replies, this isn't their primary purpose.
Depending what, exactly, you're trying to do, there are a few approaches. All three of them require fulfillment code, which you can do using the built-in editor, or (better) use a webhook more under your control
If you want to use Intents to determine how to reply
This isn't really the best idea, but it is possible. In your fulfillment code, you would have a switch statement against the parameter with the user's selection. Based on this, you would trigger a followup event from your fulfillment. Your other Intents would have the Event section populated with the possible events, and the system would pick which one to trigger and use for fulfillment/response.
This is a bit of a kludge for what you want, probably.
Update to clarify based on questions in the comments. Sending an event directly triggers a different Intent. Sometimes this is what you want, but it is somewhat exceptional. Most of the time you want to use one of the methods below. In particular, you should remember that Intents are mostly meant to represent what the user is trying to do (what they "intend" to do), and this is mostly represented by what they're saying. Intents are good to capture the complex ways people talk instead of forcing them into a phone-tree-like "conversation".
If you just want to reply to each possible user response differently
You can use the fulfillment webhook code to determine what response should be sent to the user. You don't indicate what library you're using, but in general you'd write code that would determine what message should be sent to the user based on the drink type selected and include that as the speech and/or display text in the response.
You wouldn't use the other, drink specific, Intents in these cases. There isn't any need for them. Unless...
You want to reply to each user response differently, and the followup conversation might be different
Remember - Intents are really best for specifying what you expect the user to say. Not what you expect to reply with. So it is reasonable that you may have a different conversation based on if they selected Coffee (where you might ask how much sugar they want) or Juice (where you might ask if they want a straw).
In this case, you would still do as you have in the previous case (use your fulfillment to include a tailored message in your reply, possibly to prompt them for that info) and include in the reply an Output Context indicating what their choice was. You should do this as part of the response, rather than setting it in the Intent, since you'll want to name it differently for each beverage type.
Then you can create Intents specific to each beverage type with what you expect the user today. For those specific to Coffee, you would set the Input Context to require that the coffee context has been set. The soda context if they specified soda, and so forth.
Update, since you indicated in your comment that this sounded like the avenue you were interested in.
In this scenario, you'd do as you described (almost):
Get the value for the drink parameter with code something like
const drink = request.body.queryResult.parameters.drink;
Do a switch based on this, and in the body of each case set what we'll reply with and what context we should remember. Something like this pseudocode, perhaps:
switch( drink ){
case 'coffee':
context = 'order_coffee';
msg = 'Do you want sugar with that?';
break;
case 'soda':
context = 'order_soda';
msg = 'Do you want a bottle or can?';
break;
case 'juice':
context = 'order_juice';
msg = 'Would you like a straw?';
break;
}
// Format JSON setting the message and context
You would then have Intents that would be triggered based on a combination of two things:
What the context is
What the user has said
For example, you would want a context (let's call it "coffee.black") which would be triggered if the order_coffee context is active and the user answered your question with "No" or "Just black" or other valid combinations.
But you'd want a different context (say, "juice.nostraw") if the order_juice context is active and the user replied "No".
And it wouldn't make much sense at all if the user said "No" while the order_soda context was active, so you'd want to try and direct them back to the subject at hand.
Remember, the Intent is for what the user says. Not for what your voice agent is saying. Your agent doesn't normally "trigger" an Intent - the user triggers it based on what they say.
In the example I gave, there might be other Intents that are valid for each of those contexts. For example, you might have a "coffee.sugar" Intent that is valid for the order_coffee context and responds to them saying "Yes". And another one where they might say "Just cream". There are lots of other things they might say as well, but it is important to your agent that the directions they're giving you have to do with ordering coffee.
As for your original question...
(To answer your original, now edited, question: Yes, you can create Intents from within your fulfillment. You almost certainly don't want to do this, however.)

Looping back to an intent without repeat the responses list

I want to do something similar to this question: Looping back to an intent?
My bot is telling jokes when a user ask "Tell me a joke", (intent: smalltalk.agent.telljoke) and if the user respond with "another one" I want to send another one.
I understand the answer in the linked question, I can create repeat.smalltalk.agent.telljoke intent if the user say "another one" with a specific input context set in smalltalk.agent.telljoke intent.
But can I trigger my smalltalk.agent.telljoke intent in the repeat.smalltalk.agent.telljoke intent ? I am not calling a webhook to get the jokes so they are in the Responses section of my smalltalk.agent.telljoke intent and I do not want to write them at two places (in both intents).
Can I redirect an intent to another one's responses ?
I asked the same question on the Dialogflow Google forum:
Looping back to an intent without repeat the responses list
To have the input "another one" trigger the joke-telling intent (smalltalk.agent.telljoke), just add "another one" to the training phrases of that intent. There's no need to have two intents if they both do exactly the same thing.
You can do that by adding an output context (let's name it anotherJoke) to your smalltalk.agent.telljoke intent which can expire after two messages (to allow a follow up to a ha ha ha or lol from the user).
Then create a new intent (maybe smalltalk.agent.anotherJoke) that will take the anotherJoke as it's input context.Make this intent recognize another one, shoot again, etc and provide another set of jokes for it.
That way the smalltalk.agent.anotherJoke intent will have priority matching only after the smalltalk.agent.telljoke intent has been triggered, the context kinda links the two intents together.

Resources