FormPolicy worked wrong

Hello !There are many problems confused me when I use FormPolicy and can someone 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 can not work sometimes and slot filling not right.And the terrible problem is that when I input message with one slot again,FormPolicy always did not work and slots did not be cleared, Rasa core return the last result to me instead of asking me fill another slot.Why?Here is my some logs and configs.look forward to your reply!Thanks

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 @jiangdg,

I see a possible problem here with your stories. You can read further information here:

But what you actually want to achieve is, that your bot learns to accept one or more entities while triggering the event. I would add the following to your stories.md:

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

# request number with initial number
* greet
    - utter_answer_greet
* request_number{"number": "+491453322235"}
    - number_form
    - form{"name": "number_form"}
    - slot{"requested_slot": "item"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

# request number with initial item
* greet
    - utter_answer_greet
* request_number{"item": "your_item"}
    - number_form
    - form{"name": "number_form"}
    - slot{"requested_slot": "number"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

# request number with initial number and item
* greet
    - utter_answer_greet
* request_number{"item": "your_item", "number": "+4917645362748"}
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

With this stories your bot learns what to expect when a certain intent is triggered. It even helps the automatic augmentation of your story.

Please try if this fixes your problem and tell me, if I could help you!

Regards

Hi @JulianGerhard ,Thanks for your reply! Today I try to do it following your suggestions,but it seems not work for me and the result is same as before.Here is my ation excution log:

User : help me searching a licence number US12345
 🤖 :##### execute submit function,and current slot:item=licence number,number=US12345

User :searching ID Card
 🤖 :##### execute submit function,and current slot:item=licence number,number=US12345

User :searching phone number 1453322235
 🤖 :##### execute submit function,and current slot:item=licence number,number=1453322235

The first dialogue execute form_number with MobilePolicy instead of FormPolicy,anyway the slots filling are right.But the second dialogue begins to get wrong,here I except the bot asking me input ID Card number continue,but the bot give me the last dialogue result and the slot of item have not be filled with ID Card.The third dialogue’s satuation is the same to the second.Can you tell me why and how to solve it? Looking forward to your reply,Thank you!

Hi @jiangdg,

Okay - for further help I will need more Information.

Could you please post all of your Setup including training data and everything else? Ill take a look then in detail!

Regards

@JulianGerhard,Happy with receiving your reply!Here are some configs of my bot project,if you want another more information about the project please tell me and i will offer them do my best.Thanks

  1. nlu.md
## intent:request_number
- Help me check the [license plate number](item) [US12345](number)
- for [id card](item), the number is [441235196712302222](number)
- checking [phone number](item) [19860618422](number)
- the number is [US12345](number)
- I want to find [19860612425](number)
- help me find [441235196712302222](number)
- searching [id card](item)
- [license plate number](item)
- tell me the [phone number](item)
...
...
  1. stories.md:
# happy with request number
* greet
    - utter_answer_greet
* request_number
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

the model’s training config is:

def train_dialogue_keras_form(domain_file="configs/core/domain.yml",
                         model_path="models/dialogue_keras_form",
                         training_data_file="data/stories.md"):
    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,max_history=5),
                            FormPolicy(), fallback])

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

    agent.persist(model_path)
    return agent
  1. domain.yml
intents:
  - greet
  - goodbye
  - thanks
  - request_number
  - out_of_scope

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

entities:
  - item
  - number

actions:
  - utter_answer_greet
  - utter_answer_thanks
  - action_reset_slots
  - utter_ask_item
  - utter_ask_number
  - utter_answer_out_of_scope

forms:
  - number_form

templates:
 utter_ask_item:
    - text: "please tell me what's your item?"

  utter_ask_number:
    - text: "Okay,can you tell me your {item} number?"
  1. action.py
class NumberForm(FormAction):

    def name(self):
        """Request Number action"""
        return "number_form"

    def validate_number(self, value, dispatcher, tracker, domain):
        # TODO
        return {"number", value}


    def validate_item(self, value, dispatcher, tracker, domain):
        # TODO
        return {"item", value}


    @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 []

Hi @jiangdg,

I have taken a look upon your problem and got it fixed. See the complete working bot in the attached zip file.

rasa_jiangdg_bot.zip (99.9 KB)

  1. Your actions.py was missing the slot_mapping function or you didn’t post it.
  2. Your validation functions returned a set, because you typed return {"item", value} instead of return {"item": value} which is serializable due to being a dictionary.
  3. I increased the epoch size by 100 to 200
  4. I added some more samples for the entity id card
  5. I used specific entity extraction pipeline training to ensure, that your bot learned sufficiently from the few entity samples

Please take a look and feel free to ask, if something might be unclear. At least the desired output now is correct.

