What is the best practice to create a Q&A Alexa app? - node.js

I want to make a simple Q&A Alexa app similar to Alexa's custom Q&A blueprint app. I don't want to use blueprints because I need additional functionality. What is the best practice for creating the Alexa app? Should I create a separate intent for each question or should I somehow use utterances?

The best way depends upon what the questions are and how it will be asked.
1. If the questions has a simple structure
Consider these examples:
what is a black hole
define supernova
tell me about milkyway
what is a dwarf star
then it can be configured like this in an intent:
what is a {space}
define {space}
tell me about {space}
and the slot {space} -> black hole, supernova, milkyway, dwarf star.
From the slot value, you can understand what the question is and respond. Since Alexa will also fill slots with values other than those configured, you will be able to accommodate more questions which follows this sentence structure.
2. If the question structure is little complex
what is the temperature of sun
temperature to boil water
number of eyes of a spider
what is the weight of an elephant
then it can be configured like this in an intent:
what is the {unit} of {item}
{unit} to boil {item}
{unit} of eyes of a {item}
what is the {unit} of an {item}
Here,
{unit} -> temperature, number, weight, height etc.
{item} -> sun, moon, water, spider etc
With proper validation of slots you will be able to provide the right answer to the user.
Also, you will be able to provide suggestions if the user asks a question partially.
Ex:
user: what is the temperature
[slots filled: "unit"="temperature","item":""]
Now, you know that the user asked about temperature but the item is missing, so you respond back with a suggestion like this
"Sorry I didn't understand. Do you want to know the temperature of the sun?"
3. If the questions has totally different structure
How to deal with an annoying neighbor
What are the types of man made debris in space
Recommend few good Nickelback songs
Can I jump out of a running train
If your questions are like this, with total random structure, you can focus on certain keywords or crust of the question and group them. Even if you can't group them, find out the required fields or mandatory words.
IntentA: How to deal with an annoying {person}
IntentB: What are the types of man made {item} in {place}
IntentC: Recommend few good {person} songs
IntentD: Can I {action} out of a running {vehicle}
The advantage of using slots here is that even if the user asks a partial question and an associated intent is triggered, you will be able to identify it and respond back with an answer/suggestion or error message.
Ex:
user: what are the types of man made mangoes in space
[IntentB will be triggered]
If you have configured this without a mandatory slot, your backend will be focusing on the intent triggered and will respond with the right answer (man made debris in space), which in this case won't make any sense to the user.
Now, with proper usage of slots and validation you can find that instead of debris your backend received "mangoes" which is not valid. And therefore you can respond back with a suggestion or error message like
"Sorry, I don't know that. Do you want to know about the man made debris found in space"
Grouping questions will help you to add other similar questions later with ease. You can use one intent per question if it is too difficult to group. But remember to validate it with a slot if you want to avoid the situation mentioned right above.
While naming question-intents use a prefix. This might help you to group handlers in your backend code depending on your backend design. This is not mandatory, just a suggestion.
Summary:
Group questions with similar structure.
Use slots appropriately and validate them.
Use predefined slots wherever possible.
Don't just depend on intents alone, because intents can be mapped if its the closest match. But the question might be entirely different or might not make any sense. So use slots appropriately and validate them.
If possible provide suggestion for partial questions.
Test thoroughly and make sure it wont break your interaction model.

You should check Alexa Dialog Interface that allow you to make Q/A or QUIZZ.
https://developer.amazon.com/fr/docs/custom-skills/dialog-interface-reference.html

Related

What is the right approach for handling direct and contextual questions in dialogflow?

I am creating a HR chatbot using Dialogflow. I am unable to figure out the right approach to have the bot handle both direct questions and questions asked in a contextual manner. For example:
Contextual case:
User: I want to know how many leaves i can get in a year
Bot: You get x number of leaves
User: Ok cool how do i apply for one then?
Bot: Follow this process to apply for a leave
Direct case (2 separate conversations with direct questions):
Conversation 1:
User: I want to know how many leaves i can get in a year
Bot: You get x number of leaves
Conversation 2:
User: I want to know how to apply for leave
Bot: Follow this process to apply for a leave
Approaches I have tried:
1) Adding input and output contexts to handle contextual cases and add direct questions to knowledge base.
The issue with this approach is that since we cannot give multiple phrases in knowledge base, most direct questions do not match
2) Have 2 intents, one with input and output contexts and one to handle direct questions. (For example: One intent would be leaves.apply.context which would have both input and output context set and would have training phrases like how do i apply for this and another intent leaves.apply.direct which would have training phrases like how do i apply for a leave and no context). I'm not convinced that this is the right way as I am essentially creating two intents for the same question with the same response.
So is there a recommended approach to solve this problem?
I don't think there is a recommended approach to this, it is a matter of taste. Your solutions are a nice way of approaching this, but I don't think you will get around the fact that you will have to make an extra intent with the same response if you want to allow a follow-up question to also be approachable directly due to the context.
If you really don't like to create two intents for the same response, I think you would be able to workout this scenario by creating two intents and dropping the contextual flow. Just create a HowManyLeavesAvailableIntent and a HowToApplyForLeaveIntent without any context and train the HowToApplyForLeaveIntent to trigger on phrases that would follow-up HowManyLeavesAvailableIntent and direct questions for HowToApplyForLeaveIntent. Due to the missing context, this might not be ideal because it can create weird mappings to intents, but it would allow you to have just one intent for how to apply for leave.

Is it possible to deviate from a conversation flow and come back to the original flow in DF

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.

How to create a search form with dialogflow

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.

entities vs follow-up intent

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.

Steering Alexa towards a specific slot value response

I've defined a custom slot types in the Amazon Developer console, the slot contains a list of names, as below.
homer simpson
ned flanders
principal skinner
comic book guy
I've then defined the sample utterances as below.
PlayAudio to play {Name}
So in the end, I want the user to be able to say something similar to the folliowing:
Alexa, ask the simpsons to play homer simpson
Alexa, ask the simpsons to play ned flanders
Alexa, ask the simpsons to play principal skinner
Alexa, ask the simpsons to play comic book guy
Of course, there is an extremely high chance that Alexa will hear the name incorrectly, so I need to be able to match the name that is heard as closely as possible one of the slot values.
How would I go about doing this, would I have to code it in the function or is there a better way?
When using custom slots, there is a chance that Alexa will provide a value not in the list. This gets specially problematic as the list grows in size. Using the beta testing functionality as Tom suggested can help but you won't be able to catch all the issues and eventually this will not scale.
I found out that the only way to completely ensure you are getting a value from your list is to have the full list in the skill and check against it every time. In order to check, exact matching is not always the best option and I've tried two approaches:
String Edit Distance functions: work well when a used may say incomplete utterances or add words to the utterances in your list. Check: https://en.wikipedia.org/wiki/Edit_distance
Acoustic/Phonetic: relatively easy to implement may work better for identifying foreign words or proper names. You can preprocess your list for quick comparisons. Check: https://en.wikipedia.org/wiki/Soundex
You are right that there is a high chance 'that Alexa will hear the name incorrectly'. My solution is to do a bunch of trial and error with human testers to discover what the common mis-interpretations are, and then hard-code fixes for those.
So I get a tester to say the different names and make a record of what they said. I then look at what Alexa gives me as the slot value, and where there are discrepencies I add a hard-coded substitution to my skill.

Resources