/  Technology   /  A Step wise guide to create a Chatbot Using RASA

A Step wise guide to create a Chatbot Using RASA

In this article, I will guide you on how to build your own Rasa chatbot in a simple way.

 

Why Rasa Stack for Building Chatbots?

 

To build AI assistants and chatbots the best open source machine learning framework is Rasa. To build complex chatbots it’s time efficient and one of the most effective tools.

Rasa has two main modules:

  1. Rasa NLU for understanding user messages
  2. Rasa Core for holding conversations and determining what to do next

 

Rasa Component

 

Rasa X — It’s a Browser based GUI tool. By using GUI based interactive mode it will allow you to train Machine learning model.  It’s an optional tool in Rasa Software Stack.

 

Rasa NLU — This is the area, where rasa tries to know User messages to detect Intent and Entity in your message. Rasa NLU is a tool for intent classification, response retrieval and entity extraction in chatbots,most of which have some additional dependencies.

  1. Spacy (You need to install it separately)
  2. Tensorflow (By Default available with Rasa)

 

Rasa Core — It helps you with contextual message flow. Depending on User message, it can forecast dialogue as a reply and can trigger Rasa Action Server.

Whenever you do “pip install rasa” Rasa uses Tensorflow internally, or “pip install rasa-x”, by default it installs Tensorflow.

 

Prerequisite: Anaconda distribution to be installed.

Step 1:

 

Make a conda environment with the name of rasa(you can name anything).

 

conda create -n rasa python=3.6

 

Activate the rasa environment.

 

conda activate rasa

 

Step 2:

 

Install Rasa Open Source using pip.

 

Pip3 install rasa

 

Step 3:

 

Now create a new folder where you want to create the Rasa project and navigate into the folder.Now execute the below command to create a new Rasa project.

Below command creates a new basic Rasa project along with some required files that are essential to run Rasa project.

 

rasa init

 

It prompts with the below message. Then press enter.

Please enter a path where the project has to be created.

It prompts with another message

“Do you want to train an initial model?” . Press Y/n.

If you press “Y” then the essential model will be trained and this basic model is prepared to run.

If you press “n” then the model will not be trained and if you want to train the model later use the command “rasa train”

Once the project is made, you can see the below files are going to be created within the project folder.

 

rasa

 

 

Let’s understand the files created by Rasa.

Under the data folder, two files are created.The first file is nlu.md and therefore the other one is stories.md.

nlu.md: NLU means Natural Language Understanding and contains your training data.

The messages that have same meaning are grouped together and named with intents. Intent means finding the user’s intentions. After you train the model, Rasa will find the correct intent for your new/unseen messages.

Now, the new intent named as inform is added to our nlu.md file.

 

