Knowledge Base Actions

Knowledge Base Actions

Warning

This feature is experimental. We introduce experimental features to get feedback from our community, so we encourage you to try it out! However, the functionality might be changed or removed in the future. If you have feedback (positive or negative) please share it with us on the forum.

Using ActionQueryKnowledgeBase

Create a Knowledge Base

The data used to answer the user’s requests will be stored in a knowledge base. A knowledge base can be used to store complex data structures. We suggest you get started by using the InMemoryKnowledgeBase. Once you want to start working with a large amount of data, you can switch to a custom knowledge base (see Creating Your Own Knowledge Base).

To initialize an InMemoryKnowledgeBase, you need to provide the data in a json file. The following example contains data about restaurants and hotels. The json structure should contain a key for every object type, i.e. "restaurant" and "hotel". Every object type maps to a list of objects – here we have a list of 3 restaurants and a list of 3 hotels.

{
    "restaurant": [
        {
            "id": 0,
            "name": "Donath",
            "cuisine": "Italian",
            "outside-seating": true,
            "price-range": "mid-range"
        },
        {
            "id": 1,
            "name": "Berlin Burrito Company",
            "cuisine": "Mexican",
            "outside-seating": false,
            "price-range": "cheap"
        },
        {
            "id": 2,
            "name": "I due forni",
            "cuisine": "Italian",
            "outside-seating": true,
            "price-range": "mid-range"
        }
    ],
    "hotel": [
        {
            "id": 0,
            "name": "Hilton",
            "price-range": "expensive",
            "breakfast-included": true,
            "city": "Berlin",
            "free-wifi": true,
            "star-rating": 5,
            "swimming-pool": true
        },
        {
            "id": 1,
            "name": "Hilton",
            "price-range": "expensive",
            "breakfast-included": true,
            "city": "Frankfurt am Main",
            "free-wifi": true,
            "star-rating": 4,
            "swimming-pool": false
        },
        {
            "id": 2,
            "name": "B&B",
            "price-range": "mid-range",
            "breakfast-included": false,
            "city": "Berlin",
            "free-wifi": false,
            "star-rating": 1,
            "swimming-pool": false
        }
    ]
}

Once the data is defined in a json file, called, for example, data.json, you will be able use this data file to create your InMemoryKnowledgeBase, which will be passed to the action that queries the knowledge base.

Every object in your knowledge base should have at least the "name" and "id" fields to use the default implementation. If it doesn’t, you’ll have to customize your InMemoryKnowledgeBase.

Define the NLU Data

In this section:

For the bot to understand that the user wants to retrieve information from the knowledge base, you need to define a new intent. We will call it query_knowledge_base.

We can split requests that ActionQueryKnowledgeBase can handle into two categories: (1) the user wants to obtain a list of objects of a specific type, or (2) the user wants to know about a certain attribute of an object. The intent should contain lots of variations of both of these requests:

## intent:query_knowledge_base
- what [restaurants](object_type:restaurant) can you recommend?
- list some [restaurants](object_type:restaurant)
- can you name some [restaurants](object_type:restaurant) please?
- can you show me some [restaurant](object_type:restaurant) options
- list [German](cuisine) [restaurants](object_type:restaurant)
- do you have any [mexican](cuisine) [restaurants](object_type:restaurant)?
- do you know the [price range](attribute:price-range) of [that one](mention)?
- what [cuisine](attribute) is [it](mention)?
- do you know what [cuisine](attribute) the [last one](mention:LAST) has?
- does the [first one](mention:1) have [outside seating](attribute:outside-seating)?
- what is the [price range](attribute:price-range) of [Berlin Burrito Company](restaurant)?
- what about [I due forni](restaurant)?
- can you tell me the [price range](attribute) of [that restaurant](mention)?
- what [cuisine](attribute) do [they](mention) have?
 ...

The above example just shows examples related to the restaurant domain. You should add examples for every object type that exists in your knowledge base to the same query_knowledge_base intent.

In addition to adding a variety of training examples for each query type, you need to specify the and annotate the following entities in your training examples:

Remember to add those entities to your domain file (as entities and slots):

entities:
  - object_type
  - mention
  - attribute

slots:
  object_type:
    type: unfeaturized
  mention:
    type: unfeaturized
  attribute:
    type: unfeaturized

