-
-
Notifications
You must be signed in to change notification settings - Fork 193
Multi turn dialogs with Alexa
In this example we'll build a chatbot for Alexa to turn on the home lights. The chatbot will also ask for the room and the color of the lights and will be smart enough to not ask if these are already specified in the first sentence. The chatbot will also request confirmation for each step (yes, it's overzealous but this is just an example to test the potential).
First some definitions before proceeding:
- model: text recognition must be trained with some sentences and variations of the same user's intention, the more the better. One saved and compiled it will be used at runtime (by Alexa) to understand what the user is saying
-
intent: it's label for a group of training sentences that means a specific intention of the user (for example
switch_lights
) - slot: it's a bit of a sentence that can vary inside a sentence and need to be extracted into a variable (for example the room in the sentence "switch on the lights in the kitchen")
- slot type: the allowed values for a slot (for example a date, a number or a predefined list of values)
First thing is to train a model model for the intent switch_lights, start writing some sentences like
switch on the lights
switch lights in the {room}
switch on lights in {color} in the {room}
switch on {room} lights in {color}
In curly brackets are the slots: as soon as you type the {
the editor ask to pick up an existing slot or to create a new one. We'll create to new slot: room and color.
It's not possible to save the model yet since the two new slots are not assigned to any slot type:
- color: select the predefined type AMAZON.color
- room: create a custom slot type for room with these elements: kitchen, bedroom, dining room, basement, restroom
Then, to make the example more complex will make both slots required and to be confirmed:
In this way, if not specified in the first sentence, Alexa will ask for the slot room
(make sure to fill in the the "Alexa speech prompts" field under Slot Filling) and after that will ask a confirmation (make sure to fill "Alexa speech prompts" field under Slot Confirmation and include the {room}
slot in the string to have it automatically replaced with the chosen value).
Repeat a similar configuration with the color
slot, also turn on the intent confirmation and provide a prompt for it (that should include include the slot placeholders to make the sentence more meaningful)
The Alexa chatbot is different compared to other chatbot platforms, the Alexa Receiver node will only send out message of type intent which is the result of the natural language processing of the user's speech, it basically contains:
- the detected intent (in this case we're interested in switch_lights
- the extracted slots values (in this case the room and color chosen by the user)
- the confirmation status for each slot (could be 'none', 'confirmed', 'denied')
- the confirmation status of the whole intent (could be 'none', 'confirmed', 'denied')
- the dialog state
So basically when the user says something like "Alexa, switch on the lights", the chatbot will receive a message like
{
payload: {
type: 'intent',
variables: {
room: null,
color: null
},
confirmationStatus: 'none',
slotConfirmationStatus: {
room: null,
color: null
},
dialogState: 'started'
}
}
Alexa will send an updated intent at the end of every turn, so ideally the conversation will Alexa will be:
User: Alexa, switch on the lights
Alexa: In which room?
User: the kitchen
Alexa: Do you confirm the kitchen?
User: yes
Alexa: What color?
User: Blue
Alexa: Do yo confirm color blue?
User: yes
Alexa: Do you confirm to switch on the lights in the kitchen in color blue?
User: yes
Yes, it's overzealous, but it's just to give the idea of all the capabilities. At each turn and after the user answer, Alexa sends through the callback the updated intent (variable, statuses, etc) and it expects an answer: the calls to the callback are synchronous (the Express response object is included in the originalMessage) and for this reason the response flow of Node-RED cannot exceed 3000ms or the callback will time out.
The RedBot flow can be implemented in order to delegate all the moves to Alexa or take control over each single step.
The first strategy is implemented in this way
Description of the nodes
- The first Rules node intercepts the event "start" (which is triggered when the chatbot is launched when the user says "launch redbot") and a message of type intent with the name "switch_lights". In the first case the flow is redirected to a welcome speech ("Ok, started") in the second case goes on
- The Context node takes the variables of the intent (room and color) and stores them in the chat context, they will be available in the next steps (be sure to select "Store values from intent")
- The second Rules node filters dialogs that are in started and progress state, it just skips conversation already concluded
- The third Rules node checks (first output) that the dialog status is confirmed (that means that also the required slots are confirmed), in this case the dialog is complete and the flow can take proper action (with the
Function node
for example) and send a confirmation speech "Ok, lights switched on in {{room}} with color {{color}}" - The second pin of third Rules node handles all the other case ("If none of above applies"), that means that the dialog is not confirmed, in this case the Alexa Directive node sends the "delegate" directive: that tells Alexa to decide the next move (ask a missing slot, ask a confirmation, etc) until the dialog is completed.
If everything is correct the results in the test console should be
If we need an implementation that takes control of every turn, the flow is a little bit more complex:
The first part of the flow is the same while the final Rules node does a bunch of additional checks
- If the variable room is not defined, then instruct Alexa to ask the user for slot room by sending the directive Dialog.ElicitSlot (note the chained Alexa Speech node with the context of the request
- If the variable room is defined but the confirmation status is denied or none then instruct Alexa to ask for confirmation by sending the directive Dialog.ConfirmSlot (the chained Alexa Speech node may include some chat context variable in order to make the message more contextual)
- Repeat the above steps for the variable color
- If the intent confirmation status is none then instruct Alexa to ask the user to confirm the intent with the directive Dialog.ConfirmIntent
- If the intent confirmation status is confirmed the dialog is complete and the flow can take the proper action it was designed for
Check the Alexa Sandbox