Hi @JulianGerhard , Thanks for your project! I run your project immediately when I saw your reply and I found the result was truely what I excepted.But there is another question confused me and hope you can give me some suggestions.The problem is:In my project,there is another form action called request_business with three slots item/number/business,and item/number is the same one of request_number.Now I want to query more infomations of the number after executing request_number without cleanup the slots of item and number,so I try to remove action_restart from the stories.md. However,the results go back to what is before. So How can I solve it?

Here is my new configs :

nlu.md

## intent:request_number
- Help me check the [license plate number](item) [US12345](number)
- for [id card](item), the number is [441235196712302222](number)
- checking [phone number](item) [19860618422](number)
- the number is [US12345](number)
- I want to find [19860612425](number)
- help me find [441235196712302222](number)
- searching [id card](item)
- [license plate number](item)
- tell me the [phone number](item)
...
...
## intent:request_business
- telling me the [traffic violation](business) of [US12345](number)
- [traffic violation](business)
- I want to know the [owner](business) of a [license plate number](item),the number is  [US12345](number)
....
...

stories.md

# happy with request number
* greet
    - utter_answer_greet
* request_number
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
* goodbye
    - utter_answer_thanks
    
# request number with initial number
* greet
    - utter_answer_greet
* request_number{"number": "+491453322235"}
    - number_form
    - form{"name": "number_form"}
    - slot{"requested_slot": "item"}
    - form{"name": null}

# request number with initial item
* greet
    - utter_answer_greet
* request_number{"item": "id card"}
    - number_form
    - form{"name": "number_form"}
    - slot{"requested_slot": "number"}
    - form{"name": null}

# request number with initial number and item
* greet
    - utter_answer_greet
* request_number{"item": "id card", "number": "+4917645362748"}
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
    

# happy with request business
* greet
    - utter_answer_greet
* request_business
    - business_form
    - form{"name": "business_form"}
    - form{"name": null}
* thanks
    - utter_answer_thanks
    
    
# happy with request business base on request_number
* greet
    - utter_answer_greet
* request_number
    - number_form
    - form{"name": "number_form"}
    - form{"name": null}
* request_business
    - business_form
    - form{"name": "business_form"}
    - form{"name": null}
* thanks
    - utter_answer_thanks

domain.yml

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

entities:
  - item
  - number
  - business

actions:
  - utter_ask_item
  - utter_ask_number
  - utter_ask_business

forms:
  - number_form
  - business_form

Best regards!

Hi @jiangdg

I guess there are many possibilites to achieve this. First of all, - form{"name": null} results in the form being finished, so you might want to remove that - I never tried that. I’d anyway recommend you to start thinking about a tracker store, e.g. with MongoDB, such that you could just take the tracker and query all past events to e.g. take a look for apreviously given / filled slot.

What do you think?

Regards

That’s a good idea and I’ll try it now. If there is any new situation, I will tell you in time. Thanks for your help again!@JulianGerhard

Best regards!

Hi @JulianGerhard I configurated my MongoDB according to Tracker Stores and My MongoDB instance has started, but it seems not working. Can any else need to configed? Here is my endpoint.yml:

action_endpoint:
  url: "https://localhost:8088/webhook"
nlu:
  url: "http://localhost:5000/"
tracker_store:
    type: mongod
    url: mongodb://localhost:27017
    db: rasa
    username: jiangdg
    password: 123456
    auth_source: rasa

tip: my rasa core’s version is 0.13.2.
Thank you!

@jiangdg since you’re still using Core and NLU, you want these docs: Tracker Stores

Do you have mongo running on port 27017?

@erohmensing Yes,I could access mongo server by terminal cammands and I also configurated my endpoint.yml following Tracker Stores, but I could not seen any changes in Rasa Core.When Core and NLU is working I also could not get any data about Rasa conversations .Do you know why?

@jiangdg

You can try @erohmensing s question by opening a terminal/cmd and typing in:

mongo

if the shell starts, it has started on the default port 27017.

Hi @JulianGerhard @erohmensing,

My Problem was solved by upgrading Rasa Core to 0.14.4 and the mongoDB worked well.By the way,How can I run the command liking rasa run -m models --enable-api --log-file out.log in win10 terminal and is python -m rasa_core.run -d xx -u xx --port 5002 --credentials configs/credentials.yml --endpoints configs/endpoints.yml --debug has been deprecated?

Thank you!

Hi @jiangdg, if you are using rasa core, 0.14.4, not rasa, Then you cannot run the rasa run command. However you should be able to still run

python -m rasa_core.run -d xx -u xx --port 5002 --credentials configs/credentials.yml --endpoints configs/endpoints.yml --debug 
1 Like