Chapter 14
Amazon Lex

WHAT'S IN THIS CHAPTER

  • Introduction to the Amazon Lex service
  • Use the Amazon Lex management console to create a chatbot
  • Use the Amazon Lex management console to test a chatbot
  • Create Amazon DynamoDB tables and AWS Lambda functions to support the chatbot

Amazon Lex is a fully managed web service that allows you to create conversation interfaces that can support both voice and text. Using Amazon Lex you can leverage the power of the conversational engine that is used by Amazon Alexa to create chatbots in your own applications.

You can integrate your chatbot into mobile applications using the AWS Mobile SDK, with web applications using the AWS JavaScript SDK, and into common messaging platforms such as Facebook Messenger, Slack, and Twilio. You do not need to worry about provisioning and maintaining infrastructure to support your chatbot.

Key Concepts

In this section you learn some of the key concepts you will encounter while working with Amazon Lex.

Bot

A bot (also known as a chatbot) is a program that can accept natural-language input and is designed to simulate human conversation. Chatbots are generally accessed over the internet and used to provide some kind of commercial service to customers, such as order fulfillment, technical support, etc. Used properly, chatbots can support conversational interfaces within desktop, mobile, and web applications and can cut the cost of maintaining a large team of support personnel in a call center. Chatbots also incorporate an element of NLP to understand the input provided by a customer and work out what action to take. In order for chatbots to provide business services, they are usually integrated with a variety of business back-end systems such as order processing, customer management, etc.

Client Application

Amazon Lex chatbots are server-side applications that expose their functionality using REST APIs. While these APIs can work with both text and voice, Amazon Lex does not include a front-end interface. The front-end user interface is something that the customer directly interacts with, and in the case of text-only chatbots it looks like a chat window where the customer can type something. You can either create your own desktop, web, or mobile client application and integrate with the Amazon Lex chatbot via an API, or use an existing messaging platform such as Slack, Facebook Messenger, or Twilio to act as the front-end interface for your Amazon Lex chatbot.

Intent

An intent is an object that represents an action that a user of your chatbot can perform. When creating an intent, you provide the following information:

  • A descriptive intent name.
  • A set of sample phrases that a customer can use to invoke the functionality provided by the intent.
  • One or more optional placeholders for the customer to provide inputs. This would depend on the functionality encapsulated within the intent. For example, an intent that allows a customer to order shoes will require the customer to provide information such as shoe size, color, and material.
  • A mechanism by which Amazon Lex can fulfill the customer's request. The recommended fulfillment mechanism is an AWS Lambda function; however, you can configure the chatbot to return a JSON object to the front-end application so that the client can handle the fulfillment of the customer's request through other means.

An Amazon Lex chatbot can support multiple intents. The intent selected by the chatbot will depend on a phrase typed or spoken by the user. For example, a chatbot that allows a customer to order a new pair of shoes and track the status of an order could have two intents. The first intent could handle the scenario where the customer wants to order a new pair of shoes and could be invoked when the customer types (or speaks) a phrase similar to “Hi, I would like to order a pair of shoes.” The second intent could handle order tracking and could be invoked when the customer types a question similar to “Where is my order?”

Slot

A slot is a parameter within an intent that the customer must provide a value for. For instance, an intent that allows a customer to order a pair of shoes could require the user to provide a number of parameters such as the color, size, and material. Since chatbots aim to provide conversational interfaces, they need to be fairly robust to minor input variations. These variations could arise from a number of factors, including typographical errors and use of synonyms. For example, a chatbot that asks the customer to specify a date should be able to handle a range of values including words like today, tomorrow, and next Friday, and date formats in different locales. In order to build this kind of robustness, Amazon Lex requires that each slot is assigned a slot type.

A slot type is conceptually similar to an enumerated data type, except that Amazon Lex uses the list of enumerated values that the slot type can accept to train a machine learning model that provides the robustness needed to handle subtle variances. There are two kinds of slot types:

  • Built-in slot types: Amazon Lex supports some of the built-in slot types from the Amazon Alexa Skills kit as well as additional slot types that are not included in the Amazon Alexa Skills kit. These built-in slot types can handle common inputs like email addresses, date, time, and location. You can find more information on built-in slot types at https://docs.aws.amazon.com/lex/latest/dg/howitworks-builtins-slots.html.
  • Custom slot types: A custom slot type is an enumeration that you define. For each element of the enumeration, you can also define a number of synonyms. Custom slot types also let you define how Amazon Lex should resolve the values provided by the customer. You can choose to configure the slot type to accept the user's input only if the value is an exact match with one of the enumerated values or synonyms. When configured in this manner, the output of the user-input resolution process will be a single value.

Alternatively, you can configure a slot type to accept free-form input and then resolve it to the closest matching element of the enumeration or synonym. When configured in this manner, a machine learning model is used to assist with the matching process and the user input will be used to continuously train the machine learning model so that it performs better over time. The output of the resolution process in this case is a list of possible enumeration values, each with a probability value.

Utterance

