柏拉图数据智能。
垂直搜索和人工智能。

使用 Amazon Lex 捕获街道地址

日期:

亚马逊Lex 提供自动语音识别 (ASR) 和自然语言理解 (NLU) 技术来转录用户输入、识别其请求的性质并有效地管理对话。 Lex 让您可以创建复杂的对话、简化您的用户体验以提高客户满意度 (CSAT) 分数,并增加您联络中心的遏制力。

自然、有效的客户交互要求 Lex 虚拟代理准确解释客户提供的信息。 一种特别具有挑战性的场景是在通话期间捕获街道地址。 例如,考虑一位最近搬到一个新城市的客户,他打电话来更新他们的无线帐户的街道地址。 即使是一个美国邮政编码也可以包含范围广泛的街道名称。 通过电话获取正确的地址可能很困难,即使对于人工代理也是如此。

在这篇文章中,我们将演示如何使用 Amazon Lex 和 亚马逊定位服务 为通过语音或文本获取地址提供有效的用户体验。

解决方案概述

在本示例中,我们将使用一个提供自助服务功能的 Amazon Lex 自动程序,作为 亚马逊通 接触流。 当用户打电话时,他们可以要求更改地址,机器人会询问他们的客户号码和新地址。 在许多情况下,新地址将在第一次尝试时被正确捕获。 对于更具挑战性的地址,机器人可能会要求他们重述街道名称、拼写街道名称或重复邮政编码或地址号码以获取正确的地址。

下面是一个示例用户交互来模拟我们的 Lex 机器人:

IVR: 您好,欢迎来到 ACME 银行客服。 我能提供什么帮助? 您可以查看账户余额、订购支票或更改您的地址。

用户: 我想换地址。

IVR: 你能告诉我你的客户号码吗?

用户:123456。

IVR: 谢谢。 请告诉我你的新邮政编码。

用户:32312。

IVR: 好的,你的新街道地址是什么?

用户:托马斯维尔路 6800 号,套房 1-oh-1。

IVR: 谢谢。 为了确保我理解正确,你能告诉我你所在街道的名称吗?

用户: 托马斯维尔路。

IVR: 好的,您的新地址是 6800 Thomasville Road, Suite 101, Tallahassee Florida 32312, USA。 是对的吗?

用户:是的。

IVR: 好的,你的地址已经更新了。 还有什么我可以帮忙的吗?

用户: 不,谢谢。

IVR: 谢谢你的来电。 祝你有美好的一天!

作为一种替代方法,您可以一次捕获整个地址,而不是先询问邮政编码:

IVR: 您好,欢迎来到 ACME 银行客服。 我能提供什么帮助? 您可以查看账户余额、订购支票或更改您的地址。

用户: 我想要 更新 我的地址。

IVR: 你能告诉我你的客户号码吗?

用户:123456。

IVR: 谢谢。 请告诉我您的新地址,包括街道、城市、州和邮政编码。

用户: 6800 Thomasville Road, Suite 1-oh-1, Tallahassee Florida, 32312。

IVR: 谢谢。 为了确保我理解正确,你能告诉我你所在街道的名称吗?

用户: 托马斯维尔路。

IVR:好的,您的新地址是 6800 Thomasville Road, Suite 101, Tallahassee Florida 32312, US。 是对的吗?

用户:是的。

IVR: 好的,你的地址已经更新了。 还有什么我可以帮忙的吗?

用户: 不,谢谢。

IVR: 谢谢你的来电。 祝你有美好的一天!

解决方案架构

我们将在此解决方案中使用与 Amazon Connect 集成的 Amazon Lex 自动程序。 当用户打电话并提供他们的新地址时,Lex 使用自动语音识别将他们的语音转录为文本。 然后,它使用一个 AWS Lambda 实现功能将转录文本发送到 Amazon Location Service,后者执行地址查找并返回规范化地址。

