Building contextual assistants with Rasa Forms

Could you please explain the use of form{"name": "restaurant_form"} and also form{"name": null}mantigames.

Thanks

@somlaychong @srikarplus Apologies for a late reply :slight_smile:

form{"name":"restaurant_form" means that the form has been activated and that now it’s time for the FormPolicy to jump in. Once the form is activated, the code of the ActionForm will be used to check which required slots are populated and, which ones to ask for next. form{"name":"null"} means the deactivation of the form and allows other policies in the configuration to take over the prediction of what happens in the dialogue next. The form can be deactivated in a happy path (when all slots are populated) or druing the deviations from it (chitchat, etc).

Hi @Juste @juste_petr

You have created a separate intent as chitchat and in stories, you have defined different paths- happy, unhappy, stop and continue path etc.

However, in the paths that involve chitchat intent, I wish to give users the flexibility that they can talk about any other intent but I have about 10 different intents!

So, how do i produce stories that replace chitchat intent with the other 10 intents?

1 Like

Hi @Juste

When I train the model using the keras policy I get a bunch of the following warnings:

“Feature ‘active_form_restaurant_form’ could not be found in feature map.”

Why is that and is it hurting performance?

Hi @Juste. Thank you for your post. We went through your post as well

We have a FormAction that has a postal code as an only slot in the domain file: forms:

- store_search_form

we have the slots under corresponding utterances for our single slot also in the domain file (the 2nd stores slot is where our submit action puts the response back for UI stories): slots:

  postal_code:
    type: unfeaturized

  stores:
    type: unfeaturized

And we have the convention-based utterance that FormAction needs to prompt the user for the only value it needs as per the required_slots method:

templates:
  utter_ask_postal_code:
  - text: "Please enter the Postal Code you wish to use to search for a Bell Store"

  utter_postal_code_slot_value:
  - text: "I am going to run a Google API search for The Source near:{postal_code}"

The second utterance we use to echo back to make sure form slot was populated correctly.

Our form action in actions.py that dictate the required slots.

class FormActionSearchStores(FormAction):

    def name(self):
        return 'store_search_form'

    @staticmethod
    def required_slots(tracker):
       # type: () -> List[Text]
       return ["postal_code"]

And our story:

* locate_store
  - store_search_form
  - form{"name": "store_search_form"}
  - utter_postal_code_slot_value
  - action_suggest
  - form{"name": null}
  - utter_goodbye
  - action_restart

Note: I tried this configuration with same effect:

* locate_store
  - store_search_form
  - form{"name": "store_search_form"}
  - form{"name": null}
  - utter_postal_code_slot_value
  - action_suggest
  - utter_goodbye
  - action_restart

action_suggest simply sets the “stores” slot with the results.

And here is the problem: while the slots gets filled and my action cod runs and my API logic executes (in the action server log), it seems my conversation is falling back to the default policy due to stating it does not recognize the intent. It seems the 2 policies are fighting or we are doing something wrong.

Hers is the debug rasa core log. I’ve added notes where I provide inputs and then what happens after i hit enter:

Enter to bot: store locator

Bot log in debug mode

Recreating tracker for id 'UF97SURFC'
Received user message 'store locator' with intent '{'name': 'locate_store', 'confidence': 0.778114378452301}' and entities '[]'
Logged UserUtterance - tracker now has 139 events
Current slot values:
        requested_slot: None
        name: None
        stores: None
        b1_number: None
        postal_code: None
Current tracker state [None, None, None, {}, {'prev_action_listen': 1.0, 'intent_locate_store': 1.0}]
There is a memorised next action '69'
There is no active form
Predicted next action using policy_2_MemoizationPolicy
Predicted next action 'store_search_form' with prob 1.00.
Calling action endpoint to run action 'store_search_form'.
Action 'store_search_form' ended with events '['Form(store_search_form)', 'SlotSet(key: requested_slot, value: postal_code)']'
Bot utterance 'BotUttered(text: Please enter the Postal Code you wish to use to search for a Bell Store, data: {
  "attachment": null,
  "elements": null,
  "buttons": null
})'
Current tracker state [None, None, None, {}, {'prev_action_listen': 1.0, 'intent_locate_store': 1.0}]
There is a memorised next action '69'
There is an active form 'store_search_form'
Predicted next action using policy_3_FormPolicy
Predicted next action 'action_listen' with prob 1.00.
Action 'action_listen' ended with events '[]'

Enter to bot: M2N1A1

Bog log in debug mode

