数极客首页

Bot对话设计之奥卡姆剃刀原则

“奥卡姆剃刀原则”体现在Bot设计上,是同一个功能,从三个维度都可以去完成,甚至不同维度也有不同的子方式,但哪种方式最为简洁,这才是真正尤为重要的一点,而不是仅仅局限于完成这个功能本身。

Bot对话设计之奥卡姆剃刀原则

一、Bot框架本质

搭建NLU语义解析框架,在上篇文章中我我已经提到,它作为最开始顶层设计的基本解析框架,是整个Bot产品的基石。

在系统上,会影响到整个框架的是否足够简洁,意图内的多轮或跨意图多轮的可实现与否,场景中每个意图触发的边界(抛开模型泛化的意图句式不谈)等等。

我之前将这个搭建NLU语义解析框架的本质,定义为从“用户语音需求”、“服务”和“NLU语义技术”三个维度,去寻找“最优解”集合的问题。但这这个感觉是从上帝视角,对他们结构性的一种描述。

但具体在去做每个Domain的时候作为Bot的产品,定位就不在是一种俯瞰的上帝视角,而是作为“NLU语义”这个圈本身定位这个感觉。

从这个角度出发,Bot产品在实际工作中,起到的更像是一种“连接”的作用,将用户的语音中的要素识别并抽取出来,通过Bot产品,精准连接到对应的服务细节,然后再返回给用户结果,完成这个从语音输入到语音输出的产品闭环设计。

二、Bot框架初步探究

接下来结合我最近的思考和实践,在Bot基本框架上,我尝试去回答下面这三个问题:

  1. 对每个Bot场景的框架来说,一个极为重要的评价标准
  2. 什么因素,是我们在最初设计Bot解析框架时,所不需要考虑。(注意,这里是不需要考虑的)
  3. 简化框架,采取怎样的操作方式更加合理

先附上一个基本框架形式,方便之后的论述:

Bot对话设计之奥卡姆剃刀原则

还有必要声明一点:下面的所有思考,都将暂时抛去模型训练对意图语料的影响。并不是因为它对于语音交互来说不重要,相反基于算法的语料训练的越好,每个场景不同意图的句式的精准性和泛化性会同步提高。

只不过Bot产品设计在这个层面上,起到的作用不会很大,这部分的工作都是“模型训练师”(算法工程师)去通过线上大量Query数据和标注语料去训练,实现意图句式的泛化。

产品在设计Bot框架时,意图句式的泛化应该是在整个框架搭建好,逻辑走通以后的最后一步,对于产品设计来说并非最重要的影响要素。

2.1框架的简洁性

我个人评价一个Bot框架的标准,是在可以满足该场景所有功能情况下,它的简洁性。以最常见的“查天气”这个场景为例,要实现它很容易,可以通过多种框架形式去实现。

比如可以有三个意图“search_weather”(普通天气查询)、“search_tem”(普通温度查询)和“search_con”(查询天气指数)去搭建Bot框架,这也是亚马逊这个Domain的做法,通过这三个意图实现天气功能。

但如果是涉及到更多服务参数的场景,比如车载场景,服务参数并不会像天气那么少,那么意图可能就会随着增加,而意图的增加,对于整个框架来讲,它的简洁性必然是下降的。

与此同时会带来另外一个在现象上更严重的问题:在“多轮对话”模块,过多的意图会导致多轮配置的复杂度大幅提升,搞起来非常痛苦,同时后期Bot框架的维护成本非常高。这无论对于产品还是技术来讲,都会影响该场景下的可拓展性。

所以,我将在满足功能下一个Bot框架的简洁性视为评价一个框架,最为重要的指标。当然它有一个前提假设,就是能够实现该场景下所有的意图和功能,不能陷入单纯为了形式上的简化而简化。

2.2探究一个功能的三个路径

接下来我会通过实验,去验证并尝试回答第二个问题:即什么因素,在进行Bot框架顶层设计的时候,不需要考虑的因素(至于为什么是不需要考虑的,最后会提及到)。在此提出三个假设,稍后会进行验证:

  1. 用户在现象层面的“意图”,对单间搭建Bot框架的影响
  2. 用户同一个“现象意图”的不同类型表达句式对Bot框架的影响
  3. 整个场景内,服务参数的多少对Bot框架的影响