作为一部分 AWS CloudFormation 堆栈,您还可以创建一个可选的 Amazon CloudWatch日志 用于捕获 Lex 对话日志的日志组,可用于创建对话分析仪表板以可视化结果(参见帖子 为您的 Amazon Lex 机器人构建商业智能仪表板 一种方法来做到这一点)。

产品思路

该解决方案结合了多种技术来创造有效的用户体验,包括:

  • Amazon Lex 自动语音识别技术,可将语音转换为文本。
  • 与 Amazon Location Service 集成以进行地址查找和规范化。
  • 莱克斯 拼写风格,在语音输入不清晰时实施“拼写”方法(例如,要求用户说出他们的街道名称,然后在必要时拼写)。

第一步是确保已捕获所需的插槽。

在随后的第一个代码部分中,我们使用 Lex 提示用户输入他们的邮政编码和街道地址 ElicitSlot 对话动作。 这 elicit_slot_with_retries() 功能根据一组可配置的提示提示用户。

 
    # check for ZipCode code slot; if not available; elicit it
    zip_code = None
    zipCode = slot_values.get('ZipCode', None)
    if zipCode is not None:
        zip_code = zipCode['value'].get('interpretedValue', None)
    else:
        response = helpers.elicit_slot_with_retries( intent, activeContexts, sessionAttributes, 'ZipCode', requestAttributes)
        return response		
    # check for StreetAddress slot
    street_address = None
    streetAddress = slot_values.get('StreetAddress', None)
    if streetAddress is not None:
        street_address = streetAddress['value'].get('interpretedValue', None)
    else:
        # give the caller extra time for this response
        sessionAttributes['x-amz-lex:audio:end-timeout-ms:' + intent_name + ':StreetAddress'] = 2000
        response = helpers.elicit_slot_with_retries( intent, activeContexts, sessionAttributes, 'StreetAddress', requestAttributes)
        return response
    street_address = parse_address.parse(street_address)
    sessionAttributes['inputAddress'] = street_address

上面的最后一段代码使用了一个辅助函数 parse_address.parse() 将口语数字转换为数字(例如,它将“6800”转换为“XNUMX”)。

然后,我们将用户的话语发送到 Amazon Location Service 并检查响应。 我们会丢弃任何没有街道、门牌号或邮政编码不正确的条目。 如果我们必须重新提示输入街道名称或号码,我们还会丢弃任何以前建议的地址。

# validate the address using the AWS Location Service
    location_response = locationClient.search_place_index_for_text(IndexName='explore.place', Text=street_address)
    # inspect the response from Amazon Location Service
    if location_response.get('Results', None) is not None:
        for address in location_response['Results']:
            if address.get('Place', None) is not None:
                addressLabel = address['Place'].get('Label', None)
                addressNumber = address['Place'].get('AddressNumber', None)
                street = address['Place'].get('Street', None)
                postalCode = address['Place'].get('PostalCode', None)
                if street is None:
                    continue                    
                if addressNumber is None:
                    continue                    
                if zip_code is not None:
                    if postalCode[:len(zip_code)] != zip_code:
                        continue
                already_tried = False
                prior_suggestions = helpers.get_all_values('suggested_address', sessionAttributes)
                for prior_suggestion in prior_suggestions:
                    if addressLabel == prior_suggestion:
                        already_tried = True
                        break                    
                if already_tried:
                    continue
                # the first entry with a valid street that was not already tried is the next best guess
                resolvedAddress = addressLabel
                break

一旦我们有了解析的地址,我们就会与用户确认。

if (event.get('inputMode') == 'Speech'):
        response_string = '<speak>OK, your new address is <say-as interpret-as="address">'
        response_string += resolvedAddress + '</say-as>. Is that right?</speak>'
        response_message = helpers.format_message_array(response_string, 'SSML')
    else:
       response_string = 'OK, your new address is ' + resolvedAddress + '. Is that right?'
        response_message = helpers.format_message_array(response_string, 'PlainText')
    intent['state'] = 'Fulfilled'
    response = helpers.confirm(intent, activeContexts, sessionAttributes, response_message, requestAttributes)
    return response

