How To Add Structure To Chatbot Intents Using Rasa

Introduce A Simple Data Structure On A NLU Level With Retrieval Intents

Cobus Greyling
6 min readJan 21, 2021



Chatbot frameworks are continuing to move in a general direction with the proliferation of the following elements:

  • Merging of Intents & Entities
  • Entities being contextually defined within the user utterance examples.
  • Data structures within Entities (Roles & Patterns etc.)
  • Nested Entities (Sub-Entitles, Sub-Sub-Entities etc.)
  • Intent Categories

In this story I want to look at a feature within Rasa called retrieval intents, which can be used when defining intents. This can be very helpful in larger application to organize data.

So, with Rasa you can define sub-categories in intents with what Rasa calls retrieval intents.

This is a specific type of intent, where an Intent can be extended with a sub-intent. You can see this as categorizing your Intents into smaller sub-categories.

In this story you will find a few simple examples on how to implement this feature with practical examples.

There are a few limitations which need to be noted regarding this feature.

And, towards the end of this article there are comments on how this feature can be built out.

Retrieval Intents

This feature in Rasa NLU reminds me of the Categories Hierarchy option in IBM Watson NLU API.

Relevant categories returned based on a phrase

In Watson NLU, if set to true, explanations are returned for each categorization; as you can see in the image.

Watson can return up to a five-level taxonomy of the content.

Here in the image the top three categories are returned; if available.

An explanation can be added which can be toggled on and off.

Categories returned defaults to three, but this can be set.

Another IBM Watson NLU API Example

When adding retrieval intents, your NLU training data could look like this example:

- intent: balance/savings
examples: |
- What is the balance in my savings account?
- Give me my savings balance?
- I need to know the balance of savings.
- What is my savings balance?
- Savings Balance
- balance for savings
- intent: balance/checking
examples: |
- What is the balance in my checking account?
- Give me my checking balance?
- I need to know the balance of checking.
- What is my checking balance?
- checking Balance
- balance for checking
- intent: balance/money_market
examples: |
- What is the balance in my money market account?
- Give me my money market balance?
- I need to know the balance of money market.
- What is my money market balance?
- money market Balance
- balance for money market
- intent: balance/retirement
examples: |
- What is the balance in my retirement account?
- Give me my retirement balance?
- I need to know the balance of retirement.
- What is my retirement balance?
- retirement Balance
- balance for retirement

Notice the forward slash in the intent name. Obviously this mean that you cannot use a forward slash in your intent name. As you can see in this example, the intent name is be enriched to a large degree. With the balance intents being grouped together, and then extended from there with a nested name/description.

To name one advantage, this can save you an additional dialog turn in order to ask the user for which account type they need a balance for.

Obviously, you can also perform this function by means of entities…the practicalities will have to be weighed up in terms of the best approach to take for each use-case.

Next, run Rasa in NLU mode only with the following command:

rasa shell nlu

Once presented with the command line, enter the phrase: “What is the balance in my credit card account?”

Here you see the command line prompt to enter a message to be parsed by Rasa NLU

Below is a portion of the JSON response from the Rasa NLU engine.

The root intent is returned with the retrieved intent.

You can see the root intent of balance is returned upfront and lower down in the JSON document the nested intent is visible; balance/credit_card.

When running Rasa NLU only, this feature can be used effectively in the following scenarios:

  • Post-processing text which needs to be classified. Think here of archived live agent conversations.
  • Initial intent routing of customer conversations to specific agent skill groups.
  • Labeling natural language texts by relevant categories.


Nesting of intents is not possible and one sub-intent or one level-down is possible per intent. The moment you try and nest a second sub-intent with the intent name balance/savings/usd, the error below is given:

(rasa1) C:\data\rasa\demo1>rasa train nluThe configuration for pipeline was chosen automatically. It was written into the config file at 'config.yml'.RasaException: Intent name 'balance/savings/usd' is invalid, it cannot contain more than one '/'.

The idea of nesting is not foreign to NLU, currently Microsoft’s LUIS allows nesting of their Machine Learning entities.

This means that with LUIS you can nest entities a few layers deep; hence entities with sub-entities, sub-sub-entities and so on.


With Retrieval Intents a richer response is possible from Rasa NLU and intents can be categories.

Management of intents are simplified.

Related intents can be grouped together and distinguished by sub-entity.

As mentioned before, currently Rasa only allows nesting one level deep. It could be a convenient feature to nest three to five levels deep in retrieving intents and organize data in such a way.

Be that as it may, the retrieval intent feature is a very handy tool which is perhaps not that commonly known.

It needs to be noted that with IBM Watson NLU API the categories are available by default; hence preloaded.



Cobus Greyling

I explore and write about all things at the intersection of AI & language; LLMs/NLP/NLU, Chat/Voicebots, CCAI.