An utterance is a phrase associated with an intent. When a user of your chatbot types (or speaks) that phrase, Amazon Lex will initialize the intent that is preconfigured to handle the phrase. When you create intents, you specify a list of utterances. Amazon Lex uses the list of utterances to train a machine learning model that is used to resolve similar phrases. This approach provides a layer of robustness so that your users do not have to type the same phrases word for word that the bot developer defined while building the chatbot.

Programming Model

Amazon Lex provides two sets of APIs: the model-building API and the runtime API. The model-building API can be used to create, build, and deploy a chatbot application on the AWS cloud. The Amazon Lex runtime API can be used to interact with a chatbot that is deployed.

Amazon Lex also provides a web-based management console that can be used to create, deploy, and test chatbots. The web-based management console includes an embedded test harness, which appears like a chat window and can be used as a test client for the chatbot. Behind the scenes, the web-based management console uses the model-building and runtime APIs. To integrate a chatbot with a client application, you are unlikely to use the runtime APIs directly; instead, you will use one of the AWS SDKs for the programming language of your choice. The AWS SDK will then use the Amazon Lex runtime API to interact with your server-side chatbot.

Inputs and outputs to the Amazon Lex APIs are JSON objects. The web-based management console provides tools to inspect the underlying API calls to the chatbot generated by the embedded test harness.

Each intent in the chatbot can have an AWS Lambda function that can be used for initialization, slot validation, and fulfillment. Fulfillment need not be handled by an AWS Lambda function; you can configure your chatbot to return to the client a JSON object that contains all the relevant details needed to fulfill the intent. You can learn more about the Amazon Lex model-building and runtime API operations at https://docs.aws.amazon.com/lex/latest/dg/programming-model.html.

Pricing and Availability

Amazon Lex is available on a pay-per-use model. You will be charged based on the number of text or voice requests processed by your bots at the end of each month. This service is not included in the AWS free-tier account; however, you can try Amazon Lex free for a year as long as you process fewer than 10,000 text requests and 5,000 speech requests in a month. You can get more details on the pricing model at https://aws.amazon.com/lex/pricing/.

Amazon Lex is not available in all regions. You can get information on the regions in which it is available at https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/.

Creating an Amazon Lex Bot

In this section you will use the Amazon Lex management console to create a bot called ACMEBankBot, which can be used by customers of a fictional bank called ACMEBank to perform simple account operations through a conversational interface. The bot will be text-only, and support the following customer actions through the use of intents:

  • Account overview: Returns a JSON object that contains information on the accounts held by the customer and the balance in each account. The customer will be asked to provide a four-digit numeric customer identifier, which will be used by the bot to retrieve a list of accounts for the customer from a database.
  • View recent transactions: Returns a JSON object that contains information on five recent transactions in an account. The customer will be asked to provide a customer identifier and an account identifier, which will be used by the bot to retrieve a list of transactions in the account from a database.

The data for the customers and accounts of the fictional bank will be held in DynamoDB tables, which will also be created in this section. We will start by creating the DynamoDB tables that hold account and transactional data, followed by AWS Lambda functions that will be used by the two intents listed above. With the DynamoDB tables and AWS Lambda functions in place, you will then proceed to build, deploy, and test the chatbot using the web-based management console.

Creating Amazon DynamoDB Tables

Log in to the AWS management console using the dedicated sign-in link for your development IAM user account. Use the region selector to select a region where both the Amazon DynamoDB service and Amazon Lex are available. Click the Services menu and access the Amazon DynamoDB service home page (Figure 14.1).

Screenshot of accessing the Amazon DynamoDB service home page.

FIGURE 14.1 Accessing the Amazon DynamoDB service home page

The screenshots in this section assume that the console is connected to the EU (Ireland) region. If you have never used DynamoDB, you will be presented with the splash screen (Figure 14.2).

Screenshot of Amazon DynamoDB splash screen.

FIGURE 14.2 Amazon DynamoDB splash screen

If you have used DynamoDB in the past, you will arrive at the DynamoDB dashboard (Figure 14.3).

Screenshot of Amazon DynamoDB dashboard.

FIGURE 14.3 Amazon DynamoDB dashboard

Regardless of which screen you arrive at, click the Create Table button to get started with creating a DynamoDB table. On the Create DynamoDB Table screen (Figure 14.4), name the new table ACMEBankAccount and specify the name of the partition key attribute to be a string called CustomerIdentifier, and the sort key attribute to be a string called AccountIdentifier.

Screenshot of specifying the table name, partition key, and sort key.

FIGURE 14.4 Specifying the table name, partition key, and sort key

Uncheck the Use Default Settings check box and scroll down to the bottom of the page to locate the Provisioned Capacity section. Disable auto scaling and change the number of read and write units to 1 each (Figure 14.5).

Screenshot of changing the provisioned I/O capacity,

FIGURE 14.5 Changing the provisioned I/O capacity

Click the Create button to create the table. The table takes a few minutes to form. Once it is created, your screen should resemble Figure 14.6.

Screenshot of Amazon DynamoDB table overview.

FIGURE 14.6 Amazon DynamoDB table overview