Create an Action to Query your Knowledge Base

To create your own knowledge base action, you need to inherit ActionQueryKnowledgeBase and pass the knowledge base to the constructor of ActionQueryKnowledgeBase.

from rasa_sdk.knowledge_base.storage import InMemoryKnowledgeBase
from rasa_sdk.knowledge_base.actions import ActionQueryKnowledgeBase

class MyKnowledgeBaseAction(ActionQueryKnowledgeBase):
    def __init__(self):
        knowledge_base = InMemoryKnowledgeBase("data.json")
        super().__init__(knowledge_base)

Whenever you create an ActionQueryKnowledgeBase, you need to pass a KnowledgeBase to the constructor. It can be either an InMemoryKnowledgeBase or your own implementation of a KnowledgeBase (see Creating Your Own Knowledge Base). You can only pull information from one knowledge base, as the usage of multiple knowledge bases at the same time is not supported.

This is the entirety of the code for this action! The name of the action is action_query_knowledge_base. Don’t forget to add it to your domain file:

actions:
- action_query_knowledge_base

Note

If you overwrite the default action name action_query_knowledge_base, you need to add the following three unfeaturized slots to your domain file: knowledge_base_objects, knowledge_base_last_object, and knowledge_base_last_object_type. The slots are used internally by ActionQueryKnowledgeBase. If you keep the default action name, those slots will be automatically added for you.

You also need to make sure to add a story to your stories file that includes the intent query_knowledge_base and the action action_query_knowledge_base. For example:

## Happy Path
* greet
  - utter_greet
* query_knowledge_base
  - action_query_knowledge_base
* goodbye
  - utter_goodbye

The last thing you need to do is to define the response utter_ask_rephrase in your domain file. If the action doesn’t know how to handle the user’s request, it will use this response to ask the user to rephrase. For example, add the following responses to your domain file:

utter_ask_rephrase:
- text: "Sorry, I'm not sure I understand. Could you rephrase it?"
- text: "Could you please rephrase your message? I didn't quite get that."

After adding all the relevant pieces, the action is now able to query the knowledge base.

How It Works

ActionQueryKnowledgeBase looks at both the entities that were picked up in the request as well as the previously set slots to decide what to query for.

Query the Knowledge Base for Objects

In order to query the knowledge base for any kind of object, the user’s request needs to include the object type. Let’s look at an example:

Can you please name some restaurants?

This question includes the object type of interest: “restaurant.” The bot needs to pick up on this entity in order to formulate a query – otherwise the action would not know what objects the user is interested in.

When the user says something like:

What Italian restaurant options in Berlin do I have?

The user wants to obtain a list of restaurants that (1) have Italian cuisine and (2) are located in Berlin. If the NER detects those attributes in the request of the user, the action will use those to filter the restaurants found in the knowledge base.

Query the Knowledge Base for an Attribute of an Object

If the user wants to obtain specific information about an object, the request should include both the object and attribute of interest. For example, if the user asks something like:

What is the cuisine of Berlin Burrito Company?

The user wants to obtain the “cuisine” (attribute of interest) for the restaurant “Berlin Burrito Company” (object of interest).

Resolve Mentions

Following along from the above example, users may not always refer to restaurants by their names. Users can either refer to the object of interest by its name, e.g. “Berlin Burrito Company” (representation string of the object), or they may refer to a previously listed object via a mention, for example:

What is the cuisine of the second restaurant you mentioned?

Customization

Customizing ActionQueryKnowledgeBase

You can overwrite the following two functions of ActionQueryKnowledgeBase if you’d like to customize what the bot says to the user:

Creating Your Own Knowledge Base Actions

ActionQueryKnowledgeBase should allow you to easily get started with integrating knowledge bases into your actions. However, the action can only handle two kind of user requests:

Customizing the InMemoryKnowledgeBase

The class InMemoryKnowledgeBase inherits KnowledgeBase. You can customize your InMemoryKnowledgeBase by overwriting the following functions:

Creating Your Own Knowledge Base

If you have more data or if you want to use a more complex data structure that, for example, involves relations between different objects, you can create your own knowledge base implementation. Just inherit KnowledgeBase and implement the methods get_objects(), get_object(), and get_attributes_of_object(). The knowledge base code provides more information on what those methods should do.