Recreating tracker for id 'UF97SURFC'
Received user message 'M2N1A1' with intent '{'name': None, 'confidence': 0.0}' and entities '[{'entity': 'postal_code', 'extractor': 'ner_crf', 'end': 6, 'start': 0, 'value': 'M2N1A1', 'confidence': 0.968162055366042}]'
Logged UserUtterance - tracker now has 146 events
Current slot values:
        requested_slot: postal_code
        name: None
        stores: None
        b1_number: None
        postal_code: M2N1A1
NLU confidence 0.0 is lower than NLU threshold 0.3. Predicting fallback action: action_default_fallback
Current tracker state [None, None, None, {}, {'prev_action_listen': 1.0, 'intent_locate_store': 1.0}]
There is a memorised next action '69'
There is an active form 'store_search_form'
Predicted next action using policy_3_FormPolicy
Predicted next action 'store_search_form' with prob 1.00.
Calling action endpoint to run action 'store_search_form'.
Action 'store_search_form' ended with events '['SlotSet(key: postal_code, value: M2N1A1)', 'SlotSet(key: stores, value: work time:   Monday: 10:00 AM – 6:00 PM', 'Form(None)', 'SlotSet(key: requested_slot, value: None)']'
Bot utterance 'BotUttered(text: Form Action Submit complete, postal code is M2N1A1., data: {
  "attachment": null,
  "elements": null,
  "buttons": null
})'
NLU confidence 0.0 is lower than NLU threshold 0.3. Predicting fallback action: action_default_fallback
Current tracker state [None, None, {}, {'prev_action_listen': 1.0, 'intent_locate_store': 1.0}, {'prev_store_search_form': 1.0, 'intent_locate_store': 1.0}]
There is a memorised next action '68'
There is no active form
Predicted next action using policy_1_FallbackPolicy
Predicted next action 'action_default_fallback' with prob 1.00.
Action 'action_default_fallback' ended with events '['UserUtteranceReverted()']'
Bot utterance 'BotUttered(text: I am sorry, I didn't understand that. Please try again., data: {
  "attachment": null,
  "elements": null,
  "buttons": null
})'
Current tracker state [None, None, None, {}, {'prev_action_listen': 1.0, 'intent_locate_store': 1.0}]
There is a memorised next action '69'
There is an active form 'store_search_form'
Predicted next action using policy_3_FormPolicy
Predicted next action 'action_listen' with prob 1.00.
Action 'action_listen' ended with events '[]'

Note this part in the above:

Logged UserUtterance - tracker now has 146 events Current slot values: requested_slot: postal_code name: None stores: None b1_number: None postal_code: M2N1A1 NLU confidence 0.0 is lower than NLU threshold 0.3. Predicting fallback action: action_default_fallback

So while the form action executed I think successfully - in the UI - instead of the output from the Action (store hours above).   It falls back to the default utterance of "I do not understand"


  utter_default:
  - text: "I am sorry, I didn't understand that. Please try again."

Can you help? How can we train/signal the bot that if the FormAction processed ok, that all is good? Are we missing something?

Or is this have nothing to do with Forms, but rather we have to keep working on the NLU training set? (keep in mind we have a good set of postal code - in phrases, out of phrases, lower/upper cases) - maybe 50 of each? Remember my post about the NLU training API crashing :slight_smile:

Your help is much appreciated

Thanks Serge

I’m using the Form Action to fill the Slots. I’ve about 7 slots such as:

“NAME”, “CAB_TYPE”, “P_COUNT”, “SOURCE”, “DESTINATION”, “RIDEPREFERENCE”, “DURATION”

but as soon as I fill the DESTINATION Slot the Form starts again. I’ve my all the entities & slots listed in Domain file.

entities:

  • NAME
  • CAB_TYPE
  • P_COUNT
  • SOURCE
  • DESTINATION
  • RIDEPREFERENCE
  • DURATION

slots: NAME: type: unfeaturized auto_fill: false CAB_TYPE: type: unfeaturized auto_fill: false P_COUNT: type: unfeaturized auto_fill: false SOURCE: type: unfeaturized auto_fill: false RIDEPREFERENCE: type: unfeaturized auto_fill: false DURATION: type: unfeaturized auto_fill: false DESTINATION: type: unfeaturized auto_fill: false requested_slot: type: unfeaturized

Stories:

  • greeting
    • utter_greeting
  • request_booking
    • booking_form
    • form{“name”: “booking_form”}
    • utter_slots_values
  • mood_affirm
    • utter_booking_details
    • utter_bye Need help on this.

You may be missing the “stop collecting form” directive in your story utterance:

  • form{“name”: null}

