A systematic approach to building and analyzing your Dialogflow bot's behavior will go a long way towards helping you develop better Dialogflow bots.
In this article, I introduce the CTFS framework which will be very useful for analyzing your Dialogflow bot's behavior.
If you have used contexts in your Dialogflow agent, and have ever wondered why a completely different intent (than what you expected) matched the user query, you should read this article.
This is the first part of a series which introduces some theory about how Dialogflow works under the hood.
First, here is a little puzzle:
Before you move on to the next part, try and explain to yourself what is going on.
So you saw in part 1 some unexpected behavior from Dialogflow.
Did you spend some time thinking about what is going on?
You can watch part 2 to understand what happened.
Now that you understand why the default context lifespan used in the followup intents can make it difficult to understand/predict your chatbot's behavior, we will take a look at an alternate approach in the next lesson.
An alternative approach
So you have understood the problem in using follow up intents.
But the notion of the follow up intent is still very practical. So how can we simulate the follow up intent and get similar behavior? I explain how in the 3rd video.
When using the context lifespan of 1, you lose the ability to save the values you collect during the conversation. However, you can get around this issue with a little more planning and by using a "session variables" style context.
I explain how in this video.
Reading from session variables
In the previous lesson, you saw how you can mimic "session variable" contexts to store user inputs.
What happens once we use the session-vars context? How can we read the values out? I give you a quick overview in this video:
I didn't explicitly mention it in the video, but the idea is that at the end of your dialog, you can access the values inside the session-vars context by either #session-vars.variablename if you are simply using it in the text response section, or by parsing the JSON sent to the webhook and extracting the appropriate value if you need to send the values over to your business logic code.
Fallbacks for Followup Intents
There are also other issues when using followup intents.
For example, it is very hard to design good fallbacks inside a followup intent tree when user provides an unexpected input. In the video below, you can see why.
So what is a good way to create fallback intents in this scenario?
When you use a flat structure to mimic the behavior of the followup intents, you also get an extra benefit: it is much easier to design good fallbacks.
What are good fallbacks?
My definition is: good fallback design should allow you to choose the number of times you want the user to attempt to correct their mistake.
It may not even be a mistake sometimes. It is well known that date inputs work better in a certain format (mm-dd-yy) than others (mm/dd/yy).
In fact, someone asked me a question related to this:
Here is the link I mention in that reply.
At any point in the conversation, there is a set of intents which can fire. We will call these candidate intents. To understand candidate intents, it helps to first understand which intents cannot fire.
Which intent cannot fire?
Suppose an intent has an input context called ContextA. Unless ContextA is active at that point in the conversation, the intent cannot fire.
An intent with no input context can fire anytime
If an intent doesn't have an input context, it can fire (i.e. be mapped) at any point during the conversation.
The video below explains candidate intents:
I also have another article where I go into this topic in some depth.
There will usually be many candidate intents which can fire at any given point in the conversation. But if we are building a chatbot to achieve specific goals, we would like only a set of specific intents to fire.
Let us call these target intents.
Clearly, target intents are a function of where you are in the conversation. A target intent for the first step in your conversation is almost certainly not going to be a target intent for a future step, because otherwise we would be regressing during the conversation rather than moving forward.
In the video below, I explain target intents.
The idea behind fallback intents is mostly the same as how they are defined in Dialogflow. There are two kinds - the "catch-all" fallback intent without any input context and the "context-based" fallback intent which does have an input context.
I explain more in the video below:
Now that we have defined the ideas of candidate, target and fallback intents, we can look at the next concept which will help us pull all these together - the surplus intent.
A surplus intent is the opposite of the target intent - it is a candidate which you don't want to fire at a given point in the conversation. An excellent example is the intent which was introduced at the beginning of this series which fires when it isn't expected to: the intent which captures the first name.
Here is an explanation of surplus intents:
Les has commented:
Great tutorial, even though I had to watch it ten times to sink your unique concept of CTFS.
Well, I think it is because I hadn't used a full example to explain target and surplus intents the first time around.
If you would like to understand CTFS using a more concrete example, you should check out my YouTube playlist where I use the florist bot (which was created by the Dialogflow team to explain how contexts work).
Now that you are familiar with the concepts of candidate (C), target (T), fallback (F) and surplus (S) intents, you can use these for building better Dialogflow chatbots.
Here is a formula which roughly summarizes what we have learnt till now:
C = T + F + S
# of candidate intents = # of target intents + # of fallback intents + # of surplus intents 
System design goals
Given this equation, what is our goal in designing our chatbot?
We should try and minimize the total number of candidate intents at any (and every) step in the conversation. This helps Dialogflow with its pattern matching - if there is only a small group of candidates, Dialogflow is less likely to make errors in its intent mapping.
Make S = 0
If possible, you should never have surplus intents. Every surplus intent is a potential mapping error, as we saw with the intent which captures the first name (in the follow up intent tree example from part 1).
This follows from the first goal, we would also like to minimize the number of target intents at a given step in the conversation.
As you build out your chatbot, do the following exercise.
This will help you narrow down the options at each step in the conversation, and help produce much more predictable intent mapping in your Dialogflow chatbot. In turn, this will lead to easier debugging and faster development iterations.
Need some help with this analysis?
Would you like some help using these rules of thumb to design your chatbot? Get in touch. Don't get too hung up on deciding if a particular intent is a target intent or not at a specific point in the conversation. In certain types of bots (e.g. question answering bots), it can be quite hard to figure this out precisely. Use this equation as a rule of thumb.
- How to learn Dialogflow in a week
- Reader Question: Do I need a contextual fallback intent for every single context?
- Reader Question: Can I use a single agent for Facebook, WhatsApp and website bot?
- Five ways to integrate a Dialogflow chatbot into your website
- BotFlo vs Dialogflow CSV Importer
- Build Better Dialogflow Bots
- Deploy NodeJS Webhook to Google Cloud
- Dialogflow Firebase Tutorial
- Reader Question: Is there a feedback mechanism to like and dislike a Dialogflow response?
- How to debug your Dialogflow bot