How to map few numbers from user utterance to slots

Dear colleagues, we have two questions:

1. we want Rasa to extract quantity in phrases like

I want to order two cups of tea and one coffee

We have the phrase like this in our config /nlu/order.yml:

version: "2.0"
nlu:
- intent: orderdrink
  examples: |
    - we want to order drinks
    - we want [two]{"entity": "black_tea_qty", "value": "2"} [tea]{"entity": "order_black_tea", "value": "true"} and [one]{"entity": "coffee_qty", "value": "1"} [coffee]{"entity": "order_coffee", "value": "true"}
    - we want [two]{"entity": "black_tea_qty", "value": "2"} [tea]{"entity": "order_black_tea", "value": "true"}
    - we want [two]{"entity": "green_tea_qty", "value": "2"} [tea]{"entity": "order_green_tea", "value": "true"}
    - we want [one]{"entity": "water_qty", "value": "1"} [water]{"entity": "order_water", "value": "true"}
...

In above example bot understand correctly and put values int slots:

order_coffe: true
coffee_qty: 1
order_black_tea: true
black_tea_qty: 2

But if we say something like this

we want two tea two green tea and one water

Bot understand only first part (two tea and put values in slots order_black_tea: true, black_tea_qty: 2) and then ask how many cups of green tea? and how many bottles of water? in spite of the fact that we have such phrases in nlu.

Should we put in nlu config the whole phrases for this case:

 - we want [two]{"entity": "black_tea_qty", "value": "2"} [tea]{"entity": "order_black_tea", "value": "true"}[two]{"entity": "green_tea_qty", "value": "2"} [green tea]{"entity": "order_green_tea", "value": "true"}   and [one]{"entity": "coffee_qty", "value": "1"} [coffee]{"entity": "order_coffee", "value": "true"}

or bot shoul should learn from separate phrases?

Our /stories.yml for order coffee, water and tea :

- story: Order black tea and coffee and water
  steps:
  - intent: orderdrink
    entities:
    - order_water                                   # water
    - order_black_tea                            # black tea
    - order_coffee                                  # coffee
  - slot_was_set:
      - order_water: true
      - order_black_tea: true
      - order_coffee: true
  - action: water_order_form
  - active_loop: water_order_form
  - active_loop: null
  - action: black_tea_order_form 
  - active_loop: black_tea_order_form
  - active_loop: null
  - action: coffee_order_form                      
  - active_loop: coffee_order_form
  - active_loop: null
  - action: utter_water_black_tea_coffee_slots_values 
  - intent: affirm
  - action: action_order_drinks
  - action: utter_order_confirmed                    
  - action: clear_slots 

2. What is the best way to map numbers to slots? We think it is not a good idea to put in nlu config all phrase variations. We found such way: botfront

What is the best practice?

Rasa Version      :         2.8.5
Minimum Compatible Version: 2.8.0
Rasa SDK Version  :         2.8.2

Thanks

Hello and welcome to the forum :slight_smile:

Please take a look at entity roles and groups.

As for mapping numbers to slots, I suggest using Duckling.

Hello ChrisRahme.

Thanks for your reply. We are using Duckling. It works ok with date and time. But we don’t know how to use Duckling in our “order drinks” scenario. We put to config.yml:

  - name: "DucklingEntityExtractor"
    url: "http://SOME_IP_ADDRESS:8000"
    dimensions: ["time", "duration", "number"]
    locale: "ru_GB"
    timezone: "Europe/Moscow"

In this if we say please one coffee one water and one green tea we get the such result from duckling:

start	:	0
end	    :	4
text	:	one
value	:	1
confidence	:	1
	additional_info	
            value	:	1
            type	:	value
entity	    :	number
extractor	:	DucklingEntityExtractor

start	:	9
end	    :	13
text	:	one
value	:	1
confidence	:	1
	additional_info	
            entity	    :	number
            extractor	:	DucklingEntityExtractor

start	:	19
end	    :	23
text	:	one
value	:	1
confidence	:	1
	additional_info	
            value	:	1
            type	:	value
entity	    :	number
extractor	:	DucklingEntityExtractor