Follow the same steps to create another table with the following settings (see Figure 14.7):

Screenshot of settings for the ACMEAccountTransaction table.

FIGURE 14.7 Settings for the ACMEAccountTransaction table

  • Table Name: ACMEAccountTransaction
  • Partition Key: AccountIdentifier
  • SortKey: TransactionIdentifier

Ensure you uncheck the Use Default Settings check box, and scroll down to the bottom of the page to disable auto scaling and change the number of read and write units to 1 each.

Create another table with the following settings:

  • Table Name: ACMEBankCustomer
  • Partition Key: CustomerIdentifier

After creating the ACMEBankCustomer, ACMEBankAccount, and ACMEAccountTransaction tables, your Amazon DynamoDB dashboard should list all three tables (see Figure 14.8).

Screenshot of Amazon DynamoDB table overview.

FIGURE 14.8 Amazon DynamoDB table overview

Now that you have created the tables, in order for the bot to function correctly, the tables will need some data. The ACMEBankCustomer table will hold details on the bank's customers, and for the purposes of this chatbot, a couple of customer records in this table will be sufficient. Click on the ACMEBankCustomer table in the Amazon DynamoDB dashboard, switch to the Items tab, and click the Create Item button (Figure 14.9).

Screenshot of creating a new item in the ACMEBankCustomer table.

FIGURE 14.9 Creating a new item in the ACMEBankCustomer table

You will be presented with a dialog box that lets you specify the attributes for the new item. Create an item using the following information:

  • CustomerIdentifier: 1000
  • FirstName: John
  • LastName: Woods

Create a second item using the following information:

  • CustomerIdentifier: 2000
  • FirstName: Sonam
  • LastName: Mishra

After creating the two items, your screen should resemble Figure 14.10.

Screenshot of ACMEBankCustomer table with two items.

FIGURE 14.10 ACMEBankCustomer table with two items

After creating a couple of customer records in the ACMEBankCustomer table, you need to create accounts for these customers. Account data will be held in the ACMEBankAccount table, so for the purposes of this chatbot, add five entries to the ACMEBankAccount table using the information in Table 14.1.

TABLE 14.1: ACMEBankAccount Table Items

CUSTOMERIDENTIFIER ACCOUNTIDENTIFIER ACCOUNTTYPE ACCOUNTBALANCE
1000 1001 Saving 5000
1000 1002 Current 10000
2000 2001 Saving 50000
2000 2002 HighInterestSaver 275000
2000 2003 Current 10000

These entries ensure that two accounts belong to the customer with identifier 1000, and three accounts to the customer with identifier 2000. The customer identifier can be used with the ACMEBankCustomer table you created earlier to obtain the name of customer. After creating these five entries in the ACMEBankAccount table, your screen should resemble Figure 14.11.

Screenshot of ACMEBankAccount table with five items.

FIGURE 14.11 ACMEBankAccount table with five items

After creating five accounts in the ACMEBankAccount table, you need to create a few transactions in these accounts. Add items to the ACMEAccountTransaction table using the information in Table 14.2.

TABLE 14.2: ACMEAccountTransaction Table Items

ACCOUNTIDENTIFIER TRANSACTIONIDENTIFIER DATE TYPE AMOUNT
1001 1 02.28.2019 CR 5500
1001 2 03.01.2019 CW 200
1001 3 03.01.2019 TFR 300
1002 1 02.28.2019 CR 10000
2001 1 02.28.2019 CR 52000
2001 2 03.06.2019 TFR 2000
2002 1 02.28.2019 CR 275000
2003 1 02.28.2019 CR 10000

The ACMEAccountTransaction table contains details of all transactions across all accounts. Each transaction has the following attributes:

  • AccountIdentifier: Identifies an account held by the customer.
  • TransactionIdentifier: Uniquely identifies a given transaction.
  • Date: The date of the transaction in mm.dd.yyyy format. For simplicity this table does not store the time of the transaction.
  • Type: The type of transaction. For simplicity, this attribute will only have one of three possible values: CR – Credit, CW – Cash Withdrawal, TFR – Account Transfer.
  • Amount: The amount of the transaction.

With these changes in place, you have built the table structure needed to store data on ACMEBank's customers, accounts, and transactions. You have also loaded these tables with some data. The chatbot that is built later in this chapter will use AWS Lambda functions to access the data you have loaded into these tables.

Creating AWS Lambda Functions

In this section you will create two AWS Lambda functions, which will be used by the chatbot. The chatbot will consist of two intents. While creating an intent, Amazon Lex allows you to specify a validation function and a fulfillment function. The validation function is used to validate the input provided by the user; the fulfillment function is called by the chatbot to fulfill the intent. While it is possible to use separate AWS Lambda functions for validation and fulfillment, the approach taken in this chapter is to use the same function for both validation and fulfillment—which is why you will make only two functions and not four.

