Asking for a Name

⚠️

Note: This is material for Rasa 2.x. The syntax has updated slightly in Rasa 3.0 so we recommend new users to check the new course found here.

In this lesson we'll expand our understanding of forms by writing one that's highly customised. We will make a dynamic form that will also generate buttons on our behalf.

Video


Install

If you don't have it installed already, be sure that you install Rasa X first. You can install it locally via pip.

pip install rasa-x --extra-index-url https://pypi.rasa.com/simple

If you appreciate more guidance, we've also gotten installation videos for Rasa X.


Windows Installation

MacOS Installation

Ubuntu Installation

Code

Most of the magic of this demo is handled in the actions.py file. Primarily we're using the required_slots method to indicate which slots are required at a given point in the form.

async def required_slots(
self,
slots_mapped_in_domain: List[Text],
dispatcher: "CollectingDispatcher",
tracker: "Tracker",
domain: "DomainDict",
) -> Optional[List[Text]]:
first_name = tracker.slots.get("first_name")
if first_name is not None:
if first_name not in names:
return ["name_spelled_correctly"] + slots_mapped_in_domain
return slots_mapped_in_domain

The idea here is that if we see a name that doesn't appear in our predefined name list that we'll add another required slot. This required slot will allow us to double-check if the user spelled their name correctly. The way we ask for this slot is defined in our domain.yml file.

responses:
utter_ask_name_spelled_correctly:
- buttons:
- payload: /affirm
title: Yes
- payload: /deny
title: No
text: Is {first_name} spelled correctly?

The payload of the buttons carry an intent. The buttons can either trigger the affirm or deny intent. These intents can then be extracted by our custom code and be picked up by our validators.

def extract_name_spelled_correctly(
self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
) -> Dict[Text, Any]:
# Explained in more detail on our docs.
# https://rasa.com/docs/rasa/forms#custom-slot-mappings
intent = tracker.get_intent_of_latest_message()
return {"name_spelled_correctly": intent == "affirm"}
def validate_name_spelled_correctly(
self,
slot_value: Any,
dispatcher: CollectingDispatcher,
tracker: Tracker,
domain: DomainDict,
) -> Dict[Text, Any]:
"""Validate `first_name` value."""
if tracker.get_slot("name_spelled_correctly"):
return {
"first_name": tracker.get_slot("first_name"),
"name_spelled_correctly": True
}
return {"first_name": None, "name_spelled_correctly": None}

Here's the great trick: by dynamically adding a slot value we're able able to invalidate the first_name slot if the user indicates that they'd like to see a correction.

Links

Exercises

Try to answer the following questions to test your knowledge.

  1. You can generate buttons by defining it as a response in the domain.yml file. How can you configure a response to trigger an intent?
  2. When buttons are generated for the user, does that mean they cannot speak to the assistant anymore?
  3. What does it mean when a form validator has a method called extract_<slot_name>? What are these methods meant for?

2016-2022 © Rasa.