亚马逊AWS官方博客

借助 Microsoft Excel 构建 Amazon Lex 聊天机器人

本文是 AWS 社区大咖 Cyrus Wong 所写的一篇客座文章。

我们的香港机构 (IVE) 已开始尝试将 Amazon Lex 应用于教学、研究和医疗保健领域。我们有很多非技术员工,如 IVE 的英语教师,以及 IVE 育儿、长者及社区服务处的治疗师;他们没有技术知识,不会在 Amazon Lex 控制台中构建自然语言对话自动程序 (聊天自动程序)。我们完成了几个为非技术用户构建 Amazon Lex 聊天自动程序的试点项目。非技术用户将问题填入 Excel 电子表格,然后由开发人员将他们的问题复制到 Amazon Lex 控制台中。当用户想要更改聊天自动程序中的内容时,开发人员都必须重复同样的复制和粘贴过程。

后来,我们想:为什么不直接用 Excel 构建聊天自动程序,停止这种反复的复制和粘贴工作呢?

我们的员工都会使用 Microsoft Excel,因此,我们决定创建一个名为“ExcelLexBot”的项目,使他们借助极少的编程技能就可以使用 Excel 创建聊天自动程序。

ExcelLexBot 是一款无服务器应用程序,可以将预定义格式的 Excel 文件 (xlsx) 转换为 Amazon Lex 聊天自动程序所需的格式。我们开发的 ExcelLexBot 可应用在很多方面,不仅可以快速创建,而且所需的开发技能也极少。像我这样的老师也可以使用 ExcelLexBot 创建交互式对话测试和作业。学生可以使用它将聊天自动程序功能添加到他们的期末项目中,并可以快速完成这一操作:参加云及数据中心管理高级文凭课程的 80 名学生在一个小时内创建了 80 个聊天自动程序。

在本文中,我将说明 ExcelLexBot 的工作原理,以及部署和使用方式。

Amazon Lex 概念

Amazon Lex 是一种供开发人员在应用程序中构建语音和文字对话接口的服务。借助 Amazon Lex,支持 Amazon Alexa 的深度学习技术现在可供所有开发人员使用,因此您能够快速轻松地构建出成熟的聊天自动程序。

Amazon Lex 聊天自动程序由三类组件构成:

  1. 自动程序 – 自动程序包括对话的所有组件。
  2. 意图 – 意图表示自动程序用户想完成的操作 (安排约会、订购鲜花等)。
  3. 槽类型 – 槽类型定义槽中数据的识别和处理方式。Amazon Lex 支持 Alexa Skills Kit 的内置槽类型。您可以自行创建自定义槽类型

更多详情,请参阅 Amazon Lex 概念中的 Amazon Lex – 构建对话语音和文本接口

架构和设计

ExcelLexBot 利用 AWS 无服务器应用程序模型 (AWS SAM) 创建连接 Excel 的 AWS SAM Amazon Lex 应用程序。AWS SAM 是一种描述基于 Lambda 应用程序的规范。它提供一种专门表示无服务器资源的语法。

ExcelLexBot 生成器堆栈

它包括 Amazon S3 存储桶和 ExcelLexBuilder Lambda 事件钩子函数。当用户上传 Excel 文件时,ExcelLexBuilder Lambda 函数会执行下列操作:

  1. 解析 Excel 文件。
  2. 生成 ExcelLexBot SAM 模板。
  3. 创建 Lambda 代码包。
  4. 将 Lambda 代码包上传至 S3 存储桶。
  5. 从 ExcelLexBot SAM 模板中创建更改集。
  6. 部署聊天自动程序堆栈。

ExcelLexBuilder 会读取 Excel 文件,然后生成 ExcelLex SAM 模板和部署包。它现在会为每个工作表创建一个 JSON 文件,然后我利用 AWS Lambda 支持的自定义资源执行 JSON 文件,创建聊天自动程序。通过练习 1:创建 Amazon Lex 自动程序 (AWS CLI),您可以查看使用 JSON 创建 Amazon Lex 自动程序的详细信息。

聊天自动程序堆栈

如需了解基本的 Lex 术语 (例如,什么是意图),请参阅 AWS 博客中的 Amazon Lex – 构建对话语音和文本接口

