Entity Resolution for Custom Slot Types

Alexa uses entity resolution to resolve the user's utterance for a slot value to a single, known entity. For a custom slot type, you define these entities, their identifiers, and the synonyms that resolve to the entity.

For more about entity resolution, see Entity Resolution.

Slot value synonyms, unique identifiers, and entity resolution

For a custom slot type, you define your custom slot type values as entities with fixed identifiers and synonyms. When users make requests to your skill, Alexa attempts to resolve the possible slot values in the utterance to the entities you have defined. When entity resolution is successful, your skill gets the actual value that the user spoke and an array of possible known entities. Each possible entity in the array has the canonical name for the entity and a unique identifier.

Users often use different words to say the same thing. For instance, for a MEDIA_TYPE slot intended to collect a particular type of media, a user might say "song," "track," or "single." In most cases, you would want your code to handle these three different values the same way.

To simplify this, define your slot type values as entities. An entity consists of:

  • A possible slot value (such as "song"). This is the canonical slot value.
  • An optional list of synonyms (such as "track" and "single"). These synonyms are tied to the canonical slot value.
  • A unique ID (such as SONG).

Alexa uses these entities to resolve the user's utterance. The IntentRequest sent to your skill includes:

  • The actual value the user spoke. This might be the canonical value, one of the synonyms, or another matching value.
  • The canonical value defined for the matching entity.
  • The unique ID of the matching entity.

Note that multiple possible matches can be returned.

You can use the unique ID in your code directly and not worry about the specific word that the user said for the slot. For example, for a MEDIA_TYPE slot type, the slot value "song" could have the ID SONG and the synonyms "track" and "single." When a user says "track" for this slot, your skill gets:

  • The value "track"
  • The canonical value "song"
  • The ID SONG

Also note that the IntentRequest can include multiple possible matches for a slot rather than just one.

Create synonyms and unique identifiers for your custom slot type values

You can define the synonyms and unique identifiers for any custom slot type or extensible built-in slot type.

In the developer console, you can define the ID and synonyms for each slot value when editing the type. Alternatively, you can use the JSON Editor to view and edit these values in JSON.

To edit slot type values and identifiers

  1. In the developer console, add or edit a custom slot type. Select the type from the Slot Types area in the left-hand navigation.
  2. Add slot values normally.
  3. Click in the ID column for a value to edit its ID.
  4. Click in the Synonyms column for a value to enter a synonym, then click the plus or press Enter to save it.

To view or edit slot type values in the JSON Editor

You can also use the JSON Editor to view and edit the IDs and synonyms for the slot type values in the JSON. For example, the following JSON defines a custom slot type called MEDIA_TYPE with two values. Each value ("album" and "song") has an ID and three synonyms:

{
  "types": [
    {
      "name": "MEDIA_TYPE",
      "values": [
        {
          "id": "SONG",
          "name": {
            "value": "song",
            "synonyms": ["tune","single","track"]
          }
        },
        {
          "id": "ALBUM",
          "name": {
            "value": "album",
            "synonyms": ["record","lp","cd"]
          }
        }
      ]
    }
  ]
}

See the JSON syntax shown below for definitions of these JSON properties.

After making any changes in the JSON Editor, always click Save Model. Then build your model before testing.

Custom Slot Type JSON Reference

The JSON format for custom slot types specifies the types property as an array of objects. Each object represents a custom slot type and includes a name and array of values. Each value consists of:

  • A unique identifier (id).
  • A string value (name.value).
  • An optional array of synonyms for that value (name.synonyms[]).

When a user's utterance mentions either the value or one of the synonyms, Alexa resolves the utterance to the value and includes it in the IntentRequest sent to your skill.

Slot type definition syntax:

{
  "types": [
    {
      "name": "string",
      "values": [
        {
          "id": "string",
          "name": {
            "value": "string",
            "synonyms": [
              "string",
              "string"
            ]
          }
        }
      ]
    }
  ]
}

Parameter Description Type Required
name Name of the slot type. Can contain alphabetic characters only. The only special character allowed is the underscore ("_"). string Yes
values An array of objects defining the values for the slot type. array Yes
values[].id An identifier for the slot value. This identifier is included in the IntentRequest when Alexa recognizes a slot value or synonym in the user's utterance. The ID can't include spaces. string Yes
values[].name An object representing the name of this value. This object defines the text value and synonyms for the entity. object Yes
values[].name.synonyms An array of strings representing synonyms for this value. If Alexa recognizes the user's utterance as one of these synonyms, Alexa resolves the utterance to this value and includes information for the value in the IntentRequest. array No
values[].name.value A string containing the canonical value associated with this slot type value. For example, for a MEDIA_TYPE slot type, one value might be "album". string Yes

For an example, see Sample Slot Type Definition and IntentRequest.

Slot value resolutions in the IntentRequest

The IntentRequest sent to your skill includes additional information for the slot values. The additional properties are all within the slots object on the intent.

Continuing the earlier MEDIA_TYPE slot type example, an intent using this type for the MediaType slot might produce an IntentRequest like the following example.

{
  "type": "IntentRequest",
  "requestId": "amzn1.echo-api.request.1",
  "locale": "en-US",
  "timestamp": "2021-01-15T21:25:48Z",
  "intent": {
    "name": "GetMediaIntent",
    "confirmationStatus": "NONE",
    "slots": {
      "MediaType": {
        "name": "MediaType",
        "value": "track",
        "resolutions": {
          "resolutionsPerAuthority": [
            {
              "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.MEDIA_TYPE",
              "status": {
                "code": "ER_SUCCESS_MATCH"
              },
              "values": [
                {
                  "value": {
                    "name": "song",
                    "id": "SONG"
                  }
                }
              ]
            }
          ]
        },
        "confirmationStatus": "NONE",
        "source": "USER",
        "slotValue": {
          "type": "Simple",
          "value": "track",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.1.MEDIA_TYPE",
                "status": {
                  "code": "ER_SUCCESS_MATCH"
                },
                "values": [
                  {
                    "value": {
                      "name": "song",
                      "id": "SONG"
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  },
  "dialogState": "STARTED"
}

In this request:

  • The value property for the slot object (MediaType) reflects the value the user spoke. In the previous example, the user spoke one of the synonyms defined for the SONG value.
  • The resolutions property contains the results of entity resolution. These are organized by authority. 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.
  • The values array within resolutionsPerAuthority contains the possible matching slot values. This includes the canonical value (resolutionsPerAuthority[].values[].value.name) and unique ID (resolutionsPerAuthority[].values[].value.id) for each possible match. Multiple matches can be returned. The values in the resolutionsPerAuthority[].values[] array are ordered from the most likely to least likely matches. Therefore, the first value in the array is considered the best match.

See the standard IntentRequest definition for details about the IntentRequest properties.

For an example, see Sample Slot Type Definition and IntentRequest, below.

Sample Slot Type Definition and IntentRequest

The following example shows the JSON for a GetMediaIntent intent and two custom slot types that include identifiers and synonyms (MEDIA_TYPE and MEDIA_TITLE).

{
  "interactionModel": {
    "languageModel": {
      "invocationName": "my sample skill",
      "intents": [
        {
          "name": "GetMediaIntent",
          "slots": [
            {
              "name": "MediaType",
              "type": "MEDIA_TYPE"
            },
            {
              "name": "MediaTitle",
              "type": "MEDIA_TITLE"
            }
          ],
          "samples": [
            "tell me about the {MediaType} {MediaTitle}",
            "get the {MediaType} called {MediaTitle}",
            "get the {MediaType} {MediaTitle}",
            "many more sample utterances"
          ]
        }
      ],
      "types": [
        {
          "name": "MEDIA_TYPE",
          "values": [
            {
              "id": "VIDEO",
              "name": {
                "value": "video",
                "synonyms": [
                  "music video"
                ]
              }
            },
            {
              "id": "SONG",
              "name": {
                "value": "song",
                "synonyms": [
                  "tune",
                  "single",
                  "track"
                ]
              }
            },
            {
              "id": "ALBUM",
              "name": {
                "value": "album",
                "synonyms": [
                  "record",
                  "lp",
                  "cd"
                ]
              }
            }
          ]
        },
        {
          "name": "MEDIA_TITLE",
          "values": [
            {
              "id": "song_id_456",
              "name": {
                "value": "Rolling in the Deep",
                "synonyms": [
                  "in the deep",
                  "rolling deep"
                ]
              }
            },
            {
              "id": "song_id_123",
              "name": {
                "value": "Ray of Light",
                "synonyms": [
                  "ray",
                  "ray of lights",
                  "ray of the ligh"
                ]
              }
            }
          ]
        }
      ]
    }
  }
}

The user might interact with the skill like this:

User: Alexa, ask My Sample Skill to get the song rolling in the deep

This utterance mentions values for both slots (MediaType, MediaTitle). Alexa resolves these mentions using the data provided in your custom slot type and sends your skill the following IntentRequest:

{
  "type": "IntentRequest",
  "intent": {
    "name": "GetMediaIntent",
    "slots": {
      "MediaType": {
        "name": "MediaType",
        "value": "song",
        "resolutions": {
          "resolutionsPerAuthority": [
            {
              "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TYPE",
              "status": {
                "code": "ER_SUCCESS_MATCH"
              },
              "values": [
                {
                  "value": {
                    "name": "song",
                    "id": "SONG"
                  }
                }
              ]
            }
          ]
        },
        "slotValue": {
          "type": "Simple",
          "value": "song",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TYPE",
                "status": {
                  "code": "ER_SUCCESS_MATCH"
                },
                "values": [
                  {
                    "value": {
                      "name": "song",
                      "id": "SONG"
                    }
                  }
                ]
              }
            ]
          }
        }
      },
      "MediaTitle": {
        "name": "MediaTitle",
        "value": "rolling in the deep",
        "resolutions": {
          "resolutionsPerAuthority": [
            {
              "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TITLE",
              "status": {
                "code": "ER_SUCCESS_MATCH"
              },
              "values": [
                {
                  "value": {
                    "name": "Rolling in the Deep",
                    "id": "song_id_456"
                  }
                }
              ]
            }
          ]
        },
        "slotValue": {
          "type": "Simple",
          "value": "rolling in the deep",
          "resolutions": {
            "resolutionsPerAuthority": [
              {
                "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TITLE",
                "status": {
                  "code": "ER_SUCCESS_MATCH"
                },
                "values": [
                  {
                    "value": {
                      "name": "Rolling in the Deep",
                      "id": "song_id_456"
                    }
                  }
                ]
              }
            ]
          }
        }
      }
    }
  }
}

Because the entity definitions include synonyms, your skill gets a similar result if the user uses slightly different wording:

User: Alexa, ask My Sample Skill to get the track rolling in the deep

Because track was defined as a synonym of song, Alexa can resolve this value and provide you with the same ID (for brevity, this example only shows the request JSON for the MediaType slot):

{
  "MediaType": {
    "name": "MediaType",
    "value": "track",
    "resolutions": {
      "resolutionsPerAuthority": [
        {
          "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TYPE",
          "status": {
            "code": "ER_SUCCESS_MATCH"
          },
          "values": [
            {
              "value": {
                "name": "song",
                "id": "SONG"
              }
            }
          ]
        }
      ]
    },
    "slotValue": {
      "type": "Simple",
      "value": "track",
      "resolutions": {
        "resolutionsPerAuthority": [
          {
            "authority": "amzn1.er-authority.echo-sdk.<skill_id>.MEDIA_TYPE",
            "status": {
              "code": "ER_SUCCESS_MATCH"
            },
            "values": [
              {
                "value": {
                  "name": "song",
                  "id": "SONG"
                }
              }
            ]
          }
        ]
      }
    }
  }
}