“全双工”一词对于通信专业出身的老码农而言太容易引起曾经的记忆了,“通信就是计算机”也是大学的一位老师给我印象很深的一句话。那么——
什么是全双工呢?
AI时代的全双工又意味着什么呢?
我们如何更好地应用AI时代的全双工呢?
本文试图解释这些问题。
什么是全双工?
全双工(Full Duplex)是通信传输的一个术语。
通信允许数据在两个方向上同时传输,在能力上相当于两个单工通信方式的结合。全双工指可以同时进行信号的双向传输(A→B且B→A,)即A→B的同时B→A,是瞬时同步的。------来自百度百科(baike.baidu.com)
与双工通信对应的是单工通信,单工通信就是在只允许A向B发送信息,而乙方不能向甲方传送 。在全双工和单工之间,还有一种通信方式叫“半双工”,是指一个时间段内只允许A向B发送信息,另一个时间段内只允许B向A发送信息,也就是说A和B通过时间段的组合完成双向通信。
列举现实中的例子可以帮助我们更容易理解这些通信方式。
我们日常使用的移动电话、固定电话以及各种远程工作的会议系统都是全双工通信的方式,半双工的通信工具比较典型的是对讲机,某些调度系统也还在使用半双工的方式。单工通信依然非常普遍,例如广播系统(FM103.9),电视系统等等。
广义上看,传统的音箱或者家庭影院都可以认为是单工通信方式。随着智能设备,尤其是智能语音交互设备的兴起,本质上是从单工通信方式向双工通信方式的转变和演进。
智能语音交互与全双工
目前,比较典型的智能语音交互产品应该是智能音箱了,不论是无屏音箱(例如 小度智能音箱系列产品)还是有屏音箱(例如, 小度在家系列产品),都是为音箱设备引入了智能交互的能力,提供了双向通信的赋能。
看一下一般的智能音箱是如何完成完成智能语音交互的。以小度智能音箱为例,如果我想听李健的《贝加尔湖畔》这首歌,我会对小度音箱说,“小度小度,播放李健的贝加尔湖畔”,小度音箱就会传来悠扬的音乐,很自然没有疑问。如果我想在小度在家上玩小度种树的游戏,我会说
“小度小度,我要种树”, 小度回复“...”
“小度小度,播种” , 小度回复“...”
“小度小度,浇水” ,小度回复“...”
你会发现,每次都要说“小度小度”,有些不方便,这里涉及一个语音交互中的基本概念——唤醒词,关于唤醒的更多资料可以参考《令人激动的语音UI背后》。
举个例子,在一个房间里大家都在聊天,我想对其中的一位朋友——康夫说话,我会说,“康夫,你BSP层一般的优化流程是什么?”,这时康夫会转向我,给我描述他是如何在内核和驱动间做权衡的,相当于,我通过叫他的名字“康夫”和他建立起了对话。我们和智能音箱的交互也是如此,召唤“小度小度”就是为了让音箱和我建立对话。
但是,智能音箱在一次交互之后,一般不好判断您是否接下来还会和它交互,所以,保险的做法是每次交互都要唤醒它,这相当于半双工的通信方式,当然,模糊一点的话,也可以认为这是“单工”。
每一次交互都带有唤醒词,尤其在多轮对话的时候,显得不那么智能,能不能在音箱说话的时候,我也同时说话,就像我和康夫聊天时那样自由问答呢?实现这一功能的方式,就是智能语音交互中的全双工。
还以种树的游戏为例,我能否直接对智能音箱说“我要种树”,“浇水”,“施肥”等等呢?如果音箱支持全双工的话,是没问题的。但这样会带来另一个问题,如果没有唤醒的话,智能音箱需要随时处于拾音的状态,而且语音识别在云端完成的话,可能会涉及用户的隐私问题。而语音唤醒都是在设备端完成的,可以有效地保护用户的隐私,关于智能语音设备的安全问题可以参考《放心用吧!浅谈DuerOS的安全性》。
那么,如何有效地解决每次唤醒和全双工通信直接的矛盾呢?智能语音交互系统——DuerOS提出了小度系列产品的全双工免唤醒技术。
DuerOS的全双工免唤醒
DuerOS(可以参考《感知人工智能操作系统》)的全双工免唤醒技术,是指一次唤醒即可实现连续对话,还能在与他人对话的同时互不干扰地实现人机交互。
一次唤醒连续对话,很容易理解,那什么是“与他人对话的同时互不干扰地实现人机交互“呢?
举个笑话,有人说在与智能音箱交互的时候,忽然家里的猫叫了两声,结果音箱就开始了对猫叫声的应答,而中断了主人与音箱的对话,这是一个尴尬的场面。在小度系列的产品中,是不会让类似的尴尬局面发生的的。这里要引入一个技术概念——拒识。
一般地,拒识是智能语音识别系统对无效输入不做特殊处理的能力,进而减少无效输入对智能系统的影响。在DuerOS中,拒识能力分布在不同的子系统中,除了语音识别的拒识之外,同样在NLP方面提供了不同策略的拒识。还以种树的游戏为例,在支持全双工的条件下,你在对话过程中说“喝咖啡”,种树游戏将不做特殊响应。
目前,只需对小度喊出口令:【小度小度,打开极客模式】,即可即可召唤彩色小度,触发连续对话技能;想退出极客模式,只需对小度喊出口令:【小度小度,退出极客模式】,就可以让彩色小度退下。在交互体验上给人的感受非常的真实、自然,让小度更像一个既“听话”又“懂事”的孩子。
应用全双工,赋能DuerOS语音技能
DBP(dueros.baidu.com/dbp)作为DuerOS的技能开放平台(详见 揭秘“语音交互”背后的AI硬核黑科技!),目前已经有数千个语音技能应用。原则上,这些技能都可以使用全双工的能力,但是,为了保证达到完美的全双工效果,目前全双工作为“preview feature”在DBP 平台上开放了。
作为一个开发者,如何在自己的技能中应用全双工能力呢?
1. 选择全双工能力
目前的全双工能力主要面向“自定义技能”,因为多轮对话才是全双工的用武之地。在我们创建技能或者升级技能的时候,可以在DBP 平台选中“全双工”,这样在DBP后台的运营同学就可以对开发者的资质和技能的形态进行审核,审核通过之后就可以在技能开发中针对全双工进行修改了。
2. 技能中的代码支持——ER的使用
为了更好地在技能中支持全双工的能力,强烈建议在技能服务的响应中使用ER。
什么是ER呢?ER不是我们曾经所熟知的Entity Relationship。在DBP(DuerOS Bot Platform)中,指的是expectResponse,即技能推测用户可能的回复。
在DBP的自定义技能技术文档中,给出了响应消息的示例,指出了ER(expectResponse)在响应消息中的位置。
代码语言:javascript复制{
"version" : "2.0",
"context" : {
"intent" : {
"name" : "{{STRING}}",
"slots" : {
"{{STRING}}" : {
"name" : "{{STRING}}",
"value" : "{{STRING}}",
}
}
},
"expectResponse" : [
{
"type": "{{STRING}}",
"text": "{{STRING}}",
"slot": "{{STRING}}",
}
],
},
......
}
在技能Bot返回给DuerOS的信息中,context上下文字段用于反馈给DuerOS的意图结果。context中的expectResponse用于推测用户可能的回复。
对于开发过程中的开发者而言,只需要在技能交互模型中稍微关注一下expectResponse字段,按需增加数据即可。其中具体的字段含义如下:
expectResponse.type
技能所期待用户回复内容的类型,取值如下:PlainText:普通文本类型;Slot:槽位类型。Intent: 意图类型
expectResponse.text
技能期待用户的回复内容,普通文本不超过256个字符。当type取值为PlainText时,该字段为必选字段。
expectResponse.slot
当技能期待用户针对特定槽位进行回复时,此时应填写对应槽位的名称,长度不超过256个字符。当type取值为Slot时,该字段为必选字段。
expectResponse.intent
意图类型的意图名称,意图名字为开发者在平台上定义的意图名称,当type取值为Intent时,该字段为必须字段,长度不能超过256个字符。
对于已经开发的线上技能,需要做一下简单的升级。例如,在waitAnswer()之前,增加一行expectResponse()代码即可,参数就是包含上面字段的JOSN数组字符串(以PHP为例):
代码语言:javascript复制{
... ...
$this->addExpectTextResponse($Text);
$this->waitAnswer();
... ...
}
ER的使用,可以有效地提高DuerOS理解能力。对全双工而言,使用expectResponse.intent 还可以辅助DuerOS的拒识能力,会得到更好的用户体验。
3 调试与测试
支持全双工能力的技能调试和真机上的技能调试模式类似,对小度说“打开技能调试模式”,再说“打开极客模式”,就可以在真机上调试支持全双工能力的技能了。关于调试和测试的更多内容可以参考《调试DuerOS的智能语音技能》。
4 注意事项
鉴于全双工中的拒识限制,对于在技能中完全自行使用NLU的情况,可能暂时无法使用全双工的能力。一个技能如果使用自己的NLP能力,往往需要订阅system_default
意图,进而进行自己的NLP处理。因此,订阅了system_default
意图的技能可能暂时无法使用DuerOS全双工面唤醒的能力。
那么,问题来了,很多技能都订阅了system_default
意图作为兜底话术,如果没有兜底话术,影响用户体验怎么办呢?DuerOS 提供了ai.dueros.common.unknown_intent
专门作为兜底话术意图,只要在技能中引用ai.dueros.common.unknown_intent
,然后在代码中对处理该意图进行回复即可。
细心的开发者还会发现,DBP 平台还新增了一个系统意图——场景命名意图(ai.dueros.context.naming_intent
),而且用法有些独特。场景命名意图必须有前置意图,并在ExpectResponse 返回场景命名意图后,才能在下一轮对话中收到该意图。也就是说,如果没有前置意图的话,技能将无法收到场景命名意图,从而也无法处理。
再以种树的语音游戏为例,在第一次进入游戏的时候有这样一个环节:
用户:“小度小度,打开种树。”
小度:“......,请给你的农庄起个名字吧。” (A1)
用户:“老曹的农场”。
小度:“好的,.......”
在种树游戏回复A1的时候,需要在响应的ER中使用expectResponse.Intent类型, 具体的值为ai.dueros.context.naming_intent
。理由是显然的,名字可以是任意的,但任意的值可能会遭遇拒识,而场景命名意图则有效地解决了这一矛盾。
总之,开发者技能的意图、槽位、词典和常用表达描述的越充分,全双工所实现的效果就会越好。
不是小结的小结
全双工是一个智能语音系统综合能力的体现,DuerOS 一直在为打造良好的用户交互体验而不懈的努力着。尽管当前DuerOS全双工能力作为“Preview Feature”受限开放,但是,再经过一小段时间的打磨之后,将很快向全部开发者开放。
DuerOS的开发者们可以自由使用全双工能力为自己的技能赋能,给大家的生活带来更多的便利和欢乐!