Rasa Google

Rasa Google

Session configuration#

A conversation session represents the dialogue between the assistant and the user. Conversation sessions can begin in three ways:

the user begins the conversation with the assistant,

the user sends their first message after a configurable period of inactivity, or

a manual session start is triggered with the /session_start intent message.

You can define the period of inactivity after which a new conversation session is triggered in the domain under the session_config key.

Available parameters are:

The default session configuration looks as follows:

session_expiration_time: 60 # value in minutes, 0 means infinitely long

carry_over_slots_to_new_session: true # set to false to forget slots between sessions

This means that if a user sends their first message after 60 minutes of inactivity, a new conversation session is triggered, and that any existing slots are carried over into the new session. Setting the value of session_expiration_time to 0 means that sessions will not end (note that the action_session_start action will still be triggered at the very beginning of conversations).

A session start triggers the default action action_session_start. Its default implementation moves all existing slots into the new session. Note that all conversations begin with an action_session_start. Overriding this action could for instance be used to initialize the tracker with slots from an external API call, or to start the conversation with a bot message. The docs on Customizing the session start action shows you how to do that.

The config key in the domain file maintains the store_entities_as_slots parameter. This parameter is used only in the context of reading stories and turning them into trackers. If the parameter is set to True, this will result in slots being implicitly set from entities if applicable entities are present in the story. When an entity matches the from_entity slot mapping, store_entities_as_slots defines whether the entity value should be placed in that slot. Therefore, this parameter skips adding an explicit slot_was_set step manually in the story. By default, this behaviour is switched on.

You can turn off this functionality by setting the store_entities_as_slots parameter to false:

store_entities_as_slots: false

If you're looking for information on the config.yml file, check out the docs on Model Configuration.

A story is a representation of a conversation between a user and an AI assistant, converted into a specific format where user inputs are expressed as intents (and entities when necessary), while the assistant's responses and actions are expressed as action names.

Here's an example of a dialogue in the Rasa story format:

- story: collect restaurant booking info # name of the story - just for debugging

- intent: greet # user message with no entities

- action: utter_ask_howcanhelp

- intent: inform # user message with entities

- action: utter_on_it # action that the bot should execute

- action: utter_ask_cuisine

- action: utter_ask_num_people

While writing stories, you do not have to deal with the specific contents of the messages that the users send. Instead, you can take advantage of the output from the NLU pipeline, which lets you use just the combination of an intent and entities to refer to all the possible messages the users can send to mean the same thing.

It is important to include the entities here as well because the policies learn to predict the next action based on a combination of both the intent and entities (you can, however, change this behavior using the use_entities attribute).

All actions executed by the bot, including responses are listed in stories under the action key.

You can use a response from your domain as an action by listing it as one in a story. Similarly, you can indicate that a story should call a custom action by including the name of the custom action from the actions list in your domain.

During training, Rasa does not call the action server. This means that your assistant's dialogue management model doesn't know which events a custom action will return.

Because of this, events such as setting a slot or activating/deactivating a form have to be explicitly written out as part of the stories. For more info, see the documentation on Events.

Slot events are written under slot_was_set in a story. If this slot is set inside a custom action, add the slot_was_set event immediately following the custom action call. If your custom action resets a slot value to None, the corresponding event for that would look like this:

- story: set slot to none

# ... other story steps

- action: my_custom_action

There are three kinds of events that need to be kept in mind while dealing with forms in stories.

A form action event (e.g. - action: restaurant_form) is used in the beginning when first starting a form, and also while resuming the form action when the form is already active.

A form activation event (e.g. - active_loop: restaurant_form) is used right after the first form action event.

A form deactivation event (e.g. - active_loop: null), which is used to deactivate the form.

In order to get around the pitfall of forgetting to add events, the recommended way to write these stories is to use interactive learning.

Dynamic Form Behavior#

By default Rasa Open Source will ask for the next empty slot from the slots listed for your form in the domain file. If you use custom slot mappings and the FormValidationAction, it will ask for the first empty slot returned by the required_slots method. If all slots in required_slots are filled the form will be be deactivated.

If needed, you can update the required slots of your form dynamically. This is, for example, useful when you need further details based on how a previous slot was filled or you want to change the order in which slots are requested.

If you are using the Rasa SDK, we recommend you to use the FormValidationAction and override required_slots to fit your dynamic behavior. You should implement a method extract_ for every slot which doesn't use a predefined mapping, as described in Custom Slot Mappings. The example below will ask the user if they want to sit in the shade or in the sun in case they said they want to sit outside.

from typing import Text, List, Optional

from rasa_sdk.forms import FormValidationAction

class ValidateRestaurantForm(FormValidationAction):

def name(self) -> Text:

return "validate_restaurant_form"

async def required_slots(

slots_mapped_in_domain: List[Text],

dispatcher: "CollectingDispatcher",

domain: "DomainDict",

) -> Optional[List[Text]]:

