"alexa, ask NiuNiu open the light." 如果你这样说,但是技能不知道你要开哪个灯,这时候技能就应该提示用户“Which light do you open?”, 接着执行下面的动作,这就是多轮对话。
首先,你需要登录到alexa skill 控制台,创建一个custom skill。
在控制台里面设置你的对话模型。对话模型设置完之后,需要接入endpoint,可以是你自己的服务器,也可以是lambda函数,在这里本人使用lambda函数。
设置对话模型里面几个重要参数:
1、技能调用名,即通过这个名字才能调用到这个技能,就像上面"NiuNiu"就是一个技能调用名。
2、意图,“open”就是一个意图,怎么才能让技能知道你的意图呢?就需要样本话语了。
3、槽位,就是想设置一些关键字,通过这句话能不能获取到相应的关键字;
4、槽位类型,关键字可以看成是一个变量,变量就有很多类型,如int, char等。
如果你想支持多轮对话,必须要使能槽位填充,即,当技能发现你的对话里面没有包含相应的槽位值时,会提示用户该怎么做?以上步骤网上资料很多就不详细写出来了,最好阅读alexa官方文档。
其次,前面说了对话模型设置完之后,需要接入endpoint,本人使用lambda函数,这个函数是技能的主要部分,对话模型相当于一个界面,lambda函数才是处理后台逻辑的关键部分。在这里关键讨论多轮对话的实现方式,具体技能是用来干什么的由开发者自己定义。开始以为对话模型设置好了,使能槽位填充就能实现多轮对话了,后来测试发现不是这么回事。通过对官方文档的理解,多轮对话是需要lambda函数进行处理的。多轮对话有三种方式:
1、托管(提示语句由控制台设置);
2、自己控制(提示语句由用户自己设置);
3、托管+自己控制(两种方式结合);
想要简单实现,使用方式1最好。
"alexa, ask NiuNiu open the light.", 这句被alexa云端处理之后,会产生相应的消息传入到lambda函数,lambda函数需要根据传过来的对话状态返回Delegate Directive,如果槽位填满了状态值就是COMPLETED。
代码示例如下:
通过 this.emit(':delegate') 返回delegate directive.
const handlers = {
'LedOpen': function () {
if (this.event.request.dialogState === 'STARTED') {
let updatedIntent = this.event.request.intent;
// Pre-fill slots: update the intent object with slot values for which
// you have defaults, then emit :delegate with this updated intent.
updatedIntent.slots.SlotName.value = 'DefaultValue';
this.emit(':delegate', updatedIntent);
} else if (this.event.request.dialogState !== 'COMPLETED'){
this.emit(':delegate');
} else {
// All the slots are filled (And confirmed if you choose to confirm slot/intent)
handlePlanMyTripIntent();
}
}
};
这段代码是node.js写的,可以参考https://www.npmjs.com/package/alexa-sdk#dialog-interface。