To better understand the how AWS Lambda functions are used with chatbot intents, consider the example of a chatbot that helps a customer order a pizza. Such a chatbot may include an intent called OrderPizza that will be invoked when a user types (or speaks) a phrase similar to “I want to order a pizza.” The intent will then ask the user for the toppings, type of crust, and the size of the pizza. The first time the validation function is invoked is when the intent is loaded. The validation function is subsequently invoked each time the user provides information for one of the intent's slots. Once the customer provides values for all the slots, the fulfillment function will be invoked to place the order with the local pizza store.

The AWS Lambda functions that will be created in this section are briefly described here:

  • ACMEBankBotAccountOverview: Used to validate the four-character numeric customer identifier slot and retrieve information on the accounts held by the customer.
  • ACMEBankBotTransactionList: Used to validate the four-character numeric customer identifier slot and the four-character numeric account identifier slot, and retrieve a list of transactions from the specified account.

CREATING THE ACMEBankBotAccountOverview AWS LAMBDA FUNCTION

Click the Services menu and access the AWS Lambda service home page. Ensure the management console is configured to use the same region in which your Amazon DynamoDB tables have been created. Click the Create Function button to start the process of creating a new AWS Lambda function. If you are new to AWS Lambda, or would like to refresh your knowledge, refer to Chapter 12 before continuing with the rest of this section.

After clicking the Create Function button, you will be asked to select a template for the function (Figure 14.12). Select the Author From Scratch option.

Screenshot of creating an AWS Lambda function from scratch.

FIGURE 14.12 Creating an AWS Lambda function from scratch

Name the function ACMEBankBotAccountOverview, use the Runtime drop-down to select the Python 3.6 runtime, and select the Create A New Role With Basic Lambda Permissions option in the Execution Role drop-down (Figure 14.13).

Screenshot of Lambda function name and runtime settings.

FIGURE 14.13 Lambda function name and runtime settings

AWS will create a new IAM role for your function with a minimal set of permissions that will allow your function to write logs to AWS CloudWatch. The name of this IAM role is displayed below the Execution Role drop-down in Figure 14.13 and will be similar to ACMEBankBotAccountOverview-role-xxxxx. Make a note of this name as you will need to modify the role to allow access to Amazon DynamoDB. Click the Create Function button at the bottom of the page to create the AWS Lambda function and the IAM role.

After the AWS Lambda function is created, use the Services menu to switch to the IAM management console and navigate to the new IAM role that was just created for you when you created the Lambda function. Locate the permissions policy document associated with the role and click the Edit Policy button (Figure 14.14).

Screenshot of viewing the default policy document associated with the IAM role created by AWS Lambda.

FIGURE 14.14 Viewing the default policy document associated with the IAM role created by AWS Lambda

You will be taken to the policy editor screen. Click the JSON tab to view the policy document as a JSON file (Figure 14.15).

Screenshot of updating the default policy document associated with the IAM role created by AWS Lambda.

FIGURE 14.15 Updating the default policy document associated with the IAM role created by AWS Lambda

Add the following object to the Statement array:

       {
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "*"
        },

Your final policy document should resemble this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:eu-west-1:xxxxx:log-group:/aws/lambda/ACMEBankBotAccountOverview:*"
        },
        {
            "Effect": "Allow",
            "Action": "dynamodb:*",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:eu-west-1:xxxx:*"
        }
    ]
}

This policy document allows AWS Lambda to write logs to CloudWatch, and perform any action on any Amazon DynamoDB table. Click the Review Policy button at the bottom of the page to go to the Review Policy screen (Figure 14.16).

Screenshot of Review Policy screen.

FIGURE 14.16 Review Policy screen

Click the Save Changes button to finish updating the IAM policy. After the policy changes have been saved, use the Services menu to switch back to the AWS Lambda management console and navigate to the ACMEBotAccountOverview Lambda function (Figure 14.17). The function designer section of the page should now list both Amazon CloudWatch Logs and Amazon DynamoDB as the resources that can be accessed by the function.

Screenshot of AWS Lambda function designer.

FIGURE 14.17 AWS Lambda function designer

The Lambda function you have created will not do much at this point, as you have not specified the code for the body of the function nor the triggers that should be associated with the function. Scroll down to the function code editor and replace the boilerplate code in the code editor with the contents of Listing 14.1.

Click the Save button at the top-right corner of the screen to save your code changes.

To understand the code in Listing 14.1, you need to consider the sequence of events between Amazon Lex and AWS Lambda. This function will be invoked at different times during the course of a customer's interaction with a front-end chat client application, which will in turn use one of the Amazon Lex runtime APIs to communicate with the chatbot. The first time this function will be invoked is when the AccountOverview intent is initialized. Initialization occurs when a customer types an utterance that the chatbot is able to match to the AccountOverview intent. At the point of initialization, the customer has not yet been asked to provide the value of the CustomerIdentifier slot. The input event to the AWS Lambda function resembles the following:

{
    'messageVersion': '1.0',
    'invocationSource': 'DialogCodeHook',
    'userId': '32p0rg8zzgoqhABCDEFG',
    'sessionAttributes': {},
    'requestAttributes': None,
    'bot': {
        'name': 'ACMEBankBot',
        'alias': '$LATEST',
        'version': '$LATEST'
    },
    'outputDialogMode': 'Text',
    'currentIntent': {
        'name': 'AccountOverview',
        'slots': {
            'CustomerIdentifier': None
        },
        'slotDetails': {
            'CustomerIdentifier': {
                'resolutions': [],
                'originalValue': None
            }
        },
        'confirmationStatus': 'None',
        'sourceLexNLUIntentInterpretation': None
    },
    'inputTranscript': 'view accounts'
}

You can find the complete specification for this event at https://docs.aws.amazon.com/lex/latest/dg/lambda-input-response-format.html. For this discussion, the important fields are:

  • invocationSource: The value DialogCodeHook implies that this function is being used for initialization and validation (and not fulfilment).
  • bot: Contains information on the bot that created the event.
  • currentIntent: Contains information on the intent within the bot that created this event. The slots object contains a list of slots and their current values. Note that the value of the CustomerIdentifier slot is None.
  • inputTranscript: Contains the text typed by the customer in the chat client window.

The code in the lambda_handler() method of the AWS Lambda function starts by extracting the name of the bot and the name of the current intent, and ensuring they are what the function expects:

# name of the bot that is executing this function
    bot_name = event['bot']['name']
 
    # name of the intent that has executed this function.
    intent_name = event['currentIntent']['name']
 
    # ensure this lambda function is not being called by
    # the wrong bot/intent.
    if bot_name != 'ACMEBankBot':
        raise Exception('This function can only be used with the ACMEBankBot')
 
    if intent_name != 'AccountOverview':
        raise Exception('This function can only be used with the AccountOverview intent')

This is followed by extracting the current value of the CustomerIdentifier slot and the invocation source:

# get CustomerIdentifier slot
    intent_slots = event['currentIntent']['slots']
    customer_identifier = intent_slots["CustomerIdentifier"]
 
    # is this function being executed for validation or fulfillment?
    invocation_source = event['invocationSource']

Since the value of invocation_source is going to contain the string DialogCodeHook, which implies that the function is being used for initialization and slot validation, the function inspects the current value of the CustomerIdentifier slot. It the value is None, it implies that the slot does not contain a valid value, and the function sends a response that will result in the chatbot asking the user to provide a value for the slot. This is handled in lines 119 to 130, which contain the following code:

# initialization and validation
    if invocation_source == 'DialogCodeHook':
 
        # If the user has not provided a value for the
        # CustomerIdentifier slot, then return a response
        # that will result in the chatbot asking the user
        # to provide a value for the slot.
        if customer_identifier is None:
            return elicit_slot('CustomerIdentifier',
                                session_attributes,
                                intent_name,
                                intent_slots)

The elicit_slot function is defined elsewhere in the code. It constructs the following JSON response object and sends it to the chatbot:

{
    'sessionAttributes': {},
    'dialogAction': {
        'type': 'ElicitSlot',
        'intentName': 'AccountOverview',
        'slots': {
             'CustomerIdentifier': None
        },
        'slotToElicit': 'CustomerIdentifier'
    }
}

The chatbot reads the dialogAction object and determines that the AWS Lambda function is asking it to elicit the value of the CustomerIdentifier slot. The chatbot generates the following JSON object and sends it to the client application:

{
  "dialogState": "ElicitSlot",
  "intentName": "AccountOverview",
  "message": "What is your 4 digit customer number?",
  "messageFormat": "PlainText",
  "responseCard": null,
  "sessionAttributes": {},
  "slotToElicit": "CustomerIdentifier",
  "slots": {
    "CustomerIdentifier": null
  }
}
 

Recall that the chatbot is a server-side API component, and the customer uses a client application (such as a chat window in a web page) to interact with the chatbot with presentation logic residing solely in the domain of the front-end client application. The client application interprets this response from the chatbot and asks the customer to provide a value for the CustomerIdentifier slot.

When the customer types a value, the client application uses one of the Amazon Lex runtime API methods to submit the value typed by the user. The chatbot executes the AWS Lambda function a second time; this time the input event object is slightly different:

{
    'messageVersion': '1.0',
    'invocationSource': 'DialogCodeHook',
    'userId': 'zqw0yk3qeiw,
    'sessionAttributes': {},
    'requestAttributes': None,
    'bot': {
        'name': 'ACMEBankBot',
        'alias': '$LATEST',
        'version': '$LATEST'
    },
    'outputDialogMode': 'Text',
    'currentIntent': {
        'name': 'AccountOverview',
        'slots': {
            'CustomerIdentifier': '1000'
        },
        'slotDetails': {
            'CustomerIdentifier': {
                'resolutions': [],
                'originalValue': '1000'
            }
        },
        'confirmationStatus': 'None',
        'sourceLexNLUIntentInterpretation': None
    },
    'inputTranscript': '1000'
}

The key difference to point out in this event is that the value of the CustomerIdentifier slot is not None anymore; it is 1000—which is the value the customer typed into the chat window. The code path through the AWS Lambda function will be similar to the path taken during the first invocation, except that the slot now has a value, and therefore the following snippet will be executed to validate the value provided by the customer:

# validate CustomerIdentifier slot.
        # if it is invalid, then ask the customer to
        # provide a value.
        if not validate_customer_identifier(customer_identifier):
 
            # set the invalid intent slot to None so that
            # the chatbot knows that the slot does not have
            # a value.
            intent_slots['CustomerIdentifier'] = None
 
            return defer_next_action_to_chatbot(session_attributes,
                                intent_slots)

The validate_customer_identifier() function is defined elsewhere in the code. It returns True if the value provided in the CustomerIdentifier slot corresponds to a value in the CustomerIdentifier column of the ACMEBankCustomer table. The code for the validate_customer_identifier() function is reproduced here:

# this function returns True if the specified customer_identifier
# exists in the ACMEBankCustomer table.
def validate_customer_identifier(customer_identifier):
 
    customer_table = dynamodb_resource.Table('ACMEBankCustomer')
 
    dynamodb_response = customer_table.query(
        KeyConditionExpression = Key('CustomerIdentifier').eq(customer_identifier)
    )
 
    if dynamodb_response['Count'] == 0:
        return False
 
    return True

If the validate_customer_identifier() function returns True, the AWS Lambda function will retrieve a list of accounts held by the customer, format the results into a string, and return the string back to the chatbot as an attribute in a JSON object:

# read a list of accounts for the customer
# from DynamoDB table ACMEBankAccounts and
# return a JSON object with account details.
 
account_overview = get_account_overview(customer_identifier)
 
return {
    'sessionAttributes': session_attributes,
    'dialogAction': {
        'type': 'Close',
        'fulfillmentState' : 'Fulfilled',
        'message': {
            'contentType': 'PlainText',
            'content': account_overview
        }
    }
}

The response received by the client application in this case would resemble the following:

{
    "dialogState": "Fulfilled",
    "intentName": "AccountOverview",
    "message": "The balance in account number 1001 is £5000, The balance in account number 1002 is £10000. Is there anything else I can help you with?",
    "messageFormat": "PlainText",
    "responseCard": null,
    "sessionAttributes": {},
    "slotToElicit": null,
    "slots": {
        "CustomerIdentifier": "1000"
    }
}

Note that the dialogState variable in the JSON object sent to the client has the value of Fulfilled, which indicates that the AWS Lambda function has fulfilled the user's request. You could, if you wanted, send a JSON object in the message attribute, instead of a string. Your chat client would need to be able to handle the JSON object and perhaps render the information in a table within the chat window. For the purposes of the chatbot being built in this chapter, which is to be tested using the client provided by the AWS Lex management console, a formatted string message is sufficient.

CREATING THE ACMEBankBotTransactionList AWS LAMBDA FUNCTION

Navigate to the AWS Lambda dashboard and click the Create Function button to start the process of creating a new AWS Lambda function. When prompted to select a template for the function, select the Author From Scratch option and use the following options:

  • Name: ACMEBankBotTransactionList
  • Runtime: Python 3.6
  • Role: Choose an existing role.
  • Existing Role: Choose the role created earlier in this chapter.

Click the Create Function button to create the function. After the function is created, you will be taken to the Lambda function configuration page.

Locate the function designer section of the page and click the function name to reveal the code editor. Replace the boilerplate code in the code editor with the contents of Listing 14.2.

Click the Save button below the function editor to finish creating your Lambda function. This function operates in a similar manner to the one presented in Listing 14.1; hence it will not be discussed here in detail.

Now that you have created the Amazon DynamoDB tables and AWS Lambda functions, you can create the Amazon Lex chatbot in the next section. You may be wondering why the AWS Lambda functions were created before the chatbot. The reason is that while creating the chatbot, the Amazon Lex management console does not let you create AWS Lambda functions inline.

Creating the Chatbot

In this section, you will use the Amazon Lex management console to create a chatbot. Keep in mind that the management console makes use of the Amazon Lex model-building APIs to interact with the Amazon Lex service, and you can directly use the model-building APIs from the AWS CLI. To get started with creating the Amazon Lex chatbot, click the Services menu and access the Amazon Lex service home page (Figure 14.18).

Screenshot of accessing the Amazon Lex service home page.

FIGURE 14.18 Accessing the Amazon Lex service home page

If this is the first time you are using Amazon Lex, you will be greeted with the Amazon Lex service splash screen (Figure 14.19). Click the Get Started link on the Amazon Lex splash screen.

Screenshot of Amazon Lex service splash screen.

FIGURE 14.19 Amazon Lex service splash screen

If you have used Amazon Lex in the past, then you will arrive at the Amazon Lex dashboard (Figure 14.20). Click the Create button in the Bots section of the dashboard.

Screenshot of Amazon Lex dashboard.

FIGURE 14.20 Amazon Lex dashboard

You will arrive at the Create A Bot wizard, and will be asked to select whether you want to author the bot from scratch, or choose from one of the existing templates. Select the Custom Bot option to indicate you want to author the bot from scratch (Figure 14.21).

Screenshot of creating a custom bot.

