Using the Rasa Framework for Creating Chatbots

0
1092
creating chatbots apps

“AI (artificial intelligence) is going to change the world more than anything in the history of mankind. More than electricity,” said Dr Kai Fu Lee, AI oracle and venture capitalist. His words ring true today, as AI pervades almost every part of human life. This article talks about how chatbots can be built using the Rasa framework.

All of us use artificial intelligence and machine learning (AIML) technology in some way or the other today — be it video predictions, online shopping, social media, surveillance, food delivery, transportation, self-driving cars, and so on.

National language processing (NLP) is a discipline of AI that is used to help understand, interpret and manipulate human language. Let us first look at NLP and its applications, and then build a chatbot from scratch using the Rasa framework.

Natural language processing
NLP helps computers communicate with humans in their own language and scales other language-related tasks. For example, it opens up the possibility for computers to read text, hear and interpret speech, as well as measure sentiment and determine important parts of it.

Today’s machines can analyse more language based data than humans, without fatigue and in a consistent, unbiased way. Considering the staggering amount of unstructured data, from medical records to social media, that’s generated every day, automation is critical to fully analyse text and speech data efficiently.

Sample applications of NLP include sentiment analysis, customer reviews, customer segmentation, anomaly detection, product improvement; topic modelling such as coming up with new topics from the text and using them to assign new supervised learning labels, providing insights that are too difficult to find from manual searching; and text categorisation of animal species, fake news, bank transactions, etc.

Chatbots
A chatbot is a computer program that simulates human conversation through voice commands, text chats or both. Short for chatterbot, it is an AI feature that can be embedded and used through any major messaging/text application. This automated program interacts like a human, and costs little to nothing to engage with. Key examples are those used by businesses in Facebook Messenger, or as virtual assistants, such as Amazon’s Alexa.

Chatbots tend to operate in one of two ways—either via machine learning or with set guidelines.

Rasa
Rasa helps in creating virtual assistants, which are used to automate human-to-computer interactions across platforms ranging from websites to social media. It supplies conversational AI infrastructure for a global community of developers, providing the tools to build chat-based and voice-based contextual assistants.

Rasa is powered by open source software and runs across organisations ranging from startups to Fortune 500s, and industries like healthcare, financial services, retail and insurance. It has three main functions, which together provide everything needed to build a virtual assistant.

Natural language understanding: It converts raw text from user messages into structured data, parses the user’s intent and extracts important key details.

Dialogue management: Machine learning-powered dialogue management decides what the assistant should do next, based on the user’s message and context from the conversation.

Integrations: It has built-in integration points for over 10 messaging channels, plus endpoints to connect with databases, APIs, and other data sources.

Installation
The first step is to install Rasa.

Installation
The first step is to install Rasa.

% python -m venv env
% source env/bin/activate
% pip install rasa 
	For UI: pip install rasa-x -i https://pypi.rasa.com/simple [optional]
% rasa init # setup the basic file structure
% update config.yml and endpoint.yml [optional]
% rasa train # train your model
	% rasa train nlu
	% rasa train core
% rasa shell # run the bot from shell
% rasa run actions # action server
% rasa data validate # validate if the data given in the configuration is good
% rasa run -m models --enable-api --cors “*” --debug # run the rasa as rest http server

