Working with forms as a beginner

So I wanted to create a bot that sort of takes order. For now I have taken basic entities like category and company For ex: I want kfc chicken. This should map chicken as category(misnamed it instead of product) and company. For this I have decided to use forms. So if i say I want kfc chicken, it does map kfc as company and chicken as category in my bot. I also made another intent, so that in a sentence if a user only says entity category, it asks for the company, so that i can fill it out. For ex: I want chicken. Which company kfc

But 2 problems arise. Problem 1: Only categories and companies I have given in nlu.ym as entities in an intent can be picked up by the bot, and it does not pick up entities by itself from the sentence that has not been given in an intent. Problem 2: If I say “I want kfc chicken” and then I say I want chicken the next, it does not ask for which company, but takes kfc. I tried looking for a way to reset, but the way I saw in other problems was to write a reset function in actions.py , but I did not know where to call it.

Relevant code:

nlu.yml - intent: inform examples: | - milk - water - kfc

- intent: request_grocery
  examples: |
    - I want [milk](category)
    - Add [Chips](category) to my cart.
    - Could I have some [biscuits](category)

- intent: request_grocery_comp
  examples: |
    - I want [kfc](company) [chicken](category)
    - Give me [tropicana](company) [juice](category)

rules.yml - rule: activate grocery form steps: - intent: request_grocery # intent that triggers form activation - action: grocery_form # run the form - active_loop: grocery_form # this form is active

- rule: activate grocery form 2
  steps:
  - intent: request_grocery_comp  # intent that triggers form activation
  - action: grocery_form      # run the form
  - active_loop: grocery_form # this form is active

- rule: submit form
  condition:
  - active_loop: grocery_form   # this form must be active
  steps:
  - action: grocery_form      # run the form
  - active_loop: null            # the form is no longer active because it has been filled
  - slot_was_set:
    - requested_slot: null
  - action: utter_submit         # action to take after the form is complete
  - action: utter_slots_values   # action to take after the form is complete
  - active_loop: null

domain.yml intents: - request_grocery - request_grocery_comp - inform

entities:
  - category
  - company

forms:
  grocery_form:
    category:
      - type: from_entity
        entity: category
    company:
      - type: from_entity
        entity: company

slots:
  category:
    type: text
    auto_fill: false
    influence_conversation: false
  company:
    type: text
    auto_fill: false
    influence_conversation: false

responses:
 # utter_ask_category:
 # - text: "What category?"
  utter_ask_company:
  - text: "What company?"
  utter_submit:
  - text: "All done!"
  utter_slots_values:
  - text: "I am going to run a shopping search using the following parameters:\n
            - category: {category}\n
            - company: {company}"

Addition qn: Is using forms the way I have done the optimal way to go about this problem or is there an easier way. Thanks.

Hello @CharuchithRanjit , welcome to the Forum!

Is using forms the way I have done the optimal way to go about this problem or is there an easier way.

Yes, using a form for this is a good approach.

Problem 1: Only categories and companies I have given in nlu.ym as entities in an intent can be picked up by the bot

This is true if you use only the RegexEntityExtractor. But if you use DIET for entity extraction, it can potentially lean to identify them also by their position in the sentence. This only works, though, if you provide enough training examples (at least 15 for each intent I’d say, but the more the better).

Problem 2: If I say “I want kfc chicken” and then I say I want chicken the next, it does not ask for which company

This is a bit of an odd use case. Normally, you want the bot to remember all the choices that the user makes, but of course it should recognize if the user changes their mind. In any case, you can use validation actions to see if a slot is already filled.

1 Like

Thanks a lot for the help. So the idea behind problem 2 was not that i change the current order. I wanted to take multiple orders and store it somewhere, so to take the second order, I dont want it to be filled by the first order’s information right, hence the question.

I wanted to take multiple orders and store it somewhere, so to take the second order, I dont want it to be filled by the first order’s information right, hence the question.

Ah, in that case you can create a form for one order. At the end of the form, you use a custom action to move all the information from the form slots into some other “storage” slot that doesn’t affect the form. Then you have it restart the form with the empty slots (except for the storage slot that doesn’t affect it).