FIGURE 14.21 Creating a custom bot

You will be asked to provide some basic information on the new bot. Select the following options on the screen and click the Create button at the bottom on the screen to proceed:

  • Bot name: ACMEBankBot
  • Output voice: None
  • Session timeout: 3 minutes
  • COPPA: No

You will be taken to the bot editor, where you can customize the bot (Figure 14.22).

Screenshot of Amazon Lex bot editor.

FIGURE 14.22 Amazon Lex bot editor

The bot that you have just created will not do anything useful as you have yet to create intents. You can think of an intent as something that a user will be able to achieve by using your bot (such as order a takeaway, purchase something, return something, etc.). The purpose of the chatbot being built in this chapter is to allow customers of a bank to get a summary of their accounts and view recent transactions. Therefore, the bot that is being built in this section will have two intents:

  • Account overview: Provides information on the accounts held by the customer and the balance in each account.
  • View recent transactions: Provides up to five recent transactions in an account.

Click the + button beside the intent section to begin creating the first intent, and click the Create Intent option in the pop-up dialog box that appears on the screen (Figure 14.23).

Screenshot of configuring the slots for your new intent.

FIGURE 14.23 Configuring the slots for your new intent.

You will be asked to provide a name for the intent. Type AccountOverview and click the Create button (Figure 14.24).

Screenshot of specifying the name of the new intent.

FIGURE 14.24 Specifying the name of the new intent

Repeat this process to create one more intent called ViewTransactionList. Once you have created both intents, your bot editor screen should resemble Figure 14.25.

Screenshot of Amazon Lex bot editor with two intents.

FIGURE 14.25 Amazon Lex bot editor with two intents

Customizing the AccountOverview Intent

Ensure the AccountOverview intent is selected in the list of intents in the bot editor and locate the Sample Utterances section (Figure 14.26) on the page. An utterance is a phrase that a user can type into your chatbot to invoke the associated intent. If the chatbot supports speech, then the user can speak the phrase. Amazon Lex uses the information you provide in the Sample Utterances section to train a machine learning model that is used to ensure that intent is robust enough to handle subtle variations of user input. The machine learning model ensures that the user can type (or speak) phrases very similar to the utterances you have configured and still invoke the correct intent. To ensure the machine learning model has sufficient training data, provide a number of sample utterances that you think could be mapped to the intent.

Screenshot of The Sample Utterances section of the bot editor.

FIGURE 14.26 The Sample Utterances section of the bot editor

The example in this section will associate six utterances with the AccountOverview intent. If you wish, you can associate additional utterances with the intent. Type the following phrases into the Sample Utterances text field and click the + button beside the text field after each phrase to create an utterance from the phrase:

  • View accounts
  • Account summary
  • Account list
  • I would like a summary of my accounts
  • I would like to view my accounts
  • Show me my accounts

After you have created these utterances, the bot editor screen should resemble Figure 14.27.

Screenshot of utterances associated with the AccountOverview intent.

FIGURE 14.27 Utterances associated with the AccountOverview intent

Expand the Lambda Initialization And Validation section of the bot editor screen and check select the Initialization And Validation Code Hook option. You will be presented with a drop-down list of available AWS Lambda functions in your account. Select the ACMEBankBotAccountOverview entry in the list (Figure 14.28).

Screenshot of specifying the validation function for the AccountOverview intent.

FIGURE 14.28 Specifying the validation function for the AccountOverview intent

The AccountOverview intent requires one input from the customer: a four-character numeric customer identifier, which will be used to by the bot to locate the customer's accounts in the ACMEBankAccount table. Intents use the concept of slots to solicit input from users. You can think of a slot as a user-input parameter that the intent needs to perform its function. A slot can have one or more prompts associated with it; these prompts are displayed (or spoken) by the chatbot when it wants to solicit a value for the slot. Associated with the slot is a data type, known as the as the slot type. There are two types of slot types: built-in and custom. For the purposes of the customer identifier slot, we can use a built-in slot type called AMAZON.FOUR_DIGIT_NUMBER.

Scroll down to the Slots section of the page and create a slot with the following settings:

  • Name: CustomerIdentifier
  • Slot type: AMAZON.FOUR_DIGIT_NUMBER
  • Prompt: What is your customer identifier?

Your screen should now resemble Figure 14.29, showing the new slot listed under the Slots section.

Screenshot of slots for the AccountOverview intent.

FIGURE 14.29 Slots for the AccountOverview intent

Click the gear icon beside the slot name to access the slot settings dialog box. Add an additional prompt “What is your 4-digit customer number?” to the list of prompts associated with this slot and change the number of retries to 3 (Figure 14.30). Click Save to update the slot settings.

Screenshot of CustomerIdentifier slot settings.

FIGURE 14.30 CustomerIdentifier slot settings

The prompt is a string that will be displayed (or spoken) to the user when your bot wants the user to provide a value for the slot. In this example, you have provided two prompts for the CustomerIdentifier slot type:

  • What is your customer identifier?
  • What is your 4-digit customer number?