additional_slots = ["outdoor_seating"]

if tracker.slots.get("outdoor_seating") is True:

additional_slots.append("shade_or_sun")

return additional_slots + slots_mapped_in_domain

Validating Form Input#

After extracting a slot value from user input, you can validate the extracted slots. By default Rasa Open Source only validates if any slot was filled after requesting a slot.

Forms no longer raise ActionExecutionRejection if nothing is extracted from the user’s utterance for any of the required slots.

You can implement a Custom Action validate_ to validate any extracted slots. Make sure to add this action to the actions section of your domain:

- validate_restaurant_form

When the form is executed it will run your custom action.

This custom action can extend FormValidationAction class to simplify the process of validating extracted slots. In this case, you need to write functions named validate_ for every extracted slot.

The following example shows the implementation of a custom action which validates that the slot named cuisine is valid.

from typing import Text, List, Any, Dict

from rasa_sdk import Tracker, FormValidationAction

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk.types import DomainDict

class ValidateRestaurantForm(FormValidationAction):

def name(self) -> Text:

return "validate_restaurant_form"

def cuisine_db() -> List[Text]:

"""Database of supported cuisines"""

return ["caribbean", "chinese", "french"]

def validate_cuisine(

dispatcher: CollectingDispatcher,

) -> Dict[Text, Any]:

"""Validate cuisine value."""

if slot_value.lower() in self.cuisine_db():

return {"cuisine": slot_value}

return {"cuisine": None}

You can also extend the Action class and retrieve extracted slots with tracker.slots_to_validate to fully customize the validation process.

Calling Responses as Actions#

If the name of the response starts with utter_, the response can directly be used as an action, without being listed in the actions section of your domain. You would add the response to the domain:

- text: "Hey! How are you?"

You can use that same response as an action in your stories:

- action: utter_greet

When the utter_greet action runs, it will send the message from the response back to the user.

If you want to change the text, or any other part of the response, you need to retrain the assistant before these changes will be picked up.

Using a Custom Action to Ask For the Next Slot#

As soon as the form determines which slot has to be filled next by the user, it will execute the action utter_ask__ or utter_ask_ to ask the user to provide the necessary information. If a regular utterance is not enough, you can also use a custom action action_ask__ or action_ask_ to ask for the next slot.

from typing import Dict, Text, List

from rasa_sdk import Tracker

from rasa_sdk.events import EventType

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk import Action

class AskForSlotAction(Action):

def name(self) -> Text:

return "action_ask_cuisine"

self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict

) -> List[EventType]:

dispatcher.utter_message(text="What cuisine?")

If there is more than one asking option for the slot, Rasa prioritizes in the following order:

Rumah Rasa Kaliurang adalah kafe estetik yang menawarkan pengalaman unik seolah memasuki negeri dongeng. Dengan vibes penuh taman bunga dan dominasi warna krem, kafe ini menjadi destinasi favorit bagi banyak orang.

Pengunjung seolah diajak mengingat kenangan pulang ke rumah nenek yang bikin betah. Jauh dari jalan raya, tentu ketenangan yang membawa damai dapat traveler temui di sini.

Ahmad, barista di Rumah Rasa, berbagi cerita tentang pesona kafe yang dimiliki oleh Ika, seorang pengusaha dari Yogyakarta.

SCROLL TO CONTINUE WITH CONTENT

Rumah Rasa Kaliurang berlokasi di Hargobinangun, Kapanewon Pakem, Kabupaten Sleman, Daerah Istimewa Yogyakarta. Terletak di sekitar area Karang Pramuka Kaliurang, kafe ini bukan berada di pinggir jalan besar, tetapi sedikit masuk ke dalam, menjadikannya sebuah hidden gem yang patut dicari.

"Jalan menuju ke sini sudah mulus dan aksesnya mudah, walaupun agak meliuk liuk jalannya," kata Ahmad.

Dari tempat duduk di kafe, pengunjung dapat menikmati latar belakang hutan-hutan penuh pepohonan hijau yang menambah kesan sejuk dan alami.

Konsep kafe ini homey, layaknya di kebun teras rumah sendiri. Kafe ini dikelilingi oleh banyak tanaman rimbun, namun tetap terpapar cahaya matahari yang cukup, menciptakan suasana yang nyaman dan menenangkan.

"Orang sering menyebut suasananya 'vibes Bandung banget'," ungkap Ahmad.

Di tembok kafe, terdapat tulisan yang berbunyi, "Aku adalah warna, kamu adalah kata, kita adalah rasa," yang menambah keunikan dan keindahan tempat ini.

Berkunjung kemari jangan lupakan untuk berfoto di setiap sudutnya yang estetik

Rumah Rasa Kaliurang menyediakan berbagai fasilitas lengkap seperti WiFi, toilet, mushola, rumah pohon, area outdoor dan indoor, serta parkir mobil dan motor. Dengan suasana yang mengingatkan pada kunjungan ke rumah nenek saat liburan, tempat ini benar-benar adem dan bikin betah.

