下载APP
登录
关闭
讲堂
算法训练营
Python 进阶训练营
企业服务
极客商城
客户端下载
兑换中心
渠道合作
推荐作者

如何基于Amazon Alexa创建一个语音对话技能?

2018-05-21 阿里巴巴智能语音交互团队

平台概述

相信不少人都知道亚马逊 Echo 智能音箱,这款产品的最大亮点是将智能语音交互技术植入到传统的音箱中,从而赋予了音箱人工智能的属性。革命性的产品背后往往有技术的推动,Echo 能够成功,依赖的杀手锏就是 Alexa。
Alexa 是亚马逊提供的语音服务,也是亚马逊 Echo 等设备的大脑。Alexa 让用户可以通过 Alexa Skills Kit 创建个性化技能(Skill),每个技能都能用来完成特定的用户服务,比如查询天气、订车等。目前 Alexa 上已经有星巴克、Uber 等公司设计创建的成千上万个技能,这些技能都可以应用到 Echo 等设备上。Alexa 的优势在于它基于云端,可以随时对这些技能进行改进,发布后就能被 Echo 用到。看到这里,你是不是想自己动手创建一个技能了呢?

技能建设

基于 Alexa 创建技能,首先需要注册亚马逊 AWS 账号,然后会分别用到 Alexa 和 AWS Lambda 服务。其中,Alexa (https://developer.amazon.com/alexa) 是用来创建技能和交互方式,并提供语义理解功能;AWS Lambda (https://aws.amazon.com/lambda) 是个 Serverless 的计算平台,用户只需要编写并上传函数式代码,Lambda 为用户提供了运行函数代码所需要的环境并保证高可用性,我们不需要自己管理服务器。
下面以常见的查询天气为例介绍一下怎么通过 Alexa Skills Kit 创建一个对话技能:

1. 语义理解

创建对话技能的第一步是建设语义理解部分。我们说了一句话,AWS 内置的 ASR 服务将其识别成文本后,首先要用到我们配置的语义理解,完成对这句话的实体抽取和意图识别,并填充相关信息到词槽。Alexa 提供了通过填槽配置的方式实现语义理解的功能。详细过程如下:
1.1 填写技能基本信息
这里主要设置当前技能类型、语言、技能名称和技能的调用名称。
Skill Type:技能类型选择 Custom Interaction Model(自定义交互模式)。
Language:Alexa Skill 目前只支持英语、德语和日语。
Name:名称是在 Alexa App 里展示你的技能时显示的名字。
Invocation Name:调用名称是通过 Alexa 来调用你的技能时的唤醒词,比如你对着 Echo 说一声:"Weather",就会唤醒相应的天气查询技能,然后与之进行对话。
保存技能基本信息后,会生成一个 Application Id,这个 Id 很重要,在 AWS Lambda 中就是通过这个 Id 与技能进行交互的,在后面会用到。
1.2 配置交互模式
在一个技能(Skill)内,可以创建多个意图。进入 Skill Builder 可以看到 Alexa Skills Kit 默认会创建名为 CancelIntent、HelpIntent 和 StopIntent 这三个意图。意图(Intent)就是用户想要的操作或命令。在语音交互系统中,意图通常表述为例句这种自然语言的形式。每个意图可以包含零到多个词槽(Slot),词槽就是从语句中抽取出来的实体。对于 Alexa 默认创建的意图,我们无需修改,点击ADD+添加一个新的意图实现查询天气。
添加意图
添加意图时可选择创建自定义意图,或者使用 Alexa 预置的意图。这里,我们选择创建一个自定义的新意图。填写意图名称为 "QueryWeather",然后点击Create Intent创建意图,这样在左侧菜单意图列表中会看到这个新建的意图。
添加样本语句
样本语句 (Sample Utterances) 为我们提供了定制触发该意图时要说的话。比如查询天气时,我们一般会说“今天天气怎么样”、“北京天气怎么样”、“北京明天天气怎么样”。样本要尽可能丰富,覆盖用户可能说的话。
抽取词槽
天气查询需要知道要查询的城市和日期。对于查询天气的 "What will be the weather like in Beijing tomorrow" 这句话,从中可以抽取出 "Beijing" 和 "tomorrow" 两个词槽。抽取词槽时需要设置词槽名称和类型,Alexa Skills Kit 提供了很多内置的词槽类型可供使用。词槽类型就是我们所说的实体,每个词槽类型内置一组词典,当内置词槽不能满足需要时,可以自定义词槽类型。在本例中,日期使用系统内置的日期词槽类型 AMAZON.DATE。" 城市 " 是我们自定义的词槽类型 "CITY_OF_CHINA"。下面是自定义词槽类型的过程。
点击词槽类型旁边的ADD+按钮添加词槽类型,同样,这里可以选择新建词槽类型或使用内置的词槽类型。我们选择新建词槽类型,输入名称 "CITY_OF_CHINA",点击 "Create Slot Type" 创建词槽类型按钮。
完成后在菜单上可以看到新建的 "CITY_OF_CHINA" 这个词槽类型。然后在右侧页面设置词槽的值,即实体词典,我们输入 "Beijing"、"Shanghai"、"Hongkong" 三个城市作为例子。
接下来就是从样本句子中抽取词槽,在样本句子上选中 "Beijing" 这个单词,在弹出的对话框上新建一个名为 "city" 的词槽。
在右侧的意图词槽列表部分可以看到刚才新建的 "city" 词槽,词槽类型选择刚才创建的 "CITY_OF_CHINA"
以同样的方式选中 "tomorrow",新建一个 "date" 词槽,选择 "AMAZON.DATE" 作为词槽类型。依次从其他样本语句中抽取词槽,最终的效果看起来如下图:
最后对抽取出来的词槽,可以配置当用户说的话里面词槽信息不完整时,是否要引导用户提供信息,以及引导方式。
保存构建
完成以上配置后,我们保存当前技能的配置并执行构建。构建完成后我们建设的技能就生效了。

2. 内容服务

如上所述,在我们创建的查询天气意图中,当用户说 "What is the weather like in Beijing tomorrow" 这句话后,Alexa 就能够理解当前的意图是 "QueryWeather",并抽取出 "Beijing"(city)和 "tomorrow"(date)两个词槽。有了这些信息,我们还需要提供一个查询天气的内容服务,通过城市、时间两个参数查询天气。查询天气我们调用一个第三方的天气服务,核心代码如下:
public String getWeather(String city, String date) throws IOException {
final String API_KEY = " 您自己的 APK KEY";
final String API_ENDPOINT = "http://api.worldweatheronline.com/premium/v1/weather.ashx";
String url = API_ENDPOINT + "?q=" + city + "&format=JSON&num_of_days=2&date=" + date + "&key=" + API_KEY;
Request request = new Request.Builder()
.url(url)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
上述调用内容服务的函数代码是部署在 AWS Lambda 上的,我们接着往下看就会搞清楚。

3. 对话函数

接下来我们需要做的就是把语义理解和内容服务结合起来,完成当用户的意图为查询天气且词槽都有值的时候,请求天气服务。这里可以采用两种方式:一种是自己搭建服务器,提供 HTTP 地址给 Alexa Skills Kit 调用;另一种是使用 AWS lambda。相比之下,使用 AWS Lambda 更方便,我们只用编写代码并上传到 Lambda 就可以调用服务。我们采用 AWS Lambda 的方式:
3.1 创建 Function
AWS Lambda 支持 Java、Python、NodeJs、Go、C# 几种语言和平台,这里选择使用 Java 语言,当然你也可以选择自己喜欢用的语言。
3.2 导入 Alexa Skills Kit
由于我们使用 AWS Lambda 是要为 Alexa Skills 提供服务,这里需要导入 Alexa Skills Kit 开发包,并配置 Skill ID。
3.3 开发并上传 Jar 包
Alexa Skill 的开发可以参考亚马逊官方提供的例子 (https://github.com/alexa/skill-samples-java) ,开发过程很简单,在 pom.xml 中引入alexa skill sdk,然后只需在代码中配置技能 ID,并针对每个意图返回对应的结果即可。下面给出两个代码片段说明,篇幅原因,只展示核心代码。
注册技能 ID:
public class SkillHandler extends SpeechletRequestStreamHandler {
private static final Set<String> supportedApplicationIds;
static {
// 设置技能 id,技能 id 可以在 alexa 控制台看到
supportedApplicationIds = new HashSet<>();
supportedApplicationIds.add(" 您自己的 alexa skill id");
}
// ...
}
处理对话意图:
public class SkillSpeechlet implements SpeechletV2 {
@Override
public SpeechletResponse onIntent(SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {
IntentRequest request = requestEnvelope.getRequest();
Intent intent = request.getIntent();
String intentName = intent.getName();
// 处理天气意图
if ("QueryWeather".equals(intentName)) {
String city = intent.getSlot("city").getValue();
String date = intent.getSlot("date").getValue();
// 调用上文的天气服务
String weatherData = getWeather(city, date);
// 构造要返回的数据结构
SimpleCard card = getSimpleCard("Weather", weatherData);
PlainTextOutputSpeech speech = getPlainTextOutputSpeech(weatherData);
return SpeechletResponse.newTellResponse(speech, card);
} else {
// 处理其他意图
}
}
}
开发完成后,打成 jar 包并上传即可。
3.4 测试 Function
AWS Lambda 提供了完善的测试机制,可以测试 function 的结果。测试结果无误后,可以保存给 Alexa Skills Kit 调用。
3.5 Alexa Skills Kit 配置 lambda
基于 AWS Lambda 开发完函数式对话代码后,只需要在 Alexa Skills Kit 的配置界面,设置 AWS Lambda 的地址就可以了。
其中 Lambda Function 的地址如下图所示:
复制该地址,在 Alexa Skills Kit 的 Configuration 页面配置即可。

4. 技能测试

Alexa Skills Kit 提供了模拟语音交互的模拟器,可以在这里测试上面配置的对话效果。
我们通过技能测试完成验证后,接下来就是发布了。到此,基于 Alexa 建设对话技能就结束了。

结语

从上面的介绍可以看到,使用亚马逊 Alexa Skills Kit 开发一个语音交互技能还是很简单的。开发完成后,不仅可以用在自己的 Echo 等设备上,也可以放在市场上让更多的人使用。
下一篇文章我们将详细介绍基于 Google Dialogflow 平台的技能建设。

参考

 写留言

精选留言(1)

  • 2019-12-02
    大佬,可以写下如何基于Google Dialogflow创建一个语音对话技能吗?