Lex Dispatcher 是一种可捕获对话和执行事件的默认代码钩子。它可执行下列任务:

  1. 根据命名规则将请求转发至其他 Lambda 函数。有如下三条命名规则。
    1. 如果存在与意图同名的 Lambda 函数,例如 MakeAppointmentIntent,则第一条规则“Capture All”(捕获全部) 会转发对话和执行事件。
    2. 第二条规则“Capture Dialog”(捕获对话) 会将对话事件转发至以“_dialogCodeHook”结尾的 Lambda 函数,例如“MakeAppointmentIntent_dialogCodeHook”。
    3. 第三条规则“Capture Fulfillment”(捕获执行) 会将对话事件转发至以“_fulfillmentActivity”结尾的 Lambda 函数,例如“MakeAppointmentIntent_fulfillmentActivity”。

    您可以在意图配置中使用 Lambda 函数执行初始化和验证、执行或同时完成这两项操作。

  2. 如果您定义了“Capture All”(捕获全部),则不应定义“Capture Dialog”(捕获对话) 或“Capture Fulfillment”(捕获执行)。如果您还未定义“Capture All”(捕获全部),则必须同时定义“Capture Dialog”(捕获对话) 和“Capture Fulfillment”(捕获执行)。
  3. 当 fulfillmentActivity 事件发生时,它会将意图信息保存至与意图同名的 Amazon DynamoDB 表中。而且,所有表均已启用适用于 Amazon DynamoDB 的 Auto Scaling,吞吐量为 1 至 50 个容量单位。
  4. 当 fulfillmentActivity 事件发生,并且用户在 Excel 中提供电子邮件地址时,它会将意图信息发布至 Amazon SNS,由 Amazon SNS 将电子邮件发送至所提供的电子邮件地址。

此设计能够处理常见的任务,例如保存意图信息并通过电子邮件将其发送给用户,以及将自定义的代码钩子从聊天自动程序堆栈中解耦。

如果您想将现有的 Amazon Lex 聊天自动程序迁移至 ExcelLexBot,只需填写 Excel 工作表,并根据命名规则重新部署所有的 Lambda 函数代码钩子即可。Lex Dispatcher 函数并没有什么神奇之处。它只是获取当前的意图名称,添加合适的后缀,然后调用另一个 Lambda 函数。

def call_lambda(event, function_name, function_set):
    if function_name in function_set:
        response = lambda_client.invoke(
            FunctionName=function_name,
            InvocationType='RequestResponse',
            Payload=json.dumps(event)
        )
        data = json.loads(response['Payload'].read().decode("utf-8"))
        print(data)
        return data
    else:
        return None

当“FulfillmentCodeHook”事件发生时,它会在调用另一个 Lambda 函数之前,保存并发送电子邮件。

if source == 'FulfillmentCodeHook':
    save_fulfillment(intent_name, event)
    publish_to_sns(intent_name, event, aws_account_id)

借助 ExcelLexBot,可像平时一样定义代码钩子。只需像平时一样定义代码钩子即可。用作 Lex Dispatcher 的 Amazon Lex 聊天自动程序不会修改任何内容,只会将事件转发至原始代码钩子。您可以查看 Amazon Lex 和 AWS Lambda 蓝图,了解如何编写代码钩子。

Excel 格式

Excel 格式遵循规则优于配置原则:

  1. 工作表名称将使用 Amazon Lex 组件的名称。
  2. 组件类型映射到工作表名称的后缀,有三种类型的组件:自动程序、意图和类型。下面的 ExcelLexBot 图对此作出了说明;组件类型还可以映射到原始 Amazon Lex。

    一个自动程序可以有一个或多个意图。一个意图可以有一个或多个问题 (槽)。一个问题必须设置一个类型 (SlotType)。类型可以是 Lex 内置或自定义槽类型 (用户在工作表中定义)。对于自定义槽类型,有一个或多个枚举值 (可能的值)。每个枚举值可以有同义词。

我已将 JSON 数据格式重新设置为 Excel 数据,因此您可以参阅 AWS 蓝图,了解大多数字段的详细含义。

