-
Notifications
You must be signed in to change notification settings - Fork 22
Intents and Entities
Intents and entities define the user intentions a Xatkit bot understands. They are used to automatically configure the NLP provider of your bot, and to define transition conditions between your states.
In this article we review how to create intents with the Xatkit DSL, and how to use system and user-defined entities to extract information from user input.
Xatkit intents define a set of training sentences representing the different ways a user could express an intention (e.g. "Hi", "Hello" for a Greetings
intent). The following example shows how to create a Greetings
intent containing two training sentences.
val greetings = intent("Greetings")
.trainingSentence("Hi")
.trainingSentence("Hello");
This intent will be matched by Xatkit every time a user sends "Hi" or "Hello" to our bot. Note that our bot may also understand some variations of the training sentences (e.g. "Hey") depending on the underlying NLP provider it uses.
ℹ The
intent
method (and all the other methods of the Xatkit DSL) are defined in the classcom.xatkit.dsl.DSL
. You can statically import them using the following import:import static com.xatkit.dsl.DSL.*
📚 We strongly recommend to use Lombok's val to store the objects created by the Xatkit fluent API.
Intents can also define parameters that are filled with information extracted from the user input using entities. We'll explore entities later in this article, but for the moment we can consider that they specify the type of information the bot should extract (a number, a city name, anything). As an example, the intent below defines a city
parameter extracted from the user input:
val liveIn = intent("LiveIn")
.trainingSentence("I live in Barcelona")
.parameter("city").fromFragment("Barcelona").entity(city());
The parameter("city")
construct specifies the name of the parameter we want to extract. This name can be used to retrieve the extracted value from the bot's states. The fromFragment("Barcelona")
construct specifies the text fragment in the training sentences that is used to extract information. Finally, entity(city())
defines the entity to use to extract information, in our example a city name.
The table below summarizes the value extracted for different user inputs:
Input | Extracted Parameter |
---|---|
I live in Barcelona | city = Barcelona |
I live in Paris | city = Paris |
I live in a small house | ❌ Fallback Intent (or city = '' )* |
*The input "I live in a small house" does not contain the name of a city. Depending on the NLP engine you are using the result will be either a Fallback Intent (the intent is not matched if a parameter is missing), or the correct LiveIn intent with an empty city
parameter.
As we have just seen, entities are used to specify the type of information to extract from user input. Xatkit supports three kinds of entities:
- System Entities: preset entities to extract common information such as numbers or city names
- Mapping Entities: user-defined entities to extract domain specific knowledge
- Composite Entities: user-defined entities combining multiple entities
System entities are preset entities you can directly use to configure your intent's parameters. They are available as top-level methods in the DSL class, and represent common information and patterns. The table below details all the system entities available in Xatkit:
Entity | Description |
---|---|
any() |
Matches any non-empty input |
date() |
Matches a date |
dateTime() |
Matches date, time, intevals or date and time together |
datePeriod() |
Matches a date interval |
time() |
Matches a time |
timePeriod() |
Matches a time interval |
number() |
Ordinal and cardinal numbers |
cardinal() |
Cardinal numbers |
ordinal() |
Ordinal numbers |
integer() |
Mathes integers only |
numberSequence() |
Matches number sequences |
flightNumber() |
Alphanumeric flight numbers |
unitArea() |
Number + units of area |
unitCurrency() |
Number + currency name |
unitLength() |
Number + units of length |
unitSpeed() |
Number + units of speed |
unitVolume() |
Number + units of volume |
unitWeight() |
Number + units of weight |
unitInformation() |
Number + units of information |
percentage() |
Number + percents |
temperature() |
Number + temperature units |
duration() |
Number + duration units (hours, days, months, etc) |
age() |
Number + age units (years old, months old, etc) |
address() |
GB, US full address |
zipCode() |
GB, US, and Canada postal codes |
capital() |
World capitals |
country() |
Short and full names of country |
countryCode() |
Short and full country names, alpha-2, alpha-3 and numeric codes as per ISO 3166-1 |
city() |
Major cities |
state() |
Major states in GB, USA, India, Canada, Australia |
placeAttraction() |
Top tourist attractions |
airport() |
Airport names, IATA, and ICAO codes |
location() |
General entity to refer to any location |
email() |
|
phoneNumber() |
Phone number |
givenName() |
Common given names |
lastName() |
Common last names |
musicArtist() |
Matches an artist / group name |
musicGenre() |
Matches a music genre name |
color() |
Words describing colors |
language() |
Language name |
url() |
Matches an URL |
ℹ Xatkit started as a DialogFlow connector and thus supports most of DialogFlow's system entities
As we have shown above, you can use system entities to configure your intent's parameters out of the box:
val liveIn = intent("LiveIn")
.trainingSentence("I live in Barcelona")
.parameter("city").fromFragment("Barcelona").entity(city());
📚 Some NLP engines do not handle natively some Xatkit System Entities. We do our best to uniformize them, you can check the NLP providers page for further information and platform-specific support for a given entity.
Mapping entities are created by the bot designer, and consist of a set of possible entries and their synonyms. You can find below an example of a mapping entity for HTTP methods:
val httpMethod = mapping("HTTPMethod")
.entry()
.value("POST").synonym("Posting")
.entry()
.value("GET")
.synonym("Getting")
.synonym("Access");
Mapping entities can be used as any other entities to configure an intent parameter:
val performRequest = intent("PerformRequest")
.trainingSentence("Get this url")
.trainingSentence("Get the resource at this url")
.parameter("method").fromFragment("Get").entity(httpMethod)
.parameter("url").fromFragment("this url").entity(url());
Note that in this example we are using two entities: our httpMethod
mapping to extract the HTTP method, and the url
system entity to extract the location of the resource to access. The table below shows some examples of inputs that are matched by the intent:
Input | method |
url |
---|---|---|
Get www.xatkit.com | GET |
www.xatkit.com |
Access www.xatkit.com | GET |
www.xatkit.com |
Download www.xatkit.com | ❌ Fallback Intent (or method = '' )* |
❌ Fallback Intent* |
Post this letter | ❌ Fallback Intent* | ❌ Fallback Intent (or url = '' ) |
*As explained above, the returned intent may vary from one NLP provider to the other depending on whether it accepts partial parameter extraction or not.
📚 Xatkit always assigns the base value of a mapping entry to an extracted parameter. This is why the
method=GET
value is extracted from the input "Access www.xatkit.com". This allows to easily compare extracted values (you need a single comparison to know if a parameter is a GET, you don't have to deal with all the synonyms), while letting you add new synonyms to your mappings later on without dealing with them in your bot code.
Composite entities are also created by the bot designer, and group several entities/text fragment to ease the definition of complex intents. With the entities we have already defined we can define a HTTPRequest composite entity that uses our HTTPMethod mapping entity and the url system entity:
val httpRequest = composite("HTTPRequest")
.entry()
.entity(httpMethod).entity(url())
.entry()
.entity(httpMethod).text("the resource at").entity(url());
Note that we define two entries for the HTTP request we want to match: one that is a concatenation of the method and the url (to match inputs like "Get www.xatkit.com"), and a second with some text in the middle (to match inputs like "Get the resource at www.xatkit.com").
As for system and mapping entities, composite entities can be used in intents with the entity(myEntity)
construct:
val httpRequestIntent = intent("HttpRequest")
.trainingSentence("request")
.trainingSentence("I want to request")
.parameter(httpRequest).fromFragment("request").entity(httpRequest);
The table below shows some examples of inputs that are matched by the intent:
Input | httpRequest.HTTPMethod |
httpRequest.url |
---|---|---|
Get www.xatkit.com | GET |
www.xatkit.com |
Access www.xatkit.com | GET |
www.xatkit.com |
I want to access the resource at www.xatkit.com | GET |
www.xatkit.com |
Download www.xatkit.com | ❌ Fallback Intent* | ❌ Fallback Intent* |
Post this letter | ❌ Fallback Intent* | ❌ Fallback Intent* |
The result is quite similar to using the mapping entity, but the definition offers much more flexibility: we can now reuse the HTTPRequest
composite entity in every intent that needs to understand complete HTTP requests, and any improvement in the HTTPMethod
entity (e.g. support for PUT) will be reflected in HTTPRequest
.
💡 Accessing the value of a composite entity from a bot state returns a
Map
with its internal entity names as keys (in our example we have the following mapping:HTTPRequest = GET
andurl = www.xatkit.com
).
- Getting Started
- Configuring your bot
- Integrating an Intent Recognition Provider
- Adding a bot to your website
- Deploying on Slack
- Basic concepts
- Intents and Entities
- States, Transitions, and Context
- Default and Local Fallbacks
- Core Library