# A Simple Guide to Building AI Chatbots with RASA 3\.x

- Canonical: https://33rdsquare.com/a-simple-guide-to-rasa-3-x/
- Published: 2024-09-03
- Author: Jordan Brown
- Categories: [Artificial Intelligence & Machine Learning & ChatGPT](https://33rdsquare.com/category/tech/ai/)

---

Chatbots have become an increasingly important interface for businesses and organizations to interact with their customers and users. Chatbots allow providing 24/7 support, handling frequent queries, and improving user engagement in a scalable way. While rule-based chatbots work well for simple use cases, AI-powered chatbots that can understand context and engage in open-ended conversations are the future.

RASA is a leading open-source framework for building AI chatbots. It provides a set of tools and libraries to handle the end-to-end development of contextual chatbots – from understanding user messages to managing dialogue flow and integrating with external APIs and channels. The latest version of the framework, RASA 3.x, brings many enhancements and new features to simplify the bot building process.

In this guide, we‘ll do a deep dive into RASA 3.x and learn how to build and deploy AI chatbots from scratch. Whether you‘re a complete beginner or have some experience with RASA, this guide will help you get up to speed with the latest and greatest in RASA. Let‘s jump in!

## RASA 3.x Architecture and Components

At a high level, RASA uses a modular architecture consisting of:

- RASA NLU: The natural language understanding module that takes user messages as input and extracts structured data like intents and entities using machine learning models. RASA NLU is highly flexible and supports specifying a custom processing pipeline.
- RASA Core: The dialogue management module that takes the structured output from RASA NLU and decides the next bot action based on learnt patterns, rules and custom logic. It maintains the conversation state and history to enable contextual dialogues.
- Action Server: An external server that executes custom actions like calling an API, querying a database or doing some computation. It exposes a webhook that RASA Core calls with a JSON payload when a custom action needs to be triggered.

RASA also provides a set of supplementary tools to aid in building and deploying bots:

- RASA X: A toolset and UI on top of RASA to enable interactive learning, conversation driven development, and model deployment. It includes features like conversations review, annotating messages and triggering actions via GUI.
- Tracker Stores: Components to persist conversation state and history in different stores like SQLite, Redis, and custom databases.
- Channels: A set of connectors to integrate the RASA bot with 3rd party channels like Slack, Facebook Messenger, Telegram etc.

With this background, let‘s now walk through the process of building a simple translator chatbot using RASA 3.x. We‘ll build a bot that can translate a given message from English to a user-specified target language.

## Setting up the Development Environment

The first step is to set up RASA 3.x on your local machine. RASA requires Python 3.7 or 3.8. It‘s recommended to use a virtual environment to isolate the dependencies:

```
python3 -m venv ./venv
source ./venv/bin/activate
pip3 install -U pip
pip3 install rasa
```

This will install the latest version of RASA and all its dependencies in the virtual environment. You can now initialize a new RASA project:

```
rasa init
```

This sets up the scaffolding for the RASA project with some sample training data and model configuration. The key files and directories are:

- `data/`: Contains training data for the NLU and Core models
- `actions/`: Contains custom action code
- `models/`: Contains trained model files
- `config.yml`: Specifies the model configuration and pipeline
- `domain.yml`: Defines the universe of bot functionality in terms of intents, entities, slots, responses, forms, and actions
- `endpoints.yml`: Specifies the action server and tracker store endpoints
- `credentials.yml`: Contains credentials for different channels

## Defining Intents, Entities and Training Data

The next step is to define the intents and entities relevant to our translator bot. We‘ll define a single intent called `translate` to capture the user‘s translation request. We‘ll also define two entities:

- `sentence`: The sentence that needs to be translated
- `to_lang`: The target language for translation

We can add some training examples for this intent in `data/nlu.yml`:

```
nlu:
- intent: translate
  examples: |
    - Please translate [hello](sentence) to [French](to_lang)
    - Can you tell me how to say [where is the bathroom](sentence) in [Spanish](to_lang)
    - Translate [I am lost](sentence) in [German](to_lang)
    - How do you say [thank you](sentence) in [Hindi](to_lang)
```

Here each example is annotated with the entities `sentence` and `to_lang` to help RASA learn to identify them. We can also add a lookup table for supported languages in the same file:

```
- lookup: to_lang
  examples: |
    - French
    - Spanish
    - German
    - Hindi
```

This provides a pre-defined vocabulary of languages without having to add a training example for each one.

## Defining the Dialogue Flow with Stories and Rules

With the intents and entities in place, we can now define the dialogue flow of the bot using stories and rules. Stories represent example conversations demonstrating bot behavior, while rules describe small patterns that should always be followed.

Let‘s add a story for a happy path translation in `data/stories.yml`:

```
stories:
- story: happy path translate
  steps:
  - intent: translate
    entities:
    - sentence: hello
    - to_lang: French
  - action: action_translate
  - intent: thank
  - action: utter_welcome
```

This story says that when the user expresses the translate intent with the entities `sentence` and `to_lang`, the bot should execute the `action_translate` custom action. If the user says thanks after that, the bot should respond with the `utter_welcome` utterance.

We can also add a rule to handle the case where the user does not provide the target language:

```
rules:
- rule: Ask for language if not provided
  steps:
  - intent: translate
  - action: utter_ask_to_lang
  - intent: inform
  - action: action_translate
```

This rule says that if the user expresses the translate intent but `to_lang` entity is not recognized, the bot should ask for the language with the `utter_ask_to_lang` response, and once the user informs the language, execute the translation.

With this, we have provided some basic training data and dialogue patterns to RASA. Of course, in a real bot, you would add many more examples and stories to make the bot more robust.

## Defining Custom Actions

The actual translation logic needs to be implemented in a custom action. RASA custom actions are Python classes with a `name` and `run` method. The `run` method receives a `dispatcher`, `tracker` and `domain` object as arguments to send messages, get conversation state and take actions.

Let‘s implement the `action_translate` action in `actions/actions.py`:

```
from typing import Any, Text, Dict, List
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher

class ActionTranslate(Action):

    def name(self) -> Text:
        return "action_translate"

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

        sentence = tracker.get_slot("sentence")
        to_lang = tracker.get_slot("to_lang")

        if sentence is None:
            dispatcher.utter_message(text="I‘m sorry, I didn‘t catch what you wanted to translate. Could you please repeat?")
            return []

        if to_lang is None:
            dispatcher.utter_message(text="I‘m sorry, I didn‘t catch the target language. Could you please specify it again?")
            return []

        translated = self.translate(sentence, to_lang)

        dispatcher.utter_message(text=f"Here‘s the translation:\n\n{translated}")

        return []

    def translate(self, sentence: Text, to_lang: Text) -> Text:
        # TODO: implement translation here
        # This is a dummy implementation
        return f"{sentence} in {to_lang}"
```

The `run` method extracts the required entities `sentence` and `to_lang` from the tracker. It prompts the user if any of the entities is missing. Once it has both, it calls the `translate` helper method to perform the actual translation.

The `translate` method is left as a dummy implementation returning the interpolated string. In a real bot, you would call a machine translation API or library like Google Translate here to get the translated text.

## Training the Model and Starting the Action Server

With all the pieces in place, we are now ready to train the RASA model:

```
rasa train
```

This will train the NLU and Core models using the training data and save the model weights in the `models/` directory.

Before talking to the bot, we also need to start the action server:

```
rasa run actions
```

This will start the action server on port 5055.

## Talking to the Bot

We‘re now ready to talk to our translator bot:

```
rasa shell
```

This will start an interactive shell where you can chat with the bot. Let‘s try a few exchanges:

```
Your input -> Hi
Hey there! How can I help you today?

Your input -> Please translate hello to French
Here‘s the translation:

hello in French

Your input -> Thanks!
You‘re very welcome! Is there anything else I can assist you with?

Your input -> Translate where is the bathroom in German
Here‘s the translation:

where is the bathroom in German

Your input -> Cool! How about I am lost in Spanish
Here‘s the translation:

I am lost in Spanish
```

As we can see, the bot is able to handle the translation requests by extracting the entities, executing the action and responding with the translated text. It also handles the case where the language is not specified by prompting the user.

Of course, this is a very basic example and there are many ways to extend it. Some possibilities:

- Integrating with a real translation API
- Handling more languages and accents
- Adding error handling and fallback responses
- Supporting translation features like specifying source language, transliterating proper nouns etc.
- Providing an option to speak the translated phrase

## Best Practices for RASA Development

Here are some tips and best practices to keep in mind when developing RASA bots:

- Use a modular and reusable design by factoring out common functionality into custom actions
- Provide sufficient and diverse training data covering different user expressions and paths
- Continuously review and annotate real user conversations using RASA X to improve the model
- Use rules for handling small patterns that should always be followed
- Carefully design slot mappings and forms for collecting required information over multiple turns
- Implement fallback responses to handle cases where user input is not understood with high confidence
- Write test stories to automatically validate bot behavior as it evolves
- Use version control and CI/CD to enable collaboration and safe deployment

## Conclusion

In this guide, we saw how RASA 3.x enables building conversational AI bots that can engage in contextual conversations. We learnt about the different components of RASA, how to define the training data and dialogue flow, and how to implement custom actions. We also built a simple translator bot from scratch and saw it in action.

RASA‘s open source, code-first and modular approach makes it a compelling choice for organizations looking to build production-grade bots without vendor lock-in. With active development and a growing community, RASA is poised to power the next wave of conversational AI.

I hope this guide has been useful in kickstarting your RASA journey. The code for the sample translator bot is available on [GitHub](). Feel free to clone it and use it as a starting point for your own bot. Happy bot building!

---

Source: [A Simple Guide to Building AI Chatbots with RASA 3\.x](https://33rdsquare.com/a-simple-guide-to-rasa-3-x/)