如果我们没有从 Amazon Location Service 获得已解析的地址,或者如果用户说我们建议的地址不正确,那么我们会重新提示一些其他信息,然后重试。 附加信息槽包括:

  • StreetName:插槽类型 AMAZON.StreetName
  • SpelledStreetName:插槽类型 AMAZON.AlphaNumeric(使用 Amazon Lex 拼写风格)
  • StreetAddressNumber:插槽类型 AMAZON.Number

重新提示的逻辑由 next_retry() 函数,它查询要尝试的操作列表:

RETRY_ACTIONS = [
    { "street_name": {
          "method": elicit_street_name,
          "style": None,
          "no-match": "Thank you. To make sure I get it right, can you tell me just the name of your street?",
          "incorrect": "Let's try again. Can you tell me just the name of your street?"
       }
    },
    { "street_name_spelled_by_letter": {
          "method": elicit_spelled_street, 
          "style": "SpellByLetter",
          "no-match": "Let's try a different way. Can you please spell just the name of your street?",
          "incorrect": "Let's try a different way. Can you please spell just the name of your street?"
       }
    },
    { "street_address_number": {
          "method": elicit_street_address_number, 
          "style": None,
          "no-match": "I didn't find a matching address. Can you please tell me your street address number?",
          "incorrect": "OK, let's try your street address number. Can you tell me that once more?"
       }
    },
    { "street_name_spelled_by_word": {
          "method": elicit_spelled_street, 
          "style": "SpellByWord",
          "no-match": "Let's try one last time. Please spell the name of your street. You can use words for letters, such as a as in apple, or b like bob.",
          "incorrect": "Let's try one last time. Please spell the name of your street. You can use words for letters, such as a as in apple, or b like bob."
       }
    },
    { "agent": {
          "method": route_to_agent, 
          "style": None,
          "no-match": "Sorry, I was not able to find a match for your address. Let me get you to an agent.",
          "incorrect": "Sorry, I was not able to find a match for your address. Let me get you to an agent."
       }
    }
]

next_retry() 函数将按顺序尝试这些操作。 您可以通过更改命令中的顺序来修改提示的顺序 RETRY_ACTIONS 列表。 您还可以针对 Amazon Location Service 未找到匹配项的情况以及用户说建议的地址不正确的情况配置不同的提示。 如您所见,我们可能会要求用户重述他们的街道名称,如果不这样做,则使用 Amazon Lex 拼写样式进行拼写。 我们将此称为“拼写”方法,它类似于人工代理在这种情况下与客户交互的方式。

要查看实际情况,您可以将其部署在您的 AWS 账户中。

先决条件

您可以使用后面的 CloudFormation 链接在您自己的 AWS 账户中部署解决方案。 在部署此解决方案之前,您应该确认您具有以下先决条件:

  • 一个可用的 AWS账户 您可以在其中部署解决方案。
  • 访问以下 AWS 服务:
    • 亚马逊Lex
    • AWS Lambda,用于与 Amazon Location Service 集成
    • 亚马逊定位服务,用于地址查找
    • AWS身份和访问管理 (IAM),用于创建必要的策略和角色
    • CloudWatch Logs,为 Lambda 函数创建日志组,并可选择捕获 Lex 对话日志
    • CloudFormation 创建堆栈
  • 一个 Amazon Connect 实例(有关设置的说明,请参阅 创建一个Amazon Connect实例).

以下 AWS 区域支持 Amazon Lex、Amazon Connect 和 Amazon Location Service:美国东部(弗吉尼亚北部)、美国西部(俄勒冈)、欧洲(法兰克福)、亚太地区(新加坡)、亚太地区(悉尼)和亚洲太平洋(东京)。

部署示例解决方案

登录 AWS管理控制台 在您的 AWS 账户中,然后选择以下链接以部署示例解决方案:

这将创建一个新的 CloudFormation 堆栈。

