
本文介绍如何利用 alexa 内置的 amazon.yesintent 和 amazon.nointent 实现自然的多轮对话流程,无需复杂对话管理即可根据用户对“是否查看营业时间”的回答,自动触发对应逻辑并保持上下文清晰。
本文介绍如何利用 alexa 内置的 amazon.yesintent 和 amazon.nointent 实现自然的多轮对话流程,无需复杂对话管理即可根据用户对“是否查看营业时间”的回答,自动触发对应逻辑并保持上下文清晰。
在 Alexa 技能开发中,实现“用户说‘Yes’后自动执行某操作”这一需求,并不需要手动配置 ConfirmIntentDirective 或启用复杂对话委托(dialog delegation)——这些机制适用于带槽位的多步表单填写场景,而本例本质是一个简单的二元决策(Yes/No),应优先使用 Alexa 提供的内置意图。
✅ 正确做法:用 Session Attributes + 内置 Yes/No Intent
核心思路是:
- 在 LaunchRequest 中设置一个会话级标记(如 offeredOpeningHours: true);
- 当用户回应 “Yes” 时,由 AMAZON.YesIntent 捕获,并检查该标记是否存在且为真;
- 若匹配,则执行对应业务逻辑(如播报营业时间),并立即清除标记,避免后续误触发;
- 同理处理 AMAZON.NoIntent,保持状态干净。
? 技能模型配置(必要步骤)
确保你的 interaction model 中已声明:
{
"interactionModel": {
"languageModel": {
"invocationName": "coffee shop",
"intents": [
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.YesIntent",
"samples": []
},
{
"name": "AMAZON.NoIntent",
"samples": []
}
]
}
}
}
⚠️ 注意:AMAZON.YesIntent 和 AMAZON.NoIntent 无需添加 sample utterances,Alexa 会自动识别常见肯定/否定表达(如 “yes”, “yeah”, “sure”, “no”, “nah” 等)。
? 示例代码(Node.js SDK v3)
const LaunchRequestHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
sessionAttributes.offeredOpeningHours = true; // 标记已提供选项
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
const speakOutput = 'Welcome to Coffee Shop! Would you like to know our hours of operation?';
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt(speakOutput) // 引导用户明确回应
.getResponse();
}
};
const YesIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.YesIntent';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
if (sessionAttributes.offeredOpeningHours === true) {
// 执行营业时间逻辑
const speakOutput = 'We are open from nine AM to five PM. What else can I help with?';
// 清除标记,防止重复触发
delete sessionAttributes.offeredOpeningHours;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt('What else can I help with?')
.getResponse();
} else {
// 无上下文时的兜底响应
return handlerInput.responseBuilder
.speak("I'm not sure what you're saying yes to. Could you please rephrase?")
.reprompt("Can you clarify?")
.getResponse();
}
}
};
const NoIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'AMAZON.NoIntent';
},
handle(handlerInput) {
const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
delete sessionAttributes.offeredOpeningHours;
handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
const speakOutput = "Ok, have a good day!";
return handlerInput.responseBuilder
.speak(speakOutput)
.withShouldEndSession(true) // 主动结束会话
.getResponse();
}
};
// 不再需要 OperationalHoursIntent —— 它已被 YesIntent 替代
? 关键注意事项
- 不要依赖 ConfirmIntentDirective:它仅用于确认用户对当前意图内槽位值的确认(如“您要的是大杯还是中杯?”),不适用于跨意图跳转。
- 务必清理 session attributes:否则后续任意“yes”都可能误触发营业时间播报,导致体验混乱。
- Always end with a clear prompt or session closure:避免静默结束,提升交互完整性(如 "What else can I help with?" 或 withShouldEndSession(true))。
- 测试真实语音输入:模拟器中直接输入 “yes” 可能不如真实设备识别准确,建议真机测试多种表达("yeah", "sure", "yep")。
通过这种轻量、可扩展的设计,你不仅能解决当前需求,也为未来添加更多 Yes/No 分支(如“是否订阅通知?”、“是否重试?”)打下清晰的状态管理基础。