请注意几件事:

  1. Excel 文件名只能包含英文字符。例如,ChatBot- Copy.xlsx 或 ChatBot2.xlsx 无效。
  2. 为了使用更熟悉的术语,我们已将“slot”重新命名为“question”,将“slotType”重新命名为“type”,并将“slotConstraint”重新命名为“Constraint”。
  3. “Sample Utterances”(示例表述)、“Receiver Email”(接收方电子邮件)、“Question”(问题) 和“Possible Value”(可能的值) 允许输入多行内容。例如:

    这说明原始 Lex JSON Receiver Email (接收方电子邮件) 中的 JSON 数组是 Lex JSON 架构中不存在的唯一附加字段。
  4. 意图工作表中的尝试次数上限将填入槽 (问题) 的“maxAttempts”中,因为用户并不介意每个问题的重试次数。
  5. 内容单元格值仅支持 ASCII 字符,并将删除非 ASCII 字符。

自动程序工作表

  1. “Description”(说明) – 自动程序说明。
  2. “Abort Statement”(中止声明) – 如果 Amazon Lex 无法理解用户在上下文中输入的内容,则会尝试通过用户提示来多次获取信息。之后,Amazon Lex 会将中止声明中定义的消息发送给用户,而后终止对话。
  3. “Clarification Prompt”(明确提示) – 当 Amazon Lex 无法理解用户意图时,则会利用该消息进行明确。
  4. 自动程序的名称即是该工作表的名称,即 ExcelLexBot,将包含该 Excel 工作表中定义的所有意图,即 OrderFlowersIntent 和 MakeAppointmentIntent。

更多详细信息,请参阅 put-bot cli 命令。

Output ChatBot_ExcelLexBot.json
{
    "name": "ChatBot_ExcelLexBot",
    "description": "Bot to Demo Excel Lex Bot",
    "intents": [
        {
            "intentName": "ChatBot_OrderFlowersIntent",
            "intentVersion": "$LATEST"
        },
        {
            "intentName": "ChatBot_MakeAppointmentIntent",
            "intentVersion": "$LATEST"
        }
    ],
    "locale": "en-US",
    "abortStatement": {
        "messages": [
            {
                "content": "Sorry, I'm not able to assist at this time",
                "contentType": "PlainText"
            }
        ]
    },
    "clarificationPrompt": {
        "maxAttempts": 2,
        "messages": [
            {
                "content": "I didn't understand you, what would you like to do?",
                "contentType": "PlainText"
            }
        ]
    },
    "voiceId": "Salli",
    "childDirected": false,
    "idleSessionTTLInSeconds": 600
}

意图工作表

这段代码是 MakeAppointmentIntent 工作表最上面的部分。

  1. “Description”(说明) – 意图说明。
  2. “Max Attempts”(尝试次数上限) – 提示用户获取信息的次数。
  3. “Confirmation Prompt”(确认提示) – 在意图完成之前提示用户确认。
  4. “Sample Utterances”(示例表述) – 每行一条示例表述,该表述会转换成为意图配置的示例表述数组。
  5. “Receiver Email”(接收方电子邮件) – 每行一个电子邮件地址。指明意图完成的记录将通过 SNS 发送至该电子邮件地址。
  6. 意图的名称是该工作表的名称。

这段代码是 MakeAppointmentIntent 工作表的问题部分。

我了解到,用户认为理解调查问卷的制作比理解意图的想法更容易。对于开发人员或 IT 专业的学生来说,这个想法只是为强类型语言中的一组变量创建一个在线表单,例如 AMAZON.DATE Date = 10/5/2017。Amazon Lex 只是帮助您用数据类型验证来替换任何复杂的 Web 表单。我的学生则觉得使用 ExcelLexBot 构建聊天自动程序比创建 Web 表单更容易。

  1. “Name”(名称) – 问题 (槽) 的名称。它是 Amazon DynamoDB 和 JSON 数据中适用于代码钩子的属性名称。
  2. “Description”(说明) – 问题 (槽) 的说明。
  3. “Question”(问题) – 每行一个问题文本。原始 AWS Lex JSON 使用带有字符串中消息列表的 valueElicitationPrompt。我们所有用户都不知道 SSML,因此 ExcelLexBot 也不支持 SSML。
  4. “Type”(类型) – 问题 (槽) 的类型,既可以是您定义的一种自定义槽类型,也可以是内置槽类型的一种。
  5. “Constraint”(限制) – 指定槽是必需还是可选。
  6. “Priority”(优先级) – 指示 Lex 遵循从用户那里获取此槽值的顺序。例如,如果意图有两个问题 (槽),优先级为 1 和 2,Amazon Lex 则首先获取优先级为 1 的问题 (槽) 的值。如果多个问题 (槽) 具有相同的优先级,则 Lex 获取值的顺序是任意的。
  7. “Sample Utterances”(示例表述) – 如果您知道用户针对问题 (槽) 值响应 Amazon Lex 请求可能采用的特定模式,则可以提供这些表述以提高准确性。这是可选项。在大多数情况下,Amazon Lex 能够理解用户的表述。

