Validate vs. extract with custom slot mapping

Hi,

please correct me if I´m wrong, this is how I understood it:

extract_slotname():

  • only needed if custom slot mapping
  • custom extraction for this slot
  • calls validate_slotname() afterwards

validate_slotname():

  • gets called after this slot gets extracted (custom or automatically)
  • accept/reject extracted value
  • set other slots, which are dependent

So I am aware that validation is needed after a slot is set.

But if I only use custom slot mappings, why do I need extraction AND validation?

And is it possible to set other slots from the extraction method, like in the validation? Sometimes it doesn´t work for me. Example:

def extract_slot_a(
        self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
    ) -> Dict[Text, Any]:
        ...
        return {"slot_a": 1, "slot_b": 2}
2 Likes

Good question :slight_smile:

You can do them all in one method indeed. But the methods are separate because that’s programming/engineering best practices - functions should execute one logical task (extract or validate but not both) even though you can do it all in one function.

As for setting two slots from the extract_slotname() method, it seems you can’t do that and need to do it in the validate_slotname() method.

2 Likes

Thaks for that :slight_smile:

As for setting two slots from the extract_slotname() method, it seems you can’t do that and need to do it in the validate_slotname() method.

I did some testing and found out that you can use the extract_slotname() method to set other slots, but only if they are listed under required slots for this form.

Example:

Domain:

slots:
  test_slot1:
    type: text
    mappings:
    - type: custom
  test_slot2:
    type: text
    mappings:
    - type: custom
  test_slot3:
    type: text
    mappings:
    - type: custom

forms:
  form_A
    required_slots:
      - test_slot1
      - test_slot2

Action:

def extract_test_slot1(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
    ) -> Dict[Text, Any]:

        if ...
            return {"test_slot1": "aaaa"} -> works (it´s the requested slot)
            return {"test_slot2": "aaaa"} -> works (it´s in form_A required_slots)
            return {"test_slot3": "aaaa"} -> doesn´t work (test_slot3 is not in form_A required_slots)
            return {"test_slot2": "aaaa", "test_slot3": "aaaa"} -> only sets test_slot2

I briefly skimmed the code but found nothing about it.

Does anyone have any idea why this is handled this way?

1 Like