Alexa技能动态实体不被识别,触发FallbackIntent问题求助
问题
我想在Alexa Skill的某个已存在的Slot(含静态值)中使用Dynamic Entities,且只关注用户输入的动态Slot值。我在LaunchRequestHandler里更新了Dynamic Entities,但实际交互时出现异常:
- 用户:打开[技能名称]
- Alexa:欢迎...
- [其他问答环节]
- Alexa:你想看哪个电视频道?
- 用户:我想看[动态槽值]
- Alexa:直接进入FallbackIntent,无法识别Slot值或触发对应的
canalIntent
以下是简化版代码:
const LaunchRequestHandler = { canHandle(handlerInput) { return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest' || Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.StartOverIntent'; }, handle(handlerInput) { let replaceEntities = { type: "Dialog.UpdateDynamicEntities", updateBehavior: "REPLACE", types: [ { name: "canalEntretenimiento", values: [ { id: "1a", name: { value: "Antena 3", synonyms: ["la tres"] } }, { id: "1b", name: { value: "La Sexta", synonyms: ["La seis"] } } ] } ] }; console.log(replaceEntities); const speakOutput = `Bienvenido, te gustaría ver la televisión o una película`; return handlerInput.responseBuilder .speak(speakOutput) .reprompt(speakOutput) .addDirective(replaceEntities) .getResponse(); } }; // 用户需完成其他Intent交互后,才会进入需返回动态Slot的提问环节 const canalIntentHandler = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest' && handlerInput.requestEnvelope.request.intent.name === 'canalIntent'; }, async handle(handlerInput) { const responseBuilder = handlerInput.responseBuilder; const canalEntretenimiento = getStaticAndDynamicSlotValuesFromSlot(handlerInput.requestEnvelope.request.intent.slots.canalEntretenimiento); let speechText = ` No hemos encontrado el canal`; if (canalEntretenimiento.dynamic.statusCode === 'ER_SUCCESS_MATCH') { speechText = `Reproduciendo ${canalEntretenimiento.value}`; } return responseBuilder .speak(speechText) .withShouldEndSession(false) .getResponse(); }, }; // 辅助函数 function getStaticAndDynamicSlotValues (slots) { const slotValues = {} for (let slot in slots) { slotValues[slot] = getStaticAndDynamicSlotValuesFromSlot(slots[slot]); } return slotValues; }; function getStaticAndDynamicSlotValuesFromSlot (slot) { const result = { name: slot.name, value: slot.value, id:slot.id }; console.log(result) if (((slot.resolutions || {}).resolutionsPerAuthority || [])[0] || {}) { slot.resolutions.resolutionsPerAuthority.forEach((authority) => { const slotValue = { authority: authority.authority, statusCode: authority.status.code, synonym: slot.value || undefined, resolvedValues: slot.value }; if (authority.values && authority.values.length > 0) { slotValue.resolvedValues = []; authority.values.forEach((value) => { slotValue.resolvedValues.push(value); }); } if (authority.authority.includes('amzn1.er-authority.echo-sdk.dynamic')) { result.dynamic = slotValue; } else { result.static = slotValue; } }); } return result; };
排查与解决步骤
1. 确认动态实体的有效性
Alexa的动态实体仅在当前会话内有效,如果中间交互环节中某个Intent的响应设置了withShouldEndSession(true),会话会中断,动态实体也会被清除。
- 检查所有中间Intent的响应,确保都设置了
.withShouldEndSession(false),维持会话连续性。 - 或者在进入
canalIntent前的最后一个Intent处理中,重新发送Dialog.UpdateDynamicEntities指令,确保用户回答时动态实体处于激活状态。
2. 补充Intent样本语句
如果canalIntent的样本语句覆盖不足,Alexa无法匹配用户的提问,会直接触发FallbackIntent。
- 在开发者控制台的
canalIntent中添加足够的样本语句,比如:- 我想看{canalEntretenimiento}
- 打开{canalEntretenimiento}频道
- 切换到{canalEntretenimiento}
- 确保样本语句覆盖用户可能的表达方式,尤其是包含动态实体值的场景。
3. 修正动态实体格式
代码中replaceEntities的values数组最后存在多余逗号,虽然JS允许,但可能导致解析异常,建议删除该逗号。
4. 优化Slot解析逻辑
原解析函数存在容错性不足的问题,若动态实体解析结果未正确赋值,会导致canalEntretenimiento.dynamic不存在,进而执行默认逻辑。优化后的解析函数如下:
function getStaticAndDynamicSlotValuesFromSlot(slot) { const result = { name: slot.name, value: slot.value, id: slot.id, dynamic: null, static: null }; if (slot.resolutions?.resolutionsPerAuthority?.length) { slot.resolutions.resolutionsPerAuthority.forEach((authority) => { const slotValue = { authority: authority.authority, statusCode: authority.status.code, synonym: slot.value, resolvedValues: [] }; if (authority.values?.length) { slotValue.resolvedValues = authority.values.map(val => val.value.name.value); } if (authority.authority.includes('amzn1.er-authority.echo-sdk.dynamic')) { result.dynamic = slotValue; } else { result.static = slotValue; } }); } return result; }
同时在canalIntentHandler中增加可选链判断,避免报错:
if (canalEntretenimiento.dynamic?.statusCode === 'ER_SUCCESS_MATCH') { speechText = `Reproduciendo ${canalEntretenimiento.value}`; }
5. 检查会话状态维持
确保中间交互环节没有意外清除会话属性,导致动态实体上下文丢失。必要时可将动态实体信息存储到会话属性中,后续需要时重新生成更新指令。
内容的提问来源于stack exchange,提问作者nnpp
相关产品推荐
相关产品推荐