So in this Duckling mapping we can’t understand which number refers to which entity…

As we see if we add in nlu.yml as many phrases as we can imagine it will be OK. But it is not good solution, because it is difficult to combine drinks( 2 coffee 2 water, just 3 coffee, 1 water 4 green tea… etc)

We want to try rasa-composite-entities but we get the exception

Composite Entities: got an unexpected keyword argument 'composite_patterns_path'

We are still trying to find the best way for our question…

Hello colleagues. Is it a good practice to map no single word but multiply words. Here are examples:

- [five cups of black_tea]{"entity": "black_tea_qty", "value": "5", "role":"order_black_tea"}
- [five cups of green tea]{"entity": "green_tea_qty", "value": "5", "role":"order_green_tea"}

In this case when I speak to bot I want to order five cups of black tea and five cups of green tea bot will understand the second part of sentence(about green tea). As I think it is because of there is union five cups of

Please advise how we can get around this situation?

I think we have good result with role and groups. But now when we run rasa train we have the error:

asa.shared.core.trackers  - Tried to set non existent slot 'role'. Make sure you added all your slots to your domain file.

I have checked every config file - there is no slot role This error is disappeared when we comment out order_drink_stories.yml:

stories:
- story: Order black tea
  steps:
  - intent: orderdrink
  - slot_was_set:
    - black_tea_qty: true
      role: order_black_tea
  - action: black_tea_order_form
  - active_loop: black_tea_order_form
  - active_loop: null
  - action: utter_black_tea_slots_values
  - intent: affirm
  - action: action_order_drinks
  - action: utter_order_confirmed
  - action: clear_slots

The model created successfully and we can work with this model. But this error shoudn`t be…

Where is the mistake?

@NicolasD Hello, I not tried personally this scenario but give it a try or please ref this link: NLU Training Data and even this Domain for role and group only.

stories:
- story: Order black tea
  steps:
  - intent: orderdrink
    entities: 
     - black_tea_qty: true
       role: order_black_tea
  - slot_was_set:
     - black_tea_qty: true
       role: order_black_tea
  - action: black_tea_order_form
  - active_loop: black_tea_order_form
  - active_loop: null
  - action: utter_black_tea_slots_values
  - intent: affirm
  - action: action_order_drinks
  - action: utter_order_confirmed
  - action: clear_slots

PS: Even your training data is not in proper format, please sort that out

Note: We most likely would need to add the roles and groups to their respective entities in the domain file. The entities keyword in the domain file would then become a dictionary instead of a list.

Or just use entities rather than slot?

Some pointers (Thanks to Tanja) Ref: Introducing entity roles and groups

  • UserUttered.as_sub_state: Add the roles/groups to the list of entities. Concatenate the role/group names with the entity names to make sure they are unquie.
  • Update the yml stories format to include roles/groups next to entities
  • Update the domain file to be able to add entities with roles and groups
  • ignore_entities for intents should not be modified. We treat roles/groups as part of the entities. E.g. if an entity with a role was detected but it should be ignored, also ignore the role. If an entity with a role was detected and it should be considered for the intent, consider the entity and the role. To achieve that we need to split the concatenated names again.
  • Domain needs to store entities with roles and groups
  • Add a method entity_states to the Domain that returns all entity names + the concatenated names of roles/groups and entities.
  • SingleStateFeaturizer should use the new entity_states method of the domain in prepare_from_domain
  • Modify an existing example to include entity roles/groups (needs to be clarified)
  • Verify that e2e tests contains entity roles and groups

Hello Nik. Thanks for your answer. I have read this topics about training nlu, role and groups. And I have done all configuration according that guides :frowning: In domain.yml I have added:

entities:
  - black_tea_qty:
      roles:
        - order_black_tea
...
slots:
  black_tea_qty: 
    type: text
    initial_value: null
    auto_fill: true
    influence_conversation: true
...

Yesterday I gave a test: I added to the domain.yml next code in slots part:

  role: 
    type: text
    initial_value: null
    auto_fill: true
    influence_conversation: false

And after that there was no such error about

Tried to set non existent slot 'role'. Make sure you added all your slots to your domain file.

But I do not understand why we should add role as a slot…