本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
Amazon Lex V2 提供内置槽位,用于捕获用户特定的信息,例如名字、姓氏、电子邮件地址或字母数字标识符。例如,您可以使用 AMAZON.LastName
槽位捕获诸如“Jackson”或“Garcia”等姓氏。但是,Amazon Lex V2 可能会混淆难以发音或在对应区域设置中不常见的姓氏,例如“Xiulan”。要捕获此类姓氏,您可以要求用户以逐个字母拼写或逐个单词拼写样式提供输入。
Amazon Lex V2 提供了三种槽位引发样式供您使用。您设置槽位引发样式后,会改变 Amazon Lex V2 解释用户输入的方式。
逐个字母拼写:您可以使用此样式,以指示机器人听拼写而不是整个短语。例如,要捕获诸如“Xiulan”等姓氏,您可以指示用户逐个字母地说出自己的姓氏。机器人将捕获该拼写并将这些字母解析为单词。例如,如果用户说“x i u l a n”,则机器人会将姓氏捕获为“xiulan”。
逐个单词拼写:在语音对话中,尤其是在使用电话时,有几个字母会听起来相似,例如“t”、“b”、“p”。当捕获字母数字值或拼写名称导致值不正确时,您可以提示用户输入该字母的同时提供识别词。例如,如果对预订 ID 请求的语音响应为“abp123”,则您的机器人可能会改为识别短语“abb123”。如果该值不正确,您可以指示用户将输入提供为“a as in alpha b as in boy p as in peter one two three”(alpha 的 a,boy 的 b,peter 的 p,然后是 123)。机器人会将输入解析为“abp123”。
使用逐个单词的拼写样式时,您可以使用以下格式:
-
“as in”(a as in apple)
-
“for”(a for apple)
-
“like”(a like apple)
默认:使用单词发音进行槽位捕获的自然样式。例如,可以自然地捕获诸如“John Stiles”等姓名。如果未指定槽位引发样式,则机器人将使用默认样式。对于 AMAZON.AlphaNumeric
和 AMAZON.UKPostal
代码槽位类型,默认样式支持逐个字母拼写的输入。
如果使用字母和单词混合说出 “Xiulan” 这个名字,例如 “x 射线中的 x i u l as lion a n”,则必须将插槽引用样式设置为样式。 spell-by-word这种 spell-by-letter风格无法识别它。
请创建一个语音界面,用于以自然对话样式来捕获槽位值,以获得更好的体验。对于使用自然风格无法正确捕获的输入,您可以重新提示用户并将插槽引出样式设置为或。 spell-by-letter spell-by-word
您可以使用英语(美国)、英语(英国) spell-by-word和英语(澳大利亚)语言为以下插槽类型设置和 spell-by-letter样式:
启用拼写
当你从用户那里获得插槽时,你可以在运行时启用 spell-by-letter和 spell-by-word。您可以使用PutSession、RecognizeTextRecognizeUtterance、或StartConversation操作设置拼写样式。您也可以启用 spell-by-letter和 spell-by-word使用 Lambda 函数。
在上述任一 API 操作的请求中或配置 Lambda 响应时,您可以使用 sessionState
字段的 dialogAction
字段来设置拼写样式(有关更多信息,请参阅AWS Lambda Lex V2 的响应格式)。只有当对话框操作类型为 ElicitSlot
并且要引发的槽位是支持的槽位类型之一时,您才能设置样式。
以下 JSON 代码显示了设置为使用该 spell-by-word样式的dialogAction
字段:
"dialogAction": {
"slotElicitationStyle": "SpellByWord",
"slotToElicit": "BookingId",
"type": "ElicitSlot"
}
slotElicitationStyle
字段可设置为 SpellByLetter
、SpellByWord
或 Default
。如果您不指定值,则值设置为 Default
。
注意
您无法通过控制 spell-by-letter台启用 spell-by-word或激发样式。
使用 Lambda 和 Lex V2 的示例代码
如果第一次尝试解析槽位值不起作用,则通常会更改拼写样式。以下代码示例是一个 Python Lambda 函数,它在第二次尝试解析插槽时使用该 spell-by-word样式。
要使用示例代码,您必须满足以下条件:
-
拥有单语言,即英语(英国)(en_GB) 的机器人。
-
一个意图,CheckAccount“”,有一句话示例,“我想查看我的账户”。确保在意图定义的代码挂钩部分中选中使用 Lambda 函数进行初始化和验证。
-
Intent 应该有一个
AMAZON.UKPostalCode
内置类型的插槽 PostalCode “”。 -
拥有定义了 Lambda 函数的别名。有关更多信息,请参阅 为你的机器人创建 AWS Lambda 函数。
import json
import time
import os
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# --- Helpers that build all of the responses ---
def get_slots(intent_request):
return intent_request['sessionState']['intent']['slots']
def get_session_attributes(intent_request):
sessionState = intent_request['sessionState']
if 'sessionAttributes' in sessionState:
return sessionState['sessionAttributes']
return {}
def get_slot(intent_request, slotName):
slots = get_slots(intent_request)
if slots is not None and slotName in slots and slots[slotName] is not None:
logger.debug('resolvedValue={}'.format(slots[slotName]['value']['resolvedValues']))
return slots[slotName]['value']['resolvedValues']
else:
return None
def elicit_slot(session_attributes, intent_request, slots, slot_to_elicit, slot_elicitation_style, message):
return {'sessionState': {'dialogAction': {'type': 'ElicitSlot',
'slotToElicit': slot_to_elicit,
'slotElicitationStyle': slot_elicitation_style
},
'intent': {'name': intent_request['sessionState']['intent']['name'],
'slots': slots,
'state': 'InProgress'
},
'sessionAttributes': session_attributes,
'originatingRequestId': 'REQUESTID'
},
'sessionId': intent_request['sessionId'],
'messages': [ message ],
'requestAttributes': intent_request['requestAttributes']
if 'requestAttributes' in intent_request else None
}
def build_validation_result(isvalid, violated_slot, slot_elicitation_style, message_content):
return {'isValid': isvalid,
'violatedSlot': violated_slot,
'slotElicitationStyle': slot_elicitation_style,
'message': {'contentType': 'PlainText',
'content': message_content}
}
def GetItemInDatabase(postal_code):
"""
Perform database check for transcribed postal code. This is a no-op
check that shows that postal_code can't be found in the database.
"""
return None
def validate_postal_code(intent_request):
postal_code = get_slot(intent_request, 'PostalCode')
if GetItemInDatabase(postal_code) is None:
return build_validation_result(
False,
'PostalCode',
'SpellByWord',
"Sorry, I can't find your information. " +
"To try again, spell out your postal " +
"code using words, like a as in apple."
)
return {'isValid': True}
def check_account(intent_request):
"""
Performs dialog management and fulfillment for checking an account
with a postal code. Besides fulfillment, the implementation for this
intent demonstrates the following:
1) Use of elicitSlot in slot validation and re-prompting.
2) Use of sessionAttributes to pass information that can be used to
guide a conversation.
"""
slots = get_slots(intent_request)
postal_code = get_slot(intent_request, 'PostalCode')
session_attributes = get_session_attributes(intent_request)
if intent_request['invocationSource'] == 'DialogCodeHook':
# Validate the PostalCode slot. If any aren't valid,
# re-elicit for the value.
validation_result = validate_postal_code(intent_request)
if not validation_result['isValid']:
slots[validation_result['violatedSlot']] = None
return elicit_slot(
session_attributes,
intent_request,
slots,
validation_result['violatedSlot'],
validation_result['slotElicitationStyle'],
validation_result['message']
)
return close(
intent_request,
session_attributes,
'Fulfilled',
{'contentType': 'PlainText',
'content': 'Thanks'
}
)
def close(intent_request, session_attributes, fulfillment_state, message):
intent_request['sessionState']['intent']['state'] = fulfillment_state
return {
'sessionState': {
'sessionAttributes': session_attributes,
'dialogAction': {
'type': 'Close'
},
'intent': intent_request['sessionState']['intent'],
'originatingRequestId': 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
},
'messages': [ message ],
'sessionId': intent_request['sessionId'],
'requestAttributes': intent_request['requestAttributes'] if 'requestAttributes' in intent_request else None
}
# --- Intents ---
def dispatch(intent_request):
"""
Called when the user specifies an intent for this bot.
"""
intent_name = intent_request['sessionState']['intent']['name']
response = None
# Dispatch to your bot's intent handlers
if intent_name == 'CheckAccount':
response = check_account(intent_request)
return response
# --- Main handler ---
def lambda_handler(event, context):
"""
Route the incoming request based on the intent.
The JSON body of the request is provided in the event slot.
"""
# By default, treat the user request as coming from
# Eastern Standard Time.
os.environ['TZ'] = 'America/New_York'
time.tzset()
logger.debug('event={}'.format(json.dumps(event)))
response = dispatch(event)
logger.debug("response={}".format(json.dumps(response)))
return response