输入 堆栈名称,如 lex-update-address-example. 输入您将用于测试解决方案的 Amazon Connect 实例的 ARN(Amazon 资源名称)。 您可以保留其他参数的默认值,或更改它们以满足您的需要。 选择 下一页,并为堆栈添加您可能需要的任何标签(可选)。 选择 下一页 再次查看堆栈详细信息,选中复选框以确认将创建 IAM 资源,然后选择 创建堆栈.

几分钟后,您的堆栈将完成,并包含以下资源:

  • Lex 自动程序,包括具有别名 (Development-Alias)
  • 机器人的 Lambda 实现函数(BotHandler)
  • Lex 对话日志的 CloudWatch Logs 日志组
  • 必需的 Amazon IAM 角色
  • 将示例联系流添加到您的 Connect 实例的自定义资源

此时,您可以在 Lex V2 控制台中尝试上面的示例交互。 您应该会看到具有您在 CloudFormation 模板中指定的名称的示例机器人(例如, update-address-bot).

选择这个机器人,选择 机器人版本 在左侧导航面板中,选择 版本 1 版本,然后选择 意向 在左侧面板中。 您将看到意图列表以及 测试 按钮。

要测试,请选择 测试 按钮,选择 Development-Alias,然后选择 确认 打开测试窗口。

尝试“我想更改我的地址”开始。 这将使用 UpdateAddressZipFirst 意图捕获地址,首先询问邮政编码,然后询问街道地址。

你也可以说“我想 更新 我的地址”来试试 UpdateAddress 意图,它用一个单一的话语一次捕获一个地址。

使用 Amazon Connect 进行测试

现在让我们使用 Connect 实例来尝试使用语音。 您的 Connect 实例中已经配置了一个示例联系流:

您需要做的就是设置一个电话号码,并将其与此联系流相关联。 为此,请按照下列步骤操作:

  • 在 AWS 控制台中启动 Amazon Connect。
  • 通过选择 访问网址, 并登录到实例。
  • 在仪表板中,选择 查看电话号码.
  • 选择 索取电话号码, 选择一个国家 国家 下拉菜单,然后选择一个数字。
  • 输入描述,例如“使用 Amazon Lex 更新地址的示例流程”,然后选择您刚刚创建的联系流程。
  • 保存.

现在您已准备好调用 Connect 实例以使用语音测试您的机器人。 只需拨打手机上的号码,然后尝试一些美国地址。 要尝试使用邮政编码优先的方法,请说“更改我的地址”。 要尝试一次性更改地址,请说“更新我的地址”。 您也可以只说“我的新地址是”,然后是一个有效的美国地址。

但是等等……还有更多

语音场景的另一个具有挑战性的用例是捕获用户的电子邮件地址。 这通常用于用户验证目的,或者只是为了让用户更改他们存档的电子邮件地址。 Lex 使用 AMAZON.EmailAddress 内置插槽类型内置了对电子邮件地址的支持,该插槽类型还支持 Lex 拼写样式。

使用“say-spell”方法来捕获电子邮件地址可能非常有效,并且由于该方法类似于我们上面描述的街道地址捕获场景中的用户体验,因此我们将其包含在此处。 试试看!

清理

使用完机器人后,您可能希望清理作为 CloudFormation 模板的一部分创建的资源,以避免产生持续费用。 为此,请删除 CloudFormation 堆栈。

结论

Amazon Lex 提供强大的自动化语音识别和自然语言理解功能,可用于从用户那里获取所需的信息,以提供自动化的自助服务功能。 由于街道、城市和城镇的名称范围广泛,通过语音识别捕获客户的地址可能具有挑战性。 但是,您可以轻松地将 Amazon Lex 与 Amazon Location Service 集成,以根据客户的输入查找正确的地址。 您可以将此技术结合到您自己的 Lex 对话流中。


关于作者

布莱恩·约斯特 是 AWS Lex 团队的高级技术项目经理。 在业余时间,他喜欢骑山地自行车、在家酿造和修补技术。

现货图片

最新情报

现货图片

在线答疑

你好呀! 我怎么帮你?