DEV Community

loading...

Splitting your Actions in Rasa

jonathanpwheat profile image Jonathan Wheat ・4 min read

Rasa is an amazingly flexible open source system for building conversational chat bots. You can quite literally have the basic out-of-the-box bot working in less than 15 minutes. There are a host of tutorials and videos online that explain how to set up, extend and train your bot.

The main reason Rasa is so flexible is that you can build out actions to extend the functionality. If you are familiar with Alexa, you can think of these as added skills. These actions can be as simple as an API call to an external system (ie weather service or joke of the day) or could be setup to walk a user through a set of questions to gather information (think "form"), or you can build actions to interact with an external ERP, other complex system, knowledge base, or really whatever you can think of.

All of these actions are built with python and by default exist as classes in the actions.py file. You can imagine that this file can get quite large and unwieldy as your bot grows in abilities and functionality. Thankfully there is a way to split up and organize these actions to make development more streamlined. This method is not documented anywhere on the RASA site, although it is fully supported out of the box and requires only a little modification to your project's directory structure, which also helps with organization.

Note
For this tutorial, we'll reference my main project directory C3PO. I'm on Ubuntu, so I'll also give you the commands to run where necessary, but feel free to perform the necessary steps however you feel comfortable.

From a terminal, lets change to our project's home direcotry:
cd ~/RASA/C3PO

Setting Up Your New Actions Directory

Create a new directory off of the root of your project's directory called actions. This is where all of your new action files will live.

mkdir actions

You'll end up with something like this:
C3PO/actions

Now we want to make that actions folder a package in python. This sounds pretty involved, but really only requires the creating of one file with a special filename.

In the actions directory create an empty file named __init.py__ That may be hard to tell, but that is 2 underscores before and after the init.py.

From your project's home run
touch actions/__init.py__

That's all, you don't have to edit this file at all, it just has to exist. The actions directory is now considered a package and what that means is that when it is referenced all files in there will be loaded. Perfect.

Move and package

We can now move our actions.py file into our package directory. Be sure to not copy it, move it there or else Rasa won't check for the actions directory.

mv actions.py actions

GREAT. You can consider your actions.py file "packaged" :) That was pretty easy.

You can stop now and everything will work as it did before, but that's not the point of this article is it.

The Big Split

The first thing you'll want to do is open actions.py in your code editor.
Create a new file in your actions directory, the filename is arbitrary. Give it a filename that means something to you. Here is where the organizational part comes in, and only you can know what makes sense.

If you're like me, you have a naming convention throughout your bot, and you've split your NLU, Stories and Domain data already. If you have, you'll probably use that naming style here. For example, I've prefixed all of my actions with an a and an index number that references internal documentation about that particular element whether that is an intent, story, entity, etc.

Here's an example action filename from one of my bots: a004-ext-api-bmchelix-create-issue.py I can tell from the text portion that's an external api call to BMC Helix to create an issue (ticket) and I can look up item 004 on my internal documentation and read more about that particular call, if there are other references to entities, etc. Internal docs are super important, especially if you have other developers working with you on this. Even if you're a lone-wolf developer, these bots can get pretty complex, so I can't stress enough about taking your time and taking notes about what you've done.

Continuing on.

At the top of this new file, you'll need to copy / paste the top section from your main actions.py file. This includes all of the code down to the first Class statement. For me it is all of the import and from lines like this:

import logging
from typing import Any, Text, Dict, List, Union, Optional
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.forms import FormAction
from rasa_sdk.events import SlotSet, AllSlotsReset, Restarted, UserUtteranceReverted, ConversationPaused

logger = logging.getLogger(__name__)

That gives your new action file access to all of the RASA related items you'll need for an action.

Then go ahead and move (Cut / Paste) the class or classes from your main actions.py file that relate to the new file you've created.

Save it.

Repeat that process as necessary as you want.

Now you'll have an actions package directory full of .py action files.

Then What?

Then nothing. You're done. There's nothing special to do. You can still launch your bot the same way you always have with rasa run actions and it'll load all of your custom action files as if they were in one file like before.

You can try this to be sure you haven't made an error. Run rasa run actions and the server should spin up. You'll see all of your action class names scroll onto the screen and it'll sit there waiting for the Rasa server to hit it.

Help Me Help You

I want this to be useful, so if you discover I've made any errors, let me know and I'll correct them asap.

Happy developing

Discussion

pic
Editor guide
Collapse
fandy profile image
Andy Fang

Thanks for writing this :) I'm surprised Rasa doesn't document how to organize actions.