I have implemented a multi-turn dialog for Alexa. The Help-Intent provides different Help-Texts depending on the state of the dialog. After the User has triggered the HelpIntent and was presented the Help-Text, I want to elicit a specific slot with the ElicitSlotDirective
Now this seems to be not supported, since you can only elicit slots of the current intent, and the HelpIntent does not have slots.
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs/issues/162
My question now is: How can I return to my multi-turn dialog and elicit a specific slot after the user triggered the HelpIntent?
You can now use intent chaining to elicit a slot from a different Intent. For example:
.addDirective({
type: 'Dialog.ElicitSlot',
slotToElicit: 'drink',
updatedIntent: {
name: 'OrderIntent',
confirmationStatus: 'NONE'
}
})
See this blog post.
The documentation states that:
Implementing the built-in intents is recommended, but optional.
I recommend that you define your own HelpIntent with overlapping utterances to the AMAZON.HelpIntent, but with your needed Slot types.
In this case, your service receives an IntentRequest for MyHelpIntent, even though these phrases overlap with the built-in AMAZON.HelpIntent.
The documentation also states, that this practice is not recommended, because the built-in intent may have a better coverage of sample utterances. It states that it is better practice to extend the built-in Intents. But (stupid enough from Amazon), the HelpIntent does not support Slots. So the only way would be a custom Help Intent.
I don't see a way to use Dialog Directives with the built-in Intents.
Here's a convoluted workaround that might work (there's no straight forward way right now, Nov 2018):
On every loop of the multi-turn dialog save your dialog based intent in the session attributes (the whole intent object, you can use the intent.name as key)
On every triggered intent (even HelpIntent) save the intent name in a lastIntent session attribute (to keep track of the previous intent name)
User triggers help and you're now in the HelpIntent. After you provide your help message append a question in the end that will cause the user to say something that will trigger your dialog based intent again
Do the following steps when you are in the dialog based intent and only if the lastIntent was HelpIntent (the one in the previous step):
Load the most recent intent data from the session attributes and, in it, delete the slot value and resolutions of the slot you want to elicitate (alternatively if you want to start from scratch you can delete the remaining slot values too, up to you)
Replace the current intent with the modified intent of the previous step
Emit a DialogDelegate with the current intent (your model needs to flag the slot you want to elicitate with elicitationRequired set to true)
Related
I have a skill that elicits a U.S. state and county from the user and then retrieves some data. The backend is working fine, but I am concerned about how to structure the conversation. So far, I have created an intent called GetInfoIntent, which has two custom slots, state_name, and county_name
There are about 3,000 U.S. counties with many duplicate names. It seems silly to me that I am asking for a county, without first "narrowing down", by states. Another way I can think of to do the conversation is to have 50 intents, "GetNewHampshireInfo, GetCaliforniaInfo, etc. If I did it this way, I'd need a custom slot type for each state, like nh_counties, ca_counties. etc.
This must be a pretty generic problem. Is there a standard approach, or best practice, I can use?
My (not necessarily best practice) practice tips:
Single slot for single data type. Meaning only have one slot for a four digit number even if you use it in more than one place for two different things in the skill.
As few intents as you need
no more no less. You certainly can and should break up the back end code with helper code, but try and not break the intents into too many smaller pieces. It can lead to difficulty when Alexa is trying to choose the intended intent.
Keep it voice focused. How would you ask in a
conversation. Voice first development is always the way to go.
For the slot filling I think it is fine to ask both state and county.
If the matching is not correct ask for confirmation.
Another option is to not use auto filling within the Alexa skill and use the dialog interface. Ask the county first and then only when it has more than one state option and is ambiguous continue the dialog to fill the state.
Even if you did have 50 separate intents you really never want to have two slots that can be filled by the same word. For example having a mo_counties and ky_counties that Clack satisfies both is ambiguous and can cause unneeded difficultly.
So for someone looking for the "best practice" I have learning that there isn't one yet (maybe never will be). Do what makes sense for the conversation and try and keep it as simple as it needs to be and no less on the back end.
I also find it helpful to find a non-developer to test your conversation flow.
This wasn't really technical and is all opinion, but that is a lot of what Alexa development is. I would suggest Tuesday Alexa office hours at https://www.twitch.tv/amazonalexa very helpful and you can ask questions about stuff like this.
How can I make Alexa prompt me (e.g. “You want weather for which city again?”) if I missed a parameter (slot i.e. city_name) in my utterance?
I am making a skill which tells me weather of a city. I have utterances and it works alright, but when I don't define a city name (city_name is also my only slot in my intent) then it directly goes to stop intent and gives my message "Alexa cannot help you with this".
In my slot (city_name) I've even checked "Is this slot required to fulfill the intent?" and have filled Alexa prompts and user utterances but still it doesn't work.
Use alexa dialogs. Dialog automatically fills all the required slots by reprompting the user for the slot value that he has missed. A dialog has 3 states, STARTED, IN_PROGRESS, COMPLETED. Dialog state will be completed only if you have all the required slot values filled. Watch the tutorial here
You can use different Dialog interface directives to ask the user for the information you need to fulfill their request. When ever there is an user interaction with your skill, you will get a request at your backend with the mapped intent and filled(or unfilled) slots. Even if you use dialog model and has filled in all the utterances for each slot, you will have to respond back with an appropriate directive to continue.
There are three ways in which you can handle a dialog model.
1. Delegating to Alexa
You can use the Dialog.Delegate directive to let Alexa determine the next step in the dialog and uses the prompts that you have defined in the dialog model to elicit slot values, confirm slot values, or confirm the entire intent.
If you have unfilled slots just return a delegate directive, Alexa will use the prompts defined in the interaction model to fill that slot. As long as the dialogState property is not COMPLETE you can continue delegating to Alexa.
Once the conversation is complete, the incoming IntentRequest has a dialogState of COMPLETED. All required information is now available in the intent's slot values.
Note: With Dialog.Delegate directive you cannot send outputSpeech or reprompt from your code. Instead those defined in interaction model will be used. And the COMPLETED status is only possible when you use Dialog.Delegate.
2. Control the Dialog
In each turn of the conversation you can take the control and ask for what you need rather than delegating it to Alexa. This is useful especially when you want slots to be filled a particular order or you want to confirm slots as you go or your slot's "mandate" property is dynamic in nature and so on.
You can use Dialog.ElicitSlot directive to ask for a particular slot, Dialog.ConfirmSlot to confirm a particular slot and Dialog.ConfirmIntent to confirm an intent itself.
3. Combining both
When you receive an intent request you can return a delegate directive or any other directive as you wish. Even if you delegate, at any point you can take over the dialog rather than continuing to delegate to Alexa.
More on the different directive here
Sample Interactions:
1. Using delegate directive here
2. Using ElicitSlot directive here
3. Using ConfirmSlot directive here
4. Using ConfirmIntent directive here
I am developing an app and everything is working good. One condition are there where I have set the utterances but if user is speaking something else, I am throwing it to the fallbackIntent. One of my utterance is {name} so user can speak any name. But I have define range of name as well that user is allowed only these names. So my problem is if the user is choosing defined names, everything working great and if user said something else like what is weather of chicago, it is going to fallbackIntent as well but the issue is if user speak some name which is not in the list, then too it is coming into defined intent. What i want that if user speak something which is correct but not in my defined name then too redirect it to the fallbackIntent. Is there any way I can call intent in giving condition? I am using php.
When you define a custom slot, Alexa take it's values as samples. So values which are not in the slot-value-list will also be passed to you. And with respect your intent, those slot values are valid, hence that intent is triggered.
The solution is to validate the slot values at your backend and return an appropriate response.
In your case, if u get any other names other than those you have defined, respond back with an error or give FallbackIntent's response.
When you create a custom slot type, a key concept to understand is
that this is training data for Alexa’s NLP (natural language
processing). The values you provide are NOT a strict enum or array
that limit what the user can say. This has two implications
1) words and phrases not in your slot values will be passed to you,
2) your code needs to perform any validation you require if what’s
said is unknown.
I have created a dialog which checks for some Intent and entity to trigger the response, I have also added slots to capture the missing entities. But when user enter the slot value it changes the intent thus causing change in final response. I have tried adding context variable also and deleting it after response but it gets deleted before response and I am getting empty context variable in response.
Like I have added a slot for capturing missing color values in an Intent say 'looking' and color values are like 'I, G, H' and there's also an Intent let's say Goodbye which is also trained for values like 'G or H'. So, when a user fills the slot value with 'G or H' it also overrides the previous intent 'looking' to 'Goodbye' and my final response value changes. What is the best way to handle this kind of flow?
The current intent is based on the latest utterance by the end user. So when someone types in a follow up to a slot, the intent will change and this is intended.
A common confusion is that this impacts the dialog tree. Because when you test it in "Try it out" you see the intent change. Unless your dialog tree is explicitly looking for it after the slot, then it has no impact what-so-ever.
If you do need it to stay the same, then you can send back the intent object in your context. This will disable Watson Assistant from trying to guess the intent.
The danger here is you need to be mindful that what you send back might not reflect what the user has entered. For example, they may ask something that has to trigger the handler of a slot. Doing this will disable that ability.
lets say i have a skill with 2 custom intents, 'FirstIntent' and 'SecondIntent'. SecondIntent also has a required slot, 'reqSlot'.
Now, i would like to sequence my intents. After my skill sent the FirstIntent-response, i would like Alexa to send a request with SecondIntent and a directive to elicit reqSlot, without the user to invoke it.
They say here, at the parameter 'updatedInted':
"Note that you cannot change intents when returning a Dialog directive, so the intent name and set of slots must match the intent sent to your skill."
Is this generally possilbe or did anyone figure out a workaround for this scenario?
Thanks :)
There are ways to handle this.
You can try:
When you send your first response it must set the shouldEndSession flag to false.
The end of your first response's output speech should lead the user into invoking the second response. For example: 'Say telephone number followed by your number'.
This way the user doesn't need to explicitly invoke your skill to get to the next intent.
It is not currently possible to cause Alexa to start speaking without a user first having spoken to it.
So for example, I cannot create a skill that will announce to my wife that "Ron is on his way home" whenever I leave work.
I can however, create a skill that my wife can ask "Is Ron on his way home", and it can respond with the answer.
Also, the new notifications allow a skill to post a notification, but this just causes the Alexa to light up its circular ring to indicate that a notification is waiting. A user must still ask Alexa to read it. In the example I cite above, that might be ok.
A lot of us would love for Alexa to be able to spontaneously start talking, but Amazon has not enabled that. Can you just imagine the opportunity for advertising abuse that functionality might enable? Nothing like sitting down watching TV and having Alexa start talking, "Hey, wouldn't some Wonder Popcorn taste great about now? We're having a sale..."