生活中的很多对话,对我们人类来说,结合上下文很容易就能判断出真实意思。例如网传的一道「汉语八级考试题」:
——「你的牙真好看!」
——「哦,那是假的。」
——「啊?真的假的?」
——「真的。」
问:牙到底是真的还是假的?
然而对于程序来说,要想弄清楚这里的弯弯绕可就不容易了。然而很多时候,获得类似这样的能力往往是改善客户体验的关键。例如当一位客户与银行柜员交谈时,客户可能会问「余额还剩多少?」这样的请求显然比较模糊,客户并没有明确提到自己希望查询的到底是信用卡余额还是支票账户余额。这位客户也许只有支票账户,这时客服人员完全可以查找账户详细信息以确定对方提到的只可能是支票账户,借此带来良好的服务体验。
在客户服务领域,客服人员经常需要结合当前用户的上下文数据以解释用户表述中的这些不确定性因素。聊天机器人程序也面临类似的问题,同样需要添加客户上下文数据以确定对方的真实意图。
今天,我们在 Amazon Lex 上推出了自然语言理解的改进方案与置信评分机制。我们根据客户的反馈与研究进展不断改善服务能力,旨在实现更强大的大家还可以借此更好地处理种种模棱两可的场景,包括我们之前提到的查询场景。在这种情况下,如果有两项或者两项以上的 intent 能够以极高置信度进行匹配,则大家可以使用 intent 分类置信度评分确定能否以及如何使用业务逻辑来理解用户意图。如果用户只开通了信用卡服务,那么我们可以触发 intent 以显示信用卡余额;如果用户同时开通了信用卡与支票账户,则可以提出补充性问题,例如「您是指信用卡还是支票账户?」以此为基础,大家将获得更可靠的理解能力,借此管理对话流程并提升沟通效率。
本文将向大家展示如何将这些改进与置信度评分加以结合,以业务知识为基础触发最佳响应。
构建 Lex 机器人
本文将使用以下会话对机器人进行建模。
如果客户在银行中只开通了一个账户:
用户:余额还剩多少?
客服:请输入您的 ATM 卡 PIN 码以确认。
用户:5555
客服:您的支票账户余额为1234美元。
如果客户拥有多种账户,那么对话流程将变为:
用户:余额还剩多少?
客服:好的,您是指支票账户还是信用卡?
用户:信用卡。
客服:请输入您的卡片 CVV 编号以确认。
用户:1212。
客户:您的信用卡余额为3456美元。
要实现以上功能,首先需要构建一个能够支持余额查询、资金转账及账单支付等交易的 Amazon Lex 机器人。
我们可以使用 GetBalanceCreditCard
、GetBalanceChecking
以及 GetBalanceSavings
等提供账户余额信息。PayBills 这个 intent 负责处理指向收款人的支付操作,TransferFunds
支持将资金在不同账户间往来转移。最后,还可以使用 OrderChecks
这个 intent 进行支票补记。当用户向 Lex 机器人提出的请求无法使用以上 intent 加以处理时,则触发其他备选 intent 作为响应。
部署示例 Lex 机器人
要创建示例机器人,我们需要完成以下操作步骤。
在本文中,我们需要创建一个名为 BankingBot
的 Amazon Lex 机器人,以及一项名为 BankingBot_Handler
的 Amazon Lambda 函数。
- 下载 Amazon Lex 机器人定义与Lambda代码。
- 在 Lambda 控制台上,选择 Creatge function。
- 输入函数名称
BankingBot_Handler
。 - 选择 Python 运行时最新版本(例如Python 3.8)。
- 在 Permissions 部分,选择Create a new role with basic Lambda permissions。
- 选择Create function。
- 当 Lambda 函数创建完成后,在 Function code 部分,选择Actions以及Upload a .zip file。
- 选择我们之前下载到的BankingBot.zip文件。
- 选择Save。
- 在Amazon Lex控制台上,选择Actions-Import。
- 选择我们之前下载的BankingBot.zip文件,而后选择Import。
- 在Amazon Lex控制台上,选择BankingBot机器人。
- 在Fulfillment部分,为每一项intent,包括备选intent(BankingBotFallback)选择Amazon Lambda function而后从下拉菜单中选择BankingBot_Handler函数:
- 在页面提示向Lambda函数Add permission时,选择OK。
- 在所有intents更新完毕之后,选择Build。
到这里,一个能够正常工作的Lex机器人就创建完成了。
设置置信度评分阈值
现在,我们可以为intent设置置信度评分阈值了。这项设置将根据intent的置信度评分,控制何时将Amazon Lex的Fallback intent作为默认选项。要完成这项设置,请执行以下操作:
- 在Amazon Lex控制台上,选择Settings,而后选择General。
- 在us-east-1、us-west-2、ap-southeast-2或eu-west-1区域中,下滚至Advanced选项,并选择Yes以选择精度改进以及置信度评分所使用的各项特征。
在默认设置下,其他区域已经直接启用了这些改进与置信度支持选项:
在Confidence score threshold部分,输入一个0到1之间的数字。我们可以选择保留默认值,即0.4。
随后选择Save,而后选择Build。
在机器人配置完成后,Amazon Lex会在PostText及PostContent响应当中显示置信度评分与备选intents:
"alternativeIntents": [
{
"intentName": "string",
"nluIntentConfidence": {
"score": number
},
"slots": {
"string": "string"
}
}
]
使用 Lambda 函数与置信度评分识别用户意图
当用户发出比较模糊的请求时,例如「账户余额还剩多少?」Lambda 函数会解析 Amazon Lex 返回的 intent 列表。如果返回了多项 intent,则函数会检查排名最高的 intent 是否具有与 AMBIGUITY_RANGE 值的定义具有相似的评分。
举例来说,如果某项 intent 的置信度得分为0.95,而另一项 intent 的评分为0.65,则前者的正确率显然更高。但如果一项 intent 的评分为0.75,而另一项评分为0.72,我们就需要结合应用程序中的业务知识对二者加以区分。在我们的用例中,如果客户拥有多个账户,则该函数将设置一项补充性的问题,例如「您是指信用卡还是支票账户?」但如果客户只拥有一个账户(如支票账户),则直接向其返回该账户的余额数字。
在使用置信度评分时,Amazon Lex 会在每条响应中返回概率最高的intent,以及最多四项备用 intent 及其对应置信度评分。如果所有 intent 的置信度评分均小于预定义阈值,则 Amazon Lex 会使用 AMAZON.FallbackIntent intent、AMAZON.KendraSearchIntent intent 或二者兼有。我们可以直接使用默认阈值,也可以根据需求另行设定。
以下代码所示,为我们在本文的示例机器人中下载的Lambda代码。此函数同样适用于各类其他 Amazon Lex 机器人。
此 Lambda 函数的分派器函数会将请求转发至处理程序函数,但GetBalanceCreditCard、GetBalanceChecking 以及 GetBalanceSavings intent 则会被其转发至 determine_intent。
其中还有负责检查Lex报告中各top事件及其他备选intent的determine_intent函数。如果某一备选intent适用于当前用户查询(以其账户为基础),且置信度评分处于top事件的AMBIGUITY_RANGE范围之内,则该intent将被添加至可能事件列表当中。
possible_intents = []
# start with the top intent (if it is valid for the user)
top_intent = intent_request["currentIntent"]
if top_intent["name"] in valid_intents:
possible_intents.append(top_intent)
# add any alternative intents that are within the AMBIGUITY_RANGE
# if they are valid for the user
if intent_request.get("alternativeIntents", None):
top_intent_score = top_intent["nluIntentConfidenceScore"]
for alternative_intent in intent_request["alternativeIntents"]:
alternative_intent_score = alternative_intent["nluIntentConfidenceScore"]
if top_intent_score is None:
top_intent_score = alternative_intent_score
if alternative_intent["name"] in valid_intents:
if abs(top_intent_score - alternative_intent_score) <= AMBIGUITY_RANGE:
possible_intents.append(alternative_intent)
如果用户只有一项可能的intent,则(在找出所有缺失的slots之后)直接实现。
num_intents = len(possible_intents)
if num_intents == 1:
# elicit any missing slots or fulfill the intent
slots = possible_intents[0]["slots"]
for slot_name, slot_value in slots.items():
if slot_value is None:
return elicit_slot(intent_request['sessionAttributes'],
possible_intents[0]["name"], slots, slot_name)
# dispatch to the appropriate fulfillment method
return HANDLERS[possible_intents[0]['name']]['fulfillment'](intent_request)
如果存在多项可能的intent,则进一步请求用户做出说明。
elif num_intents > 1:
counter = 0
response = ""
while counter < num_intents:
if counter == 0:
response += "Sure. Is this for your " +
INTENT_TO_ACCOUNT_MAPPING[possible_intents[counter]["name"]]
elif counter < num_intents - 1:
response += ", " +
INTENT_TO_ACCOUNT_MAPPING[possible_intents[counter]["name"]]
else:
response += ", or " +
INTENT_TO_ACCOUNT_MAPPING[possible_intents[counter]["name"]] + "?"
counter += 1
return elicit_intent(form_message(response))
如果没有适用于用户的intent,则触发后备intent。
else:
return fallback_handler(intent_request)
要进行方案测试,大家可以调整check_available_accounts函数的返回值,以更改代码中的测试用户配置:
# This could be a DynamoDB table or other data store
USER_LIST = {
"user_with_1": [AccountType.CHECKING],
"user_with_2": [AccountType.CHECKING, AccountType.CREDIT_CARD],
"user_with_3": [AccountType.CHECKING, AccountType.SAVINGS, AccountType.CREDIT_CARD]
}
def check_available_accounts(user_id: str):
# change user ID to test different scenarios
return USER_LIST.get("user_with_2")
我们可以在Amazon Lex控制台或Lambda函数的CloudWatch Logs日志文件中查看Lex的置信度评分。
置信度评分也可用于测试各机器人的不同版本。例如,如果添加了新的intent、话语或者slot值,则可以测试机器人并检查新的置信度评分,确认相关变更是否达到了预期效果。
总结
虽然人们在与机器人交互时,使用的词语往往不那么精确,但我们仍然需要努力提供自然顺畅的用户体验。Amazon Lex此次推出的一系列自然语言理解改进与置信度评分,将帮助大家结合更多上下文信息设计出智能度更高的对话过程。我们也可以在机器人开发过程中通过测试确定准确的置信度得分阈值,借此确定针对特定intent的样本话语更改是否能够实现预期效果。这些改进将帮助您设计出更加高效的对话流程。关于将这些技术整合至您聊天机器人内的更多详细信息,请参阅Amazon Lex说明文档。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。