Alexa无法识别意图
Posted
技术标签:
【中文标题】Alexa无法识别意图【英文标题】:alexa not recognizing intent 【发布时间】:2019-01-05 15:35:03 【问题描述】:我正在尝试将自己的响应添加到自定义意图。 LaunchRequest 文本有效,但除了 AMAZON.HelpIntent 和其他默认意图之外,我自己的意图没有得到识别。
意图:
"interactionModel":
"languageModel":
"invocationName": "my personal heartbeat",
"intents": [
"name": "AMAZON.FallbackIntent",
"samples": []
,
"name": "AMAZON.CancelIntent",
"samples": []
,
"name": "AMAZON.HelpIntent",
"samples": []
,
"name": "AMAZON.StopIntent",
"samples": []
,
"name": "start",
"slots": [],
"samples": [
"Talk to my personal heartbeat"
]
,
"name": "currentbpm",
"slots": [],
"samples": [
"what's my current BPM",
"how fast is my heart beating right now",
"How many beats per minute is my heart making at the moment"
]
],
"types": []
index.js(改编自 nodejs 教程的示例:https://github.com/alexa/skill-sample-nodejs-fact/blob/en-US/lambda/custom/index.js 我添加了 CurrentBPM 函数并将其添加到底部的 addRequestHandlers 中。它看起来匹配的意图名称是上面列表中的 currentbpm 意图。
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require('ask-sdk');
const GetNewFactHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'GetNewFactIntent');
,
handle(handlerInput)
const speechOutput = "Welcome to your personal heart health monitor. What would you like to know?";
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(speechOutput)
.getResponse();
,
;
const CurrentBPMHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'currentbpm';
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak('seventy five bpm')
.reprompt('seventy five bpm')
.getResponse();
,
;
const HelpHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'AMAZON.HelpIntent';
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak(HELP_MESSAGE)
.reprompt(HELP_REPROMPT)
.getResponse();
,
;
const ExitHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.CancelIntent'
|| request.intent.name === 'AMAZON.StopIntent');
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak(STOP_MESSAGE)
.getResponse();
,
;
const SessionEndedRequestHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
,
handle(handlerInput)
console.log(`Session ended with reason: $handlerInput.requestEnvelope.request.reason`);
return handlerInput.responseBuilder.getResponse();
,
;
const ErrorHandler =
canHandle()
return true;
,
handle(handlerInput, error)
console.log(`Error handled: $error.message`);
return handlerInput.responseBuilder
.speak('Sorry, an error occurred.')
.reprompt('Sorry, an error occurred.')
.getResponse();
,
;
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
.addRequestHandlers(
GetNewFactHandler,
CurrentBPMHandler,
HelpHandler,
ExitHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
当我调用该技能时: “Alexa 开始了我的个人心跳。” 它确实说出了剧本中的欢迎词。但是当我当时问“我现在的心跳有多快”时,它只会回答“抱歉,不确定”,而不是说出硬编码的回答。
【问题讨论】:
【参考方案1】:解决办法是在LaunchRequest的响应中加一行:
.withShouldEndSession(false)
如果不添加,则默认设置为true,因此技能会在给出第一个响应(欢迎意图)后立即结束。 见文档:https://ask-sdk-for-nodejs.readthedocs.io/en/latest/Response-Building.html
感谢Suneet Patil 我相应地更新了脚本(见下文) 起初只有这样有效:
用户:“Alexa,问问我个人的心跳,我现在的心跳有多快。” Alexa:'75 bpm'但我无法达到目的:
用户:“Alexa 与我的个人心跳对话” Alexa:“欢迎使用您的个人心脏健康监测器。你想知道什么?'(默认退出技能) 用户:“我现在的心跳有多快?” Alexa:“抱歉,我不确定。”使用下面的新脚本:
/* eslint-disable func-names */
/* eslint-disable no-console */
const Alexa = require('ask-sdk');
const GetNewFactHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'start');
,
handle(handlerInput)
const speechOutput = "Welcome to your personal heart health monitor. What would you like to know?";
return handlerInput.responseBuilder
.speak(speechOutput)
.withSimpleCard(speechOutput)
.withShouldEndSession(false)
.getResponse();
,
;
const CurrentBPMHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'currentbpm';
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak('seventy five bpm')
.reprompt('seventy five bpm')
.getResponse();
,
;
const HelpHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& request.intent.name === 'AMAZON.HelpIntent';
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak(HELP_MESSAGE)
.reprompt(HELP_REPROMPT)
.getResponse();
,
;
const ExitHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'IntentRequest'
&& (request.intent.name === 'AMAZON.CancelIntent'
|| request.intent.name === 'AMAZON.StopIntent');
,
handle(handlerInput)
return handlerInput.responseBuilder
.speak(STOP_MESSAGE)
.getResponse();
,
;
const SessionEndedRequestHandler =
canHandle(handlerInput)
const request = handlerInput.requestEnvelope.request;
return request.type === 'SessionEndedRequest';
,
handle(handlerInput)
console.log(`Session ended with reason: $handlerInput.requestEnvelope.request.reason`);
return handlerInput.responseBuilder.getResponse();
,
;
const ErrorHandler =
canHandle()
return true;
,
handle(handlerInput, error)
console.log(`Error handled: $error.message`);
return handlerInput.responseBuilder
.speak('Sorry, an error occurred.')
.reprompt('Sorry, an error occurred.')
.getResponse();
,
;
const HELP_MESSAGE = 'You can say tell me a space fact, or, you can say exit... What can I help you with?';
const HELP_REPROMPT = 'What can I help you with?';
const STOP_MESSAGE = 'Goodbye!';
const skillBuilder = Alexa.SkillBuilders.standard();
exports.handler = skillBuilder
.addRequestHandlers(
GetNewFactHandler,
CurrentBPMHandler,
HelpHandler,
ExitHandler,
SessionEndedRequestHandler
)
.addErrorHandlers(ErrorHandler)
.lambda();
现在可以了:
用户:“Alexa 与我的个人心跳对话” Alexa:“欢迎来到您的 个人心脏健康监测器。你想知道什么?' 用户:“我现在的心跳有多快?” Alexa:'75 bpm。'(技能保持开放状态以提出另一个问题)【讨论】:
这是正确的解决方案。给定的代码按预期执行。 非常感谢。为我节省了很多时间。【参考方案2】:对于任何请求,如果未提供,shouldEndSession
默认为 true
。在您的情况下,对 LaunchRequest
的响应将没有此 shouldEndSession
参数并且会话关闭。
尽管您始终可以使用 ask-nodejs-sdk's shouldEndSession(false)
来保持会话保持活动状态,但您不必每次都专门将其设置为 false。相反,更好的方法是在您的LaunchRequest
中使用reprompt
。如果您包含reprompt()
,那么sdk 会在您的回复中自动添加"shouldEndSession": false
。
使用您现在的代码,您的LaunchRequest
将等待 8 秒,如果没有用户响应,会话将关闭。但是,对于CurrentBPMHandler
或HelpHandler
,您已经包含了一个重新提示,它将在reprompt
之后再等待8 秒。当您期望用户的响应时,包含一个重新提示总是一个好主意。
您的交互模型定义了 AMAZON.FallbackIntent
意图,但您尚未在代码中处理它。 AMAZON.FallbackIntent
可帮助您处理意外的话语,或者当用户说出与您技能中的任何意图无关的内容时。如果没有处理程序,那么它将被您的错误处理程序捕获。将其作为错误处理没有问题,但更好的方法是专门为此添加一个处理程序并给出类似“对不起,我不明白,请您改写您的问题”的响应 em> 或类似的东西。
【讨论】:
【参考方案3】:请进行以下更改以使其有效。 1. 在交互模型中,intent start 只需给出与“to start”相同的话语,而不是 current。 例如:Alexa,让我的个人心跳开始。
在您的 lambda 代码中,在 getnewfact 方法的 lambda 代码中,您忘记将意图的名称从 getnewfactintent 更改为 start。
要调用 currentbpm 意图,请使用“Alexa,询问我的个人心跳我现在的心跳有多快。
希望这会有所帮助。
【讨论】:
您的三个建议都有效,谢谢!我觉得我真的很亲近。但是对于第 3 点:我想要实现的是使用 LaunchRequest 来打开技能。然后在技能中询问它当前的bpm意图,而不是在外部。 (所以在实际的意图请求之前,我不必问“Alexa 询问我的个人心跳......”。)就像谷歌助手一样,你问“Ok Google 与我的个人心跳交谈”。然后你可以问“我现在的心跳有多快”。 默认情况下,Alexa 会在响应后立即结束会话,因此当您问任何问题时,它不会达到您的技能水平并且不会给出您期望的正确响应。这是 Alexa 的行为。因此,请将 shudendsession(false) 设置为您从 Launch 请求意图发送的响应。它会工作.. 谢谢,这成功了!我将根据您的调整更新工作脚本。 干杯...希望我的代码和建议对您有所帮助。如果是,请接受我的回答以上是关于Alexa无法识别意图的主要内容,如果未能解决你的问题,请参考以下文章