Present alternative utterance when slot is filled with "None"

Hey there!

In my use case there is the possibility that the user introduces himself with his name. The bot then tries to pick up the name with the help of a slot and presents an utterance containing this name in the following (e.g. User: “Hi, my name is Mike.” – Bot: “Mike – wow, what a nice name!”).

As it is hard to grasp the diversity of names, the bot at the moment often reproduces “None” instead of the actual name (“None - wow, what a nice name!”). Is there a possibility, that the bot utters an alternative utterance without the name in it, in case it isn’t able to recognise the name? But only as kind of a fallback – because with name is always nicer :).

Thanks in advance!

You could do this by making name a text slot (Slots):

E.g. in domain.yml:

slots:
    name:
        type: text

And then in your stories, have one for the slot being filled and one for it being empty:

## name is set
* greet{"name":"Mark"}
    - slot{"name":"Mark"}
    - utter_greet_with_name

## name is not set
* greet
    - utter_greet_no_name

And of course make sure you have responses defined for each utter_ action

1 Like

Hey Melinda,

Thanks for the quick answer. I have just implemented it the way you said and tested it. Unfortunately, the bot seems to randomly use one of the stories – no matter if it recognised the name, or not. Do you have an explanation for this?

Thanks, again! :slight_smile:

No problem - Which policies do you have in your config? And which policy does it say it is using for prediction?

Hey Melinda,

I had a problem with my policies. The MemoizationPolicy was set to 5 by default but works better with value 1 in my case. After changing it, your solution is working very well. Thank you! :slight_smile:

Edit: I have a small follow up question. In case a user types his/her name with an incorrect capitalization (e. g. john instead of John) – is it possible to automatically capitalize the first letter of my name slot when reproducing it?

1 Like

Glad you got it working. You could write a custom action that capitalizes the slot value (e.g. returns [SlotSet("name":tracker.get_slot("name").capitalize()) ), or, if you’re using a closed set of entity values (probably not since they are names?) you could map lowercased values to uppercase ones as synonyms.

Hey @mloubser,

I hope you’re fine. I am stumbling upon another problem in this case. For my bot I am now using mappings for all my one-turners (user asks, bot answers). Unfortunately I can only connect one action to an intent – here: to my introduce-intent. Because of this, my bot cannot make a decision based on whether it has recognised a name in the slot or not and cannot choose the appropriate (re)action (utterance with name or utterance without name). Is there any way to work around this problem?

Thanks in advance!

Yes, once you want more complicated behaviour like this you need to write stories, not mappings. You’ll also have to re-check your max_history since you want it to take a slot event into account too.

If you’re interested, you can check out the 2.0 alpha release which has a new format for training data + a unified RulesPolicy - might be interesting for what you want.

Hey Melinda,

Thank you for replying so fast. Please let me elaborate on my situation in a few sentences: In the past I had problems with handling both, one-turn stories as well as longer stories with the MemoizationPolicy's default max_history of 5. My one-turners most of the time led to a falIback and utter_default. When setting the max_history to 1 instead, only the one-turners worked, but the longer stories didn’t anymore. I have now found a solution by mapping all of my one-turners while switching back to to the default max_history of 5. Now both kinds of stories work well. For the one-turners I have written down both, the mappings in my domain.yml as well as the corresponding stories.

With this in mind, can you help me with the specific case? I guess my max_history with 5 is fine for handling the slot interpretation. But if I do not map my introduce-intent, it is followed by a fallback. On the other hand, If I do map it, only one action (utter_greet_with_name or utter_greet_no_name) is possible. In case I choose utter_greet_with_name and the bot doesn’t recognise the name, I get the None output.

This is what my relevant stories look like:

## greet with name

* introduce{"name": "John"}
	- slot{"name": "John"}
    - utter_greet_with_name


## greet no name

* introduce
    - utter_greet_no_name

Thanks so much in advance! :slight_smile:

Regards,

Sebastian

Hmm that sounds like a problem; even if you don’t use mapping, both one and multiturn stories should be handleable by the MemoizationPolicy. Could you post your full domain, config & stories? Also, when you’re testing this, are you testing it through rasa shell relying on NLU?

Hey Melinda,

Thanks for replying. I did almost everything via Rasa X, also the testing. In the testing I often tested my stories in a random order as I don’t expect a “standard” flow that a user will pass through. Maybe this got the MemoizationPolicy confused?

I attached my domain and stories, this is my config:

language: de
pipeline: supervised_embeddings
policies:
  - name: MemoizationPolicy
    max_history: 4
  - name: KerasPolicy
  - name: MappingPolicy
  - name: FallbackPolicy
    nlu_threshold: 0.4
    core_threshold: 0.4
    ambiguity_threshold: 0.1
    fallback_action_name: action_default_fallback

Thanks so much for looking into it, cause I am really stuck at this point.

rasa_sebastian_domain.yaml (54.0 KB) rasa_sebastian_stories.md (12.2 KB)

Looks like you’re using mappings ('triggers") together with stories for the same intent; this is going to lead to confusion. You need to remove the mapping for greet to use the stories.

In general, for each intent, you should either have a mapping, or stories, but not both. If you anticipate these becoming contextual exchanges, you should rather write them as stories so that it’s more flexible; if not, you can leave it as a mapping only.