你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

开发自定义命令应用程序

重要

自定义命令将于 2026 年 4 月 30 日停用。 自 2023 年 10 月 30 日起,无法在 Speech Studio 中创建新的自定义命令应用程序。 与此更改相关的是,LUIS 将于 2025 年 10 月 1 日停用。 自 2023 年 4 月 1 日起,无法创建新的 LUIS 资源。

本操作指南文章介绍如何开发和配置自定义命令应用程序。 自定义命令功能可帮助你生成针对语音优先交互式体验进行优化的丰富语音命令应用。 该功能最适合用于“任务完成”或“指挥控制”方案。 它非常适合物联网 (IoT) 设备以及环境和无外设设备。

在本文中,你将创建一个可以打开和关闭电视、设置温度以及设置闹钟的应用程序。 创建这些基本命令后,你将了解用来对命令进行自定义的以下选项:

  • 将参数添加到命令
  • 将配置添加到命令参数
  • 生成交互规则
  • 创建语言生成模板以生成语音响应
  • 使用自定义语音工具

使用简单的命令创建应用程序

首先创建一个空的自定义命令应用程序。 有关详细信息,请参阅快速入门。 在此应用程序中创建一个空白项目,而不要导入项目。

  1. 在“名称”框中,输入项目名称 Smart-Room-Lite(或你所选的其他名称)。

  2. 在“语言”列表中选择“英语(美国)”。

  3. 选择或创建 LUIS 资源。

    Screenshot showing the

更新 LUIS 资源(可选)

可以更新你在“新建项目”窗口中选择的创作资源。 还可以设置预测资源。

发布自定义命令应用程序时,一个预测资源将会用于识别。 在开发和测试阶段无需使用预测资源。

添加 TurnOn 命令

在创建的空 Smart-Room-Lite 自定义命令应用程序中添加一个命令。 该命令会处理语句 Turn on the tv。 它使用消息 Ok, turning the tv on 进行响应。

  1. 在左侧窗格的顶部选择“新建命令”以创建一条新命令。 此时会打开“新建命令”窗口。
  2. 在“名称”字段中,提供值 TurnOn
  3. 选择“创建”。

中间窗格将列出命令的属性。

下表解释了命令的配置属性。 有关详细信息,请参阅自定义命令的概念和定义

配置 说明
示例句子 用户可以说出的用于触发此命令的示例言语。
参数 完成该命令而需要的信息。
完成规则 为履行该命令而要执行的操作。 示例:向用户做出响应,或者与 Web 服务通信。
交互规则 用于处理更具体或更复杂情形的其他规则。

Screenshot showing where to create a command.

添加示例句子

在“示例句子”部分,提供用户可以说出的示例句子。

  1. 在中间窗格中,选择“示例句子”。

  2. 在右侧窗格中添加示例:

    Turn on the tv
    
  3. 在窗格顶部,选择“保存”

目前尚未指定参数,因此可以转到“完成规则”部分。

添加完成规则

接下来,该命令需要一个完成规则。 此规则让用户知道正在执行一项履行操作。

有关规则和完成规则的详细信息,请参阅自定义命令的概念和定义

  1. 选择默认的完成规则“完成”。 然后按如下所示对其进行编辑:

    设置 建议值 说明
    名称 ConfirmationResponse 用于描述规则用途的名称
    条件 用于确定规则何时可以运行的条件
    操作 “发送语音回复”>“简单编辑器”>Ok, turning the tv on 当规则条件求值为 true 时要执行的操作

    Screenshot showing where to create a speech response.

  2. 选择“保存”以保存操作。

  3. 返回“完成规则”部分,选择“保存”以保存所有更改。

    注意

    并非一定要使用命令随附的默认完成规则。 可以删除默认的完成规则,并添加自己的规则。

添加 SetTemperature 命令

现在再添加一个命令:SetTemperature。 此命令会采用单个语句 Set the temperature to 40 degrees,并使用消息 Ok, setting temperature to 40 degrees 进行响应。

若要创建新命令,请遵循你对 TurnOn 命令所用的步骤,但要使用示例句子 Set the temperature to 40 degrees

然后按如下所示编辑现有的完成规则“完成”:

设置 建议的值
名称 ConfirmationResponse
条件
操作 发送语音响应>简单编辑器>第一个变体>Ok, setting temperature to 40 degrees

选择“保存”以保存对命令所做的全部更改。

添加 SetAlarm 命令

创建新的 SetAlarm 命令。 使用示例句子 Set an alarm for 9 am tomorrow。 然后按如下所示编辑现有的完成规则“完成”:

设置 建议的值
名称 ConfirmationResponse
条件
操作 发送语音响应>简单编辑器>第一个变体>Ok, setting an alarm for 9 am tomorrow

选择“保存”以保存对命令所做的全部更改。

试试看

使用测试窗格测试应用程序的行为:

  1. 在窗格的右上角,选择“训练”图标。
  2. 训练完成后,选择“测试”。

使用语音或文本尝试以下言语示例:

  • 键入:“set the temperature to 40 degrees”
  • 预期响应:“Ok, setting temperature to 40 degrees”
  • 键入:“turn on the tv”
  • 预期响应:Ok, turning on the tv
  • 键入:“set an alarm for 9 am tomorrow”
  • 预期响应:“Ok, setting an alarm for 9 am tomorrow”

Screenshot showing the test in a web-chat interface.

提示

在测试窗格中,可以选择“轮次详细信息”,获取有关此语音输入或文本输入的处理状况的信息。

向命令添加参数

本部分介绍如何将参数添加到命令。 命令需要使用参数来完成任务。 在复杂的方案中,可以使用参数来定义触发自定义操作的条件。

为 TurnOn 命令配置参数

首先编辑现有的 TurnOn 命令以打开和关闭多个设备。

  1. 现在,该命令既可处理“开”场景又可处理“关”场景,那么便将该命令重命名为 TurnOnOff

    1. 在左侧窗格中,选择“TurnOn”命令。 然后在窗格顶部的“新命令”旁,选择编辑按钮。

    2. 在“重命名命令”窗口中,将名称更改为 TurnOnOff

  2. 将一个新参数添加到命令。 该参数表示用户是要打开还是关闭设备。

    1. 在中间窗格顶部,选择“添加”。 在下拉菜单中,选择“参数”。

    2. 在右侧窗格的“参数”部分的“名称”框中,添加 OnOff

    3. 选择“必需”。 在“为必需的参数添加响应”窗口中,选择“简单编辑器”。 在“第一个变体”字段中,添加“On or Off”

    4. 选择更新

      Screenshot that shows the 'Add response for a required parameter' section with the 'Simple editor' tab selected.

    5. 使用下表配置参数的属性。 有关命令的所有配置属性的信息,请参阅自定义命令的概念和定义

      配置 建议的值 说明
      名称 OnOff 参数的描述性名称
      必需 选定 该复选框指示在命令完成之前,此参数的某个值是否是必需的。
      必需参数的响应 简单编辑器>On or Off? 一条提示,请求提供此参数的值(如果未知)。
      类型 字符串 参数类型,例如“数字”、“字符串”、“日期时间”或“地理位置”。
      配置 接受来自内部目录的预定义输入值 对于字符串,此设置将输入限制为一组可能的值。
      预定义的输入值 onoff 一组可能的值及其别名。
    6. 若要添加预定义的输入值,请选择“添加预定义的输入”。 在“新建项目”窗口中,按前面表中所示键入“名称”。 在本例中你不使用别名,因此可将此字段留空。

      Screenshot showing how to create a parameter.

    7. 选择“保存”以保存参数的所有配置。

添加 SubjectDevice 参数

  1. 若要添加另一个参数来表示可使用此命令控制的设备的名称,请选择“添加”。 使用以下配置。

    设置 建议的值
    名称 SubjectDevice
    必需 选定
    必需参数的响应 简单编辑器>Which device do you want to control?
    类型 字符串
    配置 接受来自内部目录的预定义输入值
    预定义的输入值 tvfan
    别名 (tv) televisiontelly
  2. 选择“保存”。

修改示例句子

对于使用参数的命令,添加涵盖所有可能组合的示例句子会很有帮助。 例如:

  • 完整参数信息:turn {OnOff} the {SubjectDevice}
  • 部分参数信息:turn it {OnOff}
  • 无参数信息:turn something

