You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:15:16