Collect Multiple Values in a Slot

Use a multiple-value slot to collect multiple values from a user utterance into single slot. For example, an utterance like "I want a pizza with pepperoni, mushrooms, and olives" sends your skill an array with three values in a single {toppings} slot. This lets the user provide multiple values in a more natural utterance.

You can use multiple-value slots in the following locales:

  • English (AU)

  • English (CA)

  • English (UK)

  • English (US)

About multiple value slots

Multiple-value slots let users provide a list of items in a more natural way. Instead of stringing together multiple slots or asking multiple questions to get a list of related items, you can use a single slot. In your interaction model, you define your sample utterances with a single slot that collects all the values:

order a pizza with {toppings}

When a user speaks this utterance, they can say multiple items separated with pauses, the conjunction "and", or a combination of the two. For example:

User: Order a pizza with pepperoni, mushrooms, and black olives

Your skill gets a request with an array of values as the slot value for the toppings slot. In the pizza example, the array contains three items (full details removed for brevity):

{
  "values": [
    {
      "type": "Simple",
      "value": "pepperoni",
      "resolutions": {}
    },
    {
      "type": "Simple",
      "value": "mushrooms",
      "resolutions": {}
    },
    {
      "type": "Simple",
      "value": "black olives",
      "resolutions": {}
    }
  ]
}

Valid user utterances for a multiple value slot

A multiple-value slot requires the user to separate values in the utterance with pauses, "and", or a combination of the two. For example, the following utterances are valid ways to fill a multiple value toppings slot:

  • "Order a pizza with pepperoni"
  • "Order a pizza with pepperoni and mushrooms."
  • "Order a pizza with pepperoni, mushrooms."
  • "Order a pizza with pepperoni, mushrooms, and black olives."
  • "Order a pizza with pepperoni, mushrooms, black olives, and roasted garlic."

Steps to use a multiple-value slot in your skill

Using a multiple value slot requires you to update your interaction model and change your skill code to accommodate changes in the IntentRequest.

To create a multiple-value slot

  1. Create your interaction model with at least one custom intent with at least one slot.
  2. Configure the slot for multiple values as described in Configure a slot to accept multiple values.
  3. Update your skill code to handle the revised slot object in the IntentRequest. For details, see Update your code to handle the multiple-value slot object and IntentRequest slot object reference.
  4. Test the utterances you expect users to speak. Test many different combinations of list items and verify that your skill gets the correct set of values. Update the slot type with more values as needed to improve recognition. See Test the slot and revise your model as needed.

Configure a slot to accept multiple values

You configure a slot to collect multiple values on the intent, not on the slot type. A multiple-value slot can use any custom or built-in slot type except for AMAZON.SearchQuery. When you write your utterances, reference the slot as you normally would, with curly braces:

order a pizza with {toppings}
i want a pizza with {toppings}
i want {toppings}
...

You can configure the multiple value option in the developer console or with the ASK CLI.

Use the developer console to configure a slot for multiple values

  1. Open your skill in the developer console.
  2. Click an intent in the left-hand navigation to open the detail page for the intent.
  3. In the list of Intent Slots, find the slot to change. The MULTI-VALUE column indicates whether this slot can collect multiple values.
  4. Click the slot to open the slot detail page.
  5. Under Multi-Value, enable the Can this slot contain multiple values? option.
Multiple value setting for a slot
Multiple value setting for a slot

Use the ASK CLI to configure a slot for multiple values

  1. In the JSON file for your interaction model, update the intent slot you want to configure. Set interactionModel.languageModel.intents[].slots[].multipleValues.enabled to true.

     {
       "name": "OrderPizzaIntent",
       "slots": [
         {
           "name": "toppings",
           "type": "PizzaToppings",
           "multipleValues": {
             "enabled": true
           }
         }
       ],
       "samples": [
         "order a pizza with {toppings}",
         "i want a pizza with {toppings}",
         "i want {toppings}"
       ]
     }
    

    For a reference to the interaction model JSON, see Interaction model schema reference.

  2. Use the ASK CLI deploy command to upload and deploy the interaction model.

     ask deploy --profile "default" --target "model"
    

Interaction model schema reference

Multiple-value slots change the schema for defining a slot. The multipleValues object lets you enable multiple values for the slot:

{
  "name": "OrderPizzaIntent",
  "slots": [
    {
      "name": "toppings",
      "type": "PizzaToppings",
      "multipleValues": {
        "enabled": true
      }
    }
  ],
  "samples": [
    "order a pizza with {toppings}",
    "i want a pizza with {toppings}",
    "i want {toppings}"
  ]
}
Property Description Type Required

multipleValues

Determines whether this slot allows single values or multiple values. When this object is not present, the slot defaults to allowing single values only.

Object

No

multipleValues.enabled

When true, the slot recognizes and collects multiple values spoken in list format, such as "pepperoni, mushrooms, and black olives".

Boolean

No

For more about the interaction model JSON structure, see Interaction Model Schemas.

Update your code to handle the multiple-value Slot object

The structure of the Slot object in the IntentRequest has changed for all requests and all slots, even those that you don't configure for multiple values. These changes are fully backwards-compatible. Your existing code that accesses values for single-value slots continues to work unchanged. However, you must update your code to access a slot that returns multiple-values.

The following sections describe the overall changes. For the full reference to the updated Slot object, see IntentRequest Slot object reference.

The slotValue property and the legacy value and resolutions properties

When the user provides a slot value in an utterance, the corresponding Slot object in the IntentRequest includes a new slotValue property. Access this at request.intent.slots.slotName.slotValue:

{
  "slotName": {
    "name": "slotName",
    "value": "user-provided slot value",
    "resolutions": {},
    "slotValue": {
      "type": "Simple",
      "value": "user-provided slot value",
      "resolutions": {}
    },
    "confirmationStatus": "NONE",
    "source": "USER"
  }
}

The slotValue property contains a SlotValue object that represents the value the user provided. The SlotValue object represents either a single value or list of values. The slotValue.type property is Simple for single values or List for multiple values.

The slotValue property is present regardless of how you configured the slot in your interaction model. That is, a slot configured for single values also includes the slotValue property when the user provides a value. When the slot is left unfilled, slotValue is omitted.

When the user speaks a single value for the slot, the Slot object reports the value in two places, regardless of the slot configuration:

  • The new slotValue property in slotValue.value and slotValue.resolutions
  • The legacy value and resolutions properties at the top level of the Slot object.

For example, if you configured the toppings slot for multiple values, but the user said they want "pepperoni," that value is available in both places:

{
  "toppings": {
    "name": "toppings",
    "value": "pepperoni",
    "resolutions": {},
    "confirmationStatus": "NONE",
    "source": "USER",
    "slotValue": {
      "type": "Simple",
      "value": "pepperoni",
      "resolutions": {}
    }
  }
}

When the user provides multiple values for the slot, the array of values is available in the slotValue.values array. The slot doesn't include the legacy value and resolutions properties. Existing code that expects those properties doesn't work.

{
  "toppings": {
    "name": "toppings",
    "slotValue": {
      "type": "List",
      "values": [
        {
          "type": "Simple",
          "value": "pepperoni",
          "resolutions": {}
        },
        {
          "type": "Simple",
          "value": "mushrooms",
          "resolutions": {}
        }
      ]
    },
    "confirmationStatus": "NONE",
    "source": "USER"
  }
}

Note that each object within the slotValue.values array is also a SlotValue object and therefore has type value and resolutions properties.

Because of this structure, you might want to change your code for accessing slot values to use the new slotValue property for all requests, not just those with multiple values. Use the slotValue.type property to distinguish between requests with single and multiple values.

Entity resolution

Entity resolution resolves the spoken value into a slot value and provides additional information for the slot values, such as unique identifiers and multiple possible matches. Entity resolution also resolves spoken synonyms to your slot values.

Entity resolution generates values for both single-value and multiple-value slots. The new slotValue property includes entity resolution results for each value:

  • For a single-value slot, or a multiple-value slot where the user spoke a single value, entity resolution results are in the slotValue.resolutions property. The same results are also in the legacy resolutions property.
  • For a multiple-value slot, resolutions for each value are in the resolutions property for each individual value in the values array: slotValue.values[].resolutions.

This example shows a slot with a single value. The resolutions data is available in both the legacy resolutions property and slotValue.resolutions. The results include two potential ER matches for the utterance "olives".

{
  "toppings": {
    "name": "toppings",
    "value": "olives",
    "resolutions": {
      "resolutionsPerAuthority": [
        {
          "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.PizzaToppings",
          "status": {
            "code": "ER_SUCCESS_MATCH"
          },
          "values": [
            {
              "value": {
                "name": "black olives",
                "id": "OLIVES_BLACK"
              }
            },
            {
              "value": {
                "name": "green olives",
                "id": "OLIVES_GREEN"
              }
            }
          ]
        }
      ]
    },
    "confirmationStatus": "NONE",
    "source": "USER",
    "slotValue": {
      "type": "Simple",
      "value": "olives",
      "resolutions": {
        "resolutionsPerAuthority": [
          {
            "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.PizzaToppings",
            "status": {
              "code": "ER_SUCCESS_MATCH"
            },
            "values": [
              {
                "value": {
                  "name": "black olives",
                  "id": "OLIVES_BLACK"
                }
              },
              {
                "value": {
                  "name": "green olives",
                  "id": "OLIVES_GREEN"
                }
              }
            ]
          }
        ]
      }
    }
  }
}

This example shows multiple values for the same slot when the user said "olives, sausage, and ham". Each value has its own entity resolution results. In this example, there are again two possible matches for the utterance "olives". In addition, the value "ham" is not defined in the custom slot type, as shown by the ER_SUCCESS_NO_MATCH code.