有了信息丰富程度不同的多个示例句子,自定义命令应用程序可以使用部分信息得出单轮次解决方案和多轮次解决方案。

考虑到这些信息,请编辑示例句子以使用这些建议的参数:

turn {OnOff} the {SubjectDevice}
{SubjectDevice} {OnOff}
turn it {OnOff}
turn something {OnOff}
turn something

选择“保存”。

提示

在示例句子编辑器中,使用大括号来引用参数。 例如,turn {OnOff} the {SubjectDevice}。 将一个选项卡用于前面创建的参数所支持的自动完成。

修改完成规则以包含参数

修改现有的完成规则 ConfirmationResponse

  1. 在“条件”部分,选择“添加条件”。

  2. 在“新建条件”窗口中的“类型”列表内,选择“必需参数”。 在随后出现的列表中,选择“OnOff”和“SubjectDevice”。

  3. 选择“创建”。

  4. 在“操作”部分,通过将鼠标悬停在“发送语音响应”操作上并选择编辑按钮,对该操作进行编辑。 这一次请使用新建的 OnOffSubjectDevice 参数:

    Ok, turning the {SubjectDevice} {OnOff}
    
  5. 选择“保存”。

选择右侧窗格顶部的“训练”图标,尝试使用所做的更改进行训练。

训练完成后,选择“测试”。 此时将显示“测试应用程序”窗口。 尝试以下交互:

  • 输入:“turn off the tv”
  • 输出:“Ok, turning off the tv”
  • 输入:“turn off the television”
  • 输出:“Ok, turning off the tv”
  • 输入:“turn it off”
  • 输出:“Which device do you want to control?”
  • 输入:“the tv”
  • 输出:“Ok, turning off the tv”

配置 SetTemperature 命令的参数

修改 SetTemperature 命令,使其能够根据用户的指示设置温度。

添加 TemperatureValue 参数。 使用以下配置:

配置 建议的值
名称 TemperatureValue
必需 选定
必需参数的响应 简单编辑器>What temperature would you like?
类型 Number

编辑示例言语以使用以下值。

set the temperature to {TemperatureValue} degrees
change the temperature to {TemperatureValue}
set the temperature
change the temperature

编辑现有的完成规则。 使用以下配置。

配置 建议的值
条件 “必需参数”>“TemperatureValue”
操作 发送语音响应>Ok, setting temperature to {TemperatureValue} degrees

配置 SetAlarm 命令的参数

添加名为 DateTime 的参数。 使用以下配置。

设置 建议的值
名称 DateTime
必需 选定
必需参数的响应 简单编辑器>For what time?
类型 DateTime
日期默认值 如果缺少日期,则使用当天的日期。
时间默认值 如果缺少时间,则使用当天的起始时间。

注意

本文主要使用“字符串”、“数字”和“日期时间”参数类型。 有关所有受支持参数类型及其属性的列表,请参阅自定义命令的概念和定义

编辑示例言语。 请使用以下值。

set an alarm for {DateTime}
set alarm {DateTime}
alarm for {DateTime}

编辑现有的完成规则。 使用以下配置。

设置 建议的值
操作 发送语音响应>Ok, alarm set for {DateTime}

使用与不同命令相关的言语对这三个命令一起进行测试。 (可以在不同的命令之间切换。)

  • 输入:“Set an alarm”
  • 输出:“For what time?”
  • 输入:“Turn on the tv”
  • 输出:Ok, turning on the tv
  • 输入:“Set an alarm”
  • 输出:“For what time?”
  • 输入:“5 pm”
  • 输出:Ok, alarm set for 2020-05-01 17:00:00

将配置添加到命令参数

本部分详细介绍高级参数配置,包括:

  • 参数值如何属于自定义命令应用程序外部定义的某个集。
  • 如何针对参数值添加验证子句。

将参数配置为外部目录实体

使用自定义命令功能可将字符串类型的参数配置为引用通过 Web 终结点托管的外部目录。 因此,无需编辑自定义命令应用程序,就能单独更新外部目录。 存在大量目录项时,此方法很有用。

