Conversational UX for chatbots

An overview of essential discourse patterns, part 2

This is a continuation of our description of essential discourse patterns for chatbots. If you haven’t read it already, part 1 (which was about error handling and error messages) is right here. In this section, we will take a more varied approach and talk about counter proposals, contextual constraint checks and digression.

Counter-proposals

A conversation with a chatbot doesn’t have to follow a simple question-answer structure. For example, bots can offer suggestions to the user: this paves the way to even more complex interactions. This means more fluid and natural conversations, but also that more efforts need to be made in the dialogue’s design.

If your bot suggests actions or responses, one thing that should be considered is the potential desire for the user to modify them. This is what we call a counter-proposal. It follows the following structure:

  1. Chatbot makes a suggestion
  2. User refuses the suggestions and modifies it
  3. Chatbot acknowledges the correction.
To feel organic, a good counter-proposal should require exactly one interaction from the user, immediately after the bot’s proposal.

The simple fact that the user is correcting the new value implies that the original proposal is refused. Of course, you could always achieve the same effect with more steps:

  1. Chatbot makes a suggestion
  2. User refuses it
  3. Chatbot asks what user wants
  4. User says it
  5. Chatbot acknowledges.

But it feels contrived, and only supporting that structure could lead to a scenario where the user would have to repeat the same information twice. This is a cardinal sin in chatbot-land:

Feels more artificial than intelligent, right? This is why it is not recommended to implement bot suggestions without support for counter-proposals if you want to offer a more natural conversational experience, like so:

Contextual constraints for entities

Out of the box, most conversational frameworks (like Google Dialogflow or IBM Watson) offer some ways to control what information can be extracted as entities in the dialogue. Typically, there are two options: use already defined system entities or create custom entities, most of the time by writing a list of possible values, although some platforms also accept regular expressions to delimit what can be extracted as a given entity. Here is an example of Entity declaration in Dialogflow:

This is all very nice and useful, but it can be quite lacking in terms of flexibility. While the type of an entity is a pertinent information, in a lot of situations, it’s not in itself enough to control the flow of the dialogue. Suppose you want your bot to ask for a date to, let’s say, book a flight. To check if the answer given by the user is actually a date is one thing, but it’s another to verify that the date is valid in the context of the conversation. Here, one constraint would be that the date needs to be in the future. But in another conversation, it could be perfectly valid (or even expected) for the user to give a date in the past (like if he’s asked for his birthdate). The constraints can also be defined by a dependency on another entity. To keep the flight booking example, if the bot asks for a return date, it stands to reason that it must be posterior to the departure date.

Constraints check on entities is a basic conversational pattern that can be very useful to control the flow of a dialogue.

Of course, like any conversational concept, constraints checking is not a silver bullet; it is but a piece of a larger puzzle.

Digressions

According to the Oxford English Dictionary, a digression is “a temporary departure from the main subject in speech or writing.” This is something we humans do everyday: a quick discursive detour to ask for more information or inject a little by-the-way to an ongoing conversation. Our brain is naturally wired to easily handle this kind of context switching. Most dialogue models for chatbots, sadly, are not.

It’s a shame, really, because digressions should not be considered as an optional feature, but as a cornerstone of dialogue design.

The ability for a bot to handle multiple concurrent dialogue contexts is fundamental to create a believable conversational virtual agent.

Without this, chatbots feel very limited, constrained to a specific discursive path from which the user is not really permitted to stray. Of course, digression support is not magic either, and chatbots, especially task-oriented ones, will probably always be restrained, at least to some extent, to a relatively small conversational perimeter. But supporting digression is mostly about empowering the users by giving them more control on the flow and the shape of the dialogue.

There are a lot of interesting use cases for digression. One of them is informational query, where the user needs the bot to give them some crucial details before they can make a decision. This can be coupled with bots proposal (and, possibly, counter proposal)

When the user asks how much money he has in his account, he doesn’t really want to change the subject: he just needs more data (in this case, how much money is available in his savings account) in order to make an informed decision. This can be a very useful tool to improve the user-friendliness of a chatbot. Also, we can see from this example that dialogue patterns are not components that are to be integrated in isolation; they can mesh together to provide a more pleasant flow to the conversation.

Hopefully you have gained some knowledge about conversational design and why it matters by reading this article. Thanks to my colleagues Linda Thibault, Pascal Deschênes and Karine Déry for their precious input.