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

2 评论 4398 浏览 20 收藏 24 分钟

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

一、Bot框架本质

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

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

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

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

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

二、Bot框架初步探究

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

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

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

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

只不过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},那么将会出现下面的两种不同配置方式

第一种配置方式(句式、槽位词表图):

第二种配置方式(句式、槽位词表图):

(1)第一种Value化缺陷

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

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

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

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

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

(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 协议

更多精彩内容,请关注人人都是产品经理微信公众号或下载App
评论
评论请登录
  1. 你写的8篇文章我都看了,真的受益匪浅。请问一下,你还在更新作品吗?有gzh吗?想一同交流。

    来自北京 回复
  2. What meaning Bot?

    来自湖北 回复