In the previous chapter we have created a newsletter form and wrote a story for it. Although this worked, there is a better way of invoking form loop when subscribe intent is recognized.
But before we make any changes, let's write a test for our form to make sure that the changes we are about to make do not break anything.
Let's add the following test story to our
# tests/test_stories.yml # ... previous contents ... - story: newsletter form happy path steps: - user: | hi intent: greet - action: utter_greet - user: | I want to subscribe intent: subscribe - action: newsletter_form - active_loop: newsletter_form - user: | my email is [email@example.com](email) intent: inform_email - action: newsletter_form - user: | twice a week intent: inform_frequency - action: newsletter_form - active_loop: null - action: utter_subscribed
Let's go though this test line by line.
- First, we are saying, that when a user writes "hi", it should be classified as greet intent, followed by utter_greet action.
- Then, when user writes "I want to subscribe", it should be classified as subscribe intent, followed by newsletter_form action and newsletter_form should be activated.
- Then, user writes "my email is firstname.lastname@example.org". This should be classified as inform_email intent and also email@example.com should be classified as email entity from this message.
- The inform_email should be followed by another newsletter_form action (asking for the frequency of emails).
- Then, when user writes "twice a week", it should be classified as inform_frequency intent.
- At this point, all slots of the form are filled and we are saying that the form should end by
- action: newsletter_formand
- active_loop: null.
- Then, the chatbot should perform the utter_subscribed action, informing us about our subscription details.
Make sure our tests pass by running
Now let's get back to our improvements!
Rules describe parts of conversations that should always follow the same path no matter what has been said previously in the conversation.
We want our assistant to always respond to a certain intent with a specific action, so we use a rule to map that action to the intent.
In our case, we would like to trigger the newsletter_form whenever the user expresses the intent subscribe.
# data/rules.yml version: "2.0" rules: - rule: activate subscribe form steps: - intent: subscribe - action: newsletter_form - active_loop: newsletter_form
We also also want to trigger the utter_subscribed action once all the required information has been provided.
# data/rules.yml # ... previous contents ... - rule: submit form condition: - active_loop: newsletter_form steps: - action: newsletter_form - active_loop: null - action: utter_subscribed
The submit form rule only applies when the newsletter_form is active to begin with. Once it is no longer active (
- active_loop: null), the form is complete.
We now no longer need our greet and subscribe story and we can delete it from
rasa test you can see, that both our tests still pass!
Rules, however do not generalize to unseen conversations. You should reserve them for single-turn conversation snippets, and use stories to train on multi-turn conversations. More on this in the documentation.
You can learn more about rules in the documentation.
In the next chapter, we will look at handling unhappy paths.
Repository for this tutorial:
You can checkout the state of the repository at the end of this tutorial by running:
git clone --branch 04-rules-and-testing-forms firstname.lastname@example.org:petr7555/rasa-dev-tutorial.git