Alexa Python 开发:构建和部署 Alexa 技能
目录
就在几年前,智能家居扬声器还是一个新颖的想法。今天,它们已成为许多人家庭和办公室的核心部分,而且它们的采用率预计只会增长。这些设备中最受欢迎的是由亚马逊 Alexa 控制的设备。在本教程中,您将通过部署您自己的 Alexa 技能成为Alexa Python 开发人员,该应用程序用户将使用语音命令与 Amazon Alexa 设备进行交互。
在本教程中,您将学习:
- Alexa 技能的主要组成部分是什么
- 如何设置 Alexa 技能并创建意图
- 什么是
ask_sdk_core
Alexa Python 包 - 如何使用
ask_sdk_core
Alexa Python 技能创建业务逻辑 - 如何使用在线开发人员控制台构建、部署和测试您的 Alexa Python 技能
Alexa Python 开发入门
要学习本教程,您需要创建一个免费的 Alexa开发者帐户。在该页面上,您将执行以下步骤:
- 单击开始按钮。
- 单击后续页面上的注册按钮。
- 单击创建您的亚马逊帐户。
- 使用所需的详细信息填写表格。
- 单击提交以完成注册过程。
您还需要熟悉Python 中的列表和字典等概念,以及 JavaScript 对象表示法 (JSON)。如果您不熟悉 JSON,请查看在 Python 中使用 JSON 数据。
了解 Alexa 技能
Alexa Python 开发人员必须熟悉许多不同的 Alexa 技能组件,但最重要的两个组件是界面和服务:
- 技能界面处理用户的语音输入并将其映射到意图。
- 技能服务包含确定给定用户输入的响应并将其作为 JSON 对象返回的所有业务逻辑。
技能界面将是您的 Alexa 技能的前端。您将在此处定义将执行特定功能的意图和调用短语。本质上,这是负责与用户交互的技能的一部分。
技能服务将成为您的 Alexa 技能的后端。当用户触发特定意图时,它将将该信息作为请求发送到技能服务。这将包含要与有价值的信息一起返回给前端的业务逻辑,这些信息最终将被转发回用户。
设置您的环境
是时候开始构建您的第一个 Alexa Python 技能了!登录到 Alexa开发人员控制台,然后单击“创建技能”按钮开始。在下一页上,输入技能名称,即Joke Bot:
这将是您技能的调用短语。这是用户开始使用您的 Alexa 技能时会说的短语。如果您愿意,您可以稍后将其更改为其他内容。另请注意,Alexa 技能可以用多种语言进行交互,您可以从“默认语言”下拉菜单中看到。现在,只需将其设置为English (US)。
接下来,您需要选择一个模型以添加到您的技能中。这些模型就像 Amazon 团队预先设计的模板,可帮助您基于一些常见用例开始 Alexa Python 开发。对于本教程,您应该选择自定义模型。
最后,您需要选择一种方法来托管 Alexa 技能的后端。此服务将包含您的应用程序的业务逻辑。
注意:如果您选择Provision your own选项,则您必须为您的 Alexa Python 项目托管您自己的后端。这可以是在您选择的平台上构建和托管的API。另一种选择是创建一个单独的 AWS Lambda 函数并将其链接到您的 Alexa 技能。您可以在他们的定价页面上了解有关 AWS Lambda 定价的更多信息。
现在,选择Alexa-Hosted (Python)作为 Alexa 技能的后端。这将自动为您提供 AWS 免费套餐内的托管后端,因此您无需预先支付任何费用或立即设置复杂的后端。
最后,单击“创建技能”按钮继续。您可能会被要求在此处填写 CAPTCHA,因此也请务必填写。大约一分钟后,您应该被重定向到开发者控制台的Build部分。
了解 Alexa 技能模型
登录 Alexa 开发人员控制台并选择或创建技能后,您将看到“构建”部分。此部分为您提供了许多选项和控件来设置技能的交互模型。此交互模型的组件允许您定义用户将如何与您的技能交互。这些属性可以通过左侧面板访问,它看起来像这样:
作为 Alexa Python 开发人员,您需要了解 Alexa 技能交互模型的一些组件。首先是调用。这是用户开始与您的 Alexa 技能交互时会说的话。例如,用户会说“Joke Bot”来调用您将在本教程中构建的 Alexa 技能。您可以随时从“调用”部分更改此设置。
另一个组件是intent,它代表您的应用程序的核心功能。您的应用程序将具有一组意图,这些意图将代表您的技能可以执行的操作类型。要为给定意图提供上下文信息,您将使用一个槽,它是话语短语中的一个变量。
考虑以下示例。调用天气意图的示例语句可能是,“告诉我有关天气的信息。” 为了使技能更有用,您可以将意图设置为“告诉我芝加哥的天气”,其中“芝加哥”一词将作为槽变量传递,从而改善用户体验。
最后,还有槽类型,它们定义了如何处理和识别槽中的数据。例如,AMAZON.DATE槽类型可以轻松地将指示日期的单词(例如“今天、明天”等)转换为标准日期格式(例如“2019-07-05”)。您可以查看官方插槽类型参考页面以了解更多信息。
注意:要了解有关 Alexa 技能交互模型的更多信息,请查看官方文档。
此时,Intents面板应该是打开的。如果不是,那么您可以通过从左侧边栏中选择Intents来打开它。您会注意到默认情况下已经设置了五个意图:
的意图面板包括HelloWorldIntent和五个内置意图。内置意图是为了提醒您考虑一些对于制作用户友好机器人很重要的常见情况。以下是简要概述:
- AMAZON.CancelIntent允许用户取消交易或任务。示例包括“没关系”、“算了”、“退出”和“取消”,但还有其他一些示例。
- AMAZON.HelpIntent提供有关如何使用技能的帮助。这可用于返回一个句子,作为用户如何与您的技能交互的手册。
- AMAZON.StopIntent允许用户退出技能。
- AMAZON.NavigateHomeIntent将用户导航到设备主屏幕(如果正在使用屏幕)并结束技能会话。
默认情况下,没有分配用于触发这些意图的示例话语,因此您还必须添加这些。将其视为 Alexa Python 开发人员培训的一部分。您可以在官方文档 中了解有关这些内置意图的更多信息。
查看示例意图
在本教程的稍后部分,您将学习如何创建新意图,但现在,最好查看一些现有意图,这些意图是您创建的每项新技能的一部分。首先,单击HelloWorldIntent以查看其属性:
您可以看到用户可以用来调用此意图的示例话语。调用此意图时,此信息将发送到您的 Alexa 技能的后端服务,然后该服务将执行所需的业务逻辑并返回响应。
在此之下,您可以选择设置对话委托策略,它允许您将您定义的特定对话委托给特定意图。虽然您不会在本教程中介绍这一点,但您可以在官方文档 中阅读更多相关信息。
接下来,您可以选择为您的意图应该收集的某些特定数据定义槽。例如,如果您要创建一个 Intent 来告知给定日期的天气,那么您将在此处有一个Date槽,用于收集日期信息并将其发送到您的后端服务。
注意:此外,当您在单个意图中从用户那里收集多个不同的数据点并且您希望在将其发送以进行进一步处理之前提示用户时,意图确认选项可能很有用。
每当您对意图进行更改时,您都需要单击“保存模型”按钮来保存它。然后,您可以单击“构建模型”按钮继续测试您的 Alexa Python 技能。
知道技能的交互模型可以完全以JSON格式表示是有帮助的。要查看 Alexa 技能的当前结构,请单击控制台左侧面板中的JSON 编辑器选项:
如果您直接使用 JSON 编辑器进行更改,那么这些更改也会反映在开发人员控制台 UI 中。要测试此行为,请添加新意图并单击Save Model。
对技能的交互模型进行所有必要的更改后,您可以打开开发人员控制台的测试部分来测试您的技能。测试是成为 Alexa Python 开发人员的重要组成部分,因此请务必不要跳过此步骤!单击开发人员控制台顶部导航栏中的“测试”按钮。默认情况下,测试将被禁用。从下拉菜单中,选择Development开始测试:
在这里,您有多种方法可以测试您的 Alexa Python 技能。让我们做一个快速测试,以便您了解您的 Alexa 技能将如何响应话语。
从左侧面板中选择Alexa Simulator选项,然后输入短语“嘿 Alexa,打开 Joke Bot”。您可以通过在输入框中键入它或使用麦克风选项来执行此操作。几秒钟后,一个响应将返回给您:
除了语音响应之外,您还可以看到发送到 Alexa 技能后端服务的JSON 输入,以及接收回控制台的JSON 输出:
这是到目前为止发生的事情:
- JSON 输入对象是根据用户通过语音或文本输入的输入数据构建的。
- Alexa 模拟器将输入与其他相关元数据打包在一起,并将其发送到后端服务。您可以在JSON 输入框中看到这一点。
- 后端服务接收输入的 JSON 对象并对其进行解析以检查请求的类型。然后,它将 JSON 传递给相关的意图处理函数。
- 意图处理程序函数处理输入并收集所需的响应,该响应作为 JSON 响应发送回 Alexa 模拟器。您可以在JSON 输出框中看到这一点。
- Alexa 模拟器解析了这个 JSON 并将语音响应读回给您。
注意:您可以在官方文档 中阅读有关 Alexa 技能的 JSON 请求-响应机制。
现在您已经了解了 Alexa 技能的不同组成部分以及信息如何从一个部分流向另一个部分,是时候开始构建您的笑话机器人了!在下一部分中,您将通过创建新意图来测试您的 Alexa Python 开发人员技能。
创建新意图
让我们从创建JokeIntent开始,它将从列表中向用户返回一个随机笑话。打开Alexa 开发人员控制台的Build部分。然后,单击左侧面板中Intents选项旁边的Add按钮:
随着创建自定义意图选项中选择,将名称设置为JokeIntent,然后点击创建自定义的意图按钮:
接下来,您需要添加用户将说出的示例话语以调用此意图。这些可以是“给我讲个笑话”或“我想听个笑话”之类的短语。输入短语并单击加号 ( +
) 将其添加为示例话语。这应该是这样的:
您可以添加更多示例话语,但就目前而言,这些都可以。最后,单击窗口左上角的保存模型按钮以保存这些更改。
请记住,您需要先构建模型,然后才能对其进行测试。单击构建模型按钮以重新构建 Alexa Python 技能的交互模型。您会在浏览器窗口的右下角看到进度通知。构建过程成功后,您应该会看到另一个弹出通知,指示构建过程的状态。
您可以检查是否成功触发了JokeIntent。单击开发者控制台右上角的Evaluate Model按钮。旁边会弹出一个小窗口,让您可以检查给定的输入话语将触发什么意图。输入任何示例话语以确保成功调用JokeIntent。
要摆脱评估弹出窗口,请再次单击评估模型按钮。
注意:这里要记住的一个关键点是,该模型在作为示例话语短语一部分的关键字方面非常灵活。例如,使用短语“这是某种玩笑吗?” 即使是这句话也会触发JokeIntent。作为 Alexa Python 开发人员,选择在您的技能中执行其他意图的可能性较低的话语非常重要。
现在您已经成功创建了一个意图,是时候编写 Python 代码来处理这个意图并返回一个笑话作为响应。
构建技能后端
现在您已经创建了一个可由用户触发的意图,您需要在技能后端添加功能来处理此意图并返回有用的信息。打开Alexa 开发人员控制台的代码部分以开始使用。
注意:由于您在设置过程中选择了 Alexa-Hosted Python 选项,您将获得一个完整的在线代码编辑器,您可以在其中编写、测试、构建和部署 Alexa 技能的后端,所有这些都在开发人员控制台中完成。
当您打开开发者控制台的代码部分时,您可以看到一个在线代码编辑器,其中包含一些已经设置好的文件供您开始使用。特别是,您将在lambda子目录中看到以下三个文件:
- lambda_function.py:这是后端服务的主要入口点。来自 Alexa 意图的所有请求数据都在此处接收,并且应该仅从此文件返回。
- requirements.txt:此文件包含此项目中正在使用的 Python 包的列表。如果您选择设置自己的后端服务而不是使用亚马逊提供的服务,这将特别有用。要了解有关需求文件的更多信息,请查看使用需求文件。
- utils.py:此文件包含 lambda 函数与Amazon S3服务交互所需的一些实用程序函数。它包含一些关于如何从 Amazon S3 存储桶中获取数据的示例代码,稍后您可能会发现这些代码很有用。目前,该文件未在
lambda_function.py
.
现在,您只会在 中进行更改lambda_function.py
,因此让我们仔细看看文件的结构:
7import logging
8import ask_sdk_core.utils as ask_utils
9
10from ask_sdk_core.skill_builder import SkillBuilder
11from ask_sdk_core.dispatch_components import AbstractRequestHandler
12from ask_sdk_core.dispatch_components import AbstractExceptionHandler
13from ask_sdk_core.handler_input import HandlerInput
14
15from ask_sdk_model import Response
16
17logger = logging.getLogger(__name__)
18logger.setLevel(logging.INFO)
19
20
21class LaunchRequestHandler(AbstractRequestHandler):
22 """Handler for Skill Launch."""
23 def can_handle(self, handler_input):
24 # type: (HandlerInput) -> bool
25
26 return ask_utils.is_request_type("LaunchRequest")(handler_input)
27
28 def handle(self, handler_input):
29 # type: (HandlerInput) -> Response
30 speak_output = "Welcome, you can say Hello or Help. " \
31 "Which would you like to try?"
32
33 return (
34 handler_input.response_builder
35 .speak(speak_output)
36 .ask(speak_output)
37 .response
38 )
39...
首先,您导入ask_sdk_core
Alexa Python 包中提供的必要实用程序。然后,您需要执行三个主要任务lambda_function.py
来处理来自 Alexa 技能前端的意图的请求:
- 创建一个意图处理程序类,该类继承自
AbstractRequestHandler
该类,具有函数can_handle()
和handle()
. 已经有一对情侣在定义的处理程序类lambda_function.py
,如LaunchRequestHandler
,HelpIntentHandler
等。这些处理 Alexa 技能的基本意图。这里需要注意的重要一点是,您需要为您定义的每个意图创建一个新的意图处理程序类。 - 创建一个
SkillBuilder
对象,作为您的 Alexa Python 技能的入口点。这会将所有传入的请求和响应负载路由到您定义的意图处理程序。 - 将意图处理程序类作为参数传递
.add_request_handler()
给 ,以便在收到新请求时按顺序调用它们。这SkillBuilder
是一个单例,因此只需要它的一个实例来处理所有传入请求的路由。
这是你经历的好时机lambda_function.py
。您会注意到,重复使用相同的模式来处理可以由您的 Alexa Python 技能触发的不同意图。
既然您已经对在后端处理 Intent 所需执行的所有不同事情有了一个广泛的了解,现在是时候编写将处理您在上一节中构建的JokeIntent的代码了。
创建 JokeIntent 处理程序
由于ask_sdk_core
Alexa Python 包中的重要实用程序已经导入,因此您无需再次导入它们。如果你想更深入地了解这些,那么你可以查看官方文档。
接下来,您将创建一个新的意图处理程序来处理从JokeIntent收到的请求。在下面的代码片段中,意图处理程序将简单地返回一个示例短语。这表明从后端收到了对JokeIntent的响应。将以下代码添加到lambda_function.py
的类定义上方LaunchRequestHandler()
:
20class JokeIntentHandler(AbstractRequestHandler):
21 def can_handle(self, handler_input):
22 return ask_utils.is_intent_name("JokeIntent")(handler_input)
23
24 def handle(self, handler_input):
25 speak_output = "Here's a sample joke for you."
26
27 return (
28 handler_input.response_builder
29 .speak(speak_output)
30 .ask(speak_output)
31 .response
32 )
让我们来看看每个部分的作用。在第 20 行中,您为JokeIntent创建了一个新的意图处理程序类,它是该类的子AbstractRequestHandler
类。当您在前端创建意图时,您需要在后端创建一个可以处理来自 Alexa 的请求的意图处理程序类。您为此编写的代码需要做两件事:
JokeIntentHandler.can_handle()
识别 Alexa 发送的每个传入请求。JokeIntentHandler.handle()
返回适当的响应。
在第 21 行中,您定义了.can_handle()
. 它handler_input
作为一个参数传入,它是一个dict()
包含所有输入请求信息的类型的对象。然后,它使用ask_utils.is_intent_name()
或ask_utils.is_request_type()
来检查它收到的 JSON 输入是否可以由这个意图处理程序函数处理。
您使用.is_intent_name()
并传入意图的名称。这将返回一个predicate,它是一个函数对象,True
如果给定handler_input
来自指示的意图则返回。如果这是真的,则SkillBuilder
对象将调用JokeIntentHandler.handle()
。
注意:如果JokeIntent是从 Alexa 技能前端触发的,那么它会发送一个 JSON 对象,该对象type
的正文中包含一个键request
,表明JokeIntent
已接收到名为输入的 Intent 。
此语句随后调用.handle()
您在第 24 行中定义的。此方法接收输入请求以及可能需要的任何其他重要信息。它包含成功处理特定意图所需的业务逻辑。在JokeIntent的情况下,需要此方法将包含笑话的响应发送回 Alexa 前端。
该speak_ouput
变量包含将由 Alexa 技能前端讲回给用户的句子。speak(speak_output)
指示 Alexa 前端将作为语音向用户播放的内容。ask("Question to ask...")
可用于提出后续问题。在此方法中,类的对象response_builder
将响应返回给 Alexa 技能。
注意:Sorry, I had trouble doing what you asked. Please try again.
如果.handle()
不存在,将发回默认响应消息 ( ) 。
请注意,现在的值speak_output
设置为固定响应。稍后您将更改此设置以从笑话列表中随机返回一个笑话。
这是您的代码在编辑器中的样子:
创建意图处理程序类后,您需要将其作为参数传递给SkillBuilder.add_request_handler
. 滚动到底部lambda_function.py
并添加以下行:
sb.add_request_handler(JokeIntentHandler())
这里需要注意的重要一点是,这一行的放置很重要,因为代码是从上到下处理的。因此,请确保对自定义意图处理程序的调用高于对InstantReflectHandler()
类的调用。这是它的外观:
171sb = SkillBuilder()
172
173sb.add_request_handler(LaunchRequestHandler())
174sb.add_request_handler(JokeIntentHandler())
175sb.add_request_handler(HelloWorldIntentHandler())
176sb.add_request_handler(HelpIntentHandler())
177sb.add_request_handler(CancelOrStopIntentHandler())
178sb.add_request_handler(SessionEndedRequestHandler())
179
180# Make sure IntentReflectorHandler is last so it
181# Doesn't override your custom intent handlers
182sb.add_request_handler(IntentReflectorHandler())
183
184sb.add_exception_handler(CatchAllExceptionHandler())
185
186...
好了,是时候测试你的代码了!单击“部署”按钮以保存更改并部署后端服务。您将通过 Alexa 技能前端检查它是否会按预期工作。
部署过程成功后,返回开发人员控制台的测试部分并调用JokeIntent。请记住,输入话语短语以调用您的 Alexa Python 技能,然后输入短语以执行意图:
如果您收到与上图中类似的响应,则表示您已成功为技能后端服务中的JokeIntent创建了一个意图处理程序。恭喜!现在,剩下要做的就是将列表中的随机笑话返回到技能前端。
Adding Jokes
打开开发者控制台的代码部分。然后,添加jokes
变量lambda_function.py
:
15from ask_sdk_model import Response
16
17logger = logging.getLogger(__name__)
18logger.setLevel(logging.INFO)
19
20jokes = [
21 "Did you hear about the semi-colon that broke the law? He was given two consecutive sentences.",
22 "I ate a clock yesterday, it was very time-consuming.",
23 "I've just written a song about tortillas; actually, it's more of a rap.",
24 "I woke up this morning and forgot which side the sun rises from, then it dawned on me.",
25 "I recently decided to sell my vacuum cleaner as all it was doing was gathering dust.",
26 "If you shouldn't eat at night, why do they put a light in the fridge?",
27 ]
28
29class JokeIntentHandler(AbstractRequestHandler):
30...
这jokes
是一个list
包含一些单行笑话的类型变量。确保在函数或类定义之外添加它,以便它具有全局作用域。
注意:由于这个列表只会被JokeIntentHandler()
类引用,所以你是否在函数体中声明它并不重要。然而,这样做确实有助于函数体摆脱混乱。
接下来,您将添加.handle()
需要从笑话列表中随机选择一个笑话并将其返回给用户的功能。JokeIntentHandler.handle()
使用以下代码修改的主体:
29class JokeIntentHandler(AbstractRequestHandler):
30 def can_handle(self, handler_input):
31 return ask_utils.is_intent_name("JokeIntent")(handler_input)
32
33 def handle(self, handler_input):
34 speak_output = random.choice(jokes)
35
36 return (
37 handler_input.response_builder
38 .speak(speak_output)
39 .ask(speak_output)
40 .response
41 )
在 的正文中.handle()
,您jokes
使用从列表中随机选择一个笑话random.choice()
并将其返回作为对 Alexa 技能前端的响应。
最后,random
通过在 顶部添加 import 语句来导入包lambda_function.py
:
15from ask_sdk_model import Response
16
17import random
18
19logger = logging.getLogger(__name__)
20logger.setLevel(logging.INFO)
21
22...
这是编辑应该如何看待这一点:
在测试之前还有一个最后的改变。您需要允许 Alexa确认该技能已被触发。为此,请在内部LaunchRequestHandler.handle()
查找speak_output
变量并将其值设置为下面突出显示的行中的文本:
45class LaunchRequestHandler(AbstractRequestHandler):
46 """Handler for Skill Launch."""
47 def can_handle(self, handler_input):
48 # type: (HandlerInput) -> bool
49
50 return ask_utils.is_request_type("LaunchRequest")(handler_input)
51
52 def handle(self, handler_input):
53 # type: (HandlerInput) -> Response
54 speak_output = "Hey there! I am a Joke Bot. You can ask me to tell you a random Joke that might just make your day better!"
55
56 return (
57 handler_input.response_builder
58 .speak(speak_output)
59 .ask(speak_output)
60 .response
61 )
62...
您的笑话机器人已准备好进行最终测试!单击Deploy按钮保存更改并返回到开发者控制台的Test部分。这一次,您应该会在第一次调用您的技能时看到一条新的问候消息。然后,当你让机器人给你讲一个笑话时,它每次都应该给你一个不同的笑话:
而已!您已经成功地创建了作为 Alexa Python 开发人员的第一个技能!
结论
恭喜您迈出 Alexa Python 开发的第一步!您现在已经成功构建了您自己的 Alexa Python 技能。您现在知道如何创建新技能、创建意图、编写 Python 代码来处理这些意图并将有价值的信息返回给用户。
通过尝试以下一些方法来提升您的技能:
- 增加后台的笑话列表。
- 创建一个名为Trivia的新意图,它将以一个有趣的琐事事实作为回应。
- 将您的技能发布到亚马逊市场。
可能性是无限的,所以继续深入吧!要了解有关 Alexa Python 开发的更多信息,请查看官方文档。您还可以查看如何使用 Tweepy 在 Python 中制作 Twitter 机器人和如何在 Python中制作 Discord 机器人,以了解有关如何使用 Python 为不同平台制作机器人的更多信息。
- 点赞
- 收藏
- 关注作者
评论(0)