## intent:inform
- [telugu](language)
- [english](language)
- [hindi](language)
- [tamil](language)
- [malayalam](language)
- [Bahubali](movie_name)
- [Ala Vaikuntapuramlo](movie_name)
- [Villan](movie_name)
- [joker](movie_name)
- [Murder](movie_name)
- [Noescape](movie_name)
- [murder](movie_name)
- [villan](movie_name)
- [2020-05-13](planned_date)
- [2020-05-14](planned_date)
- [2020-05-16](planned_date)
- [2020-06-01](planned_date)
- [2020-05-18](planned_date)
- [2020-05-20](planned_date)
- [2020-05-22](planned_date)
- [2020-05-25](planned_date)
- [2020-06-20](planned_date)
- [2020-06-12](planned_date)
- [2020-06-16](planned_date)
- [2020-05-28](planned_date)
- [Asian Cinemas](theater_name)
- [PVR Icon](theater_name)
- [GVK](theater_name)
- [Forum Mall](theater_name)
- [Manjeera Mall](theater_name)
- [Prasad's Mlutiplex](theater_name)
- [PVR Cinemas](theater_name)
- [Gokul Theater](theater_name)
- [INOX](theater_name)
- [Carnival Cinemas](theater_name)
- [Platinum Movie Time](theater_name)
- [Asian Shiv Ganga](theater_name)
- [Sensation theater](theater_name)
- [Sensation Ismonia](theater_name)
- [Vijetha Theater](theater_name)
- [Bhujanga Theater](theater_name)
- [Carnival Movie Time](theater_name)
- [Asia Multiplex](theater_name)
- [PVR](theater_name)
- [GVK](theater_name)
- [10:00 AM](planned_time)
- [11:00 AM](planned_time)
- [12:00 PM](planned_time)
- [12:30 PM](planned_time)
- [01:00 PM](planned_time)
- [02:00 AM](planned_time)
- [04:00 AM](planned_time)
- [05:00 PM](planned_time)
- [07:30 PM](planned_time)
- [09:00 PM](planned_time)
- [1](no_of_tickets)
- [3](no_of_tickets)
- [5](no_of_tickets)
- [7](no_of_tickets)
- [9](no_of_tickets)
- [10](no_of_tickets)
- Book a [10](no_of_tickets) [Bahubali](movie_name) [telugu](language) tickets for [GVK](theater_name) on [2020-05-20](planned_date) at [09:00 PM](planned_time) show.
- Please Book a [5](no_of_tickets) [Villan](movie_name) [hindi](language) tickets for [PVR](theater_name) on [2020-06-12](planned_date) at [07:00 PM](planned_time) show.
- Kindly book a [2](no_of_tickets) [Noescape](movie_name) [english](language) tickets for [Krishna Mahal theater](theater_name) on [2020-05-28](planned_date) at [11:00 AM](planned_time) show.
- Book a [4](no_of_tickets) [Ala vaikuntapuramlo](movie_name) [telugu](language) tickets.
- Book [Bahubali](movie_name) tickets.
- I wanted to go for [telugu](language) movies
- Iam looking for [telugu](language) movies
- Iam palnnig to book [English](language) movies
- Iam palnnig to book [Hindi](language) movies
- Iam wanted to book [Bahubali](movie_name) [telugu](language) movie.
- I wanted to go for [Dhangal](movie_name) [telugu](language) movie
- Iam looking for [Robo](movie_name) [telugu](language) movies
- Iam palnnig to book [Bahubali](movie_name) [English](language) movies
- Iam palnnig to book [Bahubali](movie_name) [Hindi](language) movies

 

So, we have added the new intent(inform) and entities language, movie name, planned date, theater name, planned time, no_of_tickets.

Entity which is nothing but significant data and usually this can be names, date, time etc. The entities which are useful for taking next actions can be extracted from the intent.

Stories.md:The user interaction stories will be present here. In this file, we will explain our assistant how to reply to specific intents either in the form of text or actions. Actions can be whatever either calling the backend or some third-party API’s.

 

## happy path
* greet
- find_language_types
- slot{"language":"telugu"}
* inform{"language": "telugu"}
- find_movie_names
- slot{"movie_name":"Bahubali"}
* inform{"movie_name":"Bahubali"}
- find_available_dates
- slot{"planned_date":"13-05-20"}
* inform{"planned_date":"13-05-20"}
- find_theater_names
- slot{"theater_name":"Asian Cinemas"}
* inform{"theater_name":"Asian Cinemas"}
- find_show_timings
- slot{"planned_time":"10:00 AM"}
* inform{"planned_time":"10:00 AM"}
- find_no_of_tickets
- slot{"no_of_tickets":"5"}
* inform{"no_of_tickets":"5"}
- ticket_booking_form
- form{"name": "ticket_booking_form"}
- form{"name": null}
* goodbye
- utter_goodbye
## happy path 1
* inform{"language": "telugu", "movie_name":"Bahubali"}
- find_available_dates
- slot{"planned_date":"13-05-20"}
* inform{"planned_date":"13-05-20"}
- find_theater_names
- slot{"theater_name":"Asian Cinemas"}
* inform{"theater_name":"Asian Cinemas"}
- find_show_timings
- slot{"planned_time":"10:00 AM"}
* inform{"planned_time":"10:00 AM"}
- find_no_of_tickets
- slot{"no_of_tickets":"5"}
* inform{"no_of_tickets":"5"}
- ticket_booking_form
- form{"name": "ticket_booking_form"}
- form{"name": null}
* goodbye
- utter_goodbye

 

From the above code, we are teaching our assistant to execute the action(find_language_types) once the greet intent is identified, and fill the slot language. Language slot may be filled with any value.

Slot is nothing but a variable which holds the values entered by the user throughout the session and the slot values can be passed through next conversation.

 

Step 4:

 

domain.yml file defines your assistant domain. It contains list of intents, entities, slots, actions, responses.

 

session_config:
session_expiration_time: 60
carry_over_slots_to_new_session: false
 
intents:
- greet
- goodbye
- affirm
- deny
- mood_great
- mood_unhappy
- bot_challenge
- search_movies
- inform 

entities:
- language
- movie_name
- planned_date
- theater_name
- planned_time
- no_of_tickets 

slots:
language:
type: text
movie_name:
type: text
no_of_tickets:
type: text
planned_date:
type: text
planned_time:
type: text
status:
type: unfeaturized
theater_name:
type: text
 
responses:
utter_greet:
- text: Hey! Iam Bot. I can assist you in booking movie tickets. Please choose one of the following language of movies you wanted to go for?utter_cheer_up:
- text: 'Here is something to cheer you up:'
image: https://i.imgur.com/nGF1K8f.jpg
utter_did_that_help:
- text: Did that help you?
utter_happy:
- text: Great, carry on!
utter_goodbye:
- text: Bye
utter_iamabot:
- text: I am a bot, Assist you in booking movie tickets.
utter_ask_movie_name:
- text: I understand you like to go for {language} movies. Please enter the Movie Name.
utter_select_movie_name:
- text: I understand you like to go for {language} movies. Please select the Movie Name.
utter_ask_planned_date:
- text: Please enter the date in the format of dd-mm-yy
utter_select_planned_date:
- text: Please select the date.
utter_ask_theater_name:
- text: Please enter the theater name.
utter_select_theater_name:
- text: Please select the theater name.
utter_ask_planned_time:
- text: Please enter the time in the format of hh:mm
utter_select_planned_time:
- text: Please select the show time.
utter_ask_no_of_tickets:
- text: How many tickets you want to book?
utter_select_no_of_tickets:
- text: Please select number of tickets you want to book.
utter_booking_status:
- text: As per your interest, {no_of_tickets} tickets for {movie_name} {language}movie in {theater_name} on {planned_date} at {planned_time} booked successfully.  

actions:
- utter_greet
- utter_cheer_up
- utter_did_that_help
- utter_happy
- utter_goodbye
- utter_iamabot
- find_language_types
- find_movie_names
- find_available_dates
- find_theater_names
- find_show_timings
- find_no_of_tickets
- utter_ask_theater_name
- utter_select_theater_name
- utter_select_planned_time
- utter_ask_movie_name
- utter_select_movie_name
- utter_ask_no_of_tickets
- utter_select_no_of_tickets
- utter_booking_status
- utter_ask_planned_date
- utter_select_planned_date
- utter_ask_planned_time 

forms:
- ticket_booking_form

 

Rasa predicts the user intention as per the user message and identifies the intent from nlu.md file and depending on the intent the respective utterance will be activated as per we have mentioned in stories.md file.

So, if the utterance is action then respective action will be triggered from actions.py file and if the utterance is response then the respective utterance response(“Bye”) will be executed as per domain.yml file.

In the same way, If the user enters as “hello”, the Rasa predicts the intent as “greet” from nlu.md file and the action “find_language_types” will be activated as per stories.md file which we will be implementing now in actions.py.

 

Step 5:

 

actions.py contains code for custom actions. If your bot wants to do some action when a specific intent is triggered then you can implement the custom actions in actons.py file. Whereas, if your bot wants to display a simple response then you can manage these responses in the domain.yml file.

 

## Importing the required libraries 
from rasa_sdk.forms import FormAction
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from typing import Any, Text, Dict, List
from rasa_sdk.events import SlotSet, Form
import logging
import datetime 
LANGUAGES = {
    "telugu":
        {
            "name": "telugu",
            "resource": "tl"
        },
    "english":
        {
            "name": "english",
            "resource": "en"
        },
    "hindi":
        {
            "name": "hindi",
            "resource": "hn"
        }
} 
def _resolve_name(languages, resource) ->Text:
    for key, value in languages.items():
        if value.get("resource") == resource:
            return value.get("name")
    return ""
class FindLanguageTypes(Action):
    """This action class allows to display buttons for languages to choose.""" 
def name(self) -> Text:
        """Unique identifier of the action"""return 
"find_language_types" 
def run(self,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict[Text, Any]) -> List:

        buttons = []
        for t in LANGUAGES:
            language = LANGUAGES[t]
            payload = "/inform{\"language\": \"" + language.get(
                "name") + "\"}" 
buttons.append({"title": "{}".format(language.get("name").title()),
                 "payload": payload}) 
# TODO: update rasa core version for configurable `button_type`
        dispatcher.utter_button_template("utter_greet", buttons, tracker)
        return []

 

The above function displays buttons to choose available language movies. You can call the API to fetch the data, instead of considering the Languages dictionary,

So, if you run the application and enter a message “hi”, then “greet” intent will be identified by Rasa and then “find_language_types” action will be executed and displays buttons as below.

 

 

Let’s assume, If you click on “telugu”, then the “/inform{“language”: “telugu”}”(which we have appended the payload to the buttons in the find_language_types action) intent will be identified and then corresponding action “find_movie_names” will be called.

 

Step 6:

 

Credentials file contains credentials of various platforms in which your bot is running.We run our bot in a simple webapage which uses socket connection to connect the bot. A Socket is helpful to send/receive messages and it is a bi-directional protocol which listens continuously.

To run our bot through socket channel add the below code.

 

socketio:
user_message_evt: user_uttered
bot_message_evt: bot_uttered
session_persistence: true/false

 

Step 7:

 

endpoints.yml: It contains different endpoints your bot can use. We will tell the bot to listen our actions from the host — localhost, through the port — 5055 and /webhook is the endpoint. This can be done by adding the below code into the endpoints file.

 

action_endpoint:
url: "http://localhost:5055/webhook"

 

Step 8:

 

Config.yml: Configurations related to NLU and the Rasa core is contained in this file. It also contains different pipelines which are used to predict the specific intent and extract the entities. To respond to how and what the next action should be we use policies.

 

Step 9:

 

Run the bot with the following command.

 

rasa run -m models --enable-api --cors "*" --debug

 

So, our bot will run in http://localhost:5005with the above command.

And simultaneously run the rasa actions with the below command

 

rasa run actions

 

By running below command you can test your bot with Rasa UI and click on top left icon talk to your bot.

 

rasa x

rasa

 

Hence, can integrate your bot into any webpage or into your existing website.

So finally, you can build a simple movie ticket booking bot by following with these steps.

 

Leave a comment