Hello @Serge. Apologies for taking so long to respond. Do you have an intent for providing info (in our Rasa examples we usually call it inform intent where the user simply provides a piece of information. I think the underlying issue is related with the NLU data, because a fallback action get’s triggered where an actual intent should be predicted.

Hi @shubhamm. Just like Serge mentioned, you have include form{“name”:“null”} in your stories to model the situations where the form was filled successfully. Another cause for this issue could be in your form action code. Would it be possible to share at least some of your form action code?

Hi @Juste. Do you still have to give the inform intent in rasaX when filling in the forms? And follow up questions if so, do you have an example how to rewrite form policy to just lock in the next slot based on the utterance and I would just break form loop on certain keywords (the default botframework form usability)

Hello @Juste !Thanks for your article about using FormPolicy,and It is really useful.But when I use it like yours,There are many problems confused me,and hope you can help me.The problem is : I have a form action named ‘number_form’ and two slots of it.When I first input some infomations with two slots,FormPolicy always can not work and slot filling also not right.And the terrible problem is that when I input message with one slot again,FormPolicy also did not work and slots did not be cleared, Rasa core return the last result to me.Why?Here is my some logs and configs.look forward to your reply!Thank you.

Rasa Core logs:

192.168.0.110 - - [2019-06-08 11:44:37] "POST /webhooks/rest/webhook HTTP/1.1" 200 452 1.066897
2019-06-08 11:44:51 DEBUG    rasa_core.tracker_store  - Recreating tracker for id '152869574032212890:123'
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Received user message 'Help me check the license plate number AB12345' with intent '{'name': 'request_number', 'confidence': 0.964844109378438}' and entities
'[{'entity': 'item', 'value': 'license plate number', 'start': 2, 'end': 6, 'confidence': None, 'extractor': 'ner_mitie', 'processors': ['ner_synonyms']}, {'entity': 'number', 'value': 'AB12345', 'st
art': 6, 'end': 13, 'confidence': None, 'extractor': 'ner_mitie'}]'
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Logged UserUtterance - tracker now has 170 events
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Current slot values:
        business: None
        item: None
        number: None
        requested_slot: None
2019-06-08 11:44:52 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, None, None, {}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_action_listen': 1.0, 'inten
t_request_number': 1.0}]
2019-06-08 11:44:52 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-06-08 11:44:52 DEBUG    rasa_core.policies.form_policy  - There is no active form
2019-06-08 11:44:52 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_MobilePolicy
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Predicted next action 'number_form' with prob 0.99.
2019-06-08 11:44:52 DEBUG    rasa_core.actions.action  - Calling action endpoint to run action 'number_form'.
2019-06-08 11:44:52 WARNING  py.warnings  - E:\ComPython\LittleTeligen\RasaCore\venv\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request i
s being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Action 'number_form' ended with events '['Form(number_form)', 'SlotSet(key: item, value: license plate number)', 'SlotSet(key: number, value:AB12345)', 'SlotSet(key: item, value: None)', 'Form(None)', 'SlotSet(key: requested_slot, value: None)']'
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: {"method": "queryCarInfo", "wccpproxy": "{\"result\": 1, \"resultMsg\": \"none\", \"list\": [{\"owne
rName\": \"\\u5f20\\u4e09\", \"idCard\": \"450981199305174536\", \"color\": \"\\u9ec4\\u8272\", \"firstRegDate\": \"2019-03-23\", \"brand\": \"BMW\", \"model\": \"x3\", \"carType\": \"
normal\", \"numType\": \"plate\", \"carNum\": \"\\u7ca4a12345\"}]}"}, data: {
  "elements": null,
  "buttons": [],
  "attachment": null
})'
2019-06-08 11:44:52 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, None, {}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_action_listen': 1.0, 'intent_requ
est_number': 1.0}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_number_form': 1.0, 'intent_request_number': 1.0}]
2019-06-08 11:44:52 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-06-08 11:44:52 DEBUG    rasa_core.policies.form_policy  - There is no active form
2019-06-08 11:44:52 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_MobilePolicy
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Predicted next action 'action_listen' with prob 1.00.
2019-06-08 11:44:52 DEBUG    rasa_core.processor  - Action 'action_listen' ended with events '[]'

