<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jonathan Wheat</title>
    <description>The latest articles on DEV Community by Jonathan Wheat (@jonathanpwheat).</description>
    <link>https://dev.to/jonathanpwheat</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F22646%2Fdcbb6099-9895-42df-9250-d549658bab5d.jpg</url>
      <title>DEV Community: Jonathan Wheat</title>
      <link>https://dev.to/jonathanpwheat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonathanpwheat"/>
    <language>en</language>
    <item>
      <title>Impress your boss by giving your Rasa-bot a voice with Twilio for $0</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Wed, 14 Jul 2021 19:59:56 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/impress-your-boss-by-giving-your-rasa-bot-a-voice-with-twilio-for-0-23de</link>
      <guid>https://dev.to/jonathanpwheat/impress-your-boss-by-giving-your-rasa-bot-a-voice-with-twilio-for-0-23de</guid>
      <description>&lt;p&gt;Building and interacting with a chat-bot can be fun, but calling a number and actually talking to it for the first time over the phone is next level.  It also gives others the ability to interact with your bot in a new way.  And talk about &lt;a href="https://info.rasa.com/cdd-playbook"&gt;CDD&lt;/a&gt;! (&lt;a href="https://info.rasa.com/cdd-playbook"&gt;Conversation Driven Development&lt;/a&gt;.  All hell breaks loose when people talk to it.  It's a whole different animal.&lt;/p&gt;

&lt;p&gt;This tutorial will walk you through setting up your Rasa-bot with Twilio, an online service that provides a host of products, one of which is called Programmable Voice.&lt;/p&gt;

&lt;p&gt;Twilio is a paid service, however they offer a &lt;a href="https://www.twilio.com/try-twilio"&gt;free trial&lt;/a&gt; (YEA!). They do this in a pretty cool way. They allocate a credit ($15 US) to your account and the trial lasts as long as you have money in your account.  You can spend it on anything they offer, and obviously the more you do, the faster it goes.&lt;/p&gt;

&lt;p&gt;I've setup voice (the main topic of this tutorial) as well as messaging (texting with my bot) and we'll hit on that at the end, it's pretty easy once you have the voice interface configured.&lt;/p&gt;

&lt;p&gt;The best part is that you can run your bot from your own machine!  You don't have to deploy it to a server or jump through any crazy hoops.  This is especially good if you happen to have proprietary data that the bot utters, or collect or divulge any (PII)[&lt;a href="https://www.dhs.gov/privacy-training/what-personally-identifiable-information"&gt;https://www.dhs.gov/privacy-training/what-personally-identifiable-information&lt;/a&gt;].&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;p&gt;Here's a quick run down of the various tools we'll need, just in case you're the kind of person that has to know going in.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A phone 😆 or at least some way to make a voice call to a phone number&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://rasa.com/docs/rasa/installation/"&gt;Rasa&lt;/a&gt; ^2.6.0&lt;/li&gt;
&lt;li&gt;A bot to hook up (the out of the box &lt;code&gt;rasa init&lt;/code&gt; will be fine)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.twilio.com/try-twilio"&gt;Twilio Trial Account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ngrok.com/download"&gt;NGrok&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting Started (Twilio)
&lt;/h2&gt;

&lt;p&gt;The first thing you need to do is get yourself a &lt;a href="https://www.twilio.com/try-twilio"&gt;trial Twilio account&lt;/a&gt;. It's a pretty simple process, albeit there are a few steps.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign up&lt;/li&gt;
&lt;li&gt;Verify your email address&lt;/li&gt;
&lt;li&gt;Log in&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you log in, you'll need to verify your phone number.  &lt;/p&gt;

&lt;p&gt;Next pick the following -&lt;/p&gt;

&lt;p&gt;Which Twilio product are you here to use? - Voice &lt;br&gt;
What do you plan to build with Twilio?  - IVR &amp;amp; Bots&lt;br&gt;
How do you plan to build with Twilio? - With minimal code&lt;br&gt;
What is your preferred coding language? - Python&lt;br&gt;
Would you like Twilio to host your code? - Yes, host my code&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally&lt;/strong&gt;, you'll be delivered to the console.  Depending on when you're reading this, the current console may be either the "Legacy Console" or the new "Beta Console".  &lt;/p&gt;

&lt;p&gt;I want you on the Beta console, which, like I said could be the default one now.  You'll know because there will be a button &lt;br&gt;
in the header that reads "Try the beta Console".&lt;/p&gt;

&lt;p&gt;Click that.&lt;br&gt;
Complete the little form.&lt;/p&gt;

&lt;p&gt;You should land on your Dashboard, and right there dead center is a blue button that says "Get a Trial Number"&lt;/p&gt;

&lt;p&gt;Click that.&lt;/p&gt;

&lt;p&gt;When you click it, it'll hand you a phone number.  There's a big red button that reads "Choose this Number"&lt;/p&gt;

&lt;p&gt;Click that.&lt;/p&gt;

&lt;p&gt;You'll get a Congratulations modal with a Done button.&lt;/p&gt;

&lt;p&gt;Click that.  😄&lt;/p&gt;

&lt;p&gt;You'll land back on your dashboard, and you'll see your trial balance ($15.50) as well as your new trial phone number.  If you call it, it's legit, it'll connect to Twilio, although not much happens after the initial message.&lt;/p&gt;

&lt;p&gt;Also on your dashboard are 2 very important items we'll need shortly for Rasa.  The account SIT and the Auth Token.  Keep your screen there, and head over to your bot.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure your bot for Twilio Voice
&lt;/h2&gt;

&lt;p&gt;The next thing you need to do is prep your bot for Twilio.  I'm presuming you have a bot already setup. If you don't, create a new directory and run &lt;code&gt;rasa init&lt;/code&gt; to spin one up.&lt;/p&gt;

&lt;p&gt;Rasa has something called connectors. These connectors can be used to hook to different channels such as Slack, Messenger, Telegram, etc. We, as developers, can &lt;a href="https://rasa.com/docs/rasa/connectors/custom-connectors/"&gt;build custom connectors&lt;/a&gt; too, which is pretty great, they're crazy powerful.  Fun fact, I actually started this adventure with a custom Twilio connector, a python file sitting in my project... &lt;/p&gt;

&lt;p&gt;&lt;em&gt;BUT&lt;/em&gt;... As of Rasa 2.6.0, Twilio connector is built in!  That's not to say we still can't use a custom one, but to save us some angst with respect to this tutorial, we'll use the built in one.  So be sure you have at least Rasa 2.6.0 installed.&lt;/p&gt;
&lt;h1&gt;
  
  
  credentials.yml
&lt;/h1&gt;

&lt;p&gt;Open your &lt;code&gt;credentials.yml&lt;/code&gt;, a file you probably haven't ever touched.  We're going to add a configuration that will tell that internal Twilio connector we're going to use it.&lt;/p&gt;

&lt;p&gt;First we'll configure the basic Twilio connector with the Account SID, Auth Token and phone number from our account.&lt;/p&gt;

&lt;p&gt;Add the following to your &lt;code&gt;credentials.yml&lt;/code&gt; file.  You can add it above or below the default &lt;code&gt;rest:&lt;/code&gt; and &lt;code&gt;rasa:&lt;/code&gt; config that may already be there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;twilio&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;account_sid&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;copy-paste-your-account-sid-here&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;auth_token&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;copy-paste-your-auth-token-here&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;twilio_number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;copy-paste-your-phone-number-here&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing to note for the &lt;code&gt;twilio_number&lt;/code&gt; is to just enter the digits, no &lt;code&gt;-&lt;/code&gt; or &lt;code&gt;(&lt;/code&gt; and it does require a leading country code (in the USA that's a &lt;code&gt;1&lt;/code&gt;)  So it should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;twilio_number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;12223334444&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we'll specify some custom parameters specifically for Twilio Voice.  These are items that you can change and some will directly impact the "cost" of your account.  I'll explain each one below. &lt;/p&gt;

&lt;p&gt;Add this to your &lt;code&gt;credentials.yml&lt;/code&gt; file as well&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;twilio_voice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;initial_prompt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hello"&lt;/span&gt;
  &lt;span class="na"&gt;assistant_voice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Polly.Salli"&lt;/span&gt;
  &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;en-GB"&lt;/span&gt;
  &lt;span class="na"&gt;reprompt_fallback_phrase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;didn't&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;get&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;that&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;could&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;you&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;repeat?"&lt;/span&gt;
  &lt;span class="na"&gt;speech_timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
  &lt;span class="na"&gt;speech_model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;default"&lt;/span&gt;
  &lt;span class="na"&gt;enhanced&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;false"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some quick explanation here for each piece.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;inital_prompt&lt;/code&gt; is what will get sent to your Rasa-bot in the background to trigger it.  Your bot won't respond unprompted, so this gets things started.  If you're using the out-of-the-box default Rasa bot, this will trigger the &lt;code&gt;greet&lt;/code&gt; intent.  You can also adjust the response specifically for Twilio using the &lt;a href="https://rasa.com/docs/rasa/responses#channel-specific-response-variations"&gt;channel specific variations&lt;/a&gt; Rasa allows.  I'll touch on that near the end.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;assistant_voice&lt;/code&gt; is the voice that will be used on the phone when your bot responds.  There is a &lt;a href="https://www.twilio.com/docs/voice/twiml/say/text-speech#polly-standard-and-neural-voices"&gt;giant list of voices&lt;/a&gt; you can choose from, both male and female and from many nationalities. &lt;/p&gt;

&lt;p&gt;What's great is you can play around with all of these to see what they sound like in the &lt;a href="https://console.twilio.com/?frameUrl=/console/voice/twiml/text-to-speech"&gt;Text to Speech Console&lt;/a&gt;. Choose "Basic" or "Amazon Poly" at the top, and it will load the different voices.  It's not very apparent, but click a voice and a modal will display.  Enter some text into the box, and then click the little play arrow directly over the box and it will speak whatever you've just entered. &lt;/p&gt;

&lt;p&gt;Once you find one you like, you can update the &lt;code&gt;assistant_voice&lt;/code&gt; parameter accordingly.  Use the Voice Name from the console (ie. Amy) and if you're using the Amazon Poly voice, add a &lt;code&gt;Polly.&lt;/code&gt; before the voice name like this &lt;code&gt;Polly.Amy&lt;/code&gt;.  If you're using the Basic voice, you can just add the name alone, there's no need to prefix it with Basic or anything.&lt;/p&gt;

&lt;p&gt;One thing to consider is that the &lt;a href="https://www.twilio.com/docs/voice/twiml/say/text-speech#pricing"&gt;Amazon Poly voices cost against your account&lt;/a&gt;, but it's literal fractions of a penny per character and if you're trying to impress your boss, then you want a great sounding voice, so this is worth the incremental cost.&lt;/p&gt;

&lt;p&gt;Amazon has another voice system called Neural, these voices are more human, more robust and as you can imagine, cost more.  But you have free money, so play around.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;language&lt;/code&gt; is easy, just look at the voice list (or the Language code in the speech console) it'll be in the parenthesis ( ) and enter that.  The voice names overlap, and some have the same names but different dialects and accents based on the language / nationality.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reprompt_fallback_phrase&lt;/code&gt; - this is functionally similar to Rasa's Default Fallback, however it is for Twilio.  If for some reason it can't even attempt to understand you, or translate what you said to text, it will speak back this message instead of sending a garbled stream of characters to your bot.  Because it is a different configuration you can make it a different phrase than your &lt;code&gt;utter_default&lt;/code&gt; response.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;speech_timeout&lt;/code&gt; Speech is different than text. When you complete a text message you hit send and the bot knows to process what you've typed.  When speaking, the bot doesn't know when you're done, so this timeout is how much silence it will wait for before it attempts to send what you said to your bot.  The shorter the time, the quicker response, however if you have someone that talks slow, a 1 second delay could produce a bot that interrupts that person.  And if it didn't get the complete phrase it may ask them to repeat it when they never finished it.  The flip side to this is that if it is too long, the system feels laggy, even though it's acting properly.  I changed mine to 1 second because I talk quicker and when I demo the prototype, I want as little lag-feel as possible.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;speech_model&lt;/code&gt; This is the model that Twilio will use when performing it's STT (Speech to Text) and TTS (Text to Speech) functions.  Values here are limited to &lt;code&gt;default&lt;/code&gt;, &lt;code&gt;numbers_and_commands&lt;/code&gt; and &lt;code&gt;phone_call&lt;/code&gt;.  If you &lt;a href="https://www.twilio.com/docs/voice/twiml/gather#speechmodel"&gt;read the docs on these settings&lt;/a&gt;, &lt;code&gt;default&lt;/code&gt; is best for talking to Rasa, unless of course you're building a number menu tree like many phone systems have in place, in which case you want the &lt;code&gt;phone_call&lt;/code&gt;.  If you are speaking short phrases and keywords, choose &lt;code&gt;numbers_and_commands&lt;/code&gt;.  These different models are trained up to specialize on the content that is being spoken.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;enhanced&lt;/code&gt; This allows you to enable (or disable) Twilio's enhanced premium speech transcription (STT) service.  This is a very good system and seems to nail the transcriptions better than when it's off.  However, this will impact your account balance (costs about 50% more), so for the time being, unless you really have problems with your bot responding to your voice, I'd leave it at &lt;code&gt;false&lt;/code&gt; most of the time.  But then again, you have free money, just make sure you don't burn through it before you wow your boss 😉.&lt;/p&gt;

&lt;p&gt;Believe it or not, that's all you have to do to prep your bot for voice, so it's now ready to respond to Twilio's API calls.&lt;/p&gt;

&lt;p&gt;Lets fire it up and I'll show you how to get it wired up to Twilio.&lt;/p&gt;

&lt;p&gt;Run this command -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;rasa run -m models --enable-api --log-file out.log --cors "*" --debug
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That may take a bit to start up, but eventually you'll see the wonderful message -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Rasa server is up and running.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hear you saying - "But it's on my laptop! Am I going to call my laptop?"&lt;/p&gt;

&lt;p&gt;Yes it is and no you're not, well not directly.  We'll open it up to Twilio through a secure tunnel - which is WAY easier than it sounds, and infinitely easier than trying deploy it on a server.&lt;/p&gt;

&lt;p&gt;That said - if you have one running on a server, you can certainly grab the rasa server url and skip the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting your bot accessible from the internet
&lt;/h2&gt;

&lt;p&gt;We'll use a utility called &lt;a href="https://ngrok.com"&gt;Ngrok&lt;/a&gt; to set this up.  If you don't have it installed already, go to Ngrok's site, &lt;a href="https://ngrok.com/download"&gt;download and install&lt;/a&gt; it on your system.  Once it's installed, open a new console, or Command Prompt if you're on Windows and type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;ngrok http 50005
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're looking for something like this to come up -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;ngrok by @inconshreveable                                                                               (Ctrl+C to quit)

Session Status                online
Session Expires               1 hour, 57 minutes
Version                       2.3.40
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
&lt;/span&gt;&lt;span class="gp"&gt;Forwarding                    http://f43f711b19b9.ngrok.io -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http://localhost:5005
&lt;span class="gp"&gt;Forwarding                    https://f43f711b19b9.ngrok.io -&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;http://localhost:5005
&lt;span class="go"&gt;Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see this, we're golden, it's all working.&lt;br&gt;
What this just did was setup a secure tunnel for port 5005 - where the Rasa server is running - and it maps it to a secure (yet publicly accessible url &lt;code&gt;https://f43f711b19b9.ngrok.io&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;One thing to note is that the tunnel will only last for two hours.  Notice the "Session Expires" time there.  That will actively count down before it collapses the tunnel.  And you just have to CTRL+C and run it again to generate a new tunnel.&lt;/p&gt;
&lt;h2&gt;
  
  
  &amp;gt;&amp;gt;&amp;gt;&amp;gt; UPDATE &amp;lt;&amp;lt;&amp;lt;&amp;lt;
&lt;/h2&gt;

&lt;p&gt;You can &lt;a href="https://dashboard.ngrok.com/signup"&gt;create a free account on Ngrok's site&lt;/a&gt; and then your tunnel won't expire every hour!&lt;/p&gt;

&lt;p&gt;Cool right?&lt;/p&gt;

&lt;p&gt;All the information you need to do this is right there, however you can see there is a web interface at &lt;code&gt;http://127.0.0.1:4040&lt;/code&gt;  If you hit that in a browser, you'll see the url's listed, but to get a crazy amount of information about the tunnel, click the status link.  We don't need to know any of that for what we're doing but it's good to know it's there though.  So back to the setup.&lt;/p&gt;
&lt;h2&gt;
  
  
  Configure the Twilio Webhook.
&lt;/h2&gt;

&lt;p&gt;One more step and we're ready to call our bot.  We need to Tell Twilio that our bot is temporarily living at the new Ngrok url&lt;/p&gt;

&lt;p&gt;Go to your Twilio account, click the &lt;code&gt;&amp;gt;&lt;/code&gt; next to Phone Numbers&lt;br&gt;
Then click the &lt;code&gt;&amp;gt;&lt;/code&gt; next to Manage&lt;br&gt;
And click Active Numbers&lt;/p&gt;

&lt;p&gt;Click your number to get to the configuration screen for that specific number.&lt;/p&gt;

&lt;p&gt;Scroll down to the Voice &amp;amp; Fax section&lt;/p&gt;

&lt;p&gt;In the row that says "When a call comes in"&lt;br&gt;
Make sure it says "Webhook"&lt;/p&gt;

&lt;p&gt;We want to change the first part of the URL to our ngrok email&lt;br&gt;
The final url should look something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;https://f43f711b19b9.ngrok.io/webhooks/twilio_voice/webhook
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you copy in the url from &lt;strong&gt;your&lt;/strong&gt; Ngrok terminal.&lt;/p&gt;

&lt;p&gt;And that's it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Time to try it out
&lt;/h2&gt;

&lt;p&gt;Grab your phone, call your Twilio number.  A brief trial message will play telling you to hit a number to execute your code.  This will send your &lt;code&gt;initial_prompt:&lt;/code&gt; value through Ngrok to your local instance of Rasa. When it does, you'll see the webhook hit Ngrok in the console, and then you'll see your rasa terminal spin like a top (because we launched it in debug mode).  &lt;/p&gt;

&lt;p&gt;Rasa will process what came in from Twilio, and send back text and Twilio will translate that into speech, and your bot will talk back to you!  (now quickly ask for a raise)&lt;/p&gt;

&lt;p&gt;There are times in your bot where you may have a response like this -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;utter_greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello, I am TwilBot. \nPlease let me know how I can help you&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this is read to you, Twilio (and any other TTS engine) will read back the line break &lt;code&gt;\n&lt;/code&gt; and it will say "backslash n".  But we want that line break there for our web chat component.  So what to do????&lt;/p&gt;

&lt;p&gt;Remember the &lt;a href="https://rasa.com/docs/rasa/responses#channel-specific-response-variations"&gt;channel specific responses&lt;/a&gt; we mentioned before?  This is there those come in handy.  Just change the response to this, and you're golden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;utter_tell_greet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello, I am TwilBot. \nPlease let me know how I can help you&lt;/span&gt;
      &lt;span class="na"&gt;channel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;twilio_voice"&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Hello, I am TwilBot, thank you for calling. Please let me know how I can help you&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My only gripe with the channel formatting looks a bit odd, having the &lt;code&gt;channel:&lt;/code&gt; with the same indent level as the &lt;code&gt;- text:&lt;/code&gt; response above it, and then having the channel-specific response at that same indent level.  At first I thought it was a typo in the docs, but sure enough that's how it should look.&lt;/p&gt;

&lt;p&gt;Save that and any other channel changes you want to make, train your bot and re-run it using the same command we had before&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;rasa run -m models --enable-api --log-file out.log --cors "*" --debug
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for this message...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Rasa server is up and running.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as long as your Ngrok tunnel hasn't expired, you can call again and it should greet you properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Congratulations
&lt;/h2&gt;

&lt;p&gt;Great job, you made it to the end and hopefully your boss is excited and ready to give you that raise.&lt;/p&gt;

&lt;p&gt;But wait - there's more!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Messaging
&lt;/h2&gt;

&lt;p&gt;Speaking to your bot is cool, but texting your bot is pretty awesome too.  Here's how you configure that.&lt;/p&gt;

&lt;p&gt;The number you chose will support both voice and SMS it just needs to be configured.  This was a little confusing at first, because you need to setup what they call a Messaging Service.  All this is, is a configured name, it's nothing involved.  I thought you'd need some other service to hook in, but really you just need to set a name and go.  Let's do that.&lt;/p&gt;

&lt;p&gt;Explore Products &amp;gt; Messaging&lt;/p&gt;

&lt;p&gt;This will land you on the Programmable Messaging Dashboard.  There's a blue button that reads - Start Sending Messages&lt;/p&gt;

&lt;p&gt;Click that 😆&lt;/p&gt;

&lt;p&gt;An Modal will open and want to know the Messaging Service Name, so name it.  It's arbitrary - you can call it "My Messaging Service" or you can call it "SendIt", heck you could call it AT&amp;amp;T if you wanted to, not sure why you would though.&lt;/p&gt;

&lt;p&gt;For the Messaging Service Use Case on the same modal, choose one that fits our needs - "Engage in a discussion"&lt;/p&gt;

&lt;p&gt;The blue button there that says Create - you guessed it - Click it.&lt;/p&gt;

&lt;p&gt;In the left nav, click Integration&lt;br&gt;
Then choose - Send a Webhook&lt;/p&gt;

&lt;p&gt;In the Request URL box, enter our NGrok url, the same one you entered for Voice.&lt;/p&gt;

&lt;p&gt;Click Save.  (yea I know I like to switch it up a bit)&lt;/p&gt;

&lt;p&gt;A few more steps and we're done.&lt;/p&gt;

&lt;p&gt;In the top navbar, click the "My First Twilio Account" link, then navigate back down to the phone number screen&lt;/p&gt;

&lt;p&gt;Phone Numbers &amp;gt; Manage &amp;gt; Active numbers &amp;gt; click your number&lt;/p&gt;

&lt;p&gt;Scroll down to the Messaging section and select the Messaging Service you setup.&lt;/p&gt;

&lt;p&gt;Then in the Webhook url - paste in your NGrok URL, the same one you entered for the voice config.&lt;/p&gt;

&lt;p&gt;Click Save.&lt;/p&gt;

&lt;p&gt;THATS IT!!&lt;/p&gt;

&lt;p&gt;Now jump on your phone and text &lt;code&gt;hello&lt;/code&gt; to the number you have setup.  It should reply with a message that starts with "Send from your Twilio trial account -".  This text will prefix all text messages received from your bot.  Obviously it will go away if you upgrade.&lt;/p&gt;

&lt;p&gt;Whelp, that's all I got.  Hope this go you that raise you were looking for #fingersCrossed&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>twilio</category>
      <category>ivr</category>
      <category>stt</category>
    </item>
    <item>
      <title>A Makefile for Rasa</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Fri, 30 Apr 2021 15:48:44 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/a-makefile-recipe-for-rasa-4147</link>
      <guid>https://dev.to/jonathanpwheat/a-makefile-recipe-for-rasa-4147</guid>
      <description>&lt;p&gt;As a programmer, I can be lazy and have a list of aliases I use when working with everything on the command line, Rasa included.&lt;/p&gt;

&lt;p&gt;At Nearly Human we use &lt;code&gt;make&lt;/code&gt; for a lot of different things, and I decided to utilize the muscle memory for typing &lt;code&gt;make&lt;/code&gt; all the time for my Rasa development.&lt;/p&gt;

&lt;p&gt;If you're curious, currently I work on Windows 10, and I do the bulk of my Rasa development using VSCode and use the integrated WSL Ubuntu terminal. I'm working on another tutorial about setting up VSCode for Rasa development, but haven't finished that one yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing make
&lt;/h2&gt;

&lt;p&gt;From an WSL Ubuntu terminal install &lt;code&gt;make&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;sudo apt-get update -y
sudo apt-get install -y make
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When that's completed make sure it's all happy with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;make --version
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get something like this - possibly with a different version.  The important thing here is that you don't get an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
&lt;/span&gt;&lt;span class="gp"&gt;License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="go"&gt;This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also use commit hooks with &lt;code&gt;pre-commit&lt;/code&gt; to keep some formatting standards.  Lets get that installed too.&lt;/p&gt;

&lt;p&gt;This is really easy as well. It's just&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;pip install pre-commit
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll need a configuration for this, so create a &lt;code&gt;.pre-commit-config.yml&lt;/code&gt; file in the root of your project.&lt;/p&gt;

&lt;p&gt;You can copy / paste in this generic configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;repos&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pre-commit/pre-commit-hooks&lt;/span&gt;
    &lt;span class="na"&gt;rev&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v2.4.0&lt;/span&gt;
    &lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;trailing-whitespace&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;end-of-file-fixer&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-yaml&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt;   &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;check-added-large-files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this lets check all your files manually first, then we'll create a make recipe for it.&lt;/p&gt;

&lt;p&gt;Run this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;pre-commit run --files *.yml data/*
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IF all goes well you'll see something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Trim Trailing Whitespace.......................................Passed
Fix End of Files...............................................Passed
Check Yaml.....................................................Passed
Check for added large files....................................Passed
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you get a Failed, read why, it should tell you what happened.  What's great about &lt;code&gt;pre-commit&lt;/code&gt; is that it will fix most common formatting issue on it's own. So run that again if you saw a &lt;code&gt;Failed&lt;/code&gt; line and chances are this time they'll all pass... unless of course you really botched a file badly.&lt;/p&gt;

&lt;p&gt;I'll presume you have that all working now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Makefile
&lt;/h2&gt;

&lt;p&gt;Now to create the fun part.  In the root of your Rasa project, create a new file named &lt;code&gt;Makefile&lt;/code&gt;  &amp;lt;-- there's no extension, it's all one word with a lowercase 'f'&lt;/p&gt;

&lt;p&gt;You can read online all about &lt;code&gt;make&lt;/code&gt; and how to construct recipes, but these are the ones I use.  Essentially you have a recipe name, and a set commands you want to execute, one per line&lt;/p&gt;

&lt;h3&gt;
  
  
  Clean
&lt;/h3&gt;

&lt;p&gt;This removes past model files.  If you're like me you train often and this directory can get pretty large depending on the size of your model file.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;Makefile&lt;/code&gt; add this super easy recipe&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;clean&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;rm models/*.gz -f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save that, and from the terminal run &lt;code&gt;make clean&lt;/code&gt; and it'll execute and remove your model files.  The &lt;code&gt;-f&lt;/code&gt; forces the recipe to run and not fail if the command fails.  So for example if there are no models to delete, that command technically fails and without the &lt;code&gt;-f&lt;/code&gt; flag, the recipe would fail as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validate
&lt;/h3&gt;

&lt;p&gt;This is a crazy valuable recipe that runs the validate command.  Mostly because I have a very complex &lt;code&gt;data&lt;/code&gt; directory (I do NOT have a &lt;code&gt;domain.yml&lt;/code&gt; file in the root of my project, so I have to specify a parameter)  &lt;/p&gt;

&lt;p&gt;Add a new line and add this recipe to your &lt;code&gt;Makefile&lt;/code&gt; (** see the note below)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;rasa data validate --domain data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;** You may need to remove the &lt;code&gt;--domain data&lt;/code&gt; to get this to work depending on your setup.&lt;/p&gt;

&lt;p&gt;To execute this one you can run &lt;code&gt;make validate&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Training
&lt;/h2&gt;

&lt;p&gt;The next most important recipe is the training.&lt;br&gt;
This recipe is fantastic.  It'll run the &lt;code&gt;clean&lt;/code&gt; recipe removing the model files, then check your formatting, then validate, then train.&lt;/p&gt;

&lt;p&gt;Add this recipe to your &lt;code&gt;Makefile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;train&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;clean&lt;/span&gt;
    &lt;span class="s"&gt;pre-commit run --files *.yml data/*&lt;/span&gt;
    &lt;span class="s"&gt;rasa data validate --domain data&lt;/span&gt;
    &lt;span class="s"&gt;rasa train --domain data --out models&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll note that &lt;code&gt;clean&lt;/code&gt; is on the same line as the recipe name, this is on purpose, it'll allow you to run another recipe from this one.&lt;br&gt;
As you would expect, run &lt;code&gt;make train&lt;/code&gt; to execute this time-saver.&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;Now that we have a model trained you can test it.  This command typically has many parameters so it's very handy to use a recipe for.&lt;/p&gt;

&lt;p&gt;Add this to your &lt;code&gt;Makefile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;test: check
    rasa test --stories tests/conversation_tests.yml --fail-on-prediction-errors
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run &lt;code&gt;make test&lt;/code&gt; for this one.&lt;/p&gt;

&lt;p&gt;This runs a check using my custom &lt;code&gt;conversational_tests.yml&lt;/code&gt; file.  You can change these parameters to whatever you use to run your tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Almost done
&lt;/h2&gt;

&lt;p&gt;I have two more for you.  I like to run the rasa server api locally (not &lt;code&gt;rasa shell&lt;/code&gt;) and that has many parameters.  Also in conjunction with that, I like to fire up the action server in another terminal window so here's two more recipes that are useful&lt;/p&gt;

&lt;h3&gt;
  
  
  Action Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;runactions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;rasa run actions --action actions --debug --auto-reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fire up the action server in debug mode with auto-reload enabled with &lt;code&gt;make runactions&lt;/code&gt;  There are circumstances where the &lt;code&gt;auto-reload&lt;/code&gt; flag doesn't actually reload your changes, so just be aware of that, but it's not related to the &lt;code&gt;Makefile&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rasa Server (not shell)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;run:
    rasa run -m models --enable-api --log-file out.log --cors "*" --debug
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To launch this recipe type &lt;code&gt;make run&lt;/code&gt; the rasa server will fire up with the api active, create a log file for you, enable cors for external communications and do it all in debug mode (very useful). It will sit there waiting for connections from your chat interface, whether that is a web ui, slack, messenger, whatever.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's It
&lt;/h2&gt;

&lt;p&gt;Hopefully that'll save you some keystrokes and you can become a lazy developer like me :)&lt;/p&gt;

&lt;p&gt;If you have any recipes or commands you'd like to share, do that in the comments and I just may steal ... er use them in my workflow.&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>make</category>
      <category>makefile</category>
      <category>recipe</category>
    </item>
    <item>
      <title>Organize your Rasa 2.0 training data like a boss</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Mon, 28 Dec 2020 16:13:42 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/organize-your-rasa-2-0-training-data-like-a-boss-4e37</link>
      <guid>https://dev.to/jonathanpwheat/organize-your-rasa-2-0-training-data-like-a-boss-4e37</guid>
      <description>&lt;p&gt;Rasa 2.x gives us a lot of new features as conversational designers / developers.  The coolest feature that isn't quite apparent is the ability to group and organize your training data any way you please.&lt;/p&gt;

&lt;p&gt;At my company we build "abilities" for our bot - think of them similar to Alexa Skills.  Essentially you have some domain information, nlu training data, stories and sometimes actions or forms to round out the ability.  The more abilities the bot has, the longer and more complex your files get; which leads to a longer time to grock what you're looking at if you drop in to tweak something, let alone onboard a new developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The old days
&lt;/h2&gt;

&lt;p&gt;Rasa 1.x allowed you to split up your nlu and stories files simply by creating a &lt;code&gt;data/nlu&lt;/code&gt;, and &lt;code&gt;data/core&lt;/code&gt; directory in your project and putting the individual files there.  You can group your data into separate files which makes it easier to find something if/when you need to change something.  For example if you needed to add new chit-chat training data, you could jump into  &lt;code&gt;data/nlu/chit-chat.md&lt;/code&gt; and add new data.  Initiating the &lt;code&gt;rasa train&lt;/code&gt; command utilizes the files in &lt;code&gt;data/nlu&lt;/code&gt; and &lt;code&gt;data/core&lt;/code&gt; in combination with &lt;code&gt;domain.yml&lt;/code&gt; in the root of your project to train your model.&lt;/p&gt;

&lt;p&gt;This was great, but not ideal for me.  I &lt;a href="https://gist.github.com/jwheat/9a2611b738127f45d32254117fe3b959"&gt;built a script&lt;/a&gt; to let me split my domain files in a similar way; creating a &lt;code&gt;data/domain&lt;/code&gt; directory and putting my files there.  Rasa however, didn't recognize that directory, so I wrote a script to merge these files into a single &lt;code&gt;domain.yml&lt;/code&gt; file and drop it in the root.  This allowed the &lt;code&gt;rasa train&lt;/code&gt; command to utilize my separate domain related files.&lt;/p&gt;

&lt;h2&gt;
  
  
  A New Organizational Paradigm
&lt;/h2&gt;

&lt;p&gt;Rasa 2.x gives us the ability to split up our domain files and the benefit to that is clear; smaller files with more focused data. I also don't have to utilize my custom script now! &lt;/p&gt;

&lt;p&gt;Why is this cool?  To expand on my explanation above; if your bot can handle chit-chat, weather, restaurant search, and directions you would have a single long &lt;code&gt;domain.yml&lt;/code&gt; file in the root of your project with ALL of your intents, slots, entities, responses, action calls, and form config. Your topical data is interlaced, and it makes it hard to find things.  Being able to split this into different files just makes more sense. (Thank you Rasa!)&lt;/p&gt;

&lt;p&gt;Your new data directory structure can now change to -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;data/core
data/domain
data/nlu
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And each of these can contain multiple files that make up your bot's data.  You can even &lt;a href="https://dev.to/jonathanpwheat/splitting-your-actions-in-rasa-3mfg"&gt;do this with your action files&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Kick It Up A Notch!
&lt;/h2&gt;

&lt;p&gt;Here's something that is an amazing side effect / undocumented feature of the way Rasa deals with training data in 2.x  You can create directories under &lt;code&gt;core&lt;/code&gt;,&lt;code&gt;domain&lt;/code&gt;, and &lt;code&gt;nlu&lt;/code&gt; and Rasa will recurse down through looking for files during the training process.&lt;/p&gt;

&lt;p&gt;I know you're asking - why is this awesome?  In our case, as I said we build abilities, which are mostly isolated functions and conversational scenarios. In v1 we adopted a filename convention to differentiate between abilities.  In v2, by exploiting this new directory structure we can have individual developers work on a single ability without stepping on the toes of other developers.&lt;/p&gt;

&lt;p&gt;They can create a new ability directory - let's say they're working on a book recommendation ability.  Our dev creates &lt;code&gt;data/book-recommendation&lt;/code&gt; and in that directory creates a &lt;code&gt;domain.yml&lt;/code&gt;, &lt;code&gt;nlu.yml&lt;/code&gt;, &lt;code&gt;stories.yml&lt;/code&gt;, &lt;code&gt;rules.yml&lt;/code&gt; and works solely from that directory.  Fun fact, the filename doesn't matter.  Each &lt;code&gt;.yml&lt;/code&gt; file is keyed - &lt;code&gt;intents:&lt;/code&gt;,&lt;code&gt;nlu:&lt;/code&gt;, even &lt;code&gt;rules:&lt;/code&gt; so it doesn't matter how many files you have, or what the names are, it all works!&lt;/p&gt;

&lt;p&gt;If you decide to do this, you'll need to run &lt;code&gt;rasa train&lt;/code&gt; with the &lt;code&gt;--domain&lt;/code&gt; parameter so it will find your domain files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;rasa train --domain data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you leave off the &lt;code&gt;--domain&lt;/code&gt; parameter, Rasa will look for &lt;code&gt;domain.yml&lt;/code&gt; in the directory you're running it from so be sure to delete &lt;code&gt;domain.yml&lt;/code&gt; in the root of your project, or you may be quite confused why your latest changes aren't getting pulled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't Leave Actions Out In The Cold
&lt;/h2&gt;

&lt;p&gt;You can also do this with your &lt;code&gt;action.py&lt;/code&gt; file, albeit in a different location and there's an extra file.  We create an ability directory under &lt;code&gt;actions/&lt;/code&gt;, drop in an empty &lt;code&gt;__init__.py&lt;/code&gt;  file (making python treat it as a package) then add an &lt;code&gt;actions.py&lt;/code&gt; file (or whatever filename you want)&lt;/p&gt;

&lt;p&gt;In our book recommendation example we would have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;actions/__init__.py
actions/book-recommendation 
actions/book-recommendation/__init__.py
actions/book-recommendation/actions.py
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Doing all of this directory organization centralizes the code and lets your developer spin up a local &lt;code&gt;rasa init&lt;/code&gt; project, and work on that ability from beginning to end, creating a very focused bot complete with tests. One caveat is if the ability being worked on is integrated with another ability in some way.  Depending on the level of that reliability, you may think about whether the new code is actually a separate/new function as opposed to an extension of a current ability - but that's getting away from the main topic here.&lt;/p&gt;

&lt;h2&gt;
  
  
  In practice
&lt;/h2&gt;

&lt;p&gt;We have plan to have a special repo of abilities, so when our devs are done they can just move their directories over issue a PR and that new ability will be available for everyone else on the team to pull down and add to their bot if needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  But wait, there's more
&lt;/h2&gt;

&lt;p&gt;Up until now, if your ability had any python related action code, you'd have 2 directories to manage.  What if you could create a truly self-contained ability in one directory.  Literally add one directory of files, retrain and have a new ability in your bot?&lt;/p&gt;

&lt;p&gt;You can.&lt;/p&gt;

&lt;p&gt;To achieve this, we'll move the action files into our &lt;code&gt;data/book-recommendation&lt;/code&gt; directory.  There's some setup to do this however. &lt;br&gt;
 Remember the &lt;code&gt;__init__.py&lt;/code&gt; files we've been dropping all over?  Python uses those to detect if a directory is loadable (a package).&lt;/p&gt;

&lt;p&gt;To get our all-in-one setup we'll need to drop an &lt;code&gt;__init__.py&lt;/code&gt; into &lt;code&gt;data&lt;/code&gt; and then move our &lt;code&gt;__init__.py&lt;/code&gt; and the specific &lt;code&gt;actions.py&lt;/code&gt; file from our actions' ability folder into our data's ability directory.  This way everything is 100% self-contained in one single directory like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;data/__init__.py
data/book-recommendation
data/book-recommendation/__init__.py
data/book-recommendation/actions.py
data/book-recommendation/stories.yml
data/book-recommendation/domain.yml
data/book-recommendation/nlu.yml
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The trick here is to run your action server with the &lt;code&gt;--actions&lt;/code&gt; parameter like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;rasa run actions --actions data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells rasa to load the actions files from your data directory, and it will recurse down and load any python files it finds.&lt;/p&gt;

&lt;p&gt;As noted above, you'll also need to run &lt;code&gt;rasa train&lt;/code&gt; with the &lt;code&gt;--data&lt;/code&gt; parameter like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;rasa train --domain data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That will tell Rasa where your domain files are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parting Thoughts
&lt;/h2&gt;

&lt;p&gt;I think this is a pretty cool advancement in the ability (no pun intended) to organize our data, streamline our development process and allow a very interesting approach to developing different independent functions.&lt;/p&gt;

&lt;p&gt;I'm not sure I like the python being intermingled in the same directory as my &lt;code&gt;.yml&lt;/code&gt; files, it feels a little gross, but I supposed I could also create a &lt;code&gt;data/book-recommendation/actions&lt;/code&gt; directory to move out all the python other than the &lt;code&gt;__init__.py&lt;/code&gt; file of course.  Or maybe even go crazy with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;/data/book-recommendation/actions
/data/book-recommendation/data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR even rename our &lt;code&gt;data&lt;/code&gt; directory and create something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;/abilities/book-recommendation/actions
/abilities/book-recommendation/data
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you do something crazy like this be sure to alter your --data and --action parameters when firing up Rasa!&lt;/p&gt;

&lt;p&gt;Those both feel a little over the top, but the point is the possibilities are endless and you have the ability to organize your files however makes sense to you.&lt;/p&gt;

&lt;p&gt;I'll continue iterating on this approach.  I'm interested in knowing what others are doing to organize their data.  The single file system works for smaller / simpler bots, but anything with some robustness will quickly outgrow that model (pun intended).&lt;/p&gt;

&lt;p&gt;Let me know what you think in the comments!&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>machinelearning</category>
      <category>ai</category>
    </item>
    <item>
      <title>Debugging Rasa Errors</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Tue, 22 Sep 2020 18:25:46 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/debugging-rasa-errors-3kn1</link>
      <guid>https://dev.to/jonathanpwheat/debugging-rasa-errors-3kn1</guid>
      <description>&lt;p&gt;This is a short summary of the "random" Rasa and python errors (and what to look for to fix them) you will no doubt encounter when you're developing a chat bot using Rasa.  Some are pretty obscure, and after some time you'll get used to identifying them, and other times no so much.&lt;/p&gt;

&lt;p&gt;I'll admit, this post is pretty selfish, it is more for me to have a location bookmarked that I can reference from time to time when I can't remember, but I know it'll help someone new or old to the Rasa scene.&lt;/p&gt;

&lt;p&gt;I've posted this as a repo as well (&lt;a href="https://github.com/jwheat/rasa-errors"&gt;https://github.com/jwheat/rasa-errors&lt;/a&gt;), so if you have any updates / corrections / or new errors I've missed (now that there's a new Beta out) feel free to issue a pull-request and I'll get them merged in.&lt;/p&gt;

&lt;p&gt;Now without further rambling, here are the errors, in no particular order, other than the order I've encountered them over the last few months when I was compiling this.&lt;/p&gt;




&lt;h2&gt;
  
  
  AttributeError: 'str' object has no attribute 'setdefault'
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c:&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;jonathan&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;anaconda3&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;envs&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;asa&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;lib&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;site-packages&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;asa&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;core&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;domain.py&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;290&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;_transform_intent_properties_for_internal_use&lt;/span&gt;
    &lt;span class="nx"&gt;properties&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setdefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;USE_ENTITIES_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;AttributeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;str&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;attribute&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setdefault&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt;: Syntax Error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt;: &lt;code&gt;domain.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to look&lt;/strong&gt;: &lt;code&gt;intents:&lt;/code&gt;   - specifically &lt;code&gt;use_entities: []&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure there is a space between the &lt;code&gt;:&lt;/code&gt; and the &lt;code&gt;[]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Make sure your &lt;code&gt;use_entities: []&lt;/code&gt; is indented properly under the parent intent name.
Here's an example of good indenting practices
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;intents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;enter_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;use_entities&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  AttributeError: 'bool' object has no attribute 'get'
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;c:&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;users&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;jonathan&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;anaconda3&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;envs&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;asa&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;lib&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;site-packages&lt;/span&gt;&lt;span class="se"&gt;\r&lt;/span&gt;&lt;span class="s2"&gt;asa&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;core&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;domain.py&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;265&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;collect_slots&lt;/span&gt;
    &lt;span class="nx"&gt;slot_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Slot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve_by_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;slot_dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;slot_name&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nx"&gt;AttributeError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="nx"&gt;attribute&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt;: Syntax Error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt;: &lt;code&gt;domain.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to look&lt;/strong&gt;: &lt;code&gt;slots:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the problem is&lt;/strong&gt;: indenting slot properties&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: you need an ever increasing set of indents for slot definitions.  Make sure your &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;auto_fill&lt;/code&gt;, &lt;code&gt;initial_value&lt;/code&gt; and any other properties of a slot are indented under the slot name&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I've done&lt;/strong&gt;: I utilize past code a lot, and VSCode likes to automatically indent when you past a block that has indening, so many times my indenting is off and I'm in a rush and don't see it is incorrect. Needless to say, this error is my most frequent.&lt;/p&gt;

&lt;p&gt;Here is an example of proper slot indentation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;slots&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;customer_first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unfeaturized&lt;/span&gt;
    &lt;span class="nx"&gt;auto_fill&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  pykwalify.core - ["Value 'None' is not a dict. Value path: '/slots'"]
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt;: Syntax Error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt;: &lt;code&gt;domain.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to look&lt;/strong&gt;: &lt;code&gt;slots:&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the problem is&lt;/strong&gt;: indenting slot name, and/or missing &lt;code&gt;-&lt;/code&gt; if your slot happens to be a list or array&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Similar to the above error, you need an ever increasing set of indents for slot definitions with proper &lt;code&gt;-&lt;/code&gt; hyphens as well.  Make sure your slot name is properly indented under the &lt;code&gt;slots:&lt;/code&gt; key and double check your hyphens o be sure they're all there (or not)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I've done&lt;/strong&gt;: Sometimes even though you have your hyphens, the indents are still off.  I have some custom slots that have dictionaries (multiple hyphenated items) and sometimes I forget the &lt;code&gt;-&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here is an example of proper slot indentation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nx"&gt;slots&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nx"&gt;risk_level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;categorical&lt;/span&gt;
    &lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;low&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;medium&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;high&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  rasa.core.actions.action - Failed to extract slot customer_first_name with action form_change_customer_first_name
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt;: spelling / naming error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt;: &lt;code&gt;actions.py&lt;/code&gt;, &lt;code&gt;domain.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to look&lt;/strong&gt;:  python slot code in your &lt;code&gt;actions.py&lt;/code&gt; and specifically the slot names in your &lt;code&gt;domain.yml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the problem is&lt;/strong&gt;: slot name mismatch (aka typo)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: - this is more than likely a naming / spelling issue.  Make sure the slot name you're referencing in your &lt;a href="http://actions.py"&gt;actions.py&lt;/a&gt; file MATCHES to the slot and/or response in your domain.yml file.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I've done&lt;/strong&gt;: Sometimes I'll write python code for a new slot, and forget to add it to my &lt;code&gt;domain.yml&lt;/code&gt; file, or I'll rename it in my head and forget to update it somewhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeError: 'NoneType' object is not iterable
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Type&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File&lt;/strong&gt;: &lt;code&gt;actions.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where to look&lt;/strong&gt;:  required_slots method&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the problem is&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Your required slots does not return anything.  You may have some nested if logic, and chances are whatever path you just took in chat, resulted in a path that did not return anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;A quick hack, not advisable is to add a &lt;code&gt;return []&lt;/code&gt; to the end of your &lt;code&gt;required_slots&lt;/code&gt; method.  This catch all will always return an empty list, and satisfy the actual functionality of this method.&lt;/p&gt;

&lt;p&gt;The better solution is to trace your if logic and handle the path you took in chat, and return an actual list (even one) of requiredSlots&lt;/p&gt;




&lt;p&gt;Check out the repo (&lt;a href="https://github.com/jwheat/rasa-errors"&gt;https://github.com/jwheat/rasa-errors&lt;/a&gt;) for any updates to this, or send me a pull-request if you have changes, or new errors to add!&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>python</category>
      <category>debugging</category>
      <category>errors</category>
    </item>
    <item>
      <title>Using Docker with Rasa for development</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Thu, 21 May 2020 15:25:48 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/using-docker-with-rasa-for-development-1c3h</link>
      <guid>https://dev.to/jonathanpwheat/using-docker-with-rasa-for-development-1c3h</guid>
      <description>&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker Engine &lt;a href="https://docs.docker.com/engine/install/"&gt;install docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docker Compose &lt;a href="https://docs.docker.com/compose/install/"&gt;install docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Rasa Open Source &lt;a href="https://rasa.com/docs/rasa/user-guide/installation/"&gt;install docs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're developing a chatbot with Rasa, no doubt you've gone down the same path as me and opened multiple consoles / terminals to launch the Rasa server, Action server, Duckling, your webchat ui and possibly more depending on how advanced your bot has become.&lt;/p&gt;

&lt;p&gt;This is a really easy way to develop, although unless your terminal app can do tabs, it becomes quite tiresome tracking down the proper one to restart.&lt;/p&gt;

&lt;p&gt;I'm going to show you how you can setup docker to launch them all with one command, and give you the flexibility to watch the logs, connect directly to a service, and of course stop and restart them when needed.&lt;/p&gt;

&lt;p&gt;We're going to use the &lt;code&gt;docker-compose.yml&lt;/code&gt; file to achieve this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Compose
&lt;/h3&gt;

&lt;p&gt;Briefly, the &lt;code&gt;docker-compose.yml&lt;/code&gt; file is a configuration file that tells docker how to build a stack of containers.  That means, it will fire up a single container for each service (chat server / action server / chatUI / etc.) all with one command.  It's pretty sweet, especially if you're used to opening up multiple consoles to launch each service like I mentioned above.&lt;/p&gt;

&lt;p&gt;I've attached my &lt;code&gt;docker-compose.yml&lt;/code&gt; file to this post in case you want to just jump ahead, because who has time to actually read blog posts these days. Am I right?&lt;/p&gt;

&lt;p&gt;If you do happen to have time, good for you, I'm going to explain how to get this working, and you'll be 30 minutes ahead of the people that skipped this section, wondering why my file didn't work straight away.&lt;/p&gt;

&lt;p&gt;If you have a Rasa project, you can download and drop my file into the root of your project.  My file assumes your &lt;code&gt;actions.py&lt;/code&gt; (and other action files) are located in an &lt;code&gt;actions&lt;/code&gt; directory off your project directory.  If you followed my &lt;a href="https://dev.to/jonathanpwheat/splitting-your-actions-in-rasa-3mfg"&gt;post about the actions files&lt;/a&gt;, then you're good to skip the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure your actions
&lt;/h3&gt;

&lt;p&gt;To use my file as-is, you just need to do a couple things&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create an actions directory off your project root&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;move&lt;/strong&gt;  &lt;code&gt;actions.py&lt;/code&gt; into it
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;copy&lt;/strong&gt; &lt;code&gt;__init.py__&lt;/code&gt; from your project root into it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more information about the actions files and the actions directory read my post &lt;a href="https://dev.to/jonathanpwheat/splitting-your-actions-in-rasa-3mfg"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  docker-compose.yml - Some items of note
&lt;/h3&gt;

&lt;p&gt;We're going to talk briefly about a few of the config options in the &lt;code&gt;docker-compose.yml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;First up is &lt;strong&gt;volumes&lt;/strong&gt;.  The volumes option takes an array of values, meaning you indent and use a hypen ( - ) for each item.  The items here are directories you want to map to docker.  In my file the &lt;code&gt;volumes&lt;/code&gt; section looks like this for the rasa-server service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    volumes:
      - ./:/app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the value on the &lt;code&gt;volumes:&lt;/code&gt; line is split with a :.  This tells Docker what local directory (the left side of the :) to make available to the service container and where in the container (right side of the :) to mount them to.  &lt;/p&gt;

&lt;p&gt;You end up with something like &lt;code&gt;./:/app&lt;/code&gt; That looks like a lot of dots and slashes, but essentially it is saying to map the current local project directory ./ to /app in the container. The result if this notation is that all files and directories in the project folder (think configuration, models, nlu data, etc) are made available to the rasa server container when it's fired up.&lt;br&gt;&lt;br&gt;
This makes sense if you think about it because the server requires all of those config files and your models in order to run.  It would be useless if you couldn't get your models or configuration to be read by Rasa in the container.&lt;/p&gt;

&lt;p&gt;To beat a dead horse, we'll look at the &lt;code&gt;volumes:&lt;/code&gt; value for the action-server service configuration.  It is similar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    volumes:
      - ./actions:/app/actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I know what you may be thinking, we just told docker to use the entire project directory (including the actions directory), why do we need to do it again?&lt;/p&gt;

&lt;p&gt;you'll notice in the &lt;code&gt;docker-compose.yml&lt;/code&gt; file there are different sections called &lt;code&gt;services:&lt;/code&gt;.  We have a &lt;code&gt;rasa-server&lt;/code&gt; service and an &lt;code&gt;action-server&lt;/code&gt; service.  Docker allows us to configure each one independently giving us some crazy flexibility and allows us to tune each service to use only what it needs.&lt;/p&gt;

&lt;p&gt;You also may be thinking, why didn't you use the same &lt;code&gt;./:/app&lt;/code&gt; value from the &lt;code&gt;rasa-server&lt;/code&gt;?  You could and it would work, but that would bloat the action-server container because it would also have access to the models and other config data.  Best practices say to limit access to just what is needed and make your containers as small as possible.&lt;/p&gt;

&lt;p&gt;Back to the beating that horse with actual value now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    volumes:
      - ./actions:/app/actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The actions server is mounting the actions directory we created above (./actions) and making it available at /app/actions inside the action-server container.  The action server docker image that is being pulled, knows to load the actions from it's local /app/actions directory.  Make sense?&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is this important?
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;volume:&lt;/code&gt; parameter is important because it allows outside files into the container, meaning data can be saved from the container to the volume and will persist next time you run the container.  The same in reverse as well.  If you make changes to your &lt;code&gt;domain.yml&lt;/code&gt;, &lt;code&gt;nlu.md&lt;/code&gt;, &lt;code&gt;stories.md&lt;/code&gt;, or any other config file, and retrain rasa, you just stop and restart the container and it will use your new models and configuration.&lt;/p&gt;

&lt;p&gt;These volume mappings allow you to continue to develop / train, etc locally with Docker and have your data and configuration persist.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use Docker Compose
&lt;/h3&gt;

&lt;p&gt;Provided you have the requirements mentioned at the top of this article, it is pretty easy to use docker compose.&lt;/p&gt;

&lt;p&gt;Drop the file into your rasa project directory run &lt;code&gt;docker-compose up&lt;/code&gt; and should be good to go.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up&lt;/code&gt; will keep the terminal live, and you'll see all the logs for each of the services you're firing up. You would use CTRL+C to stop everything.  &lt;/p&gt;

&lt;p&gt;You can also run &lt;code&gt;docker-compose up -d&lt;/code&gt; and that will launch them in the background and give you your terminal back.  To then stop them all if running in the background, run &lt;code&gt;docker-compose down&lt;/code&gt; and they'll all stop.&lt;/p&gt;

&lt;p&gt;One thing that may (or may not be) obvious is that you need to be in the same directory as your &lt;code&gt;docker-compose.yml&lt;/code&gt; file to run these commands. Since that is our configuration file, docker compose uses that to know what to launch or stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Becoming more proficient
&lt;/h3&gt;

&lt;p&gt;When I first started out, I never used the &lt;code&gt;-d&lt;/code&gt; flag because I like to watch logs as I test and develop. This is especially useful if you're starting out because you can immediately spot issues with configurations, etc.  But, after a while you'll want to fire this off and you'll want your cursor back :)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-d&lt;/code&gt; flag is handy because they run in the background.  This allows you to be able to stop different containers of needed, so if for example you're editing your actions.py file, you can just stop and restart the action server instead of bouncing all of your containers each time.  That is ok if you do this, to me it is just a waste of time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restarting a container
&lt;/h3&gt;

&lt;p&gt;First you need to know the name of your container.  To get a list of your running containers, run &lt;code&gt;docker ps&lt;/code&gt;.  You'll see something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                               NAMES
af21abaf9997        rasa/rasa:1.9.0       "rasa run --cors * -…"   2 hours ago         Up 8 seconds        0.0.0.0:5005-&amp;gt;5005/tcp              rasa-r2-server
f631aa0cd485        mysql:5.7             "docker-entrypoint.s…"   2 hours ago         Up 8 seconds        0.0.0.0:3306-&amp;gt;3306/tcp, 33060/tcp   mysql-rasa-r2
e18dc702ff5b        rasa/rasa-sdk:1.9.0   "./entrypoint.sh sta…"   2 hours ago         Up 8 seconds        0.0.0.0:5055-&amp;gt;5055/tcp              rasa-r2-action-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you wanted to restart the action server for example, you can take the &lt;code&gt;CONTAINER ID&lt;/code&gt; for the action server (the bottom one) and run &lt;code&gt;docker container restart e18dc702ff5b&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When that's completed, you can look with &lt;code&gt;docker ps&lt;/code&gt; again and see it was restarted under the CREATED column&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                               NAMES
af21abaf9997        rasa/rasa:1.9.0       "rasa run --cors * -…"   2 hours ago         Up 3 minutes        0.0.0.0:5005-&amp;gt;5005/tcp              rasa-r2-server
f631aa0cd485        mysql:5.7             "docker-entrypoint.s…"   2 hours ago         Up 3 minutes        0.0.0.0:3306-&amp;gt;3306/tcp, 33060/tcp   mysql-rasa-r2
e18dc702ff5b        rasa/rasa-sdk:1.9.0   "./entrypoint.sh sta…"   2 hours ago         Up 29 seconds       0.0.0.0:5055-&amp;gt;5055/tcp              rasa-r2-action-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For those of you still reading, here's some coolness that we've implemented that you didn't even know about.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's in a name
&lt;/h3&gt;

&lt;p&gt;Those hashes change each time a container is launched, and are a pain to deal with especially if you need to bounce a container a lot during development.&lt;/p&gt;

&lt;p&gt;You'll notice that each container has an actual name (NAME column), our action server is named &lt;code&gt;rasa-r2-action-server&lt;/code&gt; whether you realized it or not, we defined this in our file with the parameter &lt;code&gt;container-name:&lt;/code&gt;. Now we know what the container will be called all the time, it won't change no matter how many times you bounce it.&lt;/p&gt;

&lt;p&gt;You can use this name to restart the container like this:&lt;br&gt;
&lt;code&gt;docker container restart rasa-r2-action-server&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;That makes it easier to restart because now you don't need to always get the new hash with &lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If you leave out the &lt;code&gt;container-name:&lt;/code&gt; parameter in &lt;code&gt;docker-compose.yml&lt;/code&gt;, docker will auto generate a name for the container which is fine, but not ideal, it is just easier to give each of our containers a name, then we dictate what it is called.&lt;/p&gt;
&lt;h3&gt;
  
  
  Killing a container
&lt;/h3&gt;

&lt;p&gt;Occasionally you may need to forcibly kill a container, or even just stop one for a while instead of restarting it.  This is very similar to restarting a container, you just use the keyword &lt;code&gt;kill&lt;/code&gt; instead.  &lt;code&gt;docker kill rasa-r2-action-server&lt;/code&gt;  If you run &lt;code&gt;docker ps&lt;/code&gt; you'll see it is now gone.&lt;/p&gt;
&lt;h3&gt;
  
  
  Starting one service
&lt;/h3&gt;

&lt;p&gt;Great, you've killed a service using the container name, fixed whatever the issue is and want to fire it up again?  Well you'd think you can access it via the container name because that's what we've done in the other sections.  Don't be fooled, there is no container with the name of the one you just stopped.  We need to access it by the service name.  In our example you'd run &lt;code&gt;docker-compose up -d action-server&lt;/code&gt;  where &lt;code&gt;action-server&lt;/code&gt; is the service name defined in &lt;code&gt;docker-compose.yml&lt;/code&gt;  Check &lt;code&gt;docker ps&lt;/code&gt; and you'll see it is fired back up.&lt;/p&gt;
&lt;h3&gt;
  
  
  Watch that log
&lt;/h3&gt;

&lt;p&gt;It can be quite important to look at the logs in the event something does wrong.  You can use the container name we defined above and watch the logs like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker logs rasa-r2-action-server -f&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2020-05-20 16:38:04 INFO     rasa_sdk.endpoint  - Starting action endpoint server...
2020-05-20 16:38:04 INFO     rasa_sdk.executor  - Registered function for 'action_hello_world'.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I added the &lt;code&gt;-f&lt;/code&gt; flag to keep the logs active.  This command will take over the terminal and display changes to the log in real-time.  Hit CTRL+C to stop and get your terminal back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Get me in there!
&lt;/h3&gt;

&lt;p&gt;For Rasa, it would be rare for you to need to ssh into a container, but I'll round out the article with how to do that in case you need to verify some library version or something.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker exec -it rasa-r2-server bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will drop you into the /app directory and you'll be inside the container.  You can run something like &lt;code&gt;rasa --version&lt;/code&gt; or &lt;code&gt;python --version&lt;/code&gt;, or &lt;code&gt;pip list&lt;/code&gt; whatever you need to.  Just type &lt;code&gt;exit&lt;/code&gt; to pop back out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Compose Docs
&lt;/h3&gt;

&lt;p&gt;Take a look at the &lt;a href="https://docs.docker.com/compose/reference/overview/"&gt;docker compose docs&lt;/a&gt;, there are some other useful commands like &lt;code&gt;pause&lt;/code&gt;, &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;top&lt;/code&gt;, etc that may prove useful as you get more into developing using docker. &lt;/p&gt;

&lt;h3&gt;
  
  
  My docker-compose.yml file
&lt;/h3&gt;

&lt;p&gt;Here's a link to the file I use&lt;br&gt;
&lt;a href="https://www.dropbox.com/s/nnjizw1iewq74r1/docker-compose.yml?dl=0"&gt;docker-compose.yml&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  That's it
&lt;/h3&gt;

&lt;p&gt;That is everything you need to know to develop Rasa using Docker.  If you notice something I typed or said incorrectly, please let me know and I'll fix it right away. I tried to perform these examples as I wrote this, hopefully everything works for you.  Good luck!&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>docker</category>
      <category>chatbot</category>
      <category>python</category>
    </item>
    <item>
      <title>Splitting your Actions in Rasa</title>
      <dc:creator>Jonathan Wheat</dc:creator>
      <pubDate>Thu, 30 Apr 2020 15:21:01 +0000</pubDate>
      <link>https://dev.to/jonathanpwheat/splitting-your-actions-in-rasa-3mfg</link>
      <guid>https://dev.to/jonathanpwheat/splitting-your-actions-in-rasa-3mfg</guid>
      <description>&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;All of these actions are built with python and by default exist as classes in the &lt;code&gt;actions.py&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
For this tutorial, we'll reference my main project directory &lt;code&gt;C3PO&lt;/code&gt;.  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.&lt;/p&gt;

&lt;p&gt;From a terminal, lets change to our project's home direcotry:&lt;br&gt;
&lt;code&gt;cd ~/RASA/C3PO&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting Up Your New Actions Directory
&lt;/h3&gt;

&lt;p&gt;Create a new directory off of the root of your project's directory called &lt;code&gt;actions&lt;/code&gt;. This is where all of your new action files will live. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir actions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You'll end up with something like this:&lt;br&gt;
&lt;code&gt;C3PO/actions&lt;/code&gt;&lt;/p&gt;

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

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

&lt;p&gt;From your project's home run&lt;br&gt;
&lt;code&gt;touch actions/__init.py__&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;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 &lt;strong&gt;all&lt;/strong&gt; files in there will be loaded.  Perfect.&lt;/p&gt;
&lt;h3&gt;
  
  
  Move and package
&lt;/h3&gt;

&lt;p&gt;We can now &lt;strong&gt;move&lt;/strong&gt; our &lt;code&gt;actions.py&lt;/code&gt; file into our package directory. Be sure to not copy it, move it there or else Rasa won't check for the &lt;code&gt;actions&lt;/code&gt; directory. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;mv actions.py actions&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;GREAT. You can consider your &lt;code&gt;actions.py&lt;/code&gt; file "packaged" :)  That was pretty easy.&lt;/p&gt;

&lt;p&gt;You can stop now and everything will work as it did before, but that's not the point of this article is it.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Big Split
&lt;/h3&gt;

&lt;p&gt;The first thing you'll want to do is open &lt;code&gt;actions.py&lt;/code&gt; in your code editor.&lt;br&gt;
Create a new file in your &lt;code&gt;actions&lt;/code&gt; 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.  &lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;a&lt;/code&gt; and an index number that references internal documentation about that particular element whether that is an intent, story, entity, etc.&lt;/p&gt;

&lt;p&gt;Here's an example action filename from one of my bots: &lt;code&gt;a004-ext-api-bmchelix-create-issue.py&lt;/code&gt; 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 &lt;code&gt;004&lt;/code&gt; 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.&lt;/p&gt;

&lt;p&gt;Continuing on.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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__)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives your new action file access to all of the RASA related items you'll need for an action.&lt;/p&gt;

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

&lt;p&gt;Save it.&lt;/p&gt;

&lt;p&gt;Repeat that process as necessary as you want.&lt;/p&gt;

&lt;p&gt;Now you'll have an &lt;code&gt;actions&lt;/code&gt; package directory full of &lt;code&gt;.py&lt;/code&gt; action files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Then What?
&lt;/h3&gt;

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

&lt;p&gt;You can try this to be sure you haven't made an error.  Run &lt;code&gt;rasa run actions&lt;/code&gt; 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.&lt;/p&gt;

&lt;h3&gt;
  
  
  Help Me Help You
&lt;/h3&gt;

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

&lt;p&gt;Happy developing&lt;/p&gt;

</description>
      <category>rasa</category>
      <category>ai</category>
      <category>actions</category>
      <category>python</category>
    </item>
  </channel>
</rss>
