Common Patterns

Note

Here we go through some typical conversation patterns and explain how to implement them with Rasa Core.

Rasa Core uses ML models to predict actions, and slots provide important information these models rely on to keep track of context and handle multi-turn dialogue. Slots are for storing information that’s relevant over multiple turns. For example, in our restaurant example, we would want to keep track of things like the cuisine and number of people for the duration of the conversation.

Collecting Information to Complete a Request

For collecting a set of preferences, you can use TextSlot s like in the restaurant example:

slots:
  cuisine:
    type: text
 people:
    type: text
 ...

When Rasa sees an entity with the same name as one of the slots, this value is automatically saved. For example, if your NLU module detects the entity people=8 in the sentence “I’d like a table for 8”, this will be saved as a slot,

tracker.slots()
>>> {"people": "8"}

When Rasa Core predicts the next action to take, the only information it has about the TextSlot s is whether or not they are defined. So you have enough information to know that you don’t have to ask for this information again, but the value has no impact on which actions Rasa Core predicts. The full set of slot types and their behaviour is described here: Slot Types.

Using Slot Values to Influence Which Actions are Predicted

Maybe your restaurant booking system can only handle bookings for up to 6 people, so the request above isn’t valid. In this case you want the value of the slot to influence the next selected action (not just whether it’s been specified). You can achieve this using a custom slot class.

The way we defined it below, if the number of people is less than or equal to 6, we return (1,0), if it’s more we return (0,1), and if it’s not set (0,0).

Rasa Core can use that information to distinguish between different situations - so long as you have some training stories where the appropriate responses take place, e.g.:

# story1
...
* _inform[people=3]
- action_book_table
...
# story2
* _inform[people=9]
- action_explain_table_limit
from rasa_core.slots import Slot

class NumberOfPeopleSlot(Slot):

  def feature_dimensionality(self):
      return 2

  def as_feature(self):
      r = [0.0] * self.feature_dimensionality()
      if self.value:
          if self.value <= 6:
              r[0] = 1.0
          else:
              r[1] = 1.0
      return r

If you want to store something like the price range, this is actually a little simpler. Variables like price range usually take on one-of-n values, e.g. low, medium, high. For these cases you can use a CategoricalSlot.

slots:
  pricerange:
    type: categorical
    values: low, medium, high

Rasa automatically represents (featurises) this as a one-hot encoding of the values: (1,0,0), (0,1,0), or (0,0,1).

Storing API responses in the tracker

You often want to save some information in the tracker, like the results from a database query, or from an API call. If you don’t want the value to influence the dialogue, you can use a UnfeaturizedSlot. You can explicitly set this value in a custom action:

from rasa_core.actions import Action
import requests

class ApiAction(Action):
    def run(self, tracker, dispatcher):
      data = requests.get(url).json
      return [SetSlot("api_result", data)]