重新使用 TurnOnOff 命令中的 SubjectDevice 参数。 此参数的当前配置为“接受来自内部目录的预定义输入”。 此配置引用参数配置中设备的静态列表。 将此内容移出到可单独更新的外部数据源。

若要移动内容,请先添加一个新的 Web 终结点。 在左侧窗格中,转到“Web 终结点”部分。 添加新的 Web 终结点 URL。 使用以下配置。

设置 建议的值
名称 getDevices
URL <Your endpoint of getDevices.json>
方法 GET

然后,配置并托管一个 Web 终结点,该终结点返回一个 JSON 文件,其中列出了可以控制的设备。 该 Web 终结点应返回格式如下的 JSON 文件:

{
    "fan" : [],
    "refrigerator" : [
        "fridge"
    ],
    "lights" : [
        "bulb",
        "bulbs",
        "light",
        "light bulb"
    ],
    "tv" : [
        "telly",
        "television"
        ]
}

接下来,转到“SubjectDevice”参数设置页。 设置以下属性。

设置 建议的值
配置 接受来自外部目录的预定义输入
目录终结点 getDevices
方法 GET

再选择“保存”。

重要

除非在左侧窗格中的“Web 终结点”部分设置了 Web 终结点,否则不会显示用于将参数配置为接受来自外部目录的输入的选项。

选择“训练”以尝试该配置。 训练完成后,选择“测试”并尝试交互几次。

  • 输入:“turn on”
  • 输出:“Which device do you want to control?”
  • 输入:“lights”
  • 输出:“Ok, turning the lights on”

注意

现在,可以控制托管在 Web 终结点上的所有设备。 但仍需训练应用程序以测试新的更改,然后重新发布应用程序。

添加对参数的验证

“验证”是应用于某些参数类型的构造,可让你针对参数的值配置约束。 如果值不在约束范围内,则验证会提示你予以更正。 有关扩展验证构造的参数类型的列表,请参阅自定义命令的概念和定义

使用 SetTemperature 命令测试验证。 使用以下步骤添加针对 Temperature 参数的验证。

  1. 在左侧窗格中,选择“SetTemperature”命令。

  2. 在中间窗格中,选择“Temperature”。

  3. 在右侧窗格中,选择“添加验证”。

  4. 在“新建验证”窗口中,按下表所示配置验证。 然后选择“创建”。

    参数配置 建议的值 说明
    最小值 60 适用于数字参数,表示此参数可以采用的最小值
    最大值 80 适用于数字参数,表示此参数可以采用的最大值
    失败响应 简单编辑器>第一个变体>Sorry, I can only set temperature between 60 and 80 degrees. What temperature do you want? 验证失败时请求提供新值的提示

    Screenshot showing how to add a range validation.

选择右侧窗格顶部的“训练”图标来尝试使用此配置。 训练完成后,选择“测试”。 尝试交互几次:

  • 输入:“Set the temperature to 72 degrees”
  • 输出:“Ok, setting temperature to 72 degrees”
  • 输入:“Set the temperature to 45 degrees”
  • 输出:Sorry, I can only set temperature between 60 degrees and 80 degrees
  • 输入:“make it 72 degrees instead”
  • 输出:“Ok, setting temperature to 72 degrees”

添加交互规则

交互规则是用于处理具体或复杂情形的额外规则。 尽管你可以随意创作自己的交互规则,但本示例将使用适用于以下方案的交互规则:

  • 确认命令
  • 将一步式更正添加到命令

有关交互规则的详细信息,请参阅自定义命令的概念和定义

在命令中添加确认

