Better to use specific Intents and Actions or Generalized?

I’ve been thinking a lot about whether its better to use specific intents and actions or more generalized intents and actions (or maybe even more likely is a combination of both but when to use each kind). I think the best way to describe this would be with some examples:

“I want to go outside” → intent: DesireGoOutside vs “I want to go outside” → intent:DesireGoPlace Entity:Outside

And then using some activities as well

(specific intent and specific action) intent: DesireGoOutside action: GoOutsideThen vs (generic intent and specific action) intent: DesireGoPlace entity: Outside slot_was_set: DesiredPlace: outside action: GoOutsideThen vs (generic intent and generic action) intent: DesireGoPlace entity: Outside action:GoPlaceThen (custom action that would then figure out what action to do based on the data passed to the custom action server)

I see benefits and downsides of each of theses approaches and I’m not sure exactly which one would be best or when different approaches may be better.

With a specific intent and specific action, training is very simple for the model and the model has lots of future context about the exact action it took. But, the number of intents and actions that would have to be specified to the model could be very large or infinite.

With a generic intent and specific action, the model has the information about the exact action that will be taken but we have to specify potential very many custom actions manually. Also, the stories and model slots get a bit cluttered with slots that store the entity value from the corresponding last intent.

With a generic intent and generic action, training for the model is very simple as it just matches generic intent to generic action. Also, this brings down the number of needed specified actions and intents. However, it appears some context is lost… Consider the following extension to the above example intent: DesireGoPlace entity: Outside action:GoPlaceThen user: “should I go to a park or go hiking?”

In this scenario, the model now loses some context that the previous action was actually “GoOutsideThen” so it will be harder to respond to this user message. Perhaps the answer is to again store the result of the original intent in a slot as in the second example, but this then gets tricky as who knows how long we could be referencing slots that came from an entity being set. Also, if that slot gets overridden by a new entity we lose the context entirely. Also another concern of mine is adding more and more slots with this approach without them getting cleaned up. Do slots get garbage collected automatically or how does that work exactly?

I hope someone has some info into which of these approaches (or maybe other approaches) would be the best for a general purpose conversational AI?

Hi @ski23 sharing my thoughts on your topic. I believe in general the approach might vary from use case to use case.

In the specific example you gave, I would tend to use generalized intent and action. I believe that entity extraction combined with generalized action where I can give response based on the intent and extracted entities will provide better flexibility and maintainability.

I would also think if the use cases are small or can vary a lot depending on the domain. If we take the specific intent route then I would need to keep adding more and more intents e.g. GoToPark, GoToMall, GoToMoviehall etc. Which I believe might be come too overwhelming in long run.

However if we play with entities and utilized lookups we might have more flexibility in terms of adding more scenarios. For example: intent: DesireToGoPlace examples: |

entities: placeType

custom action: ActionPlace(): //custom logic driven by custom logic

lookup: placeType examples: |

  • market
  • outside
  • movie
  • hospital
  • stadium
  • //more can be added as per new requirements

So in this scenario using a generic intent and action, how should I handle followup requests after the generic action. ie: in the case of the market: ActionPlace user: “Which market should I go to?”

hi @ski23 - it’s a bit difficult to answer or think without knowing specific domain for which the chat bot is being developed as there can be multiple ways to implement the same thing. But here is my take on it. Rather than thinking in terms of follow up request, I would like to think this as a menu and sub menu. So for example users could say -

  • which market should i go for kids toys
  • which market should i go for medicines
  • grocery is available in which market
  • which mall has a movie theatre
  • which market has a beauty parlor
  • is there a parlor in nearby mall

then within your custom action you can get these entities / slots and build your custom logic which could get a response from the DB or external API.

What I am trying to highlight is that if your domain is such where your intent will vary far less than the entities, then having general intent with entities can be a good approach. As then you can keep adding entities via lookup without having to create more and more intents.

however if your domain is such where you have very different intents altogether then it would make sense to have specific intents and then have entities specific to those intents.

most important is to understand the domain and then plan accordingly. hope it helps.

Yea. I don’t think I explained well enough to exactly what I was meaning to ask. So, to clarify, I’m trying to make a conversational AI that can carry on meaningful conversation and also perform custom actions with backend code. It makes sense to me that, when possible, using entities and general intents is a better approach then many similar specific intents. However, based on what I’ve seen, rasa cannot predict the next action based on solely an intent and an entity; The entity has to be mapped to a slot and then in a training story, you have to check the slot value to predict the next action. This seems like a bug based on documentation so I have an issue for it on the github page but perhaps this is intended. Even assuming that I’m using the approach where I map the entity to a slot, I get a flow like this:

Intent: WantToGoToPlace Entity: Park
Action: GoToPlace

perhaps inside of the custom action GoToPlace I use an if statement like this:

if (PlaceEntity == "Park")
{
  GoToParkCustomAction()  -> "Go to a park"
}
else if (PlaceEntity == "Amusement Park")
{
 GoToAmusementParkCustomAction() -> "go to an amusement park"
}

So, this is still fairly straight forward and no real problems arise here. However, now we’ve done some processing in this custom action and essentially branched and return more than one “sub-custom-action” based on some conditions. This means that in the case where the user wanted to go to an amusement park, the real action being taken was: GoToAmusementPark but, since we return a response string from the custom action server and not a “sub-action” to execute, then rasa only knows that the action executed was “GoToPlace”. So, when the user wants to do a followup example when the action was specific, rasa could have easily learned based on this story:

Intent: WantToGoToAmusementPark
Action: GoToAmusementPark
Intent: WhatRidesToRide ("What rides should I ride")
Action: BestRidesToRide

This makes total sense and should be easy for rasa to learn to output this conversation. It learns that after it executed the action “GoToAmusementPark” then if the user later asks “WhatRidesToRide” then they are asking what rides to ride at the amusement park. However, in the general example from above, I don’t see how rasa could learn this:

Intent: WantToGoToPlace Entity: Park
Action: GoToPlace
Intent: WhatRidesToRide ("What rides should I ride")
(rasa would be confused here because it doesn't have the context that it actually just told the user to go to an amusement park. It only knows it told them to go to a place.)

So, I’m wanting to figure out how to handle cases like these (which will be very common in my model if using generic actions) and what the best way to deal with them is. Thanks so much for all the help so far!

bump

bump