aws-lambda - Amazon Lex 插槽不会在其中保存价值。返回空
问题描述
我正在尝试实施一项检查,让用户可以选择在用户在confirmIntent步骤拒绝后更新意图内特定插槽的值。
我有一个newUser意图,它具有以下插槽:
updateNewUser是一个自定义槽类型(扩展值),具有以下条目:
现在,当用户在 confirmIntent 步骤拒绝时,我询问用户他/她想要更新/更改的插槽,并使用 Lambda 函数 elicitSlot将用户输入值存储在updateNewUser插槽中。但问题来了。
- Bot 使用所有捕获的值播放确认提示
- 用户在confirmIntent说“不”
- Bot通过询问“您要更新什么值?”来引发updateNewUser槽。
- 如果用户说出与updateNewUser自定义插槽类型的条目完全匹配的单词 ,那么它可以正常工作
- 如果用户说出类似(不完全匹配)的词,例如“姓名”或“电子邮件”或“号码”,则updateNewUser中不会存储任何值,并且机器人会继续确认提示。
以下是我的 Lambda 代码:
def newUser(intent_request):
slot_details = intent_request['currentIntent']['slotDetails']
slots = intent_request['currentIntent']['slots']
f_name = slots['f_name']
l_name = slots['l_name']
cellNum = slots['cellNum']
emailAdd = slots['emailAdd']
updateSlot = slots['updateNewUser']
session_attributes = intent_request['sessionAttributes'] if intent_request['sessionAttributes'] is not None else {}
confirmation_status = intent_request['currentIntent']['confirmationStatus']
if intent_request['invocationSource'] == 'DialogCodeHook':
validation_result = validate_newusr(intent_request['currentIntent']['slots'], intent_request['currentIntent']['slotDetails'])
if not validation_result['isValid']:
slots = intent_request['currentIntent']['slots']
slots[validation_result['violatedSlot']] = None
slots['updateNewUser'] = None
return elicit_slot(
session_attributes,
intent_request['currentIntent']['name'],
slots,
validation_result['violatedSlot'],
validation_result['message']
)
if confirmation_status == 'Denied':
slots = intent_request['currentIntent']['slots']
return elicit_slot(
session_attributes,
intent_request['currentIntent']['name'],
slots,
'updateNewUser',
{
'contentType': 'SSML',
'content': '<speak>Which value do you want to change?</speak>'
}
)
return delegate(
session_attributes,
intent_request['currentIntent']['slots']
)
return close(
session_attributes,
'Fulfilled',
{
'contentType': 'SSML',
'content': '<speak>Your account has been created, and you will shortly receive an email to set up your password. Now, would you like to make a reservation for yourself, or for somone else?</speak>'
}
)
以下是验证码:
def validate_newusr(slots, slot_details):
f_name = slots['f_name']
l_name = slots['l_name']
cellNum = slots['cellNum']
emailAdd = slots['emailAdd']
updateSlot = slots['updateNewUser']
if f_name:
if ' ' in f_name:
f_name = f_name.replace(' ', '')
slots['f_name'] = f_name
if l_name:
if ' ' in l_name:
l_name = l_name.replace(' ', '')
slots['l_name'] = l_name
if cellNum and (len(cellNum) != 10):
return build_validation_result(
False,
'cellNum',
'<speak>Please provide a valid, 10 digit phone number.</speak>'
)
return build_validation_result( #I use this to check whether updateNewUser stores something or not. But of course I only paste this code here at confirmIntent step; not before.
False,
'updateNewUser',
str(updateSlot)
)
if updateSlot: # this code won't run because updateSlot is empty
return build_validation_result(
False,
'updateNewUser',
str(updateSlot)
)
if len(slot_details['updateNewUser']['resolutions']) == 1 and str(list(slot_details['updateNewUser']['resolutions'][0].values())[0]).lower() in ['last name','first name', 'cell phone number', 'email address']:
slots['updateNewUser'] = list(slot_details['updateNewUser']['resolutions'][0].values())[0]
if len(slot_details['updateNewUser']['resolutions']) == 0 or str(list(slot_details['updateNewUser']['resolutions'][0].values())[0]).lower() not in ['last name','first name', 'cell phone number', 'email address']:
return build_validation_result(
False,
'updateNewUser',
'<speak>Sorry, I could not understand. Please say first name, last name, phone number, or email address.</speak>'
)
if slots['updateNewUser'] == 'first name':
return build_validation_result(
False,
'f_name',
'<speak>Please say your updated first name.</speak>'
)
if slots['updateNewUser'] == 'last name':
return build_validation_result(
False,
'l_name',
'<speak>Please say your updated last name.</speak>'
)
if slots['updateNewUser'] == 'cell phone number':
return build_validation_result(
False,
'cellNum',
'<speak>Please say, or type your updated phone number.</speak>'
)
if slots['updateNewUser'] == 'email address':
return build_validation_result(
False,
'emailAdd',
'<speak>Please say your updated email address.</speak>'
)
return {'isValid': True}
以下是部分聊天截图:
- 用户在 confirmIntent 处拒绝,机器人询问要更新哪个值:
- 用户说“姓名”,机器人跳转到确认提示
- 如果向 Lex 提供了完全匹配的单词,它会接受它:
- 在“名称”作为输入的情况下,返回 bot 存储在 updateNewUser 中的值:
- 另一个例子:
在我的情况下,它只接受完全匹配。但是,如果我将updateNewUser插槽设为强制/必需,它也开始接受类似的单词并且工作正常。但我需要这个插槽作为可选。我的目标是更新单个插槽而不是重复整个意图。我究竟做错了什么?
解决方案
乍一看,我建议将updateNewUser
插槽类型的分辨率更改为受限值和同义词。这将使您能够添加与您的基本值匹配的同义词。
确保您valueSelectionStrategy
是TOP_RESOLUTION
这样,以便您获得基本值而不是用户的原始输入。
这简化了您的 lambda,因为您只需要为每行提供一个值。
推荐阅读
- sql - 分号 将行分成相等的批次
- duplicity - 重复增量备份:处理远程清单时出错
- multithreading - 无法使用 docker-selenium 独立实现线程
- mysql - Mysql 在两个日期条件之间的非常大的行上计算性能
- python - seaborn,python中的“free_y” facet_wrap等价物
- image - 测试文件名是否在项目文件中的任何位置的最佳方法是什么
- javascript - 什么是 DOMElement.shadowRoot?
- android - 如何在 android sdk 29 或最低版本的启动设备上启动服务?
- python - map() 如何与 python 中的字典一起使用?
- php - 未收到来自 mail() 函数的退回邮件