若要添加确认,请使用 SetTemperature 命令。 若要实现确认,请使用以下步骤创建交互规则:

  1. 在左侧窗格中,选择“SetTemperature”命令。

  2. 在中间窗格中,选择“添加”以添加交互规则。 然后选择“交互规则”>“确认命令”。

    此操作将添加三个交互规则。 这些规则请求用户确认闹钟的日期和时间。 它们预期用户对下一轮次做出确认(是或否)。

    1. 使用以下配置修改“确认命令”交互规则:

      1. 将名称更改为“确认温度”。
      2. 已设置条件“所有必需的参数”
      3. 添加新操作:“类型”>“发送语音响应”>“Are you sure you want to set the temperature as {TemperatureValue} degrees?”
      4. 在“预期”部分,保留默认值“预期收到用户确认”。

      Screenshot showing how to create the required parameter response.

    2. 修改“确认成功”交互规则,以处理成功确认(用户说“yes”)。

      1. 将名称更改为“确认温度成功”。
      2. 保留现有的“确认成功”条件。
      3. 添加新条件:“类型”>“必需参数”>“TemperatureValue”。
      4. 将默认的“执行后状态”值保留为“执行完成规则”。
    3. 修改“拒绝确认”交互规则,以处理拒绝确认(用户说“no”)时的情况。

      1. 将名称更改为“拒绝确认温度”。
      2. 保留现有的“拒绝确认”条件。
      3. 添加新条件:“类型”>“必需参数”>“TemperatureValue”。
      4. 添加新操作:“类型”>“发送语音响应”>“No problem.What temperature then?”。
      5. 将默认的“执行后状态”值更改为“等待用户输入”。

重要

在本文中,你将使用内置确认功能。 也可以手动逐个添加交互规则。

选择“训练”来尝试使用所做的更改。 训练完成后,选择“测试”。

  • 输入:“Set temperature to 80 degrees”
  • 输出:“are you sure you want to set the temperature as 80 degrees?”
  • 输入:“No”
  • 输出:“No problem. What temperature then?”
  • 输入:“72 degrees”
  • 输出:“are you sure you want to set the temperature as 72 degrees?”
  • 输入:“Yes”
  • 输出:“OK, setting temperature to 72 degrees”

在命令中实现更正

在此部分中,你将配置一个单步更正。 履行操作运行后将使用此项更正。 本部分还会演示一个示例,说明如何在命令尚未履行的情况下默认启用更正。 若要在命令尚未完成时添加更正,请添加新参数 AlarmTone

在左侧窗格中,选择“SetAlarm”命令。 然后添加新参数 AlarmTone

  • 名称>AlarmTone
  • “类型”>“字符串”
  • “默认值”>“Chimes”
  • “配置”>“接受来自内部目录的预定义输入值”
  • “预定义输入值”>“Chimes”、“Jingle”和“Echo”(这些值是单独的预定义输入。)

接下来,将 DateTime 参数的响应更新为“Ready to set alarm with tone as {AlarmTone}.For what time?”。 然后按如下所示修改完成规则:

  1. 选择现有的完成规则“ConfirmationResponse”。
  2. 在右侧窗格中,将鼠标悬停在现有操作上,并选择“编辑”。
  3. 将语音响应更新为 OK, alarm set for {DateTime}. The alarm tone is {AlarmTone}

重要

无需在使用中的命令中指定任何显式配置即可更改闹钟铃声。 例如,在命令尚未完成时可以更改铃声。 默认情况下会为所有命令参数启用更正,而不管轮次编号是什么(如果命令尚待履行)。

完成命令后实现更正

“自定义命令”平台允许进行单步更正,即使在命令完成后也是如此。 此功能默认未启用。 必须显式对其进行配置。

使用以下步骤配置一步式更正:

  1. SetAlarm 命令中,添加“更新上一个命令”类型的交互规则,以更新先前设置的闹钟。 将交互规则重命名为“更新前一个闹钟”。
  2. 保留默认条件:“需要更新上一个命令”。
  3. 添加新条件:“类型”>“必需参数”>“DateTime”。
  4. 添加新操作:“类型”>“发送语音响应”>“简单编辑器”>“Updating previous alarm time to {DateTime}”。
  5. 将默认的“执行后状态”值保留为“命令已完成”。

选择“训练”来尝试使用所做的更改。 等待训练完成,然后选择“测试”。

  • 输入:“Set an alarm.”
  • 输出:“Ready to set alarm with tone as Chimes. For what time?”
  • 输入:“Set an alarm with the tone as Jingle for 9 am tomorrow.”
  • 输出:OK, alarm set for 2020-05-21 09:00:00. The alarm tone is Jingle.”
  • 输入:“No, 8 am.”
  • 输出:“Updating previous alarm time to 2020-05-29 08:00.”

