Trigger custom behaviours from the chatbot#
In this section, you will learn what are RASA’s custom actions and how to use them eg trigger intents from the chatbot.
To have an overview of RASA and how it is used on your robot, please first have a look at Dialogue management and Create, translate or update a chatbot.
Custom actions#
Custom actions are Python functions that you can define to add custom behavior and logic to your chatbot. Custom actions allow you to go beyond simple predefined responses and enable your chatbot to perform actions, like executing some ROS code, connecting to the Web to fetch some information, or interact with databases or external APIs.
In this tutorial, we will see how to extend the robot chatbot to emit a custom robot’s Intents, ie a custom action that publishes on a ROS topic.
To create you own custom action, two steps must be followed:
name your action in the
domain.yml
corresponding to your chatbot (for instance, see theactions:
section of the chitchatdomain.yml
, located in$HOME/.pal/chatbots-enabled/en_GB/chitchat/domain.yml
). This action can then be used in your chatbot like any other RASA action.create a new python script in
$HOME/.pal/chatbots-enabled/common/actions
, called<action name>.py
(for instance if the action is namedaction_get_ip
, the script must be namedaction_get_ip.py
)
Your new action is now available. However, do not forget to retrain your chatbot as explained here.
You can use the default actions available in
$HOME/.pal/chatbots-enabled/common/actions
as example.
Important
Use the tr
function (from rasa_actions_server.helpers import
tr
) to translate any text to the target language. You will need to add the
required string(s) to each language actions_i8n.yml
(for instance, here for
en_GB
: $HOME/.pal/chatbots-enabled/en_GB/actions_i8n.yml
).
Example: recognising a bring
command#
Let’s define a custom action bring_object
to ask the robot to bring us an
object. We want the user to ask the robot to ‘bring us’ various items, and this
should be translated into an intent on the robot’s /intents topic.
To do so, we first need to define the RASA intent bring_object
in your
chatbot’s nlu.yml
and domain.yml
files, then implement the custom action
as a Python script, and finally link the RASA intent to our custom action. By
doing so, RASA will call our custom action everytime the bring_object
intent
is detected in the user’s speech:
To define the RASA intent bring_object
in your chatbot’s
nlu.yml
file and provide a few examples (check here how to
create the training data for RASA), open your chatbot’s nlu.yml
file and add
the following code:
Note
If you have not yet created your own chatbot, you
can also modify directly the provided $HOME/.pal/chatbots-enabled/<your
language>/basic_commands/nlu.yml
.
Note however that the content of this file might be overwritten when you update your robot!
Alternatively, copy the folder $HOME/.pal/chatbots-enabled/<your
language>/basic_commands/
to e.g. $HOME/.pal/chatbots-enabled/<your
language>/my_chatbot/
and work from there.
version: "3.1"
nlu:
- intent: bring_object
examples: |
- bring the [ball](object)
- bring [me](goal) the [cylinder](object)
- bring the [cube](object) [here](goal)
- bring the [box](object) to [me](goal)
- bring [here](goal) the [sphere](object)
As we want to define a custom action for such intent, we
only need to add the name of the action that we are going to implement in
domain.yml
. Open and edit this file (found next to nlu.yml
):
version: "3.1"
language: "en_GB"
intents:
- bring_object
entities:
- goal
- object
actions:
- action_bring_object
Note
If you are editing an existing domain.yml
, add the fields to existing
ones. For instance, the final domain.yml
file might look like:
version: "3.1"
language: "en_GB"
intents:
- present_content
- bring_object
entities:
- object
- goal
actions:
- action_present_content
- action_bring_object
Next, we create a new action called action_bring_object.py
that will
process the user input. It will extract the entities goal
and object
and
build the response to send to the user.
This Python class must implement a run()
method that processes the
user output from RASA. It takes as input the tracker
from which we
extract the entities, and the language
that determines whether a
translation is needed. For that reason, the class uses a method tr
defined in the script helpers
that maps English sentences to its
translations defined in the actions_i8n.yml
file.
Create the file
$HOME/.pal/chatbots-enabled/common/actions/action_bring_object
and
copy-paste this code:
1 #!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4import json
5import time
6import rospy
7from hri_actions_msgs.msg import Intent
8
9from rasa_actions_server.helpers import tr
10
11
12# the name of the class does not matter as long as the file contains *exactly*
13# one class with a run() method.
14class ActionBringObject:
15
16 def __init__(self):
17 self.intent_pub = rospy.Publisher("/intents", Intent, queue_size=10)
18
19 def run(self, tracker, language):
20
21 intent_msg = Intent()
22 intent_msg.intent = intent_msg.BRING_OBJECT
23 intent_msg.source = intent_msg.UNKNOWN_AGENT
24 intent_msg.modality = intent_msg.MODALITY_SPEECH
25 intent_msg.priority = 128
26
27 entities = {
28 e["entity"]: e["value"] for e in tracker["latest_message"]["entities"]
29 }
30
31 if "object" not in entities:
32 return {
33 "events": [],
34 "responses": [
35 {
36 "text": tr(
37 "Sorry, I did not understand what object do you want me to bring",
38 language,
39 )
40 }
41 ],
42 }
43
44 if "goal" not in entities:
45 entities["goal"] = "here" # implicit assumed goal
46
47 intent_msg.data = json.dumps(
48 {"object": entities["object"], "goal": entities["goal"]}
49 )
50
51 self.intent_pub.publish(intent_msg)
52 rospy.loginfo(
53 "Intent to bring the object <%s> to <%s> extracted from RASA and published to /intents"
54 % (entities["object"], entities["goal"])
55 )
56
57 return {"events": [], "responses": [{"text": ""}]}
Note
In this example, we publish a ROS intent on the /intents
topic. You can
modify this example to perform any other action, like fetching online
resources, connect to a database, etc.
Next, we can ‘connect’ our RASA intent to the custom action. Open
rules.yml
(found alongside nlu.yml
and domain.yml
) and add the
following rule:
version: "3.1"
rules:
- rule: bring object
steps:
- intent: bring_object
- action: action_bring_object
Finally, we can re-train the chatbot, and test that our custom action work: simply follow the steps Step 2: Train the new RASA model and Step 3: Test your chatbot.
Try to ask the robot to bring you something: if everything went well, you should
see a new intent published on the /intents
topic.
If nothing appears, keep an eye on the log of the chatbot pal_chatbot_wrapper
: you will likey find the reason
for the error there.
See also#
See Dialogue management to learn more about the NLP pipeline.
See Create, translate or update a chatbot to learn how to design, develop and deploy a chatbot.