192.168.0.110 - - [2019-06-08 11:44:52] "POST /webhooks/rest/webhook HTTP/1.1" 200 1184 1.067888
2019-06-08 11:44:58 DEBUG    rasa_core.tracker_store  - Recreating tracker for id '152869574032212890:123'
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Received user message 'Help me query the phone number' with intent '{'name': 'request_number', 'confidence': 0.9043155210530247}' and entities '[{'e
ntity': 'item', 'value': 'phone number', 'start': 2, 'end': 7, 'confidence': None, 'extractor': 'ner_mitie', 'processors': ['ner_synonyms']}]'
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Logged UserUtterance - tracker now has 180 events
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Current slot values:
        business: None
        item: None
        number: AB12345
        requested_slot: None
2019-06-08 11:44:59 DEBUG    rasa_core.policies.memoization  - Current tracker state [None, {}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_action_listen': 1.0, 'intent_request_nu
mber': 1.0}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_number_form': 1.0, 'intent_request_number': 1.0}, {'entity_item': 1.0, 'prev_action_listen': 1.0, 'intent_request_number':
 1.0}]
2019-06-08 11:44:59 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-06-08 11:44:59 DEBUG    rasa_core.policies.form_policy  - There is no active form
2019-06-08 11:44:59 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_MobilePolicy
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Predicted next action 'number_form' with prob 1.00.
2019-06-08 11:44:59 DEBUG    rasa_core.actions.action  - Calling action endpoint to run action 'number_form'.
2019-06-08 11:44:59 WARNING  py.warnings  - E:\ComPython\LittleTeligen\RasaCore\venv\lib\site-packages\urllib3\connectionpool.py:847: InsecureRequestWarning: Unverified HTTPS request i
s being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Action 'number_form' ended with events '['Form(number_form)', 'SlotSet(key: number, value: AB12345)', 'SlotSet(key: item, value: None)', 'Form(None)', 'SlotSet(key: requested_slot, value: None)']'
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Bot utterance 'BotUttered(text: {"method": "queryCarInfo", "wccpproxy": "{\"result\": 1, \"resultMsg\": \"none\", \"list\": [{\"owne
rName\": \"\\u5f20\\u4e09\", \"idCard\": \"450981199305174536\", \"color\": \"\\u9ec4\\u8272\", \"firstRegDate\": \"2019-03-23\", \"brand\": \"BMW\", \"model\": \"x3\", \"carType\": \"
normal\", \"numType\": \"plate\", \"carNum\": \"\\u7ca4a12345\"}]}"}, data: {
  "elements": null,
  "buttons": [],
  "attachment": null
})'
2019-06-08 11:44:59 DEBUG    rasa_core.policies.memoization  - Current tracker state [{}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_action_listen': 1.0, 'intent_request_number':
 1.0}, {'entity_item': 1.0, 'entity_number': 1.0, 'prev_number_form': 1.0, 'intent_request_number': 1.0}, {'entity_item': 1.0, 'prev_action_listen': 1.0, 'intent_request_number': 1.0},
 {'entity_item': 1.0, 'prev_number_form': 1.0, 'intent_request_number': 1.0}]
2019-06-08 11:44:59 DEBUG    rasa_core.policies.memoization  - There is no memorised next action
2019-06-08 11:44:59 DEBUG    rasa_core.policies.form_policy  - There is no active form
2019-06-08 11:44:59 DEBUG    rasa_core.policies.ensemble  - Predicted next action using policy_1_MobilePolicy
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Predicted next action 'action_listen' with prob 1.00.
2019-06-08 11:44:59 DEBUG    rasa_core.processor  - Action 'action_listen' ended with events '[]'
192.168.0.110 - - [2019-06-08 11:44:59] "POST /webhooks/rest/webhook HTTP/1.1" 200 1184 1.083746

Here is my story:

# happy with request number
* greet
    - utter_answer_greet
* request_number
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

Here is my action code:

class NumberForm(FormAction):

    def name(self):
        """Request Number action唯一标识"""
        return "number_form"

    def validate_number(self, value, dispatcher, tracker, domain):
        pass


    def validate_item(self, value, dispatcher, tracker, domain):
        pass


    @staticmethod
    def required_slots(tracker):
        number = tracker.get_slot('number')
        if number is not None:
            return ["number"]

        return ["item", "number"]


    def submit(self, dispatcher, tracker, domain):
        inputItem = tracker.get_slot("item")
        inputNum = tracker.get_slot("number")

        print("##### current slot:item={0},number={1}".format(inputItem, inputNum))
        
        return []

Here is my train core model configs:

