I'm trying to create a bot that should allow this kind of interaction:
(U = user, B = bot)
Case A:
U: Create a new XXX analysis
B: Got it! Let's create a new XXX analysis
B: What's your first name?
U: Joe Doe
B: etc, etc...
Case B:
U: Create a new YYY analysis
B: Got it! Let's create a new YYY analysis
B: What's your favourite color?
U: Red
B: etc, etc...
So, I need to trigger a different question depending by what the user told me in the first interaction.
Right now I properly get the type of analysis (XXX or YYY), but I can't figure out how to trigger a different follow-up intent depending by the type value.
What's the proper way to do it?
I was counting to write the bot using Node.js so if the answer requires to write a backend please I'd like to get referenced to the Node.js docs and resources.
First of all, remember that intents are triggered based on what the user does. You don't "trigger" an intent, your users do. How you process that intent is based on the intent triggered as well as other state you may have about the conversation - in this case, the analysis type. See this StackOverflow answer and the related medium article (and followup articles) that discuss how to handle this.
If you want to ask something different based on how the user replied - use your webhook fulfillment to ask something different. Responses aren't based on Intents. You don't need to "trigger" anything.
Sometimes you want only certain intents to be triggered based on state. In these cases, you can set a Context and limit Intents to be fired only when the Input Contexts are all present.
Related
Good day,
I am currently trying to create an intent that is able to put out responses depending on the user input. (The chatbot should be implemented on a website later)
Let's say we have an entity called cars with three entries: "Volkswagen" "Audi" "Ford".
Now when the user types in something with e.g. Audi in it, the response will correspond to this. Something like this: If Audi then give this response, if Ford then this response.
I couldn't find anything helpful yet.
Thank you in advance!
Remember that Intents represent what the user says and not how you handle this or how you reply. Although Dialogflow does offer the ability to respond to Intents, these aren't based on specific values that may appear in parameters.
There are, however, a variety of ways you can handle what you're doing, based on the rest of what you're trying to do.
Multiple Intents
One solution is to create an Intent for each type of thing that the user may talk about. You could then put the response you want for each in the response section of that Intent.
This is probably a bad approach, but may be useful in some ways. It requires you to duplicate phrases between the different Intents, which leads to a lot of duplication. On the upside, it does let you vary the replies, and truly represents the Intent of what the user is trying to say.
Using Parameters with Fulfillment
A better approach is to have a single Intent with many phrases representing what the users can ask. These phrases would have parameters of your Entity Type.
You can then enable Fulfillment for this Intent and write a Fulfillment webhook for the Intent that would look a the value of the parameter and send back an appropriate reply.
Using Parameters with DetectIntent
Since your ultimate goal is to embed this on a website, it may be more appropriate to have your website show something different based on what the user has said. (For example to show a picture of the car in another pane or links to different pages, to use your example of cars.)
In this case, your chat client (or a proxy) would be calling the DetectIntent API. You can structure your Intent similar to above, with parameters of the Entity Type, and the reply that is sent to your client would contain the Intent along with the value of the parameter. Your client then can check the value of the parameter and change the display accordingly.
trying to make an Intent for my first Conversational Assistant with a couple of parameters. Everything is build in Dialogflow and for some of my functionality I use fulfillment.
The easiest way to describe my assistant is as a cinema tickets booking.
I need to store #number_of_tickets, #cinema, #movie. The last two (#cinema and #movie) are very easy to solve with entities, however struggle a lot with #number_of_tickets. All of this parameters should be mandatory.
My goal is to allow such kind of functionality:
Book me a ticket for Star Wars in IMax (ticket = 1 = #number_of_tickets, Star Wars = #movie, IMax = #cinema)
Book me 2 tickets for Star Wars in IMax(2 tickets = 2 = #number_of_tickets, Star Wars = #movie, IMax = #cinema)
Book me tickets for Star Wars in IMax -> How many tickets you want to book?
I tried with composite Entities but it doesn't work as I'm expecting.
How I can enable such kind of functionality in Dialogflow?
Is there a way to require #number_of_tickets to be between 1 and 5?
Above question can be achieved by following below steps:
Solution:
Step 1:
Create Entities for movie and cinema:
Cinema:
Movie:
Step 2:
Create an intent with three parameters:
(If you want alow only from 1 to 5 then you can create an entity like cinema and movies with entries from 1 to 5 and map the number of tickets parameter with the same)
Step 3:
Make all the parameter Mandatory and define prompts for all as below:
Movie Prompts:
Cinema Prompts:
Number of tickets prompts:
Result:
It may not be obvious, but the answer to both of your questions can be addressed by remembering that Intents capture what the user says, and not what you do with what they say. You can have multiple Intents to capture different phrases, and handle them in mostly the same way in your fulfillment. (And these do require that you have some kind of fulfillment webhook behind the scenes.)
How can I assume a default of 1 ticket?
There are a couple of approaches.
The first is that you can setup an Intent to capture phrases that suggest a single ticket and a different Intent that explicitly requires a number. So perhaps one Intent (possibly book.single) with
I'd like to get a ticket for Star Wars in IMax
How about the IMax showing for Star Wars
Let me see the Star Wars for IMax
and so forth. While you'd also have a different Intent (possibly book.multiple) with
I'd like 2 tickets for Star Wars in IMax
2 tickets please for the IMax Star Wars
etc.
In your fulfillment, you might have some function that takes three parameters
bookTickets( num, movie, cinema );
In your Intent handler for book.single, you'd call this with
bookTickets( 1, movieParameter, cinemaParameter );
while in the Intent handler for book.multiple, this would be done with
bookTickets( countParameter, movieParameter, cinemaParameter );
In each case, the fulfillment still ends up calling the same function to do the actual work, but the handler sets the values as appropriate.
How can I limit how many tickets get ordered?
This goes to something that you didn't address - what do you want to happen if they try to order more? Do you want to direct them to a group order conversation? Reject it outright? Whatever you want - make sure you've planned out this path of a conversation before you try to implement it.
In this case, this isn't something you want to enforce in the Dialogflow Intent. Handling it in your fulfillment is easiest. There, you would apply any logic for the various parameters and return a message, prompting them about their next reply.
Logic is best handled in the fulfillment.
There are actually a couple of places this is important in your example. In the first, how would you handle more than 5 tickets requested? In your handler for book.multiple, you would check how many are requested. If between 1 and 5 inclusive, you'd call the book function above. But if not, you might want to just send back a replying saying "I'm sorry, you can only reserve 5 tickets maximum. How many tickets do you want?"
You would also need a new Intent to capture the reply. It could be as simple as just taking a number, but to make sure it only gets applied when you send back this prompt, you may want to set an Output Context indicating you're prompting for the number of tickets and then set this as an Input Context for the Intent that collects a number.
Are there other cases where you might want to apply logic before booking tickets? Plenty - and in each case you will probably want to make sure there is a new Intent that can capture what they want. For example, what if the movie they want to book isn't showing in that cinema? What if you already know that movie is sold out?
But what about Followup Intents?
Followup Intents are generally best avoided in general for exactly the same reason - Intents represent what the user says, and shouldn't try to model your code logic. There is nothing special about a Followup Intent - you can create an Intent at the top level that works the same way, but will be valid only if you prompt for certain things. How? Contexts again!
So if you prompt with possible showtimes ("Do you want the 2:00, 4:00, or 6:00 show?") you could also include a context (say "promptTime", for example) and then have an Intent that expects this as an Input Context and matches the times.
Conclusion
Intents represent what the user says
Your fulfillment code does something with what they've said
You can prompt them for more or different information in your fulfillment
Contexts can shape what replies you expect
Multiple Intent Handlers can call the same functions to do the work
I am trying to develop a chat-bot in google Dialog Flow where user deviates from the original conversation flow (CF) but ends up coming back to original somewhere in the middle.
bot responses are in bold
For example:
original CF: hi -> how may i help you -> i would like to go travelling -> OK, i would suggest Europe. would you be interested? -> yes -> alright here's the price
deviated CF: hi -> how may i help you -> i would like to go travelling -> OK, i would suggest Europe. would you be interested? -> maybe -> Europe has lot of beautiful destinations u can travel to. would you be interested -> yes -> alright here's the price
The only way i found to implement this is to make a new intent and develop its followups which is making this very redundant. I had to develop two separate intents fully. Is there any way i can make an intent just for the deviated CF and join it to the original intent?
One simple solution is to make many follow-up intents, but that is never ending process.
Here is another approach I want to suggest:
Make a list of important intents which you want to handle in case of
deviation
When the intent is hit, save that to some DB (or cache), let's say
unfinished_intent
In each request or every 2-3 requests check the value of
unfinished_intent, if it contains some intent name, prompt for it
After your intent is fulfilled, delete the unfinished_intent
This is just an idea, how to implement is upto you.
I suggested this because it is generic and it will catch all the cases.
Hope it helps.
Keep in mind that the user can change the direction of the conversation at any time. So using a long chain of followup intents is a bad idea. Even using a short chain is a bad idea. Followup intents should be limited to fairly narrow circumstances, and in most cases they're not wise nor necessary.
Instead, keep track of the information that you have about the user and the information that you still need as part of a context. If you are engaged in a side conversation, or have made a recommendation, keep track of that as well, since the user may ask questions about it. Build many top-level Intents that represent what the user is saying, not where you are in the conversation or how you plan to reply.
See also Thinking for Voice: Design Conversations, not Code based on this answer on StackOverflow.
Suppose i want to make a pizza ordering DialogFlow agent. To order a pizza we need 3 things: size, type and toppings.
If we want to go with follow-up intents approach rather than using entities then there will be so many combinations in which user might provide the information.
1: i want a pizza -> no info
2: i want small pizza -> size
3: i want small cheese pizza -> size and type
4: i want small cheese pizza with olives -> size, type and toppings
5: i want small pizza with olives -> size and toppings
...
and so on
How to solve this problem?
There will be so many combinations if we have more entities (2^n combinations)
Note 1: cannot take entities and slotfilling option as there are so many problems if we go down that road, like re-prompts loop, validation etc.
Is there any better solution?
Note 2: If we use entities, mark them required, and set prompts then many times if it does not get desired input from user it get stuck in re-prompt loop, i.e it keeps asking user same (or random) prompt for same entity. In my use case, it is bad for user experience. If we use follow-up intents instead, then we can set fallback intents for all those intents which solved this problem. (please note that this is just example of the use case)
This is another example of why I used follow-up intents, it solved my date capturing problem as well. I took #sys.date.recent and set a fallback intent to capture inputs like last week, last month etc, this was not possible using slots.
First, remember that Intents should reflect what the user says, not necessarily what you are doing.
On the surface, it isn't clear why slot filling (either with fulfillment or using built-in prompts) won't meet your needs. Since you've indicated that all three bits of information are necessary (size, type, and toppings), you can mark them as such in your phrases and Dialogflow will prompt for the missing information until it gets everything.
You almost certainly do not want to use Followup Intents. These are good when you always have a specific response that you send that will always have a very narrow set of replies from the user, but are very poor if the response from your action will prompt the user to reply in many different ways.
Instead, I would use a related concept: Contexts. (At least if you're not going to use slot filling.) When you ask the question of what they want, set a Context so you know they are. Then have one or more Intents that have this as an Input Context that accept the various things the user might say. Your webhook should see if you have the information you need and, if not, prompt them what else you're looking for. At the end, prompt for a confirmation, but they may say something that adjusts the order.
My bot reads and replies in simple mail conversation. More like in chat manner, one or 2 sentences only done through email. My backend is taking care of reading emails, interpreting api.ai responses, storing locally useful data and sending next questions. Before sending to api.ai, messages are split in sentences.
What I've seen from example conversations already done by humans is that the end users are quite often sending several significant information in one sentence. That means that from e.g. 8 possible peaces of information I totally can have (mostly non required) I can get in one sentence any 2 of them.
How to organize that?
I started with one intent for each field I require. But to solve case with any two intents in one sentence, I am extending user says examples with other field too. At the end I will have 8 intents which are actually filled with similar examples.
Now I am thinking to have just one intent and cover all in it. That might work, but the real question is that really way to do it?
Here are example conversations to describe issue better
v1 - simple way like in api.ai examples
- u: Hi. I need notebook bellow $700.
- b: Great. What size should it be?
- u: 17'
- b: I have gaming one at $590 and one professional for $650.
- u: I more to gaming one.
v2 - what I can expect from real life examples
- u: Hi I would like to buy 15 inch gaming laptop.
- great, what price range?
- ...
Api.ai has a feature called slot filling that allows to collect parameter values within a single intent. It's great for building conversational interfaces. You can see if it's compatible with you use case.
Here's how such intent could look like for the examples you provided:
See the "book_notebook" intent:
and how it would work in conversation:
See a test for the "book_notebook" intent: