Amazon Lex + AWS Lambda: Beyond Hello World

In my previous blog, I explained how to get started with Amazon Lex and build simple bots. This blog aims at exploring the Lambda functions used by Amazon Lex for code validation and fulfillment. We will go along with the same example we created in our first blog i.e. purchasing a book and will see in details how the dots are connected.

This blog is divided into following sections:

  1. Lambda function input format

  2. Response format

  3. Managing conversation context

  4. An example (demonstration to understand better how context is maintained to make data flow between two different intents)

NOTE: Input to a Lambda function will change according to the language you use to create the function. Since we have used NodeJS for our example, everything will thus be explained using it.
 

Section 1:  Lambda function input format

When communication is started with a Bot, Amazon Lex passes control to Lambda function, we have defined while creating the bot.

There are three arguments that Amazon Lex passes to a Lambda function:

1. event:

event is a JSON variable containing all details regarding a bot conversation. Every time lambda function is invoked, event JSON is sent by Amazon Lex which contains the details of the respective message sent by the user to the bot.

Below is a sample event JSON:

{
  currentIntent: {
    name: 'orderBook',
    slots: {
      bookType: null,
      bookName: 'null'
    },

    confirmationStatus: ’None’
},

bot: {
  name: 'PurchaseBook',
  alias: '$LATEST',
  version: '$LATEST'
},

userId: 'user-1',
inputTranscript: 'buy me a book',
invocationSource: 'DialogCodeHook',
outputDialogMode: 'Text',
messageVersion: '1.0'
};

Format of event JSON is explained below:-

  • currentIntent:  It will contain information regarding the intent of message sent by the user to the bot. It contains following keys:

    • name: intent name  (for e.g orderBook, we defined this intent in our previous blog).

    • slots: It will contain a map of slot names configured for that particular intent,  populated with values recognized by Amazon Lex during the conversation. Default values are null.  

  • confirmationStatus:  It provides the user response to a confirmation prompt if there is one. Possible values for this variable are:

    • None: Default value
    • Confirmed: When the user responds with a confirmation w.r.t confirmation prompt.
    • Denied: When the user responds with a deny w.r.t confirmation prompt.
  • inputTranscipt: Text input by the user for processing. In case of audio input, the text will be extracted from audio. This is the text that is actually processed to recognize intents and slot values.                                

  • invocationSource: Its value directs the reason for invoking the Lambda function. It can have following two values:

    • DialogCodeHook:  This value directs the Lambda function to initialize the validation of user's data input. If the intent is not clear, Amazon Lex can't invoke the Lambda function.
    • FulfillmentCodeHook: This value is set to fulfil the intent. If the intent is configured to invoke a Lambda function as a fulfilment code hook, Amazon Lex sets the invocationSource to this value only after it has all the slot data to fulfil the intent.
  • bot: Details of bot that processed the request. It consists of below information:

    • name:  name of the bot.
    • alias: alias of the bot version.
    • version: the version of the bot.
    • userId: Its value is defined by the client application. Amazon Lex passes it to the Lambda function.
    • outputDialogMode:  Its value depends on how you have configured your bot. Its value can be Text / Voice.
    • messageVersion: The version of the message that identifies the format of the event data going into the Lambda function and the expected format of the response from a Lambda function. In the current implementation, only message version 1.0 is supported. Therefore, the console assumes the default value of 1.0 and doesn't show the message version.
    • sessionAttributes:  Application-specific session attributes that the client sent in the request. It is optional.
       

2. context:

AWS Lambda uses this parameter to provide the runtime information of the Lambda function that is executing. Some useful information we can get from context object are:-

  • The time is remaining before AWS Lambda terminates the Lambda function.
  • The CloudWatch log stream associated with the Lambda function that is executing.
  • The AWS request ID returned to the client that invoked the Lambda function which can be used for any follow-up inquiry with AWS support.
     

Section 2:  Response Format

Amazon Lex expects a response from a Lambda function in the following format:

{
  sessionAttributes: {},
  dialogAction: {
   type: “ElicitIntent/ ElicitSlot/ ConfirmIntent/ Delegate/ Close”,

   <structure based on type>

 }
}

The response consists of two fields. The sessionAttributes field is optional, the dialogAction field is required. The contents of the dialogAction field depends on the value of the type field.

  • sessionAttributes: This is an optional field, it can be empty. If the function has to send something back to the client it should be passed under sessionAttributes. We will see its use-case in Section-4.
  • dialogAction (Required): Type of this field defines the next course of action. There are five types of dialogAction explained below:-

1) Close: Informs Amazon Lex not to expect a response from the user. This is the case when all slots get filled. If you don't specify a message, Amazon Lex uses the goodbye message or the follow-up message configured for the intent.

dialogAction: {
   type: “Close”,

   fulfillmentState: "Fulfilled/ Failed", // (required)
   message: { // (optional)
     contentType: "PlainText or SSML",
     content: "Message to convey to the user"
   }
 }

2) ConfirmIntent: Informs Amazon Lex that the user is expected to give a yes or no answer to confirm or deny the current intent. The slots field must contain an entry for each of the slots configured for the specified intent. If the value of a slot is unknown, you must set it to null. The message and responseCard fields are optional.

dialogAction: {
   type: “ConfirmIntent”,
   intentName: "orderBook",
   slots: {
     bookName: "value",
     bookType: "value",
   }
   message: { // (optional)
     contentType: "PlainText or SSML",
     content: "Message to convey to the user"
   }
 }

3) Delegate:  Directs Amazon Lex to choose the next course of action based on the bot configuration. The response must include any session attributes, and the slots field must include all of the slots specified for the requested intent. If the value of the field is unknown, you must set it to null. You will get a DependencyFailedException exception if your fulfilment function returns the Delegate dialog action without removing any slots.

dialogAction: {
   type: “Delegate”,
   slots: {
     slot1: "value",
     slot2: "value"
   }
 }


4) ElicitIntent: Informs Amazon Lex that the user is expected to respond with an utterance that includes an intent. For example, "I want a buy a book" which indicates the OrderBook intent. The utterance "book," on the other hand, is not sufficient for Amazon Lex to infer the user's intent

dialogAction: {
   type: “ElicitIntent”,

   message: { // (optional)
     contentType: "PlainText or SSML",
     content: "Message to convey to the user"
   }
 }


5) ElicitSlot:  Informs Amazon Lex that the user is expected to provide a slot value in the response. In below structure, we are informing Amazon lex that user response should provide value for the slot named ‘bookName’.

dialogAction: {
   type: “ElicitSlot”,
   intentName: "orderBook",
   slots: {
     bookName: "",
     bookType: "fiction",
   },

   slotToElicit: "bookName",
   message: { // (optional)
     contentType: "PlainText or SSML",
     content: "Message to convey to the user"
   }
}


Section 3:  Managing Conversation Context

Conversation context is the information that a user, your application, or a Lambda function provides to an Amazon Lex bot to fulfill an intent. Conversation context includes slot data that the user provides, request attributes set by the client application, and session attributes that the client application and Lambda functions create.

1. Setting session timeout

Session timeout is the length of time that a conversation session lasts. For in-progress conversations, Amazon Lex retains the context information, slot data, and session attributes till the session ends. Default session duration is 5 minutes but it can be changed upto 24 hrs while creating the bot in Amazon Lex console.


2.Setting session attributes

Session attributes contain application-specific information that is passed between a bot and a client application during a session. Amazon Lex passes session attributes to all Lambda functions configured for a bot. If a Lambda function adds or updates session attributes, Amazon Lex passes the new information back to the client application.

Session attributes persist for the duration of the session. Amazon Lex stores them in an encrypted data store until the session ends.


3. Sharing information between intents

If you have created a bot with more than one intent, information can be shared between them using session attributes. Attributes defined while fulfilling an intent can be used in other defined intent.

For example, a user of the book ordering bot starts by ordering books. the bot engages in a conversation with the user, gathering slot data, such as book name, and quantity. When the user places an order, the Lambda function that fulfils the order sets the lastConfirmedReservation session attribute containing information regarding ordered book and currentReservationPrice containing the price of the book. So, when the user has fulfilled the intent orderMagazine, the final price will be calculated on the bases of currentReservationPrice.

lastConfirmedReservation session attribute containing information regarding ordered book and currentReservationPrice containing the price of the book. So, when the user also fulfilled the intent orderMagazine, the final price will be calculated on the basis of currentReservationPrice.


Section 4:  Example

The details of example Bot are below:

Bot Name: PurchaseBot

Intents :

  • orderBook - bookName, bookType
  • orderMagazine - magazineName, issueMonth

Session attributes set while fulfilling the intent “orderBook” are:

  1. lastConfirmedReservation: In this variable, we are storing slot values corresponding to intent orderBook.
  2. currentReservationPrice: Book price is calculated and stored in this variable

When intent orderBook gets fulfilled we will ask the user if he also wants to order a magazine. If the user responds with a confirmation bot will start fulfilling the intent “orderMagazine”.

blog-image-chat.jpg

Conclusion

AWS Lambda functions are used as code hooks for your  Amazon Lex bot. You can identify Lambda functions to perform initialization and validation, fulfilment, or both in your intent configuration. This blog bought more technical insight of how Amazon Lex works and how it communicates with Lambda functions. This blog explains how a conversation context is maintained using the session attributes. I hope you find the information useful.


priyanka.jpg

Priyanka is an experienced software engineer with expertise in machine learning and data analysis. In the past, she worked on image classification & recognition software across domains like fingerprint analysis & geospatial analytics. Currently, she is developing intelligent chatbots with voice and text interfaces and is excited about the prospects of intelligent interfaces for B2B ISVs.