def train_dialogue_keras_form(domain_file="configs/core/domain_form.yml",
                         model_path="models/dialogue_keras_form_new",
                         training_data_file="data/stories_data/form"):
    fallback = FallbackPolicy(
        fallback_action_name="action_default_fallback",
        nlu_threshold=0.4,
        core_threshold=0.3
    )

    agent = Agent(domain_file,
                  policies=[MemoizationPolicy(max_history=5),
                            MobilePolicy(epochs=100, batch_size=16),
                            FormPolicy(), fallback])

    training_data = agent.load_data(training_data_file)
    agent.train(
        training_data,
        validation_split=0.2
    )

    agent.persist(model_path)
    return agent

my domain.yml is(section):

forms:
  - number_form

intents:
  - affirm
  - deny
  - greet
  - goodbye
  - thanks
  - whoareyou
  - whattodo
  - whereyoufrom
  - mod_happy
  - mod_unhappy
  - mod_angry
  - mod_worried
  - request_number
  - request_business
  - search_item
  - say_jokes
  - ask_age
  - ask_sex
  - out_of_scope
  - welcome

slots:
  item:
    type: unfeaturized
    auto_fill: false
  number:
    type: unfeaturized
    auto_fill: false
  business:
    type: unfeaturized
    auto_fill: false

entities:
  - item
  - number
  - business

hi it shows the video is unavailable

Hi I dont really understand. Whats the docker image for?

ya I had deleted that video

Hey @Juste. Looking back at the old code it seems the problem was self inflicted. Without understanding full details of what happens in back ground.

We had the default mapping method:

def slot_mappings(self):
       return { "postal_code": [self.from_entity(entity="postal_code")]}

The self.from_entity caused the framework to hit NER, and given our NER did not have Regex in the pipeline everything fell apart. Once we added custom config to support regex, all worked. BUT, we could have avoid all of it, by simply putting [self.from_text( … ) vs from_entity to simply capture user input and put it into the slot versus drive it through more complex NER which needs training data and complex pipeline config.

Correct me if I am wrong? :smiley:

Hi @Juste,

I have one question or it’s a my misunderstanding to handle it.

In your restaurant formbot example - Once conversation is finish, then why it is not starting again next one ? When I say hello, It response me default answer. It should give me utter_greet in response.

I was facing this issue while making own bot(related information provider for inventory [Keep responding default action]) and then I again check your example.

So, @Juste What I am missing ? It’s a related to story writing ?

Hello @Juste, action_restart is a right solution ? If i am wrong, please correct me. Sorry to bother you. I should read more and search too.

Hi @shivangpatel. Yes, you can use the actoin_restart especially if you want alls slots to be reset at the end of the conversation. :slight_smile:

1 Like

is there any limitation in the rasa http api (http://localhost:5005/model/train) to train form?

Update: I found the reason, the policies were not set properly. Now I use the policies

policies:
 - name: KerasPolicy
   epochs: 100
   max_history: 3
- name: MemoizationPolicy
  max_history: 3
- name: FallbackPolicy
  nlu_threshold: 0.1
  core_threshold: 0.2
  fallback_action_name: 'utter_ask_continue'
- name: FormPolicy

Thanks for providing the tutorial! I followed to the last step (duckling server and action server running) and ran

rasa shell -m models --endpoints endpoints.yml

Rasa server is started and bot is loaded. However, after giving my input, I got

Your input ->  hi
2019-07-22 17:57:24 DEBUG    rasa.core.agent  - Created a new lock for conversation 'default'
2019-07-22 17:57:24 DEBUG    rasa.core.tracker_store  - Creating a new tracker for id 'default'.
2019-07-22 17:57:24 WARNING  root  - Could not parse timestamp 6725a877e91146388251d8a80c8a9c0e. Instead current UTC time will be passed to duckling. Error: invalid literal for int() with base 10: '6725a877e91146388251d8a80c8a9c0e'
2019-07-22 17:57:24 DEBUG    rasa.core.processor  - Received user message 'hi' with intent '{'name': 'greet', 'confidence': 0.9533871412277222}' and entities '[]'
2019-07-22 17:57:24 DEBUG    rasa.core.processor  - Logged UserUtterance - tracker now has 2 events
2019-07-22 17:57:24 DEBUG    rasa.core.policies.form_policy  - There is no active form
2019-07-22 17:57:24 DEBUG    rasa.core.policies.ensemble  - Predicted next action using policy_0_FormPolicy
2019-07-22 17:57:24 DEBUG    rasa.core.processor  - Predicted next action 'action_listen' with confidence 0.00.
2019-07-22 17:57:24 DEBUG    rasa.core.processor  - Action 'action_listen' ended with events '[]'
2019-07-22 17:57:24 DEBUG    rasa.core.agent  - Deleted lock for conversation 'default' (unused)

The bot answers nothing, but prompt to give a further input.