注意

在真实应用程序中,还需要在此更正规则的“操作”部分,向客户端发回一个活动或调用 HTTP 终结点来更新系统中的闹钟时间。 此操作应该专门负责更新闹钟时间。 它不应负责命令的任何其他特性。 在本例中,该特性是闹钟铃声。

添加语言生成模板以生成语音响应

使用语言生成 (LG) 模板可以自定义要发送到客户端的响应。 它们会在响应中引入变体。 可通过以下方式实现语言生成:

  • 语言生成模板。
  • 自适应表达式。

自定义命令模板基于 Bot Framework 的 LG 模板。 由于自定义命令功能可根据需要创建新的 LG 模板(用于在参数或操作中生成语音响应),因此你无需指定 LG 模板的名称。

因此,无需按如下所示定义模板:

   # CompletionAction
   - Ok, turning {OnOff} the {SubjectDevice}
   - Done, turning {OnOff} the {SubjectDevice}
   - Proceeding to turn {OnOff} {SubjectDevice}

而可以定义不带名称的模板的正文,如下所示:

Screenshot showing a template editor example.

此项更改将在发送到客户端的语音响应中引入变体。 对于言语,相应的语音响应是从提供的选项中随机选出的。

利用 LG 模板还可以使用自适应表达式来为命令定义复杂的语音响应。 有关详细信息,请参阅 LG 模板格式

默认情况下,自定义命令功能支持所有功能,只是存在以下细微差别:

  • 在 LG 模板中,实体以 ${entityName} 形式表示。 自定义命令功能不使用实体。 但是,可以使用 ${parameterName}{parameterName} 表示形式的参数作为变量。
  • 自定义命令功能不支持模板撰写和扩展,因为你永远不会直接编辑 .lg 文件, 而只会编辑自动创建的模板的响应。
  • 自定义命令功能不支持 LG 注入的自定义函数。 支持预定义的函数。
  • 自定义命令功能不支持 strictreplaceNulllineBreakStyle 等选项。

将模板响应添加到 TurnOnOff 命令

修改 TurnOnOff 命令以添加一个新参数。 使用以下配置。

设置 建议的值
名称 SubjectContext
必需 未选定
类型 字符串
默认值 all
配置 接受来自内部目录的预定义输入值
预定义的输入值 roombathroomall

修改完成规则

编辑现有完成规则“ConfirmationResponse”的“操作”部分。 在“编辑操作”窗口中,切换到“模板编辑器”。 然后将文本替换为以下示例。

- IF: @{SubjectContext == "all" && SubjectDevice == "lights"}
    - Ok, turning all the lights {OnOff}
- ELSEIF: @{SubjectDevice == "lights"}
    - Ok, turning {OnOff} the {SubjectContext} {SubjectDevice}
- ELSE:
    - Ok, turning the {SubjectDevice} {OnOff}
    - Done, turning {OnOff} the {SubjectDevice}

使用以下输入和输出来训练并测试应用程序。 请注意响应的变体。 变体是使用模板值的多个替代项以及自适应表达式创建的。

  • 输入:“turn on the tv”
  • 输出:Ok, turning on the tv
  • 输入:“turn on the tv”
  • 输出:“Done, turned on the tv”
  • 输入:“turn off the lights”
  • 输出:“Ok, turning all the lights off”
  • 输入:“turn off room lights”
  • 输出:“Ok, turning off the room lights”

使用自定义语音

自定义命令响应的另一种自定义方法是选择一种输出语音。 使用以下步骤将默认语音切换为自定义语音:

  1. 在自定义命令应用程序的左侧窗格中,选择“设置”。
  2. 在中间窗格中,选择“自定义语音”
  3. 在表中,选择一种自定义语音或公共语音。
  4. 选择“保存”。

Screenshot showing sample sentences and parameters.

注意

对于公共语音,神经类型仅适用于特定的区域。 有关详细信息,请参阅语音服务支持的区域

可以在“自定义语音”项目页面上创建自定义语音。 有关详细信息,请参阅自定义语音使用入门

现在,应用程序会采用所选语音(而不是默认语音)进行响应。

后续步骤