共计 9756 个字符,预计需要花费 25 分钟才能阅读完成。
不晓得从什么时候开始,当咱们分割一些企业的客服时,越来越多的分割和反对工作都开始由 AI 机器人程序代为实现了。无论是电话下单,查问订单状态,征询业务问题,或者其余什么类型的求助,这些机器人通常都能很好地实现,而一些比拟「黑科技」的机器人,甚至在胜利解决问题之后,咱们都无奈判断电话那头的到底是人还是程序……
就是因为成果太好,很多企业甚至曾经开始次要通过这种形式向用户提供服务,甚至开始缩减人工客服的岗位。那么这就可能产生一个问题:如果机器人客服的程序挂了,你的客户该由谁来提供服务?
如果你的智能客服是基于 Amazon Lex 构建的,那么能够思考创立高可用性的多区域机器人,这样就算一个区域的机器人故障,也能够主动交由其余区域来接待客户,从根本上解决这种问题。
泛滥 AWS 客户曾经开始利用 Amazon Lex 机器人在电话及其他多种渠道上加强 Amazon Connect 自助服务的对话体验。借助 Amazon Lex,呼叫方(用 Amazon Connect 术语形容,即客户)可能疾速获取问题的答案,简直不须要人工客服的染指。但这同时也给服务可用性提出了更高的要求,因而引发了新的问题:咱们该应用哪种架构模式晋升机器人可用性?在本文中,咱们将探讨一种跨区域办法,通过在多个区域中部署 Amazon Lex 机器人以进步服务可用性。
架构概述
在这套解决方案中,一旦 Amazon Lex 呈现服务可用性问题,Amazon Connect 流可能将中断影响管制在最低水平,借此实现业务连续性。此架构模式应用以下组件:
- 两个 Amazon Lex 机器人,各自处于不同的区域内。
- 两个机器人由负责区域查看的 AWS Lambda 函数进行触发,并集成至 Amazon Connect 流内。
- 用于查看机器人运行状况的 Lambda 函数。
- 为 Amazon Connect 区域中的主机器人创立一套 Amazon DynamoDB 表,并通过 Lambda 函数进行读取。
- 应用 DynamoDB 表保留 Amazon Connect 与 Amazon Lex 之间的区域映射。由之前提到的运行状态查看函数负责更新此表。区域查看函数读取此表,以获取 Amazon Connect 与 Amazon Lex 的最新主区域映射。
之所以要在两个区域内设置实现雷同的 Amazon Lex 机器人,是为了可能随时在辅助区域中启动该机器人,进而在主区域产生故障时及时替换。
Amazon Lex 的多区域模式
随后的两节,次要形容集成有 Amazon Lex 机器人的 Amazon Connect 流如何在主区域产生服务故障或中断的状况下,疾速实现复原并应用辅助区域内的 Amazon Lex 失常响应客户呼叫。
运行状况查看函数将依据 TEST_METHOD Lambda 环境变量对两个 Amazon Lex 运行时 API 之一进行调用(PutSession 或 PostText)。咱们能够依据本人的爱好及用例要求抉择其中一个。PutSession API 调用不会产生任何额定的 Amazon Lex 关联费用,但无奈测试 Amazon Lex 提供的自然语言了解(NLU)性能。PostTextAPI 则容许咱们查看 Amazon Lex 的 NLU 性能,且额定老本不高。
运行状况查看函数会将通过测试的区域名称,更新至 DynamoDB 表(lexDR)中的 lexRegion 列。如果主区域失常通过运行状况查看,则 lexRegion 将被更新为主区域名称。如果运行状况查看失败,则该函数将基于辅助区域内的 TEST_METHOD 环境变量向相应的运行时 API 收回调用。如果测试胜利,则 DynamoDB 表中的 lexRegion 列将被更新为辅助区域;如果测试依然失败,则更新为 err,代表两个区域皆已产生服务中断。
在 Amazon Connect 收到的每项呼叫中,都会收回区域运行状况检测函数调用,借此获取以后 Amazon Connect 区域中的流动 Amazon Lex 区域。由区域运行状况查看函数返回的主区域将作为最新条目,由该查看函数写入至 DyanmoDB 表。由区域查看函数返回的可用区域内 Amazon Lex 机器人,将通过 Get Customer Input Block 配置承受 Amazon Connect 的调用。如果函数返回的是辅助区域,则 Amazon Connect 将调用辅助区域中的机器人。
部署 Amazon Lex 机器人
大家须要在主区域与辅助区域中创立雷同的对话机器人。在本文中,咱们将 us-east- 1 作为主区域,us-west- 2 作为辅助区域。接下来,先应用主区域 us-east- 1 创立机器人:
- 在 Amazon Lex 管制台上点击 Create。
- 在 Try a Sample 局部,抉择 OrderFlowers,而后在 COPPA 中抉择 No。
- 其余设置项皆保留默认值,点击 Create。
- 此机器人的创立与构建操作将主动进行。
- 在机器人构建实现(约需 1 至 2 分钟)后,抉择 Publish。
- 创立一个别名,名称为 ver_one。
对 us-west- 2 区域反复上述步骤。当初,咱们曾经在 us-east- 1 与 us-west- 2 中建设起可能失常运行的 Amazon Lex 机器人。
创立 DynamoDB 表
请确保以后处于 us-east- 1 区域内。
- 在 DynamoDB 控制台抉择 Create。
- 在 Table name 局部,输出 lexDR。
- 在 Primary key 局部,输出 connectRegion 且类型为 String。
- 其余各项保留默认值,而后抉择 Create。
- 在 Items 选项卡中,抉择 Create item。
- 将 connectRegion 的值设置为 us-east-1,而后 Append 一个类型为 String、名称为 lexRegion 的新列,并将其值设置为 us-east-1。
- 点击 Save。
为 Lambda 函数创立 IAM 角色
在此步骤中,咱们将为两项 Lambda 函数创立一个 AWS 身份与拜访治理(AWS Identity and Access Management,简称 IAM)角色。
- 在 IAM 管制台上,点击 Access management 并抉择 Policies。
- 点击 Create Policy。
- 点击 JSON。
- 粘贴以下自定义 IAM 策略,此策略容许对 DynamoDB 表 lexDR 进行读取 / 写入拜访。请将策略中的“xxxxxxxxxxxx”局部替换为咱们的 AWS 账户编号。
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:UpdateItem"],
"Resource": "arn:aws:dynamodb:us-east-1:xxxxxxxxxxxx:table/lexDR"
}]
}
- 点击 Review Policy。
- 将其命名为 DynamoDBReadWrite,而后点击 Create Policy。
- 在 IAM 管制台上,点击 Access management 下的 Roles,而后点击 Create Role。
- 为该服务抉择 Lambda,而后点击 Next。
-
附加以下权限策略:
- AWSLambdaBasicExecutionRole
- AmazonLexRunBotsOnly
- DynamoDBReadWrite
- 点击 Next: Tags。接下来点击 Next: Review 以跳过 Tags 页面。
- 将角色命名为 lexDRRole,而后点击 Save。
部署区域查看函数
咱们首先须要创立一项 Lambda 函数,用于从 DynamoDB 表中读取记录,借此判断哪个 Amazon Lex 机器人与 Amazon Connect 实例处于同一区域当中。Amazon Connect 或者应用此机器人的应用程序后续将调用此函数。
- 在 Lambda 管制台上,抉择 Create function。
- 在 Function name 局部,输出 lexDRGetRegion。
- 在 Runtime 局部,抉择 Python 3.8。
- 在 Permissions 之下,抉择 Use an existing role。
- 抉择角色 lexDRRole。
- 抉择 Create function。
- 在 Lambda 代码编辑器中,输出以下代码(下载自 lexDRGetRegion.zip):
import json
import boto3
import os
import logging
dynamo_client=boto3.client('dynamodb')
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def getCurrentPrimaryRegion(key):
result = dynamo_client.get_item(TableName=os.environ['TABLE_NAME'],
Key = {"connectRegion": {"S": key}
}
)
logger.debug(result['Item']['lexRegion']['S'] )
return result['Item']['lexRegion']['S']
def lambda_handler(event, context):
logger.debug(event)
region = event["Details"]["Parameters"]["region"]
return {
'statusCode': 200,
'primaryCode': getCurrentPrimaryRegion(region)
}
- 在 Environment variables 局部,抉择 Edit。
- 增加一项环境变量,其中 Key 为 TABLE_NAME,Value 为 lexDR。
- 点击 Save 以保留该环境变量。
- 点击 Save 以保留该 Lambda 函数。
部署运行状况查看函数
在 us-east- 1 当中创立另一项 Lambda 函数,用以实现运行状况查看性能。
- 在 Lambda 管制台上,抉择 Create function。
- 在 Function name 局部,输出 lexDRTest。
- 在 Runtime 局部,抉择 Python 3.8。
- 在 Permissions 之下,抉择 Use an existing role。
- 抉择 lexDRRole。
- 抉择 Create function。
- 在 Lambda 代码编辑器中,输出以下代码(下载自 lexDRTest.zip):
import json
import boto3
import sys
import os
dynamo_client = boto3.client('dynamodb')
primaryRegion = os.environ['PRIMARY_REGION']
secondaryRegion = os.environ['SECONDARY_REGION']
tableName = os.environ['TABLE_NAME']
primaryRegion_client = boto3.client('lex-runtime',region_name=primaryRegion)
secondaryRegion_client = boto3.client('lex-runtime',region_name=secondaryRegion)
def getCurrentPrimaryRegion():
result = dynamo_client.get_item(
TableName=tableName,
Key={'connectRegion': {'S': primaryRegion}
}
)
return result['Item']['lexRegion']['S']
def updateTable(region):
result = dynamo_client.update_item(
TableName= tableName,
Key={'connectRegion': {'S': primaryRegion}
},
UpdateExpression='set lexRegion = :region',
ExpressionAttributeValues={':region': {'S':region}
}
)
#SEND MESSAGE/PUT SESSION ENV VA
def put_session(botname, botalias, user, region):
print(region,botname, botalias)
client = primaryRegion_client
if region == secondaryRegion:
client = secondaryRegion_client
try:
response = client.put_session(botName=botname, botAlias=botalias, userId=user)
if (response['ResponseMetadata'] and response['ResponseMetadata']['HTTPStatusCode'] and response['ResponseMetadata']['HTTPStatusCode'] != 200) or (not response['sessionId']):
return 501
else:
if getCurrentPrimaryRegion != region:
updateTable(region)
return 200
except:
print('ERROR: {}',sys.exc_info()[0])
return 501
def send_message(botname, botalias, user, region):
print(region,botname, botalias)
client = primaryRegion_client
if region == secondaryRegion:
client = secondaryRegion_client
try:
message = os.environ['SAMPLE_UTTERANCE']
expectedOutput = os.environ['EXPECTED_RESPONSE']
response = client.post_text(botName=botname, botAlias=botalias, userId=user, inputText=message)
if response['message']!=expectedOutput:
print('ERROR: Expected_Response=Success, Response_Received='+response['message'])
return 500
else:
if getCurrentPrimaryRegion != region:
updateTable(region)
return 200
except:
print('ERROR: {}',sys.exc_info()[0])
return 501
def lambda_handler(event, context):
print(event)
botName = os.environ['BOTNAME']
botAlias = os.environ['BOT_ALIAS']
testUser = os.environ['TEST_USER']
testMethod = os.environ['TEST_METHOD']
if testMethod == 'send_message':
primaryRegion_response = send_message(botName, botAlias, testUser, primaryRegion)
else:
primaryRegion_response = put_session(botName, botAlias, testUser, primaryRegion)
if primaryRegion_response != 501:
primaryRegion_client.delete_session(botName=botName, botAlias=botAlias, userId=testUser)
if primaryRegion_response != 200:
if testMethod == 'send_message':
secondaryRegion_response = send_message(botName, botAlias, testUser, secondaryRegion)
else:
secondaryRegion_response = put_session(botName, botAlias, testUser, secondaryRegion)
if secondaryRegion_response != 501:
secondaryRegion_client.delete_session(botName=botName, botAlias=botAlias, userId=testUser)
if secondaryRegion_response != 200:
updateTable('err')
#deleteSessions(botName, botAlias, testUser)
return {'statusCode': 200,'body': 'Success'}
-
在 Environment variables 局部,抉择 Edit,而后增加以下环境变量:
- BOTNAME – OrderFlowers
- BOT_ALIAS – ver_one
- SAMPLE_UTTERANCE – I would like to order some flowers. (向机器人发送的示例话语。)
- EXPECTED_RESPONSE – What type of flowers would you like to order? (机器人在收到以上示例话语后应做出的预期响应。)
- PRIMARY_REGION – us-east-1
- SECONDARY_REGION – us-west-2
- TABLE_NAME – lexDR
-
TEST_METHOD – put_session 或 send_message
- send_message:此办法将调用 Lex 运行时函数 postText,该函数将提取语音并将其映射至训练得出的某一 intent。postText 将测试 Lex 的自然语言理解能力,每项申请的应用老本为 0.00075 美元,简直能够忽略不计。
- put_session:此办法将调用 Lex 运行时函数 put_session,该函数为用户创立一个新的会话。put_session 不会测试 Lex 的自然语言理解能力。
- TEST_USER – test
- 点击 Save 以保留此环境变量。
- 在 Basic Settings section 当中,将 Timeout 的值更新为 15 秒。
- 点击 Save 以保留此 Lambda 函数。
创立一条 Amazon CloudWatch 规定
为了每 5 分钟触发一次运行状况查看函数,咱们须要创立一条 Amazon CloudWatch 规定。
- 在 CloudWatch 控制台的 Events 之下,抉择 Rules。
- 抉择 Create rule。
- 在 Event Source 之下,将选项切换为 Schedule。
- 将 Fixed rate of 设置为 5 minutes。
- 在 Targets 之下,抉择 Add target。
- 抉择指标 Lambda function。
- 在 Function 局部,抉择 lexDRTest。
- 在 Configure input 之下,抉择 Constant(JSON text),而后输出 {}。
- 抉择 Configure details。
- 在 Rule definition 之下的 Name 局部,输出 lexHealthCheckRule。
- 抉择 Create rule。
当初,咱们应该曾经建设起 lexHealthCheckRule CloudWatch 规定,可能每 5 分钟调用一次 lexDRTest 函数。这项操作将查看主机器人的运行状况是否失常,并将后果对应更新至 DynamoDB 表。
创立 Amazon Connect 实例
随后咱们须要创立一个 Amazon Connect 实例,借此在创立 lexDRTest 函数的同一区域之内测试机器人的多区域模式。
- 如果还没有 Amazon Connect 实例,请首先创立一个。
- 在 Amazon Connect 管制台上,抉择作为 Amazon Connect 传输流指标的实例别名。
- 抉择 Contact flows。
- 在 Amazon Lex 之下,从 us-east- 1 区域中抉择 OrderFlowers 机器人,而后点击 Add Lex Bot。
- 在 us-west- 2 区域中抉择 OrderFlowers 机器人,而后点击 Add Lex Bot。
- 在 AWS Lambda 之下,抉择 lexDRGetRegion 并点击 Add Lambda Function。
- 点击左侧面板中的 Overview 再点击登录链接,借此登录至 Amazon Connect 实例。
- 点击左侧面板中的 Routing,而后点击下拉菜单中的 Contact Flows。
- 点击 Create Contact Flow 按钮。
- 点击 Save 按钮旁的向下箭头按钮,再点击 Import Flow。
- 下载分割流程 Flower DR Flow。在 Import Flow 对话框中上传此文件。
- 在 Contact Flow 中,点击 Inovke AWS Lambda Function 局部,借此在屏幕右侧关上一个属性面板。
- 抉择 lexDRGetRegion 并点击 Save。
- 点击 Publish 按钮,公布以后分割流程。
将电话号码关联至分割流程
接下来,咱们须要将电话号码关联至分割流程,借此调用并测试 OrderFlowers 机器人。
- 点击左侧导航栏中的 Routing 选项。
- 点击 Phone Numbers。
- 点击 Claim Number。
- 抉择国家代码并抉择电话号码。
- 在 Contact flow/IVR 抉择框中,抉择咱们在之前步骤中导入的分割流程 Flower DR Flow。
- 期待几分钟,而后呼叫该号码以与 OrderFlowers 机器人交互。
测试集成成果
要测试这套解决方案,能够执行以下操作以模仿 us-east- 1 区域产生故障的场景:
- 在 us-east- 1 区域中关上 Amazon Lex 控制台。
- 抉择 OrderFlowers 机器人。
- 点击 Settings。
- 删除机器人别名 ver_one。
在下一次进行运行状况查看时,解决方案将尝试与 us-east- 1 区域的 Lex 机器人进行通信。因为机器人别名不存在,因而无奈获得成功响应。因而,本示例随后会呼叫辅助区域 us-west- 2 并收到胜利响应。在收到响应后,示例将应用 us-west- 2 更新 lexDR 以及 DynamoDB 表中的 lexRegion 列。
接下来,所有指向 us-east- 1 区域内 Connect 的后续呼叫都将与 us-west- 2 区域内的 Lex 机器人进行理论交互。通过这一主动切换,能够证实以后架构模式的确可能在产生服务故障时保障业务连续性。
在删除机器人别名到下一次运行状况查看之间的时段内,对 Amazon Connect 的呼叫都将失败。但在运行状况查看之后,零碎将主动实现业务连续性保障。因而,每一轮运行状况查看之间的距离越短,则停机工夫越短。咱们能够通过编辑 Amazon CloudWatch 规定 lexHealthCheckRule 以调整每次运行状况查看之间的距离时长。
要让 us-east- 1 区域再次通过运行状况查看,请在 us-east- 1 中从新创立 OrderFlowers 机器人的别名 ver_one。
资源清理
为了防止产生不必要的额定老本,请删除本示例中创立的所有资源。
- 创立在 us-east- 1 与 us-west- 2 当中的 Amazon Lex 机器人 OrderFlowers
- CloudWatch 规定 lexHealthCheckRule
- DynamoDB 表 lexDR
- Lambda 函数 lexDRTest 与 lexDRGetRegion
- IAM 角色 lexDRRole
- 分割流程 Flower DR Flow
总结
配合 Amazon Lex 提供的自助服务,Amazon Connect 将帮忙咱们轻松创立便捷直观的客户服务体验。本文提供一种跨区域模式的高可用性实现办法,保障可能在某一区域中的机器人或反对实现 API 不可用时,应用来自其余区域的资源以持续响应客户呼叫。