ActionQueryKnowledgeBase, a pre-written custom action that contains
the logic to query a knowledge base for objects and their attributes.
You can find a complete example in examples/knowledgebasebot
(knowledge base bot), as well as instructions
for implementing this custom action below.
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 theInMemoryKnowledgeBase.
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.
data.json, you will be able use the 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:- we will introduce a new intent,
query_knowledge_base - we will annotate
mentionentities so that our model detects indirect mentions of objects like “the first one” - we will use synonyms extensively
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:
query_knowledge_base intent.
In addition to adding a variety of training examples for each query type,
you need to specify and annotate the following entities in your training examples:
object_type: Whenever a training example references a specific object type from your knowledge base, the object type should be marked as an entity. Use synonyms to map e.g.restaurantstorestaurant, the correct object type listed as a key in the knowledge base.mention: If the user refers to an object via “the first one”, “that one”, or “it”, you should mark those terms asmention. We also use synonyms to map some of the mentions to symbols. You can learn about that in resolving mentions.attribute: All attribute names defined in your knowledge base should be identified asattributein the NLU data. Again, use synonyms to map variations of an attribute name to the one used in the knowledge base.
Create an Action to Query your Knowledge Base
To create your own knowledge base action, you need to inheritActionQueryKnowledgeBase and pass the knowledge
base to the constructor of ActionQueryKnowledgeBase.
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:
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.query_knowledge_base and
the action action_query_knowledge_base. For example:
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:
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. In order for the bot to detect these attributes, you need to mark “Italian” and “Berlin” as entities in the NLU data: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.New in 3.6The user is not required to query the knowledge base to list any kind of object prior to this.
The
ActionQueryKnowledgeBase will extract the object type from the user’s request and query the knowledge base for an attribute of the object.ActionQueryKnowledgeBase
to extract the object type of the object the user is interested in.
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? Our action is able to resolve these mentions to the actual object in the knowledge base. More specifically, it can resolve two mention types: (1) ordinal mentions, such as “the first one”, and (2) mentions such as “it” or “that one”. Ordinal Mentions When a user refers to an object by its position in a list, it is called an ordinal mention. Here’s an example:- User: What restaurants in Berlin do you know?
- Bot: Found the following objects of type ‘restaurant’: 1: I due forni 2: PastaBar 3: Berlin Burrito Company
- User: Does the first one have outside seating?
KnowledgeBase class.
The default mapping looks like:
lambda l: l[0], meaning the
object at index 0.
As the ordinal mention mapping does not, for example, include an entry for “the first one”,
it is important that you use Entity Synonyms to map “the first one” in your NLU data to “1”:
mention entity, but puts “1” into the mention slot.
Thus, our action can take the mention slot together with the ordinal mention mapping to resolve “first one” to
the actual object “I due forni”.
You can overwrite the ordinal mention mapping by calling the function set_ordinal_mention_mapping() on your
KnowledgeBase implementation (see Customizing the InMemoryKnowledgeBase).
Other Mentions
Take a look at the following conversation:
- User: What is the cuisine of PastaBar?
- Bot: PastaBar has an Italian cuisine.
- User: Does it have wifi?
- Bot: Yes.
- User: Can you give me an address?
mention, the knowledge base action would resolve it to the last mentioned
object in the conversation, “PastaBar”.
In the next input, the user refers indirectly to the object “PastaBar” instead of mentioning it explicitly.
The knowledge base action would detect that the user wants to obtain the value of a specific attribute, in this case, the address.
If no mention or object was detected by the NER, the action assumes the user is referring to the most recently
mentioned object, “PastaBar”.
You can disable this behavior by setting use_last_object_mention to False when initializing the action.
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:
utter_objects()utter_attribute_value()
utter_objects() is used when the user has requested a list of objects.
Once the bot has retrieved the objects from the knowledge base, it will respond to the user by default with a message, formatted like:
Found the following objects of type ‘restaurant’:
1: I due forni
2: PastaBar
3: Berlin Burrito Company
Or, if no objects are found,
I could not find any objects of type ‘restaurant’.
If you want to change the utterance format, you can overwrite the method utter_objects() in your action.
The function utter_attribute_value() determines what the bot utters when the user is asking for specific information about
an object.
If the attribute of interest was found in the knowledge base, the bot will respond with the following utterance:
‘Berlin Burrito Company’ has the value ‘Mexican’ for attribute ‘cuisine’.
If no value for the requested attribute was found, the bot will respond with
Did not find a valid value for attribute ‘cuisine’ for object ‘Berlin Burrito Company’.
If you want to change the bot utterance, you can overwrite the method utter_attribute_value().
There is a tutorial on our blog about
how to use knowledge bases in custom actions. The tutorial explains the implementation behind
ActionQueryKnowledgeBase in detail.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:
- the user wants to get a list of objects from the knowledge base
- the user wants to get the value of an attribute for a specific object
rasa_sdk.knowledge_base.utils
(link to code )
to help you when implement your own solution.
We recommend using KnowledgeBase interface so that you can still use the ActionQueryKnowledgeBase
alongside your new custom action.
If you write a knowledge base action that tackles one of the above use cases or a new one, be sure to tell us about
it on the forum!
Customizing the InMemoryKnowledgeBase
The class InMemoryKnowledgeBase inherits KnowledgeBase.
You can customize your InMemoryKnowledgeBase by overwriting the following functions:
get_key_attribute_of_object(): To keep track of what object the user was talking about last, we store the value of the key attribute in a specific slot. Every object should have a key attribute that is unique, similar to the primary key in a relational database. By default, the name of the key attribute for every object type is set toid. You can overwrite the name of the key attribute for a specific object type by callingset_key_attribute_of_object().get_representation_function_of_object(): Let’s focus on the following restaurant:
get_representation_function_of_object() returns a lambda function that maps the
above restaurant object to its name.
"name" attribute of the object.
If your object does not have a "name" attribute , or the "name" of an object is
ambiguous, you should set a new lambda function for that object type by calling
set_representation_function_of_object().
set_ordinal_mention_mapping(): The ordinal mention mapping is needed to resolve an ordinal mention, such as “second one,” to an object in a list. By default, the ordinal mention mapping looks like this:
set_ordinal_mention_mapping().
If you want to learn more about how this mapping is used, check out Resolve Mentions.
See the example bot for an
example implementation of an InMemoryKnowledgeBase that uses the method set_representation_function_of_object()
to overwrite the default representation of the object type “hotel.”
The implementation of the InMemoryKnowledgeBase itself can be found in the
rasa-sdk package.
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 inheritKnowledgeBase and implement the methods get_objects(), get_object(), get_object_types() and
get_attributes_of_object(). The knowledge base code
provides more information on what those methods should do.
You can also customize your knowledge base further, by adapting the methods mentioned in the section
Customizing the InMemoryKnowledgeBase.
We wrote a blog post
that explains how you can set up your own knowledge base.