A sample UI installation (not associated with Rasa) is given here. To have conversations with Rasa in the user interface (UI), there is a module called chatroom. It is ReactJS based (URL: https://github.com/scalableminds/chatroom).

% mkdir ui; cd ui
% git clone https://github.com/scalableminds/chatroom.git
% cd chatroom
% yarn install
% yarn build (after any customised changes)
% yarn serve # to run the ui server
% update the index.html with the address of the rasa server running

Open the URL http://127.0.0.1:8080/index.html in Chrome, as seen in Figure 1. (Note: Chrome is the supported browser for now.)

Initial page loaded using the chatroom module
Figure 1: Initial page loaded using the chatroom module

Figure 2 shows the sample conversation, which was written from scratch using Rasa.

Sample Rasa conversation using Rasa shell
Figure 2: Sample Rasa conversation using Rasa shell

Now that we have seen the conversation, let’s see how each scenario is written step by step using the Rasa framework. We will also gradually learn the concepts of Rasa from these scenarios.

For each scenario we will see the output in UI form.

Scenario 1
College timings

nlu.yml

- intent: timings
examples: |
- I would like to college timings
- college time please
- what would the class start and end time
- when college reopen

stories.yml

- story: college time path
steps:
- intent: timings
- action: utter_timings

domain.yml

intents:
- timings

responses:
utter_timings:
- text: “The college is not open now we are still working through online”

Description

  • rasa run
    rasa train: Need to run this after every change we do in the configuration files.
    rasa nlu train: This is run if only the nlu is updated, such as nlu.yml, stories.yml and rules.yml.Once the train is completed, the model will be saved under model/directory. For example, you will get the message: Your Rasa model is trained and saved at ‘/Users/dev/Desktop/Technical/Blogs/Chatbot/rasa/models/20210925-140501.tar.gz’
  • nlu.yml
    NLU (Natural Language Understanding) is used to store the training data and extract structured information from user messages. This usually includes the users’ intent and any entities their message contains. From the above example, the student can know the college timings; so give some sample input for the bot to learn the student’s intention.
  • stories.yml
    Stories help the bot to learn dialogue management. They can be used to train models that are able to generalise unseen conversation paths. From the above example, when the user’s intention is to know the college timings, the bot will respond to the student’s message, saying the “colleges are still operating online.”
  • domain.yml
    Domain is the key file for the Rasa framework. It specifies the intents, entities, slots, responses, forms, and actions your bot should know about. It also defines a configuration for conversation sessions. From the above example, we have specified the intents and our responses here. The output in UI can be seen in Figure 3.
Scenario 1 — chat with bot, a simple chat
Figure 3: Scenario 1 — chat with bot, a simple chat

Scenario 2
Course duration for department

nlu.yml

- lookup: department
examples: |
- civil
- mechanical
- computer
- textile
- printing

- intent: course_duration
examples: |
- what is course duration for [civil]{“entity”: “department”}
- would like to know the [computer]{“entity”: “department”} course tenure

stories.yml

- story: college course duration
steps:
- intent: course_duration
- action: action_course_duration

domain.yml

intents:
- course_duration

actions:
- action_course_duration

entities:
- department

responses:
utter_course_duration:
- text: “For {department} course is of {duration} months”

actions.py

class ActionCourseDuration(Action):

def name(self) -> Text:
return “action_course_duration”

def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

# It will return array of entities
entities = tracker.latest_message[‘entities’]
print(entities)

course_duration = {
‘civil’: 10,
‘computer’: 12,
‘mechanical’: 14,
‘printing’: 16,
‘textile’: 18
}

entity_department = None

# Iterating through the array to retrieve the desired entity
for e in entities:
if e[‘entity’] == “department”:
entity_department = str(e[‘value’]).lower().strip()
duration = course_duration.get(entity_department, 0)

dispatcher.utter_message(
response=”utter_course_duration”,
department=entity_department,
duration=duration
)

return []

Description

  • nlu.yml
    Here we can see something new, known as entity and lookup tables. Entity is the information extracted from the intent. Lookup tables are lists of words that help to extract entities. Here we are defining a list of departments/courses offered in the college, as it will help the bot to reply better based on the student’s department.
  • stories.yml
    When the user asks about the course duration, the reply is not just a plain spoken message; instead, it’s an action taken.
  • actions.py
    The actions file holds the custom action that can run any code you want. This is used to make an API call, or to query a database, for example. Rasa framework has a beautifully decoupled actions server; to run it, we need to call ‘rasa run actions’. From the example, we are returning the course duration saved from the dict, but it could be anywhere.Output in the UI for this scenario is seen in Figure 4.
Scenario 2 — chat with bot, using entities
Figure 4: Scenario 2 — chat with bot, using entities

Scenario 3
Exam results

nlu.yml

- regex: rollnumber
examples: |
- \d{10,30}

- intent: get_roll_number
examples: |
- my roll number is [1234567891](rollnumber)
- This is my roll number [1234567891](rollnumber)
- [1234567891](rollnumber)

- intent: request_result
examples: |
- may I know the exam results
- can you please help me to know if I have passed
- am I all clear

rules.yml

- rule: activate result form
steps:
- intent: request_result # intent that triggers form activation
- action: result_form # run the form
- active_loop: result_form # this form is active

- rule: submit form
condition:
- active_loop: result_form # this form must be active
steps:
- action: result_form # run the form
- active_loop: null # the form is no longer active because it has been filled
- action: utter_submit # action to take after the form is complete
- action: utter_slots_values # action to take after the form is complete
- action: action_show_result

domain.yml

intents:
- get_roll_number
- request_result

actions:
- action_show_result

forms:
result_form:
required_slots:
rollnumber:
- type: from_entity
entity: rollnumber

slots:
rollnumber:
type: any

entities:
- rollnumber

responses:
utter_result:
- text: “For {roll}, result is {result} with {score} score”

utter_ask_rollnumber:
- text: “Please provide your roll number”

utter_submit:
- text: “All done!”

utter_slots_values:
- text: “I am going to run a result search using the following parameters:\n
rollnumber: {rollnumber}”

actions.py

intents:
- get_roll_number
- request_result

actions:
- action_show_result

forms:
result_form:
required_slots:
rollnumber:
- type: from_entity
entity: rollnumber

slots:
rollnumber:
type: any

entities:
- rollnumber

responses:
utter_result:
- text: “For {roll}, result is {result} with {score} score”

utter_ask_rollnumber:
- text: “Please provide your roll number”

utter_submit:
- text: “All done!”

utter_slots_values:
- text: “I am going to run a result search using the following parameters:\n
rollnumber: {rollnumber}”

Description

  • nlu.yml
    Sometimes, it can be hard to configure all the possible values. Regex comes to the rescue here. In this scenario, we can see Regex being used to identify the roll number.
  • rules.yml
    Rules are a type of training data used to train your assistant’s dialogue management model. They describe short pieces of conversations that should always follow the same path. Forms are used to save the student’s roll number. The most common conversation patterns are to collect a few pieces of information from a user in order to do something (book a restaurant, call an API, search a database, etc).
Note: Don’t overuse rules. Rules are great to handle small specific conversation patterns, but unlike stories, they don’t have the power to generalise to unseen conversation paths.
  • domain.yml
    Slots are your bot’s memory. They act as a key-value store, which can be used to store information the user provided (e.g., their home city) as well as information gathered about the outside world (e.g., the result of a database query). Here we have saved the student’s roll number in a slot and it is extracted from the entity.The output for this scenario in UI is seen in Figure 5.
Scenario 3 -- chat with bot, using slots
Figure 5: Scenario 3 — chat with bot, using slots

Scenario 4

  • Fee enquiry
  • Provide if only roll number is provided
  • Else ask for the roll number and then provide the fee structure

nlu.yml

- regex: rollnumber
examples: |
- \d{10,30}

- intent: get_roll_number
examples: |
- my roll number is [1234567891](rollnumber)
- This is my roll number [1234567891](rollnumber)
- [1234567891](rollnumber)

- intent: fees_enquiry
examples: |
- may I know the fees structure
- how much fees do I need to pay
- do I have any pending fees to be paid

stories.yml

- story: Ask for rollnumber and say fees
steps:
- intent: fees_enquiry
- slot_was_set:
- rollnumber_provided: null
- action: utter_ask_rollnumber
- intent: get_roll_number
- slot_was_set:
- rollnumber_provided: true
- action: action_save_roll_number
- action: action_fees_details

rules.yml

- rule: Only say `fees` if the user provided a rollnumber
condition:
- slot_was_set:
- rollnumber: true
steps:
- intent: fees_enquiry
- action: action_fees_details

domain.yml

intents:
- fees_enquiry

actions:
- action_fees_details

entities:
- department
- rollnumber

slots:
rollnumber:
type: any

responses:
utter_fees:
- text: “For {roll}, fees is {fees} INR.”

actions.py

class ActionShowFeesStructure(Action):

def name(self) -> Text:
return “action_fees_details”

def run(self,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

roll = tracker.get_slot(“rollnumber”)
print(“Rollno: “, roll)
fees = 0
if( roll ):
fees = 10000

dispatcher.utter_message(
response=”utter_fees”,
fees=fees,
roll=roll
)

return []

class ActionReceiveRollNumber(Action):

def name(self) -> Text:
return “action_save_roll_number”

def run(self, dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:

#text = tracker.latest_message[‘text’]
entities = tracker.latest_message[‘entities’]

roll = None
for e in entities:
if e[‘entity’] == “rollnumber”:
roll = str(e[‘value’]).lower().strip()

dispatcher.utter_message(text=f”I’ll remember your rollnumber {roll}!”)
return [SlotSet(“rollnumber”, roll), SlotSet(“rollnumber_provided”, True)]

All the configurations we have learnt so far will remain the same. But this scenario is written to test the bot’s memory (slot). Here, the student is not required to enter the roll number again. And in the story we have written, the roll number will be asked for if the student has not provided it, and only then will the fee structure be provided. The output is seen in Figure 6.

Scenario 4 — chat with bot, using slots and conditions
Figure 6: Scenario 4 — chat with bot, using slots and conditions

Scenario 5
Change of department request

nlu.yml

- intent: department_have_been_changed
examples: |
- I have changed from [civil]{“entity”: “department”, “role”: “from”}
- Have moved from [civil]{“entity”: “department”, “role”: “from”}

- intent: department_going_to_change
examples: |
- I am going to [civil]{“entity”: “department”, “role”: “to”} department
- I am changing to [civil]{“entity”: “department”, “role”: “to”} department
- Will be moving to [civil]{“entity”: “department”, “role”: “to”} course

stories.yml

- story: The student moving from another department
steps:
- intent: department_have_been_changed
entities:
- department: Civil
role: from
- action: utter_ask_about_experience

- story: The student is going to another department
steps:
- intent: department_going_to_change
entities:
- department: Computer
role: to
- action: utter_wish_luck

domain.yml

intents:
- department_have_been_changed
- department_going_to_change

responses:
utter_ask_about_experience:
- text: “How was your experience with the department.”

utter_wish_luck:
- text: “Wish you best luck in the new department.”

Description

  • nlu.yml
    Here we are using the features Entity Roles and Groups, where we need to specify the list that the roles and groups of an entity can belong to.

Figure 7 gives the output in UI.

Scenario 5 — chat with bot, using roles
Figure 7: Scenario 5 — chat with bot, using roles

Rasa can help us build a chatbot for use cases quickly. The scenarios given here are pretty basic, and there is a lot more that Rasa has to offer.

LEAVE A REPLY

Please enter your comment!
Please enter your name here