When your bot needs the user to provide a value for the CustomerIdentifier slot, it will alternate between the two phrases. The maximum number of retries controls the number of additional attempts given to the customer to provide a valid value for the slot before the bot will hang up on the customer.

Scroll down the page to locate the Fulfillment section. Select the AWS Lambda Function option and select the ACMEBankBotAccountOverview entry in the list of available functions (Figure 14.31).

Screenshot of specifying the Fulfillment function for the AccountOverview intent.

FIGURE 14.31 Specifying the Fulfillment function for the AccountOverview intent

Scroll down to the bottom of the page and click the Save Intent button to save your changes.

Customizing the ViewTransactionList Intent

In the previous section you created and configured the AccountOverview intent. In this section you will follow a process similar to that discussed in the previous section and build the ViewTransactionList intent. Ensure the ViewTransactionList intent is selected in the list of intents in the bot editor and locate the Sample Utterances section on the page.

Create utterances out of the following phrases:

  • I want to view a list of transactions.
  • Show me the last few transactions.
  • Show me a list of recent transactions.
  • Recent account activity
  • Transaction list

Expand the Lambda Initialization And Validation section of the bot editor screen and check select the Initialization And Validation Code Hook option. Select the ACMEBankBotTransactionList entry in the list of available functions (Figure 14.32).

Screenshot of specifying the validation function for the ViewTransactionList intent.

FIGURE 14.32 Specifying the validation function for the ViewTransactionList intent

Scroll down to the Slots section of the page and create two slots as described in Table 14.3. Ensure the required attribute is selected for each slot.

TABLE 14.3: ViewTransactionList Intent Slots

NAME SLOT TYPE PROMPTS
CustomerIdentifier AMAZON.FOUR_DIGIT_NUMBER What is your customer identifier?
What is your 4-digit customer number?
AccountIdentifier AMAZON.FOUR_DIGIT_NUMBER What is your account number?
What is your 4-digit account number?

Scroll down the page to locate the Fulfillment section. Select the AWS Lambda Function option and select the ACMEBankBotTransactionList entry in the list of available functions. (Figure 14.33).

Screenshot of specifying the fulfillment function for the ViewTransactionList intent.

FIGURE 14.33 Specifying the fulfillment function for the ViewTransactionList intent

Scroll down to the bottom of the page and click the Save Intent button to save your changes.

Testing the Chatbot

Now that you have created the chatbot, it is time to test it out. You can test the chatbot in various ways, including the following:

  • Test it using the integrated chat client in the AWS Lex management console
  • Test it using Facebook Messenger, Slack, or Twilio
  • Test it using the AWS CLI
  • Test it from within your own desktop or mobile application

In this chapter, you will use the integrated chat client in the AWS Lex management console. You can find out more about integrating your chatbot with third-party messaging platforms at https://docs.aws.amazon.com/lex/latest/dg/example1.html

However, before you can test your chatbot using any of the aforementioned means, you need to build it. Building a chatbot is simply a matter of clicking the Build button at the top-right corner of the management console (Figure 14.34).

Screenshot of building the bot.

FIGURE 14.34 Building the bot

The build process can take a few minutes, after which you can test the chatbot by expanding the integrated chat client from the right-hand side of the screen and typing an utterance to invoke an intent. Figure 14.35 depicts a chat session where the AccountSummary intent was invoked to provide information on accounts held by a customer.

Screenshot of testing the bot with the integrated chat client.

FIGURE 14.35 Testing the bot with the integrated chat client

Notice how Amazon Lex was able to invoke the AccountSummary intent even though the phrase typed into the chat window is “Show me accounts,” which does not match any of the configured utterances exactly.

Summary

  • Amazon Lex is a fully managed web service that allows you to create conversation interfaces that can support both voice and text.
  • A bot (also known as a chatbot) is a program that can accept natural-language input and is designed to simulate human conversation.
  • You can integrate your chatbot into mobile applications using the AWS Mobile SDK, with web applications using the AWS JavaScript SDK, and into common messaging platforms such as Facebook Messenger, Slack, and Twilio.
  • Amazon Lex chatbots are server-side applications that expose their functionality using REST APIs. While these APIs can work with both text and voice, Amazon Lex does not include a front-end interface.
  • An intent is an object that represents an action that a user of your chatbot can perform.
  • A slot is a parameter within an intent that the customer must provide a value for.
  • A slot type is conceptually similar to an enumerated data type, except that Amazon Lex uses the list of enumerated values that the slot type can accept to train a machine learning model that provides the robustness needed to handle subtle variances.
  • An utterance is a phrase associated with an intent. When a user of your chatbot types (or speaks) that phrase, Amazon Lex will initialize the intent that is preconfigured to handle the phrase.
  • Amazon Lex provides two sets of APIs: the model-building API and the runtime API.
  • The model-building API can be used to create, build, and deploy a chatbot application on the AWS cloud.
  • The Amazon Lex runtime API can be used to interact with a chatbot that is deployed.
  • Amazon Lex also provides a web-based management console that can be used to create, deploy, and test chatbots.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.77.180