How to build chatbots to deliver rich experiences

neha thakur
Saarthi.ai
Published in
9 min readMay 20, 2019
Charting out enriching and useful conversational flows are paramount to adoption of your chatbot

Popularity of Conversational AI driven virtual assistants has been soaring ceaselessly, and with it, the curiosity to understand the underlying dialog framework in the process of chatbot development.

“How to make a chatbot” is indeed a question of tautological nature, as it has now started to circle around the internet among the NLP community and aspiring chatbot developers, as they start unravelling the process of chatbot development.

NLU (Natural Language Understanding) and Dialog Management are essential parts of the chatbot architecture. While, the NLU engine of any framework is tasked with understanding natural language, the Dialog Manager is responsible for state management, or in other words, understanding the context of the conversation.

The effectiveness of any chatbot, therefore, is commensurate with how well its Dialog Manager can grasp the intention of the end-user in a conversation. This is where context variables come into the picture.

This article is aimed at helping readers learn better about chatbot development and design with the help of Context Variables.

To specifically focus on a single chatbot development framework and how dialog management works, we will be using RasaCore, as our Dialog Manager.

Understanding the role of Context Variables in Dialog Management

Virtual assistants today are so advanced that they can perfectly target the user according to their choices, likes and dislikes.

This robustness in conversational design of the conversational agents is possible due to their ability to memorize important information about the users. Here comes the role of Context Variables.

Let us now fasten our seat-belts and take a ride through all the information about slots and how efficiently we can use them in Rasa. Rasa is an open-source chatbot development framework, which can be used as a Dialogue Manager for creating chatbots.

Outline

Context Variables help memorize important user data and improves UX.

In this article, we shall have a look at the following topics —
1. Introduction
2. Types of Slots
3. Slot Set Techniques
4. Slot Filling using Forms
5. Slots affecting Dialogue Manager training

1. Introduction

Slots are nothing but a storehouse, where we can save any information about the user or data extracted from the external world.

Slots are bot memory. Ultimately, slots let your bot filter what type of answers will match the user’s intent and subsequently choose the correct response.

For instance, if a user wants to order a pepperoni pizza, the utterance provided by the user would be —

“I would like to have a pepperoni pizza please.”

The bot would identify the intent as place_order, and extract out the entity pizza_type as “pepperoni”. Now, the pizza type information needs to be stored by the chatbot in order to use it to make API calls. Therefore, we have our slot pizza_type store the information “pepperoni” throughout the conversation.

From there, your virtual assistant can place the order for the correct pizza and then respond to the user with payment and order details.

After this, the assistant can place order for the user and reply with appropriate response that we desire from the bot.

Context variables also help us make our bot smarter, to suggest pepperoni to the user next time he or she tries to order a pizza.

2. Types of Slots

Let us now get to know more about slots and its various types that we can use in our chatbot.

In Rasa Core, slots are defined in the domain file in the slots section. An example is given below —

slots:
name:
type: text

The slot type shown in above example is text. Text Slot is basically a type of slot which can store the information in the form of string. Text slot is used when the slot type is such that the bot should only care whether or not the slot is filled.

Let us now learn about more types of slots:

Boolean Slots are also a type of slot which can store True or False, based on the type of information that the slot encounters.

slots:
is_logged_in:
type: bool

Categorical Slots are those which can be used to store different categories of information. Boolean slots can also be defined as categorical, by stating only two categories as true or false.

slots:
humidity:
type: categorical
values:
— low
— medium
— high

List Slots are those slots which can store the information in the form of a list. This slot type is used when we have to store multiple values under a single key. Yes! Slots are nothing but key value pair.

slots:
mobile:
type: list

Each slot is featurized and used in the flow of conversation which helps in predicting the next action of the bot. The slot being set is a different scenario or story than when the slot is empty.

3. Slot Set techniques

Slots can be set through various methods of input namely Entities, Buttons and Actions, whichever is meaningful during the dialogue

In Rasa Core, slots can be set in various ways. The first method is by providing an initial value of the slot while defining the slot in the domain file. The domain definition is shown below —

slots:
name:
type: text
initial_value: “human”

However, slots also get set during conversations.

Slot Set from Entity Extraction

From our NLU (Natural Language Understanding) model, we have our entity extraction setup ready. Each entity extracted from the user’s utterances is very important and the bot needs to remember the entity.

Therefore, in Rasa Core , if we have the slot name same as the entity name, then the slot is automatically set with value same as that of the entity. This can be easily visualized from the story as shown below —

# my_example_story
* show_balance{“account_no”: “5656138511”}
— slot{“account_no”: “5656138511”}
— action_balance

Slot Set from Buttons

Buttons are used to get quick responses from the user. Each button template used in the domain file has 2 parts: title and payload. The payload consists of the information that is to be passed to the bot when the user clicks that particular button.

utter_ask_color:
— buttons:
— payload: ‘/choose{“color”: “blue”}’
title: “blue”
— payload: ‘/choose{“color”: “red”}’
title: “red”
text: “What color would you like?”