"Kafe ini cocok untuk work from cafe, nongkrong, atau berkumpul bersama keluarga," jelas Ahmad.

In Rasa, your domain defines the universe in which your assistant operates. Specifically, it lists:

If you are building an NLU-based assistant, refer to the Domain documentation to see how intents, entities, slot mappings, and slot featurization can be configured in your domain.

Custom Slot Mappings#

You can define custom slot mappings using slot validation actions when none of the predefined mappings fit your use case. You must define this slot mapping to be of type custom, for example:

action: action_calculate_day_of_week

You can also use the custom slot mapping to list slots that will be filled by arbitrary custom actions in the course of a conversation, by listing the type and no specific action. For example:

This slot will not be updated on every user turn, but only once a custom action that returns a SlotSet event for it is predicted.

You can provide an initial value for a slot in your domain file:

Responses are actions that send a message to a user without running any custom code or returning events. These responses can be defined directly in the domain file under the responses key and can include rich content such as buttons and attachments. For more information on responses and how to define them, see Responses.

Forms are a special type of action meant to help your assistant collect information from a user. Define forms under the forms key in your domain file. For more information on form and how to define them, see Forms.

Actions are the things your bot can actually do. For example, an action could:

All custom actions should be listed in your domain, except responses which need not be listed under actions: as they are already listed under responses:.

Dynamic Form Behavior#

By default, Rasa will ask for the next empty slot from the slots listed for your form in the domain file. If you use custom slot mappings and the FormValidationAction, it will ask for the first empty slot returned by the required_slots method. If all slots in required_slots are filled the form will be deactivated.

You can update the required slots of your form dynamically. This is, for example, useful when you need to fill additional slots based on how a previous slot was filled or when you want to change the order in which slots are requested.

If you are using the Rasa SDK, we strongly recommend that you use the FormValidationAction and override required_slots to fit your dynamic behavior. You must implement a method extract_ for every slot which doesn't use a predefined mapping, as described in Custom Slot Mappings. The example below will ask the user if they want to sit in the shade or in the sun in case they said they want to sit outside.

from typing import Text, List, Optional

from rasa_sdk.forms import FormValidationAction

class ValidateRestaurantForm(FormValidationAction):

def name(self) -> Text:

return "validate_restaurant_form"

async def required_slots(

domain_slots: List[Text],

dispatcher: "CollectingDispatcher",

domain: "DomainDict",

additional_slots = ["outdoor_seating"]

if tracker.slots.get("outdoor_seating") is True:

additional_slots.append("shade_or_sun")

return additional_slots + domain_slots

If conversely, you want to remove a slot from the form's required_slots defined in the domain file under certain conditions, you should copy the domain_slots over to a new variable and apply changes to that new variable instead of directly modifying domain_slots. Directly modifying domain_slots can cause unexpected behaviour. For example:

from typing import Text, List, Optional

from rasa_sdk.forms import FormValidationAction

class ValidateBookingForm(FormValidationAction):

def name(self) -> Text:

return "validate_booking_form"

async def required_slots(

domain_slots: List[Text],

dispatcher: "CollectingDispatcher",

domain: "DomainDict",

updated_slots = domain_slots.copy()

if tracker.slots.get("existing_customer") is True:

updated_slots.remove("email_address")

Custom Output Payloads#

You can send any arbitrary output to the output channel using the custom key. The output channel receives the object stored under the custom key as a JSON payload.

Here's an example of how to send a date picker to the Slack Output Channel:

text: "Make a bet on when the world will end:"

initial_date: '2019-05-21'

Using a Custom Action to Ask For the Next Slot#

As soon as the form determines which slot has to be filled next by the user, it will execute the action utter_ask__ or utter_ask_ to ask the user to provide the necessary information. If a regular utterance is not enough, you can also use a custom action action_ask__ or action_ask_ to ask for the next slot.

from typing import Dict, Text, List

from rasa_sdk import Tracker

from rasa_sdk.events import EventType

from rasa_sdk.executor import CollectingDispatcher

from rasa_sdk import Action

class AskForSlotAction(Action):

def name(self) -> Text:

return "action_ask_cuisine"

self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict

) -> List[EventType]:

dispatcher.utter_message(text="What cuisine?")

Here is a full example of a domain, taken from the concertbot example:

influence_conversation: false

influence_conversation: false

influence_conversation: true

- text: "Sorry, I didn't get that, can you rephrase?"

- text: "You're very welcome."

- text: "I am a bot, powered by Rasa."

- text: "I can help you find concerts and venues. Do you like music?"

- text: "Awesome! You can ask me things like \"Find me some concerts\" or \"What's a good venue\""

- action_search_concerts

- action_search_venues

- action_show_concert_reviews

- action_show_venue_reviews

- action_set_music_preference

session_expiration_time: 60 # value in minutes

carry_over_slots_to_new_session: true