下面以天气场景为例,如果要实现“查询温度”和“查询空气质量”这两个功能,基于当前的Bot框架实现方式,在逻辑上有以下三种:

  1. 通过两个Intent进行划分,即“查询温度”意图和“查询空气质量”意图
  2. 通过两个slots进行划分,即“温度”槽位和“空气质量”槽位
  3. 通过同一个slots中,两个Value进行划分,进“温度”值和“空气质量”值

2.2.1 Intent维度

如果在Intent层面去划分,那么整个框架已经明显:两个意图(温度、空气质量),两个槽位(城市、日期),其中的典型句式,举个例子如下:

  • Intent(温度):{city}{date}温度【是多少】
  • Intent(空气质量):{city}{date}空气【好不好】

这样的两个句式,是可以触发对应的意图,没错吧。注意【】括起来的词,表示属于“意图非必要要素”,而中间的“温度”和“空气”则为“意图必要要素”(你起码得有温度这俩字的,没毛病),也符合我之前对一个句子四种要素的基本构成。

那么这样的操作方式,是可以明确触发“查询温度”和“查询空气质量”这两个用户意图,同时通过后续配置槽位策略去请求到对应的服务。

好,这个操作是可以满足功能的,我们先放在这里不管他了。

2.2.2 slots维度

如果选择在slots这个维度去划分映射关系的话,那先假设温度为{tem},空气质量为{AQI}两个槽位,其中的典型句式,会是这样的:

Intent:

  • {city}{date}{tem}【是多少】
  • {city}{date}{AQI}【好不好】

这样配置好的两个句式,用户在发出Query之后,触发的是同一个意图,但因为槽位的性质不同,所以可以抽取出不同的实体,去进行后续的服务请求和回复话术配置,到这里好像没毛病。这样的句式可以触发意图,触发意图后也能请求到对应的服务。

(1)一个槽位一个值?

But,这样的方式可能会产生一个疑问:像{city}或{date}这样的槽位,他们内部都是包含大量信息的,而这样的处理方式,每个槽里面只包含一个信息,即“温度”或“空气质量”(顶多再会加上一些同义词),直觉上会很奇怪,它好像并不符合我们对“槽位”这个概念的基本认知。

这恰恰是需要警惕的一点:如果纠结于“槽位”本身,并且是通过观察当前普遍认同的槽位设定,比如常见的“地点”、“时间”、“歌手”、“出发地”等,这也是当前几乎所有能找到得科普文章或网站上的介绍形式。

会非常容易陷入一个误区,你得到的槽位的基本认知,是通过现象层面已经被解决问题的归纳而得出的,那么结论也仅仅是停留在现象层面的认知和结论。你应该思考的是去溯源,思考为什么会有“槽位”这个东西存在,它对于整个Bot产品来说,定位在哪里,槽位在本质上是为了解决一个什么的问题而诞生,而这个问题又为什么存在。

我想强调得是“槽位”只是基于以上思考,在最后一步推导出的一个现象层面上“解”的自然表现,而表现是可以浮动的,却非本质上的“不动因”。

这个问题在这里就不展开了,可能需要单独讲,先抛出一个结论性的观点:槽位是可以只包含一个信息点的,并且在某些情况下,也只能通过这样的存在形式,才可以完成某些场景的意图上的功能。

(2)系统影响

真正的影响,是要从系统思维的角度出发,看看这样的方式,对整个Bot后续其他模块的影响是怎样的。

在多轮上的问题,上文已经说了多轮分为意图内和跨意图。意图内的多轮,其本质就是该意图内槽位的“改变”(增、换、否的)。试想一下这样的槽位处理方式,如果用户第一轮Query“北京今天温度”,第二句“那空气质量呢”。

首先,这个功能从Bot多轮的角度来讲,是必须要支持的,用户第二句的意图非常明显是“北京今天空气质量”。那么此时DST在追踪到上一轮的Query意图的输出语境,并且本轮Query句式所触发的意图,对应的输入上文语境刚好一致的时候(其实是同一个意图,简单理解,就是它自个),它会把{city}{date}{tem}全部继承下来,又因为{AQI}在上一轮没有,属于新增槽位要加上,这时候组合成的第二轮意图:{city}{date}{tem}{AQI}

到此,就会出现问题,你到底是要干嘛?是要查温度,还是要查空气质量。如果在天气这个场景,“查温度”与“查空气质量”是分开的话,那么到这里,系统就不知道要请求什么了。

