Building contextual assistants with Rasa Forms

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.

Hi @Juste,

thank you so much for the tutorial, very helpful :slightly_smiling_face:

Is it possible to create an input/submit window with Rasa Forms? e.g. for an email-address or a phone number… (see attached image).

Many thanks for you response :raising_hand_man:

11

Hi @jackpotandy. That should be possible, but you would have to take care of the frontend part yourself (having a widget that allows you to submit responses using the frontend elements like you included as an example). Overall, in Rasa slots can be set by clicking buttons and sending a custom payload (we have an examples on that here) so that should work.

Hi @Juste ,

Thanks for this tutorial, as well as your Rasa Master class playlist on youtube which was very helpful to get started.

I have a need where I want to get the user input in entirety as an string to use in custom action, can slot be used for this purpose? below is the example of conversation:

  • chatbot: could you please provide me query for document search
  • user: technical specification on equipment x

I want to take above users entire sentence “technical specification on equipment x” and perform a custom action, i.e. call other APIs to get information.

Please let me know any resources or info that I can use to achieve above functionality?

How can I set the condition logic at the middle of the slots in action required slots

Hi @seera. I am not sure if I understand what you mean by “middle of of the slots”. Can you expand a little bit (ideally add an example) of what you are looking for?

Thank you for reply @Juste. Issue solved

1 Like