{
  "toppings": {
    "name": "toppings",
    "confirmationStatus": "NONE",
    "source": "USER",
    "slotValue": {
      "type": "List",
      "values": [
        {
          "type": "Simple",
          "value": "olives",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.PizzaToppings",
                "status": {
                  "code": "ER_SUCCESS_MATCH"
                },
                "values": [
                  {
                    "value": {
                      "name": "black olives",
                      "id": "OLIVES_BLACK"
                    }
                  },
                  {
                    "value": {
                      "name": "green olives",
                      "id": "OLIVES_GREEN"
                    }
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "Simple",
          "value": "sausage",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.PizzaToppings",
                "status": {
                  "code": "ER_SUCCESS_MATCH"
                },
                "values": [
                  {
                    "value": {
                      "name": "sausage",
                      "id": "SAUSAGE"
                    }
                  }
                ]
              }
            ]
          }
        },
        {
          "type": "Simple",
          "value": "ham",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.PizzaToppings",
                "status": {
                  "code": "ER_SUCCESS_NO_MATCH"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

For more details about entity resolution, see Define Synonyms and IDs for Slot Type Values (Entity Resolution).

When testing your skill, consider adding values that resolve to ER_SUCCESS_NO_MATCH to your custom slot type to improve multiple-value recognition. For more details, see Test the slot and revise your model as needed.

The __Conjunction slot

When an IntentRequest includes a slot configured for multiple values, the request sent to your skill includes an additional slot called __Conjunction. This contains the conjunction the user spoke to separate the values. The only supported conjunction is "and".

IntentRequest slot object reference

This section shows the complete structure for the Slot object included in an IntentRequest. For the full IntentRequest format, see IntentRequest.

Slot object

Syntax

{
  "slotName": {
    "name": "slotName",
    "value": "String representing the user-provided value",
    "resolutions": {},
    "slotValue": {},
    "confirmationStatus": "NONE | CONFIRMED | DENIED",
    "source": "USER"
  }
}

Properties

Name Description Type

confirmationStatus

An enumeration indicating whether the user has explicitly confirmed or denied the value of this slot. Possible values: NONE, CONFIRMED, DENIED

Enum

name

A string that represents the name of the slot.

String

resolutions

Included when the user provided a single value for the slot (slotValue.type is Simple). A Resolutions object representing the results of resolving the words captured from the user's utterance.

Included for slots that use a custom slot type or a built-in slot type that you have extended with your own values. Omitted when slotValue.type is List.

Resolutions object

slotValue

A SlotValue object representing the value or values captured by the slot. Added as part of the multiple-value slot beta.

SlotValue object

source

Indicates that the value came from the user. Always USER.

String

value

Included when the user provided a single value for the slot (slotValue.type is Simple). A string that represents the value the user spoke for the slot. This string is the actual value the user spoke, not necessarily the canonical value or one of the synonyms defined for the entity. Omitted when slotValue.type is List.

String

Resolutions object

Syntax

{
  "resolutions": {
    "resolutionsPerAuthority": [
      {
        "authority": "Identifier for the authority",
        "status": {
          "code": "Enum indicating ER status "
        },
        "values": [
          {
            "value": {
              "name": "String representing the resolved value",
              "id": "Identifier for the value"
            }
          }
        ]
      }
    ]
  }
}

Properties

Name Description Type

resolutionsPerAuthority[]

An array of objects representing each possible authority for entity resolution. An authority represents the source for the data provided for the slot. For a custom slot type, the authority is the slot type you defined.

Array

resolutionsPerAuthority[].authority

The name of the authority for the slot values. For custom slot types, this authority label incorporates your skill ID and the slot type name.

String

resolutionsPerAuthority[].status

An object representing the status of entity resolution for the slot.

Object

resolutionsPerAuthority[].status.code

A code indicating the results of attempting to resolve the user utterance against the defined slot types. See Entity resolution status codes.

Enum

resolutionsPerAuthority[].values

An array of resolved values for the slot. The values in the array are ordered from the most likely to least likely matches. Therefore, the first value in the array is considered the best match.

Array

resolutionsPerAuthority[].values[].value

An object representing the resolved value for the slot, based on the user's utterance and the slot type definition.

Object

resolutionsPerAuthority[].values[].value.id

The unique ID defined for the resolved slot value. This is based on the IDs defined in the [slot type definition][entity-resolution-for-slot-types#slot-type-json]

String

resolutionsPerAuthority[].values[].value.name

The string for the resolved slot value.

String

SlotValue object

Syntax

A SlotValue object contains either value or values, but never both.

{
  "slotValue": {
    "type": "Type of value (Simple or List)",
    "value": "When type is Simple, string representing the user-provided value.",
    "values": [
      {
        "type": "",
        "value": "",
        "resolutions": {}
      }
    ],
    "resolutions": {}
  }
}

Properties

Name Description Type

resolutions

Included when the type is Simple. A Resolutions object representing the results of resolving the words captured from the user's utterance.

Included for slots that use a custom slot type or a built-in slot type that you have extended with your own values.

Resolutions object

type

The type of value the slot captured from the user. Simple when the slot value is a single value , List when the slot value is an array of values.

String

value

Included when type is Simple. A string that represents the value the user spoke for the slot. This string is the actual value the user spoke, not necessarily the canonical value or one of the synonyms defined for the entity.

String

values

Included when thetype is List. An array of SlotValue objects representing the set of values the user provided. Each object in the array has its own type, value, and resolutions.

Array of SlotValue objects

Enumerations

Entity resolution status codes

  • ER_SUCCESS_MATCH – The spoken value matched a value or synonym explicitly defined in your custom slot type.
  • ER_SUCCESS_NO_MATCH – The spoken value didn't match any values or synonyms explicitly defined in your custom slot type.
  • ER_ERROR_TIMEOUT – An error occurred due to a timeout.
  • ER_ERROR_EXCEPTION – An error occurred due to an exception during processing.

Test the slot and revise your model as needed

Test your skill with a variety of utterances in your multiple-value slots. Test both filling those slots with single values and lists of values. Keep in mind that recognition for multiple slot values works best when the utterance contains five or fewer values.

Use a device or the Test page in the developer console to test your skill. When typing utterances in simulator on the Test page, separate multiple values with spaces, not commas. For example, type: "pepperoni mushrooms and olives"

The utterance profiler and NLU Evaluation tools do not support multiple-value slots.

Update your model to improve accuracy as you test. For custom slot types and built-in list types, Alexa is more accurate at parsing utterances into the correct multiple values when the slot type includes those values. When you discover values that Alexa fails to recognize correctly, do one of the following:

  • Custom slot typesEdit the slot and add the values you expect users to say to the slot type.
  • Built-in list typesExtend the slot type with those additional values.

Limitations for multi-value slots

  • You can't use a dialog model for an intent that has a multiple value slot. This means:
    • You can't use auto-delegation to collect the slot values.
    • You can't use the Dialog.Delegate, Dialog.ElicitSlot, or Dialog.ConfirmSlot directives.
  • The utterance profiler and NLU Evaluation tool do not support multiple-value slots. Test with the Test page or a device.
  • When you publish your skill, you provide up to three example phases to show users how to interact with your skill. You can use a phrase that illustrates providing multiple values in your set of example phrases. However, note that the developer console might display a warning that the phrase does not match your sample utterances. You can ignore this warning and submit the skill.