所以在每个场景框架的建立之初,一定要时刻保持对整个Bot系统思维的意识。

因为很多种方式和路径,都能完成同样的功能,但不同方式对整个系统和其他模块带来的影响是不一样的,如果在顶层设计的时候不考虑清楚,就会带来后续的某些功能不能实现,或是实现的方式更加复杂。

2.2.3value维度划分

Value维度进行划分,有两种形式:

  • 一种是仅仅把“温度”和“空气质量/空气”作为固定的Value值,就好像“北京/北京市”作为{city}槽位里的一个固定值一样。这样操作的本质是,将该句式“意图必要要素”作为槽位中的一个值;
  • 第二种方式,则是将整个“意图要素”(必要与非必要全部包含),都作为Value值做归一化的处理,同时他们共属于一个槽位,我假定这个槽位为{condition},那么将会出现下面的两种不同配置方式

第一种配置方式(句式、槽位词表图):
Bot对话设计之奥卡姆剃刀原则

Bot对话设计之奥卡姆剃刀原则

第二种配置方式(句式、槽位词表图):
Bot对话设计之奥卡姆剃刀原则

Bot对话设计之奥卡姆剃刀原则

(1)第一种Value化缺陷

先来看第一种方式,可以看到它为了满足用户后缀里“是多少”和“好不好”这两种问法,就必须要有两种句式去配置(这并不是大问题)。

但是由于“温度”和“空气质量”属于同一个槽位的两个值,也就是{condition}中出现任意一个,这两个句式都能触发该Intent,这就会导致一个现象层面的问题:即Query为“北京今天温度好不好”和“北京今天空气是多少”也能触发该意图,虽然这可能不会造成多大负面影响,但它还是破坏了意图句式的准确度。

但为什么会导致这样的现象呢?可以通过意图要素去解释。“温度是多少”这句Query属于温度意图要素,“空气好不好”属于空气质量意图要素,本来他们的边界是完全不在一起的(如下图)。

但我们基于简化框架的目的,把这两个要素中的“意图必要要素”分别抽取出来,作为同一个槽位中的值,但同时为了要满足用户更多Query的问法,就要在句式中增添“非必要意图信息”(即上文的“好不好”和“是多少”),这样的做法最终导致两个意图的边界出现了混乱。所以这样的Value化操作方式,本质上是在“精简框架”和“Cover用户更多句式”之间去做出取舍。

不过综上来看,它的效果并好,这还仅仅是最为简单场景的两类Query而已,如果是更复杂的场景,用户的表达句式更加复杂,那这样的做法所暴露的缺陷是极为明显的

Bot对话设计之奥卡姆剃刀原则

(2)第一种Value化优势

对比上面,在观察第二种Value化的操作方式,可以看到的优势就很明显:

  1. 简洁
  2. 所有“意图要素”在槽位词表的层面采用相同方式处理,而不是在句式层面。本质上不会导致“意图要素”发生边界混乱,也就不会出现说“温度好不好”这样奇怪的Query,却仍能触发意图的的问题。
  3. 后续的可拓展性、维护成本低。在此基础上优化迭代新的功能,或是发生一些比较紧急的Case,只需要在整个框架中处于在外一层的“槽位词表”维度去修改,而不用涉及到框架性、意图层面的改变。

3.反过来想,影响简洁性的不是什么因素

通过上面的实验,我想第二个问题中的三个假设,应该可以得到自然的验证。

第一个假设:用户的“现象意图”,是否要能成为影响Bot框架核心因素?

答案是:“否”。

用户在现象层面的意图,并不能作为你构建Bot框架时的核心思考因素。通过上面天气场景的例子已经证明,用户在现象层面上的两个意图,在Bot框架中,可以在逻辑上从intent/slots/value三个维度转化。用户意图,不能代表Bot意图。

第二个假设:用户同一个“现象意图”的不同类型表达句式,是否能成为影响Bot框架核心因素?

答案是:“否”。

如果连“用户意图”本身都不能作为核心因素,那么它更上一层的句式层面的泛化说法,又怎么可能成为核心因素;从技术上讲,这也只是用户说法通过模型泛化的问题。

第三个假设:整个场景内的“服务参数”多少,是否作能成为影响Bot框架核心因素?

答案还是不能。

