Sure @btotharye ! My situation is different but was hoping to get some ideas from this original post
. Here’s the rundown of my project.
I am designing a chatbot that uses FormAction to search for an appropriate recipe for a user.
My domain file includes this:
entities:
- diet
- food_keyword
- meal_type
- recipe_type
forms:
- recipe_form
intents:
- surprise_me
- goodbye
- inform_dislikes
- deny
- greet
- inform
- affirm
- inform_allergen
- search_recipe:
use_entities: []
- stop
slots:
allergen:
auto_fill: false
type: unfeaturized
diet:
auto_fill: false
type: unfeaturized
dislike_ingr:
auto_fill: false
type: unfeaturized
preference:
auto_fill: false
type: unfeaturized
meal_type:
auto_fill: false
type: unfeaturized
name:
initial_value: human
type: unfeaturized
requested_slot:
type: unfeaturized
templates:
utter_ask_allergen:
- text: Do you have any allergies I should know about?
- text: What allergies should I keep in mind?
- ...
My nlu file looks like this:
## intent:inform_allergen
- allergic to [ingredient](food_keyword)
- i am allergic to [soy](food_keyword)
- I unfortunately have a [sesame](food_keyword) allergy
- I have a [chicken](food_keyword) allergy
- ...
## intent:inform_dislikes
- I don't like [cilantro](food_keyword)
- [garlic](food_keyword) is disgusting
- [radish](food_keyword) is gross
- I dislike [salmon](food_keyword)
- i don't like [olives](food_keyword) nor [cilantro](food_keyword)
- ....
## intent:inform
- i am [vegan](diet)
- [vegetarian](diet) recipes
- [gluten-free](diet) diet
- I like [garlic](food_keyword)
- I love [tofu](food_keyword)
- I love [anchovies](food_keyword)
- [salmon](food_keyword) is delicious
- [radishes](food_keyword) are delicious
- I want something with [olives](food_keyword)
- I need something for [lunch](meal_type)
- I want a recipe for [dinner](meal_type)
- I want to make [dessert](meal_type)
- how about something with [ginger](food_keyword)
- ...
My actions.py file includes the following:
class RecipeForm(FormAction):
...
def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:
"""
A dictionary to map required slots to
- an extracted entity
- intent: value pairs
- a whole message
or a list of them, where a first match will be picked
"""
return {
"allergen": [ # THIS IS WHERE I'M GETTING STUCK
self.from_entity(entity="food_keyword", intent="inform_allergen"),
self.from_entity(entity="food_keyword"), # with/without this doesn't change mapping
self.from_intent(intent="deny", value=False)
],
"meal_type": self.from_entity(entity="meal_type", not_intent="chitchat"),
"diet": [
self.from_entity(entity="diet"),
self.from_intent(intent="deny", value=False),
],
"dislike_ingr": [ # here too
self.from_entity(entity="food_keyword", intent="inform_dislikes"), # same as w/ allergen
self.from_intent(intent="deny", value=False),
],
"preference": self.from_entity(entity="food_keyword", intent=["search_recipe", "inform"]),
}
The problem: I am not sure how to distinguish between allergens, disliked_ingr(edients), and preference. It isn’t effective to have multiple entities to represent these, because they are all food keywords/ingredients.
So, I made multiple intents (e.g. specific intents for inform_allergen and inform_dislikes) and had some success. If the chatbot runs utter_ask_allergen and the user answers with “I am allergic to eggs”, then eggs is marked as a food_keyword entity currently fills the allergen slot. Same if user replies with “no”, then allergen slot is set to false.
However… when the chatbot runs utter_ask_allergen (“Do you have any allergies I should know about?”) and the user simply answers with “yeah eggs”, then eggs is still marked as a food_keyword entity but fills (replacing whatever was already there) the general preferences slot since the intent is mapped to inform, not inform_allergen. How can the chatbot consider the question they just asked in order to correctly fill the allergen slot? I tried adding self.from_entity(entity="food_keyword")
to the slot mapping but this didn’t work.
Any advice is much appreciated 