The slot color is set to blue if user clicks on button 1, or red if the user chooses the other button.

Slot Set Using Custom Actions

Custom actions are used in RasaCore in order to execute the code that we want the bot to execute whenever it is predicted to.

For example, the process of searching hotels cannot be successfully completed by simply uttering something to the user. There needs to be a code running, which can accurately search for hotels and return the user with a wide variety of choices to choose from.

After running the hotel search action successfully, the bot needs to memorize the hotel-list that it extracte. Here comes the use of slots.

In the run method of each action, we can return events. There is an event called SlotSet. This can be used to set slots from actions.

from rasa_core_sdk.actions import Action
from rasa_core_sdk.events import SlotSet
import requests

class HotelSearchAction(Action):
def name(self):
return “action_hotel_search”

def run(self, dispatcher, tracker, domain):
url = “http://allhotels.com” ## hotel api
data = requests.get(url).json
return [SlotSet(“hotel_list”, data[“hotels”])]

4. Slot Filling Using Forms

There are situations where we need to extract multiple information from the user in order to perform an action. For example, to book a flight, the bot needs to ask the user about the source, destination, seat preference, price range, preference of meal and more. Only then the bot will be able to book a flight for the user successfully.

In order to collect multiple pieces of information in a row, it is better to use Forms in RasaCore. Forms are custom actions which inherit the parent class FormAction.

How does it work?

Once the form action gets predicted, the assistant keeps asking for necessary details until all required slots are set.

There are no restrictions on how the user should provide the details — if a user specifies all preferences in the initial restaurant request, for example, ‘Book me a table for two at the Chinese restaurant’, the assistant will skip the questions about the cuisine and number of people.

If the user does not specify any of these details in an initial request, then the assistant asks all the details in follow-up questions until all of them are provided.

Both of these situations represent two different conversations (there can be more than two), but by using FormsPolicy, they both will be learned using the same, single story.

Forms are defined in the domain file in the forms section.

forms:
— flight_form

The forms are also used in writing stories in Rasa Core. An example story is shown below.

## searching for flights
* search_flight
— flight_form
— form{“name”: “flight_form”}
— slot{“requested_slot”: “source”}
* form: inform{“source”: “Delhi”}
— slot{“source”: “Delhi”}

Here, the flight form is activated as soon as the user starts to ask anything regarding searching for flights. The requested slot is source as the slot is empty as of now. The user then informs the bot about the source which is set in the source slot. After this, the next slot in the form is requested.

Check out the data/stories.md file of the Formbot example to understand training stories in more detail.

Let us now look at the flight form which is written in the actions file.

class FlightForm(FormAction): def name(self):
# type: () -> Text
“”” The name returned by this method must be
defined in the domain file of the bot. “””
return “flight_form”

@staticmethod
def required_slots(tracker):
“””A list of required slots that the form has to fill”””

return [“source”, “destination”, “seat_type”,
“meal_preferences”, “price_range”]

def submit(self, dispatcher, tracker, domain):
“””Define what the form has to do after
all required slots are filled”””


dispatcher.utter_template(‘utter_submitted’, tracker)
dispatcher.utter_template(‘utter_please_wait’, tracker)
return []

The advantages of using forms are —

· If at the starting of the form, some of the slots are already filled because of the latest user utterance, then the form would skip requesting for the slots that are already filled. Thus eliminating any redundant conversational flows.

· It is easier to validate the slot values using forms. As soon as any slot is filled in the form, the validate function is executed where we can easily validate each slot by writing cases for each of the slots differently.

· The submit function of the form only executes after the successful extraction of all the required slots. Therefore, systematically, we can write the code that we want to execute in the submit method of the Form.

5. Slots affecting Dialogue Manager training

Efficient use of slots affects robustness of chatbots

As discussed in Section 2 of this blog, the various types of slots are featurized in order to predict the next action. The slots are used to determine the flow of the conversation.

For example, if we have a slot named authenticated, and it is set true, then it means that the user is logged in as a verified user. The bot will never predict the action to validate the user in this flow since the slot authenticated is set True throughout the conversation.

There is also an unfeaturized slot type which can be used if we do not want to use the slot to affect the flow of the conversation.

A simple example would be name of the user. Let’s assume, for some reason the bot could not set the name slot. This should not affect the flow of conversation. Because the name of the user would only be used to greet the user.

Therefore, using the slots efficiently in our domain could determine the robustness of our chatbot.

Conclusion

With this article, I hope you were able to grasp how conversational flows can be made efficient and frictionless using Context Variables in Dialog Managers, and get further in the process of chatbot development.

Please comment below with your questions or suggestions to improve the article. If you found this piece fruitful, share it with others who you think would benefit from this and don’t forget to give it a clap :)

If you want to know more about chatbot development and the nuances of Conversational AI, do give these extremely detailed pieces a read:

Emotion Detection from Hindi Text using ULMFiT

Roadmap to Chatbot Development — Part 1

Building Custom NER in Vernacular Languages using Context based Word Embeddings

Send us a shout or stay tuned with the latest on our Twitter

--

--