Dialogflow Distilled: On Preemptive Slot-filling versus Branching
As we gain experience with Google Dialogflow, we like to take a step back and identify usage patterns to feed in our development practices. This blog post aims at depicting and distilling one of such patterns: preemptive slot-filling versus branching.
Let’s say that one of your chatbot requirements is to perform a banking payment to a specific merchant. This is a fairly standard transaction involving a single intent capturing a few slots such as amount, account, merchant and a date.
Perfect. Easy peasy. You can also easily handle mixed initiative and have a user preemptively fill in the information such as “I wanna make a payment of 456.34$ to McGill University from my savings account today”. Golden.
But then at some point, a new requirement comes up and we now have to support different types of payment: one time payment and recurring payment. While nothing changes for a one time payment, a recurring payment would introduce new slots to fill: recurrence and optionally an end date. At some point within the dialogue, the chatbot needs to branch out to some other follow-up intent to fill in the missing pieces.
Hence, your bot would first capture merchant, amount, and account and then ask for the payment type, which would then have the dialogue fork onto different paths to complete the transaction:
That’s a good start! And the good thing is that’s pretty much built in Dialogflow: you would explicitly ask for the payment type as part of the intent response and then define two distinct follow-up intents that would pick up either one of the types and proceed with the remaining dialogue flow accordingly.
After a few weeks worth of production data, through careful conversation analysis, you’ve come to realize that many users preemptively ask for such a recurring payment: “I wanna make a recurring payment to Visa”. Oops. Now you have to support the payment type as part of the preemptive slot-filling, and you’re sort of out of luck with vanilla Dialogflow: you can’t really just add in this payment type specific slot to the “make payment” intent since the payment type would need to drive the actual dialogue behaviour. Indeed, some varying piece of information (i.e. recurrence details) would need to be captured based on such payment type. Or in other words,
as soon as some of the slot content steers the dialogue flow in one direction or another, one can no longer resort to default slot filling mechanism and has to rely on custom fulfillment logic.
So you have to roll-up your sleeves and fall back onto custom slot-filling fulfillment code. In order to support this behaviour, through fulfillment logic, we need to rely on two sets of custom event and associated follow-up intent that would deal with the actual payment type branching as necessary.
- First off, we go on and add the necessary slots within the top-level/parent intent, including the mandatory payment type backed by a custom entity (e.g. recurring and one-time) along with the optional (non-required) one-time date, recurring frequency and start/end dates.
- Then, we create two branching follow-up intents, one for the one-time payment and the other one for the recurring payment. Both of which would be set up so they can get triggered by a custom event from fulfillment.
- Then as part of the fulfillment code, independently from the fact that payment type has been provided preemptively or through required slot filling interaction, we will trigger the associated custom event to proceed with the next logical follow-up intent.
Putting it all together results in the following conversational capabilities:
Once you get the hang of it, this pattern can be applied to multiple scenarios similar to this one where you want to support preemptive slot filling while having one or multiple slots to influence or drive the dialogue flow.
Like any other of such pattern, this is one we are planning on integrating to our gush fulfillment SDK, which encapsulates such reusable components to help us move forward quicker as we engage with customer projects. Make sure you stay tuned as we plan on coming up with more of such patterns in the future.
Big thanks to my hard working colleagues Karine Déry and François Leroux for coming with this pattern in the first place. And thanks for @almonk for botframe.com.