I am building a flight information retrieval system. I have an entity type: location and two slots, origin and destination. The system can ask the user about the city of origin: utter_ask_origin and also ask about the city of destination: utter_ask_destination. In both cases, the user might give a simple answer like Los Angeles or New York. The intent of this message is inform_location with location entity: Los Angeles or New York. In the first case, I need it to be mapped to slot: origin and in the second case I need it to be mapped to slot: destination. What is the best way to do that?
domain.yml
intents:
- greet
- goodbye
- ask_flights
- inform_origin
- inform_dest
- inform_location
- inform_date
- inform_airline
- easter_egg
- affirm
- negate
slots:
origin:
type: text
destination:
type: text
date:
type: text
airline:
type: text
entities:
- origin
- destination
- location
- date
- airline
templates:
utter_greet:
- "Hello! How can I help you?"
- "Welcome! What can I do for you?"
utter_goodbye:
- "Bye!"
- "Goodbye!"
utter_ask_origin:
- "What is your origin city?"
- "Where do you want to travel from?"
- "Name the city from where you want to start?"
utter_ask_destination:
- "What is your destination city?"
- "Where do you want to travel to?"
- "Name the city you want to reach?"
utter_ask_date:
- "What is your date of journey?"
- "When do you want to travel?"
utter_ask_airline:
- "Which airline do you want to travel with?"
utter_easter_egg:
- "Fight on for ol’ SC!"
actions:
- utter_greet
- utter_goodbye
- utter_ask_origin
- utter_ask_dest
- utter_ask_date
- utter_ask_airline
- utter_easter_egg
- action_time
I am replying to my own question, and asking another question of my own!
To map the same entity type to different slots in my case, I declare another slot called asked_type that I set to ask_origin if the bot asks the user for the origin location and set to ask_destination if the bot asks for the destination location. Then when I retrieve a location entity, depending upon the slot value for asked_type I can accordingly either populate the origin slot or destination slot.
But I noticed that this works only if I had some prior context which for this case was the bot asking the user about the origin location or destination location. What happens when the user starts by asking something like - “I want to search for flights from Boston to New York…”. Now I retrieve 2 location entities and I don’t know which of them is origin and destination, solely from the intent. Also I have no prior context.
I can ask the user to disambiguate for us each location by questioning them whether say, Boston, is their origin or destination, but this seems a messy solution. What can I do?
I’m answering your original question here as I had to solve the exact same issue. “How can I map the same entity to different slot”.
You can solve this with new FormAction with slot_mapping.
In NLU, you can just train “country” entity only.
Then, in FormAction, you define both as required_slots like this return ["origin", "destination"]. then in slot_mappings, you define like this
@red-frog, when FormAction is executed, it asks slot by slot.
when REQUESTED_SLOT is ‘origin’ then it will run utter_ask_origin
when REQUESTED_SLOT is ‘destination’ then it will run utter_ask_destination
So mapping of that is already done. Hope this helps!
How about giving role attribute to each entity? For instance, I want to fly from [New York]{“entity”: “location”, “role”: “from”} to [Los Angeles]{“entity”: “location”, “role”: “to”}.