Form with multiple similar entries

Hi

I’m running Rasa 1.10.1

I’m wanting to fill a number of slots. Looking at the documentation and forum posts, it seems like a form is the recommended way of doing this.

The issue I’m having is, the answers are all very similar to one another, eg. yes/no questions:

Q: Question 1, yes or no?
A: Yes
Q: Question 2, yes or no?
A: No
Q: Question 3, yes or no?
A: No

So there is no way to distinguish which question is being asked, based solely on the answer. I can create affirm and deny intents, but it is not possible to create intents for each question, the answers are too similar, and the NLU won’t be able to pick up which question the answer was for.

The issue I’m having is, if I create a form, with slot mappings like:

"question1": [
  self.from_intent(intent="affirm", value="yes"),
  self.from_intent(intent="deny", value="no"),
],
"question2": [
  self.from_intent(intent="affirm", value="yes"),
  self.from_intent(intent="deny", value="no"),
]

Then a “yes” to one question fills in “yes” for all other questions, instead of just the question that has been asked.

How can I get the form to stop filling in the other slots, when the user only meant to answer the question presented to them?

I think that will not occur. The question depends on the requested_slot slot, so the answer should only fill that slot.

If I look through the forms code for the rasa-sdk, on validate, it first tries to extract other slots, then it extracts the requested slot: rasa-sdk/forms.py at master · RasaHQ/rasa-sdk · GitHub

The exact wording in the comment there is:

# extract other slots that were not requested
# but set by corresponding entity or trigger intent mapping

I’ve managed to get this working, but the method seems very hacky. Open to solutions to do this better.

The solution is dynamically setting the required_slots in the form, depending on what has already been filled out. So in required_slots, I’m only ever returning a single value in the list, the next slot to be filled. Initially I thought that the form will fill this slot, and then complete, but it seems like that doesn’t happen. This seems very fragile, but I’m not sure what the proper way of doing this in Rasa is.

def required_slots(tracker: Tracker) -> List[Text]:
    slots =  ["question1", "question2", "question3"]
    for slot in slots:
        if not tracker.get_slot(slot):
            return [slot]
    return []