I'm working in a somehow-chained intent skill.
These 4 intents are able to be called just after the user says "I want information about a career".
There are 4 intents that can be either the first one called, or called after another one. The thing is: The 4 of them require a career name slot, such as "engineering", "politics", "biology", and so on.
Is there any way to get the career on the first intent and then call the other 3 without needing to validate the user's input? If so, I'd really apretiate an example on how to achieve that.
To implement conditionally-required slots and contextual carryover you will need to use custom skill code and directly manage the logic and issue slot-elicitation directives. So if you have been using a 'dialog model' and use the delegate-directive this may be a substantial change.
In your intent handlers: use session attributes to maintain a map of your slot types and values. When you see that an intent has an unfilled slot you can decide whether to take a value from the map or to elicit one. The logic will be custom to your scenarios.
To elicit a slot value manually, see https://developer.amazon.com/docs/custom-skills/dialog-interface-reference.html. Remember to set the intent and all the known slot values so that they are preserved through to the next Request.
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.
I've got a few intents. They all just use a single fallback intent and this fallback intent has the webhook enabled.
In the fallback function what I was hoping to do is switch on the output context and then determine what should happen next depending on which intent the fallback came from.
But the line
var context = request.body.queryResult.outputContexts;
When debugged to the console gets output:
[ { name: 'projects/xxxxproj-xxxx/agent/sessions/xxxxxx-xxxxxx-xxxxx-xxxxx/contexts/xxxxxxx-context' } ]
For the switch statement i just want the last bit with the xxxxx-context. Am I going to have to split that up to get the output context?
In the "Diagnostic Info" section I am a bit surprised there is no reference to the intent from which the fallback came and the only way to work it out seems to be using the outputcontext but as show above that is quite a long string.
Thanks
Yes, the context name is just the last part of that path. Most libraries will take care of that for you, but if you're working with the JSON directly, you need to do this yourself.
There is no reference to "the Intent from which the fallback came" because this isn't quite the model of what an Intent is. Intents represent what the user has said or done, not the current state of the conversation or where you are in the conversation. That current state is represented by Contexts, should you choose to set them.
In that sense, how you use the contexts can vary. They can store parameters, so are a good way to keep information between rounds of a conversation, and you can use them the way you are - to see what state the conversation is in general. But they also take on additional uses when defining Intents.
In an Intent definition, the Intent will only be triggered if all the Contexts listed in the Input Context field are set (ie - have a lifespan greater than 0). Dialogflow uses this when it makes followup Intents, for example, and it is common so you can do things such as have "help" trigger different Intents based on Context. In an Output Context, it will automatically capture all of the parameters specified in the Intent, including those filled in by the user's response, so this can be an easy way to remember what the user has said from round to round.
To answer your question in the comments - it doesn't specifically say which Intents were previously triggered, or which most recently, although if you're consistent in how you use your Output Contexts and what lifespan you give them, you can use it this way. What it does say is in what state your conversation is in, which is generally much better anyway.
Remember - Intents represent what a user has said or done. It doesn't represent anything else about the conversation. Only the state of the system represents that, and one tool we have to control that state is through Contexts.
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 make a search algorithm with dialogflow that could take any combination of: first name, address, phone number, zip code or city as input to a search algorithm. The user does not need all of them, but we will refine our search with each additional answer until we only have one result. Basically we are trying to identify which customer we are talking to.
How should this type of intent (or set of intents) be structured? We have tried one intent with multiple parameters, but we do not need all of them to be required. We have also written a JavaScript function for fulfillment but how can we communicate back to dialogflow as to whether we need more information?
Thank you very much for your help.
Slot filling is designed for this purpose.
Hope that helps.
Please post more code/details to help answers be more specific.
First, keep in mind that Intents reflect what the user is saying, and not typically what you're replying with or what other information you need. Slot filling sometimes bends this rule, but only if you have required slots.
Since you don't - you need a different approach.
This can be done with a single intent, although you may find that multiple intents make it easier in some ways. The approach is broadly the same:
When you ask the question, make sure you set an Outgoing Context with a relatively short lifespan (2-3 is good) to indicate you are collecting user info.
Create an Intent (or Intents) that have sample phrases that capture the information you need.
Some of these will have obvious entity types (phone number and zip code) while others will be more difficult (First name has a system entity type, but it doesn't include all possible first names).
You will need to create sample phrases that collect the parameters by themselves, along with phrases that make sense. You're the best judge of this, and you should probably write some sample conversations before you write the phrases.
In your fulfillment, you'll figure out if you have enough information.
If you do, you can reply and clear the Context that was set. (Clearing it is important so Dialogflow doesn't match the information collecting Intent again.)
If you do not, you can add the information you have as parameters to the Context so you can save it for later processing, make sure you reset the Context lifespan (so it doesn't expire), and prompt the user for additional information. Again, having a conversation mocked out ahead of time will help here.
In the chat application i am developing with dialog flow has scenario like this. Users can ask details about loans that they can get. that is a one intent. once user says the loan type they want i need to save it and use it every where when they ask question. for one example i have a another intent called loan payments.
In that intent they can ask questions like
I am interested in getting a personal loan for a duration of 5 years
and the loan amount would be 5 million rupees. Can you let me know the
monthly repayment amount?
to calculate that, loan type is a must (personal loan in this case). so if any user has specified the loan type before i need to use it here other wise i need to ask users to provide it again. but if i am using context i cant add add required. how to achieve this. also since i have already set the parameters i cant change the value of them. this is how my parameters look like
This is where your business logic comes in picture. Chat application can be built in two ways, directional & open-ended. In first one, you can explicitly go on asking few questions with set options/buttons for the services that you're offering & user has to select any one of them or in the second one, you keep it open for people to type-in anything & then you extract values & respond them based on their inputs.
Now that you're of second type, even if you use contexts, dialogflow offers you a favor to extract parameter values of first intent in the second one. You just have to use, #context_name.parameter_name. But now, if you're saying that if user has already defined loan type in earlier intent then you don't want to ask him again it in next intent, then this is purely a business logic that you will have to code in your webhook. Dialogflow won't do it for you.
I hope, this answers your question & if you don't want to do it that way, go for directional flow.