因为即时要服务的参数再多,在Bot中也可以在Value层面去处理。这个在Bot中最极端的体现,就是“槽位值”这个概念,歌手足够多吧,但一个{singer}词典,就全部解决啦。

那么在请求类的服务中,逻辑也是一致的,即使要请求的服务参数再多(任何服务场景),也是同样的思路去解决,所以“服务参数”数量,也不能成为影响Bot框架核心因素。

4.奥卡姆剃刀原则

上面的简单实验,回答了最开始提出的三个问题,同时加上自己最近的一些实践。目前至少找到在做Bot设计时非常重要的原则,奥卡姆剃刀原则:

如无必要,勿增实体。

这个原则的思想是同样可以做好的事情,用较少的东西去做,切勿浪费较多东西去做,也被称为“简单有效原理”。

体现在Bot设计上,同一个功能,从三个维度都可以去完成,甚至不同维度也有不同的子方式,但哪种方式最为简洁,这才是真正尤为重要的一点,而不是仅仅局限于完成这个功能本身,“两点之间线段最短”,这是公理。

如果这个场景比较简单,涉及到功能不多,可能哪种采取方式并不会有太大影响。可假设要做的东西比较重度,或者说在初版之后要进行更丰富的拓展,那么在设计之初,让整个框架保持最大程度可能性的简洁,是十分必要的一点。

“奥卡姆剃刀原则”,也成为我在Bot产品设计时核心思想,最近在实践中重构天气场景,也尝试完成了只用两个意图(不包含用于承接多轮的重名意图),去Cover住天气场景的所有功能,算是理论结合实际,完成了一小步。

5.Bot产品感受

在文章的最后,更想谈一些自己的感受,我想表达的是上面所有的论述都是极其肤浅和缺乏根基的。它有两个非常严重的缺陷,这个缺陷倒不是说这个上面的内容或观点存在过大偏差(当然也是存在的),而是我的这些思考以及得出结论本身的思考方式本身存在缺陷。

  • 其一,本质上只是通过自己在实践中的经验,用归纳法去从现象层面得出一些因果关系上的东西,然后得出一些原则或思想,虽然并不能说他们不对,但这样的方式缺乏更为底层的“根基”(不知道能不能感受到我所说的这个味道)。
  • 其二,过于片面,这是我自己都能明显感受到的,做过这些东西归纳出这一方面的思考,做过那些东西就得出另外一些方面的思考。这样下去整个体系会变得越来越复杂,但也越来越容易流与现象的流变,而很难纵向深挖出更为底层和基础的东西。

所以最近也开始在思考寻找Bot框架设计中的第一性原理,从那个最底层的“第一因”出发,这个“第一因”一定是抽象的,且可能跟Bot本身无关,然后用演绎法去推导Bot框架设计的理论,将底层逻辑导通。

我的第二个感受是:就“现象问题”去解决“现象问题”一定是做Bot产品(或者说任何产品都是如此吧)的大坑,但Bot对话产品表现的更为明显,毕竟人的对话场景或人的Query形式有点不可穷尽的意思哦。

场景会越来越多,每种场景所表现出来的形式也不尽相同,也就是说现象层面上的东西永远是流变的。同时技术也在不断向前演化,说不定哪天有了新的技术突破,做Bot的方式方法就会发生改变。

但一定也会有那个最为本质和底层的点,是所有Bot产品共有的底层的“第一因”(第一性原理)。只要NLU底层语义技术,不突破目前基于统计模型理论的机器/深度学习方式;只要人的说话方式和习惯不改变,它也一定不会改变的那个基石元素找到,才可以。

 

本文由 @free 原创发布。未经许可,禁止转载。

题图来自 Unsplash ,基于 CC0 协议

新一代大数据用户行为分析与数据智能平台:数极客(https://www.shujike.com),是支持无埋点、前端埋点、后端埋点、API导入四种混合数据采集方式,整合分析用户行为数据和业务数据,可以自动监测网站、APP、小程序等多种渠道推广效果分析,是增长黑客们必备的互联网数据分析软件。数极客支持实时多维分析、漏斗分析、留存分析、路径分析等十大数据分析方法以及APP数据分析网站统计网站分析小程序数据统计用户画像等应用场景,业内首创了六种提升转化率的数据分析模型,是数据分析软件领域首款应用定量分析与定性分析方法的数据分析产品

发表评论

评论已关闭。

相关文章