機器人客服你見得多了,不太高可用的機器人你會造嗎?

image

不知道從何時開始,當咱們聯繫一些企業的客服時,愈來愈多的聯繫和支持工做都開始由AI機器人程序代爲完成了。不管是電話下單,查詢訂單狀態,諮詢業務問題,或者其餘什麼類型的求助,這些機器人一般都能很好地完成,而一些比較「黑科技」的機器人,甚至在成功解決問題以後,咱們都沒法判斷電話那頭的究竟是人仍是程序……html

就是由於效果太好,不少企業甚至已經開始主要經過這種方式向用戶提供服務,甚至開始縮減人工客服的崗位。那麼這就可能產生一個問題:若是機器人客服的程序掛了,你的客戶該由誰來提供服務?json

若是你的智能客服是基於Amazon Lex構建的,那麼能夠考慮建立高可用性的多區域機器人,這樣就算一個區域的機器人故障,也能夠自動交由其餘區域來接待客戶,從根本上解決這種問題。session

衆多AWS客戶已經開始利用Amazon Lex機器人在電話及其餘多種渠道上加強Amazon Connect自助服務的對話體驗。藉助Amazon Lex,呼叫方(用Amazon Connect術語描述,即客戶)可以快速獲取問題的答案,幾乎不須要人工客服的介入。但這同時也給服務可用性提出了更高的要求,所以引起了新的問題:咱們該使用哪一種架構模式提高機器人可用性?在本文中,咱們將探討一種跨區域方法,經過在多個區域中部署Amazon Lex機器人以提升服務可用性。架構

架構概述編輯器

在這套解決方案中,一旦Amazon Lex出現服務可用性問題,Amazon Connect流可以將中斷影響控制在最低程度,藉此實現業務連續性。此架構模式使用如下組件:ide

  • 兩個Amazon Lex機器人,各自處於不一樣的區域內。
  • 兩個機器人由負責區域檢查的AWS Lambda函數進行觸發,並集成至Amazon Connect流內。
  • 用於檢查機器人運行情況的Lambda函數。
  • 爲Amazon Connect區域中的主機器人建立一套Amazon DynamoDB表,並經過Lambda函數進行讀取。
  • 使用DynamoDB表保存Amazon Connect與Amazon Lex之間的區域映射。由以前提到的運行狀態檢查函數負責更新此表。區域檢查函數讀取此表,以獲取Amazon Connect與Amazon Lex的最新主區域映射。

之因此要在兩個區域內設置完成相同的Amazon Lex機器人,是爲了可以隨時在輔助區域中啓動該機器人,進而在主區域發生故障時及時替換。
image函數

Amazon Lex的多區域模式post

隨後的兩節,主要描述集成有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功能,且額外成本不高。ui

運行情況檢查函數會將經過測試的區域名稱,更新至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。

image

  • 點擊Save。

image

爲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函數。

image

部署運行情況檢查函數

在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函數。

image

建立一條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。

image

  • 在AWS Lambda之下,選擇lexDRGetRegion並點擊Add Lambda Function。
  • 點擊左側面板中的Overview再點擊登陸連接,藉此登陸至Amazon Connect實例。
  • 點擊左側面板中的Routing,然後點擊下拉菜單中的Contact Flows。
  • 點擊Create Contact Flow按鈕。
  • 點擊Save按鈕旁的向下箭頭按鈕,再點擊Import Flow。
  • 下載聯繫流程Flower DR Flow。在Import Flow對話框中上傳此文件。

image

  • 在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不可用時,使用來自其餘區域的資源以繼續響應客戶呼叫。

image

相關文章
相關標籤/搜索