更多详细信息,请参阅 put-intent cli 命令。

有关完整输出结果,请参阅 ChatBot_ExcelLexBot.json,此处只列出了部分输出结果。

{
	    "name": "ChatBot_MakeAppointmentIntent",
	    "description": "Intent to make appointment",
	    "slots": [
	        {
	            "slotType": "ChatBot_AppointmentType",
	            "name": "AppointmentType",
	            "slotConstraint": "Required",
	            "valueElicitationPrompt": {
	                "maxAttempts": 2,
	                "messages": [
	                    {
	                        "content": "What type of appointment would you like to schedule?",
	                        "contentType": "PlainText"
	                    }
	                ]
	            },
	            "priority": 1,
	            "description": "The type of flowers to pick up",
	            "sampleUtterances": [
	                "I would like a {AppointmentType}"
	            ],
	            "slotTypeVersion": "$LATEST"
	        },
…

类型工作表

  1. “Description”(说明) – 类型 (槽类型) 的说明。
  2. “Value Selection Strategy”(选值策略) – 确定 Amazon Lex 用于返回槽类型值的槽解析策略。字段可设置为下列某个值:
    ORIGINAL_VALUE – 如果用户值与槽值类似,则返回用户输入的值。
    TOP_RESOLUTION – 如果有槽解析列表,则返回解析列表中的第一个值作为槽类型值。如果没有解析列表,则返回空值。
  3. “Possible Values”(可能的值) – 可能的值 (EnumerationValue) 字符串列表,定义槽类型可提取的值。您可以通过换行创建同义词

更多详细信息,请参阅 put-slot-type cli 命令。

Output ChatBot_AppointmentType.json
{
    "name": "ChatBot_AppointmentType",
    "description": "Type of dentist appointment to schedule",
    "valueSelectionStrategy": "TOP_RESOLUTION",
    "enumerationValues": [
        {
            "value": "cleaning"
        },
        {
            "value": "whitening"
        },
        {
            "value": "root canal"
        }
    ]
}

部署 ExcelLexBot

如需部署应用程序,请执行下列步骤:

  1. 在 us-east-1 AWS 区域创建 Amazon S3 源存储桶。
  2. 下载 GitHub 上“Deployment”(部署) 文件夹中的两个文件:excellexbot.yamllex_builder_function.zip
  3. 将您从“Deployment”(部署) 文件夹中下载的源代码包“lex_builder_function.zip”上传至 S3 源存储桶。如果您不熟悉 Amazon S3 控制台,请按照教程如何将文件和文件夹上传至 S3 存储桶?进行操作。
  4. 在 AWS CloudFormation 控制台中,选择创建堆栈
  5. 选择将模板上传到 Amazon S3,选择 yaml,然后选择下一步
  6. 指定下列参数,然后选择下一步
    1. 堆栈名称:excellexbot (AWS 区域中堆栈的唯一名称)。
    2. SourceBucket:您在第一步中创建的 S3 源存储桶的名称。
    3. ExcelBucketName:您要创建的 S3 存储桶的名称。存储桶名称必须唯一。删除 AWS CloudFormation 堆栈后,该存储桶将保留下来。
  7. 在“选项”页面上,选择下一步
  8. 选择所有确认框,然后选择创建更改集
  9. 创建更改集之后,选择执行
  10. 等待 AWS CloudFormation 堆栈创建完成。

您可参阅“使用 AWS 上的 Amazon Rekognition分析视频帧样本中的情绪”。部署“HowWhoFeelInVideo”部分,部署步骤类似。

尝试您的部署

  1. 从 GitHub 中下载示例 Excel 文件 ChatBot.xlsx
  2. S3 控制台中,将 ChatBot.xlsx 上传至 ExcelBucketName 的存储桶。
  3. 打开 AWS CloudFormation 控制台

    等待聊天自动程序堆栈状态更改为 CREATE_COMPLETE。堆栈名称是 Excel 文件名称的小写形式。
  4. (可选) 如果您为意图输入电子邮件,您将收到一封电子邮件确认您的订阅,请单击确认订阅
  5. 打开 Amazon Lex 控制台,然后选择 ExcelLexBot
  6. 选择确定。Amazon Lex 将资源许可更新至 Lex Dispatcher Lambda 函数。AWS CloudFormation 已授予 Amazon Lex 许可,但是如果您不单击此处添加许可,那么每次您测试聊天自动程序时,它都会弹出。
  7. 选择左侧的 Test Chatbot (测试聊天自动程序) 栏。
  8. 您可以在 Amazon Lex 控制台中测试聊天自动程序。
  9. 该部署包含示例自动程序:ScheduleAppointment,您可按照该例进行测试。
  10. 打开 Amazon DynamoDB 控制台,表 ChatBotMakeAppointmentIntent 将包含一个新项目。
  11. (可选) 如果您为意图输入电子邮件,您将收到一封包含意图信息的电子邮件。

添加代码钩子

在本部分,您将更新 MakeAppointment 意图的配置,以将 Lambda 函数用作验证和执行活动的代码钩子。有关此代码钩子的详细信息,请参阅第三步 – 更新意图:配置代码钩子

  1. 下载 GitHub 上“Deployment”(部署) 文件夹中的两个文件:codehook.yamlcodehook.zip
  2. 重复上一部分“部署 ExcelLexBot”中的部署步骤。
  3. 指定堆栈名称和参数:
    1. 堆栈名称:codehook (AWS 区域中堆栈的唯一名称)。
    2. SourceBucket:您在部署 ExcelLexBot 第一步中创建的 S3 源存储桶的名称。
  4. 等待代码钩子步骤状态更改为 CREATE_COMPLETE。
  5. 您可以再次测试聊天自动程序,它将具有与示例自动程序:ScheduleAppointment 相同的功能。

更新和删除聊天自动程序

如果从 S3 存储桶中删除 Excel 文件,将会删除聊天自动程序堆栈。警告!如果删除聊天自动程序堆栈,也将删除 DynamoDB 表,因此在删除堆栈前,请务必备份数据。

如需更新,则需要删除 Excel 文件,并等待聊天自动程序堆栈完全删除。然后,将更新后的 Excel 上传至 Amazon S3。

限制

  1. AWS 管理控制台可立即验证输入,但 ExcelLexBot 不能验证输入。
  2. Lex 允许重复使用意图、跨自动程序的槽类型 – 但基于 Excel 的解决方案应是独立的。基本上不会重视限制。
  3. Amazon Lex 通过限制积极调用来保护自己,因此如果同一时间有多个“删除 Bot API 调用”,Lex 会返回“正在进行的操作存在冲突”,阻止您同时删除多个 Excel 文件或聊天自动程序堆栈。但是,您可以通过将多个 Excel 文件上传至 Amazon S3,来同时创建多个聊天自动程序。

结论

非技术用户学习新工具的意愿有时不太强烈。但是,如果您发送给他们几个 Excel 示例文件,让他们在电子表格中填写问题,他们中的大多数都会毫不犹豫地完成。

ExcelLexBot 通过 Excel 帮助用户轻松构建聊天自动程序。IVE 的老师只需将作业从 Word 复制到 Excel,就可以利用 Amazon AI 服务提升 IVE 教学体验。

这个项目是我与参加 IT114115 云及数据中心管理高级文凭课程的四名学生 LI, Ka WingLAU, Tik HaangHON, Ho YukMA, Shi Sum 合作开展的。另外,在 AWS Academy 课程的帮助下,我的学生学习了如何深入使用 AWS 服务!


补充阅读

了解如何使用 Amazon Lex 构建更完美的自动程序


作者简介

Cyrus Wong 是香港专业教育学院 (李惠利分校) 云创新中心一名数据科学家,还是一名 AWS 社区大咖。他获得了 7 项 AWS 认证,并通过开源项目、博客文章和其他活动与其他人分享 AWS 知识。