客户端动作(command)编写
一、 command介绍
部分意图下,除了文字/语音的回复外,还需要客户端/本地执行对应的操作才能完成用户指令,此时就需要配置【客户端动作】以向客户端发出对应指令。
例如拨打电话的技能,用户说「给XXX打电话」,要输出指令给本地执行【拨打电话】这个操作。
【客户端动作】在DUI也称为command。
1.1 command作用
command,即DUI直接向设备端下发指定的操作指令,以满足用户在该意图下的操作设备诉求。
1.2 command适用场景
command和nativeapi的作用不同,故其适用场景也不同:
- nativeapi,是向设备端获取内容源数据,是双向的,对话的中间一环。
- command,是向设备端下发指定的操作指令,是单向的,一般是对话的最后一环。如增大音量、打开爱奇艺。
注:由于nativeapi是双向传输的,会让对话延时增加约100ms,所以请避免将nativeapi当做command使用。
关于nativeapi的介绍和使用说明,参见nativeAPI编写说明。
1.3 command命名规范
基于command的作用,建议命名规范如下(以dui.deviceController.setVolume为例):
- command的名称由三部分组成,由"."相连。
- 每个部分的命名,遵循“纯英文+小驼峰”规则。
- 第一部分,用来标识该技能所属的公司或者组织,如dui|AIspeech。
- 第二部分,用来标识本地模块名称,一般为名词,如phone|deviceController。
- 第三部分,用来标识意图指令,一般为动词+名词,如dialNumber|setVolume。
如下图:
1.4 command参数规范
当客户端开发者明确了command所对应的意图指令后,就需要提取参数部分,用以辅助指令的执行。建议规范如下:
- 参数名称,应为纯英文,且为明确含义的名词,如number|volume。
- 参数名称,需要是确定的、有限个数的。
- 参数值,应为纯英文|纯中文。可引用语义槽的值(#联系人#),可引用cinfo的值($context.xx.yy$),也可传入固定值。
- 参数值,需要是有单一含义的、无歧义的。
如下图:
二、 典型场景的推荐做法
1.1 场景1:音量控制
场景分析: 该场景意图下,用户核心诉求是操作设备音量,次要诉求是听到反馈。
方案:
- 使用command来实现指令
- command命名:dui.deviceController.setVolume
- command参数:
参数名称 |
必须 |
类型 |
说明 |
---|---|---|---|
type | Y | string | 设置音量的类型。取值范围:relativeIncrease、relativeDecrease、absoluteValue、absoluteMax、absoluteMin |
volume | N | int | 音量值。取值范围:0-100。 |
客户端开发实现:
- 收到command消息:dui.deviceController.setVolume
- 解析command参数:type
- 若type == relativeIncrease,表示增大相对音量(到某个值)。
- 若type == relativeDecrease,表示减小相对音量(到某个值)。
- 若type == absoluteValue,表示调整绝对音量(到某个值)。
- 若type == absoluteMax,表示调整音量到最大。
- 若type == absoluteMin,表示调整音量到最小。
- 解析command参数:volume,获取具体数值。
- 调用操作系统的设置音量的接口,完成command指令
类似场景: 播放控制、APP控制、导航、模拟点击
1.2 场景2:这是哪首歌
场景分析: 该场景意图下,用户核心诉求是能够知道(看到|听到)设备端正在播放的音乐信息
方案:
- 使用nativeapi来实现
- nativeapi命名:dui.music.querySongInfo
- nativeapi参数:无
- nativeapi返回数据:contentWidget
- nlg播报:这首歌的歌名是$title$,演唱者是$extra.singer$。
属性 |
取值 |
---|---|
type | content |
name | default |
title | 忘情水 |
subTitle | 演唱:刘德华;作词:李安修。 |
imageUrl | https://www.qqmusic.com/pic/fdahfahsjdasd |
label | 流行,刘德华,90年代 |
linkUrl | 无 |
buttons | 无 |
recommendations | 无 |
extra | {"song":"忘情水","singer":"刘德华"} |
客户端开发实现:
- 收到nativeapi消息:sys.music.querySongInfo
- (跳过)解析nativeapi参数
- 调用QQ音乐的查询当前播放的接口,获取到歌曲信息
- 将该信息格式化为contentWidget,返回给DUI,完成nativeapi响应
- 收到contentWidget控件消息,展示UI
类似场景:查备忘提醒、查微信好友列表、查支付宝账单余额
三、 典型场景中长尾case的推荐做法
目标:技能开发者若期望增加对长尾case的处理,需力图保证:
- 不影响正常case时的流程
- 不增加正常case时的耗时
- 有长尾case需求的客户端开发者才需处理,无此需求的无需关注和处理。
1.1 场景1:音量控制
长尾case:期望有一些异常情况下的nlg播报,反馈给用户。如音量已调到最大。
方案一(推荐):
- 技能开发者不输出nlg播报。
- 客户端开发者在原有逻辑的基础上,增加步骤5:判断异常情况,并调用TTS播放异常文案。
方案二:
- 技能开发者在设计中通过$context.skill.curVol$增加对话条件判断。异常情况下,仅输出异常nlg。正常情况下,输出command和正常nlg。
- 客户端开发者在原有逻辑的基础上,增加步骤0:监听系统音量变化,当音量发生变化时,将音量值curVol通过skill.settings接口上传给DUI。
1.2 场景2:这是哪首歌
长尾case:期望要区分一些异常情况下的nlg播报,反馈给用户。如当前未安装QQ音乐、QQ音乐没在播放。
方案:
- 技能开发者对nativeapi返回的contentWidget数据,通过$extra.error$增加对话条件判断。不同异常情况下,输出不同的异常nlg。
- 客户端开发者在原有逻辑的基础上,增加步骤3.1:检查QQ音乐APP状态,若APP不存在则返回{"error":1};若APP未运行,则返回{"error":2}。
属性 |
取值 |
---|---|
type | content |
name | noQQMusic、noPlay |
title | 当前未安装QQ音乐、当前未在播放 |
subTitle | 无 |
imageUrl | 无 |
label | 无 |
linkUrl | 无 |
buttons | 无 |
recommendations | 无 |
extra | {"error":1}、{"error":2} |