# 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](https://forum.rasa.com/).

- [Using `ActionQueryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#using-actionqueryknowledgebase)

- [Create a Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#create-a-knowledge-base)

- [Define the NLU Data](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#define-the-nlu-data)

- [Create an Action to Query your Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#create-an-action-to-query-your-knowledge-base)
- [How It Works](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#how-it-works)

- [Query the Knowledge Base for Objects](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#query-the-knowledge-base-for-objects)

- [Query the Knowledge Base for an Attribute of an Object](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#query-the-knowledge-base-for-an-attribute-of-an-object)

- [Resolve Mentions](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#resolve-mentions)
- [Customization](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#customization)

- [Customizing `ActionQueryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#customizing-actionqueryknowledgebase)

- [Creating Your Own Knowledge Base Actions](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#creating-your-own-knowledge-base-actions)

- [Customizing the `InMemoryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#customizing-the-inmemoryknowledgebase)

### 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](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#custom-knowledge-base)).

```json
{
    "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
        }
    ]
}
```

### Define the NLU Data  
In this section:

- we will introduce a new intent, `query_knowledge_base`

- we will to annotate `mention` entities so that our model detects indirect mentions of objects like “the first one”

- we will use [synonyms](https://legacy-docs-v1.rasa.com/1.10.4/nlu/training-data-format/#entity-synonyms) extensively

```yaml
## 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?
 ...
```

### 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`.

```python
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](https://legacy-docs-v1.rasa.com/1.10.4/core/knowledge-bases/#custom-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.

## 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.

### 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?

### 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?

### Customizing the InMemoryKnowledgeBase

The class `InMemoryKnowledgeBase` inherits `KnowledgeBase`.  
You can customize your `InMemoryKnowledgeBase` by overwriting specific functions.  
For example, you can define a unique key attribute for each type of object:

```python
set_key_attribute_of_object()
```

You can also modify how the bot presents the objects or how it resolves mentions.

You can find a complete example in `examples/knowledgebasebot`  
( [knowledge base bot](https://github.com/RasaHQ/rasa/blob/master/examples/knowledgebasebot/)), as well as instructions for implementing this custom action below.
