How to Build a Secure AI Chatbot Using RASA & Python

Sakshi GuptaSakshi Gupta | 6 minute read | June 14, 2021

In this article

In this series 2 of the blog post on how to build a secure AI Chatbot using RASA and Python, we will learn how to level up from Basic NLU to Dialogue Management & Custom Actions.

How to Build a Secure AI Chatbot: What Did we Do in Part 1?

YouTube video player for Nk9K4s8g9yQ

If you haven’t read part 1 of this blog, you can read it here in the blog: chatbot using RASA.  In the first part, we discussed in detail the RASA framework. Using the RASA NLU component of the framework we started coding “Trippy: The Travel Agency Chatbot”. For Trippy, we created the training data and trained the model to identify the intent in the user query. So far, Trippy is able to identify when to:

  1. Greet the customer.
  2. Give information regarding flights or trains from one source to another destination.
  3. Show upcoming itineraries for a customer.

So basically the Chatbot can do natural language processing(NLP) on the incoming query and identify the intent.

Objective of Part 2?

In this part, we will use RASA Core components which form the dialogue engine to make an AI chatbot converse with the customer. So far, we have created three files in the “trippy” base directory:

  1. trippy/data/ The file holds the training data.
  2. trippy/config.yml: The config.yml file holds the configuration of the pipelines.
  3. trippy/ This file has the code to train the model and parse a sample text to extract the intent of the query.

In this blog, we will learn how to use the concept of Stories, Domain and Custom Actions to code the desired capability. So, let’s begin.

Dialogue Management: Teaching the AI Chatbot How to Respond

The dialogue management aspect is handled by the “Core” model of the RASA framework. A core model learns from data in the form of “stories”. You can learn more about Stories here. In short, a story is a formatted representation of a conversation between a user and the chatbot. An example of a story from the official documentation is as shown below:

Source: RASA

Let’s understand the format of a story.

  • Every story starts with a name denoted by ## followed by a name. You can name a story anything. It is just like naming a variable.
  • An * denotes messages sent by the user in the entity: value pair format.
  • A denotes the name of the action taken by the bot.
  • In case an action returns an “event” then it should be specified immediately on the next line following the action.

Before we go ahead and create stories for Trippy, let’s also understand the concept of Domains and Actions.

A DOMAIN is a universe in which the AI chatbot functions. It includes all the intents, entities, slots, actions and optionally responses that the bot should be aware of. We covered intents and entities in detail in part 1. Let’s understand the other three.

  • SLOT – Placeholder for information that needs to be tracked during a conversation. Example of a “categorical” slot from the documentation:
Source: RASA

You can read more about other types of slots here.

  • ACTIONS – These are things that the bot is expected to do or say in response to the user’s query. There are four kinds of actions that the RASA framework supports:

Utterance actions: start with utter_ and send a specific message to the user.

Retrieval actions: start with respond_ and send a message selected by a retrieval model.

Custom actions: run arbitrary code and send any number of messages (or none).

Default actions: e.g. action_listen, action_restart, action_default_fallback.

  • RESPONSES – These are simply the messages that the bot sends back to the user. These can be directly stored as strings in the domain file or can be generated as action responses or by creating a custom Natural Language Generation service. You can read more about responses here.

Now that we have an understanding of Stories and Domain, let’s create the stories and domain files for Trippy. If you recollect from Part 1, Trippy is coded to handle the following intents:

  1. greet
  2. thanks
  3. bye
  4. search_flights
  5. search_trains
  6. find_itineraries

First, we will create the file. Here is a snippet of the file. You can request access to the complete file by sending us a request <form_link>.

Snippet of file

Now, let’s create the domain.yml file. This file should contain all the intents, entities, actions and responses. The domain.yml file is as shown below:

Snippet of file

If you look at the responses section of the domain.yml file, you can see that it defines the responses for utter_ actions. There are other actions which are named action_ which are not defined here. Since these actions are not expected to return static text and in real-world, these should execute some query/search etc. these are examples of Custom Actions. You can read more about how to configure custom actions here. We will use the python code to define our custom actions. For this, we will create a file “”. In this file, we define and map a class for each of the custom actions mentioned in the domain.yml file.

In a real-world scenario, the AI chatbot needs to compute, retrieve, process information gained from intent and entity extraction. This file is where you can do all of that.

Snippet of file

There are some additional steps required to be performed to make these custom actions available for the AI chatbot. We need to define the endpoint url in the file endpoints.yml. Don’t create this file right now, it will get created automatically (as we perform some steps later).

You may have noticed that we also defined an action utter_unclear in and domain.yml file. This action will be taken when the chatbot is not quite confident about the intent/entity predictions. To leverage this, we need to set and define some policies in the config.yml file. The file snippet is as follows:

File: config.yml

Now that we are using more framework components, it will be better to use less python code and more framework function to tie all these configurations and data together. So we will do things a little differently from part 1. It is recommended that you create a new directory for this.


  1. Install rasa
  2. Install spacy
  3. Install rasa-sdk


  1. Create a new directory and switch
    >> mkdir trippy_2
    >> cd trippy_2
  2. Create a new Rasa project
    >> rasa init –no-prompt
    This will automatically create all the files that the project needs (with some data for the default demo project).
  3. Copy the data from the trippy/data/ to trippy_2/data/ file.
  4. Copy the data from the file to trippy_2/data/ file.
  5. Copy the data from the domain.yml file to trippy_2/domain.yml file.
  6. Copy the code from to trippy_2/
  7. Copy the configuration from config.yml to trippy_2/config.yml file.
  8. Edit the trippy_2/ endpoints.yml file. Uncomment the following lines:
    url: “http://localhost:5055/webhook” In a different shell, start the action sever:
  9. In a different shell, start the action sever:
    >> cd tripp_2
    >> rasa run actions
A screenshot of a cell phone

Description automatically generated

10. Start the training:
>> rasa train
11.Start the shell to engage with the model:
>> rasa shell –endpoints endpoints.yml

Inspired by this analysis and want to learn how to do it / wish to replicate this for your project? We can help you there. Just leave your email address in this google form and we will share the analysis with you within 48 hours.

An image of interaction with Trippy is as shown below:

Interaction with Trippy using Shell

Additionally, you can also see that the custom actions are also able to receive the entities and intents extracted from the code.

Entities and Intents extracted from Query in the Custom Action Code

You can see that Trippy is much more evolved now and is able to handle a sequence of flows in an expected manner. These capabilities are achieved using framework components without having to write a lot of code with complex IF-ELSE like statements that are good from maintainability and scalability aspects. In a real-world scenario, one rarely exposes chatbots through command-line. Trippy as of now interacts with the user through the Rasa shell. In the next Blog of this series, we will learn how to deploy Trippy on a Messaging Platform. We will be deploying Trippy on Slack. We will soon publish part 3 of the series.

For further reading, learn more about data science here or see the breakdown of the job description of a data scientist here.

Since you’re here…
Curious about a career in data science? Experiment with our free data science learning path, or join our Data Science Bootcamp, where you’ll only pay tuition after getting a job in the field. We’re confident because our courses work – check out our student success stories to get inspired.

Sakshi Gupta

About Sakshi Gupta

Sakshi is a Senior Associate Editor at Springboard. She is a technology enthusiast who loves to read and write about emerging tech. She is a content marketer and has experience working in the Indian and US markets.