# 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.19/core/knowledge-bases/#using-actionqueryknowledgebase)
  - [Create a Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#create-a-knowledge-base)
  - [Define the NLU Data](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#define-the-nlu-data)
  - [Create an Action to Query your Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#create-an-action-to-query-your-knowledge-base)
- [How It Works](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#how-it-works)
  - [Query the Knowledge Base for Objects](https://legacy-docs-v1.rasa.com/1.10.19/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.19/core/knowledge-bases/#query-the-knowledge-base-for-an-attribute-of-an-object)
  - [Resolve Mentions](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#resolve-mentions)
- [Customization](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#customization)
  - [Customizing `ActionQueryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#customizing-actionqueryknowledgebase)
  - [Creating Your Own Knowledge Base Actions](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#creating-your-own-knowledge-base-actions)
  - [Customizing the `InMemoryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#customizing-the-inmemoryknowledgebase)
  - [Creating Your Own Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#creating-your-own-knowledge-base)

## [Using `ActionQueryKnowledgeBase`](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#id4)  
### [Create a Knowledge Base](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#id5)  
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.

To initialize an `InMemoryKnowledgeBase`, you need to provide the data in a json file. The following example contains data about restaurants and hotels:

```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
        }
    ]
}
```

Once the data is defined in a json file, called, for example, `data.json`, you will be able to 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.

### [Define the NLU Data](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#id6)
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.19/nlu/training-data-format/#entity-synonyms) extensively

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

```markdown
## 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](https://legacy-docs-v1.rasa.com/1.10.19/core/knowledge-bases/#id7)
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`. You can only pull information from one knowledge base, as the usage of multiple knowledge bases at the same time is not supported.
