BOT產品的框架與認知:本質是什么,邊界在哪里?
邊界對BOT產品極為重要,因為每一個模塊要么是為了解決一個邊界問題,要么是在某個邊界內去解決某類問題。
下面的文章,是我在做BOT產品上時最近的一些思考,其中并不代表現在做BOT的通用思維或方法論,我更想通過自己的思考和總結,去嘗試推演出在做BOT產品時,到底要解決的是什么問題,而這個問題對我們來說的本質是什么,邊界是在哪里。
一、BOT配置架構
這個架構流程,是我所理解的系統搭建一個場景的模塊與流程,其中每個模塊都是去解決一個子問題,整個對話系統由他們構成。
二、NLU語義解析框架
建立NLU語義解析框架是做BOT的基礎與核心,現在絕大多數的做法,都是通過場景(即Domain)去建立場景內的用戶意圖和槽位信息。
這個框架之所以非常重要,是因為一方面在一句Query進來之后,要通過以這個框架為基礎的去觸發意圖,解析信息;另一方面又連接起解析完成后服務的請求,以及給用戶的話術回復的配置。
在我個人看來,產品在這個模塊工作本質是為“NLU語義”、“用戶語音交互需求”和“服務或內容”這三個維度找到交集,并據此建立解析框架。
對NLU技術團隊來說,理論上是可以把任何形式話語或詞語設置成意圖句式和槽位信息去處理,但這樣的技術實現沒有任何現實意義,解析出來的信息必須是去尋找用戶的意圖和其中的關鍵信息,但兩個集合的交集還不夠。
語音交互本身只是一種信息傳遞形式,最終目的是通過這個傳遞方式,幫助用戶獲取滿足其需求的服務價值——那也就必須考慮到服務本身,反過來對BOT上的限制,或者“參考”可能更加合理。因為最終的目的是去通過語義解析的參數,去精準映射服務的不同信息,并且根據不同信息的組合,去差異化配置回復話術。
這個服務方的“參考”非常重要——因為任何形式的服務,無論是像聽音樂聽相聲這樣的內容服務,還是查天氣或訂票這樣的生活服務(可能閑聊除外),服務價值本身是先于“語音交互”這個形式而存在的,服務方已經和用戶經過長久的互動和連接,彼此早就形成了互相認同信息框架。
比如對于內容播報這個領域來說,“信息傳遞框架”可提供的就像是“資源名稱、創作者、表演者、風格、年代、適合播放場景”這樣的信息;對于天氣服務來說,可提供的就是“城市、經緯度和日期”這樣的參數。
也就是說,用戶Query經過BOT后,必須能夠獲得完美映射服務的不同參數,以獲取不同的信息,才能返回給用戶他們所需要的服務,這樣才算是一個完整的以語音交互形式,從需求到價值滿足的閉環
所以,搭建NLU語義解析框架這個問題的本質,是基于以上這三個維度,去尋找一個“最優解集合”的問題
三、意圖句式配置
3.1意圖要素
在搭建起某個場景的NLU語義解析框架后(包含意圖和槽位),面臨最重要的問題就是什么樣的Query可以觸發意圖(這是需要產品去定義和配置的),即把與意圖不相關的Query擋在外面,把與意圖相關的Query盡可能使其觸發對應的意圖。
那么在本質上,這就成了一個“邊界判定”的問題:什么樣的Query可以進入到意圖邊界之內,什么樣的Query要在意圖邊界之外?
那么先暫時拋開意圖和句式這些東西不談,我嘗試從邏輯上論證并得出這個“邊界問題”的解,然后關于“意圖和句式”的問題可能自然就解開了。
假設一個元素A,它之所以能夠成為或者能被定義為元素A,而不是元素B、C或D,那么它一定含有只有它才有的要素,是其他元素“B、C、D”所沒有的;或者說即使有,也因為構成要素之間的排序差別,導致不同。
因為如果元素A與元素B擁有的要素全部相同且順序相同,那么也就不存在“A與B”的區別。
也就是說,元素A之所以能夠成為A,是因為它具備符合成為A的所有要素條件。
舉個栗子:
假設一臺“臺式電腦”(A)能夠成為電腦的必要要素是“屏幕”和“鍵盤”與“主機”(注意這里是假設,而不是事實),那么因為一臺筆記本電腦(元素B)雖然同樣具備“屏幕”和“鍵盤”,但并不具備“主機”,他們在“主機”這個要素上有差異,所以筆記本電腦不是臺式電腦
那么我們可以用演繹法將這個結論放在我們“意圖觸發邊界”這個問題上:
一個“意圖A”之所以能夠成為意圖“A”,一定有符合意圖A的全部必要要素才可以。
換句話說,只有符合該意圖的所有必要要素條件,這個Query句式才能夠觸發該意圖。
那么,關于意圖的邊界判定的問題,就成了一個“構造意圖必要要素”的問題——只有符合該意圖的所有必要要素才能觸發我們配置的意圖,不符合的就不能觸發。
那么,我將一句話的信息按照“信息類型”和“必要要素”兩個維度,去劃分為四個類別:
- 必要槽位信息
- 必要意圖信息
- 非必要槽位信息
- 非必要意圖信息
通過這樣的劃分,基本問題的解就出來了。
在確定一個意圖后,要找到得就是表格中的“意圖必要要素”,它又有兩種信息類型構成即“必要槽位信息”和“必要意圖信息”,只有符合“意圖必要要素”,那么這個句式才可以觸發對應的意圖。
先舉個栗子,假如你的一個Intent是“查天氣”,那么以下句式都是可以觸發該意圖:
A:天氣怎么樣
B:今天天氣怎么樣
C:北京今天天氣怎么樣
D:播一下天氣預報
我們來簡單分析一下:
- 在句式A,它的必要要素有兩個“天氣”和“怎么樣”;
- 在B,必要要素為“天氣”和“怎么樣”,非必要要素為“今天”;
- 在C,必要要素為“天氣”和“怎么樣”,非必要要素為“今天”和“北京”;
- 在D,必要要素為“播”和“天氣”,非必要要素為“一下”和“預報”
3.2“意圖必要”與“意圖必填”
這個問題需要解釋,“北京”和“今天”明明是必填槽位啊,怎么會在這里被劃分為“非必要要素”(也即非必要槽位信息)呢?
這里就要澄清一下“必要”和“必填”的概念:他們之間所處的BOT流的模塊和要解決的問題在本質上是不一樣的。
- “意圖必要槽位信息”是用于判定用戶的某句Query能否觸發某個意圖,它的本質是“邊界判定”,所處的位置是在一句Query進來后意圖分類和句式匹配的階段;
- 而“意圖必填槽位”,是在句式已經確認完全符合并觸發某個配置好的明確意圖之后,去請求后續服務而言是否“必填選項”。
還是以天氣為例子,在“天氣怎么樣”這個句式中,【天氣】和【怎么樣】即上表中“意圖必要信息”,他們不是某個槽位,但確實是出發這個意圖的“必要要素”,用戶說出這句話,是一定可以觸發意圖的。
但觸發意圖之后,要請求“天氣服務”則必須有“城市”和“日期”兩個信息才能完成服務,所以這時候“城市”與“日期”會成為意圖的兩個“必填槽位”。
所以可以看出:在配置意圖句式的模塊,對于能否觸發意圖這個邊界而言,“必要要素”是可以不含有解析框架中的任何槽位的。這在我一開始接觸BOT的時候給我造成了很大的困惑,因為翻看現在的一些信息,都是突出了槽位相對于已經出發意圖后,在請求對應服務上的“必填性”,而沒有強調在觸發意圖邊界上的“必要性”,但實際上他們是兩個概念。
對于某個句式能否觸發某個意圖而言,句式中必要要素是可以不含有任何“槽位信息”的(比如上文中不一定含有“北京”和“今天”就能觸發查詢天氣意圖),但是卻必須有“必要意圖信息”(比如上文的“天氣”和“怎么樣”)
這就為我們提供意圖句式配置的一個邊界標準,一個句式能否觸發某個意圖,一定要含有這個意圖句式的“必要要素”,而這個必要要素由兩部分構成分別為“必要槽位信息”和“必要意圖信息”,其中“必要槽位信息”是非必須存在的,而必要“必要意圖信息”是必須存在的,這是我在配置意圖句式要素的一個核心思路
3.3意圖表達類型句式
接下來,我們再看看另外一個現象,比較一下“A”和“D”的共性和區別。
按照我剛才的說法,A中含有的“必要意圖信息”分別為“天氣”和“怎么樣”;而D中含有的“必要意圖信息”分別為“播”和“天氣”(注意這兩個句式,都不含有“必要槽位信息”,符合我剛才的理論)。他們之間共有的必要要素為“天氣”,而差異的要素為“怎么樣”和“播”,但是他們可以觸發的是同一個Intent(查詢天氣)
這里就再引申我自己給定義的一個概念,即“意圖表達類型句式”:同樣的一個意圖,會包含有不同的表達類型句式,但是這些表達類型不同的句式都可以觸發這一個意圖。而不同的“意圖表達類型句式”,所包含的意圖必要要素又是不一樣的。
比如剛才的“句式A”和“句式D”本質上就是觸發同一個查詢天氣意圖的不同“意圖類型表達句式”,一個是“天氣怎么樣”,另一個是“播一下天氣”,在這兩個句式的必要要素中,差異的就是“怎么樣”和“播”,那么他們就屬于不同的“意圖類型表達句式”。
那么到這里,結合上面的“意圖要素理論”,可以得出一個自己在意圖句式配置中,建立意圖邊界的核心思路:
根據NLU語義解析框架進行意圖分類后,按照“意圖必要要素”去劃分出同一個意圖的不同表達類型句式,然后將必要要素,可能是槽位,也可能是意圖信息,按照順序排列好,這就可以構建“一個明確意圖、一個明確表達句式”的基礎邊界句式,只要符合這個邊界的句式,全都可以觸發這個意圖。
后面的工作就是在這個基礎上,把一些“非必要要素”配置上去以覆蓋更多句式。這里就不展開說了,比如說在必要要素為“天氣”和“怎么樣”這兩個要素配置好后,可以放的“非必要要素”是槽位信息“城市”和“日期”,組成多樣的句式如:
- {城市}天氣怎么樣
- {日期}天氣怎么樣
- {城市}{日期}天氣怎么樣
- {日期}{城市}天氣怎么樣
至于后面的包括非必要要素的配置、排列組合和詞典等,本質上都是基于這個基礎句式去服務,以符合這個邊界的更多意圖句式的。
四、多輪對話
多倫對話現在普遍的劃分方式,分為“線性多倫”和“非線性”多倫。
從功能層面上來講:
- 線性多倫是在必填槽位缺失,通過系統主動發起追問的方式,去獲得缺失的槽位;
- 非線性多倫是解決需要聯系上文才能獲得用戶完整意圖的問題。
雖然都被稱之為“多倫”,但這兩個模塊本質上在整個系統里所要解決的問題,以及問題的邊界是不同的。
4.1線性多輪定位與邊界
首先先看線性多輪所解決問題的邊界,他是為了在某一個意圖的對話中,由于用戶發起了某項意圖,但是意圖中有缺失的必填槽位,而發起的一種追問方式以獲取該槽位的信息。而該意圖及其“必填槽位信息”是已經事先被定義好的,換句話說,該意圖請求服務所需要的“完整意圖信息”是已經事先被我們所圈定好的,解決的問題只是在缺失時怎么補上就可以了。
再看它在整個對話流中的定位,是在一句Query符合“意圖觸發必要要素”,可以觸發場景中的某個意圖,但是觸發之后,卻缺失了“意圖請求服務必要要素”(即某些必填槽位信息)。
線性多輪的存在位置,就是為了彌補上兩者之間的GAP(如下圖):
這里還想區分一下“意圖觸發必要要素”和“意圖請求服務必要要素”之間的概念區別:
前者是為了判斷是否能夠觸發并進入某個意圖的邊界,而后者則是能否具備完整請求后續服務的邊界。
4.2非線性多輪
為什么說“非線性多倫”本質上與“線性多倫”并不是一回事呢?我們從三個維度上去看
“用戶完整意圖”定義
從目標上,雖然線性多倫與非線性多倫都是為了獲取用戶的完整意圖信息,但在“完整”的定義上,線性多倫是已經被設定死的。
而非線性多倫中,用戶的每一個意圖是否“完整”,都是不可知的。
問題邊界
再看解決的問題:因為人說話的習慣,往往會把前一兩句說過的信息默認忽略,即假定你已經知道上面的信息。而計算機處理的方式,卻只能以一句完整Query意圖的方式去處理。
比如你第一句“我想聽劉若英的后來”,第二句“換張智霖的”,如果光看第二句,系統并不知道你的完整意圖是“我想聽張智霖唱的后來”。
所以非線性多輪這個模塊的本質,是為了解決“人基于上下文說話習慣”與“計算機處理意圖信息”方式之間的GAP。
那么為了彌補上這個GAP,第一個要解決的問題,還是邊界問題,即“什么時候要聯系上文”——這是在非線性多倫找模塊中,找到得第一個邊界。
接下來的討論,還是只限定在一個場景內,既然是在場景內,按照指定的語義解析框架,要分為“意圖內”和“跨意圖”的非線性多倫。他們兩個又是在第一個邊界內,解決兩類問題。
4.3意圖內非線性多輪邊界問題
在用戶發起第一輪的對話后,第二輪的對話是可以任意的,但我們卻沒必要對所有的Query進行理解與回復。
比如用戶第一輪“我想聽歌”,第二輪如果是“換周杰倫的”,那么系統就有必要基于上文去理解并獲取用戶完整意圖。如果第二輪是“那明天呢”,那么這樣的Query是可以置之不理的。
這樣就引出“意圖內非線性多輪”的一個邊界:需要聯系上文,且涉及到在相同意圖內槽位信息的變動,才能獲得用戶完整意圖信息。
找到這個邊界,之后要做得就是在配置好的意圖及句式中,看看哪些槽位是可以改變的,被改變的意圖有哪些,然后按照“意圖要素”去配置句式,為“非線性多輪意圖”劃定可以觸發的邊界
4.4跨意圖非線性多倫邊界問題
“跨意圖非線性多倫”問題的邊界,我這就給出自己的理解:需要聯系上文,且兩個意圖之間的“意圖服務必要要素”(即必填槽位)必須完全相同,才能獲得用戶完整意圖信息。
因為觸發某個意圖,是可以不需要任何“槽位信息”的,但請求服務的時候,幾乎是必須要含有“槽位信息”的。而用戶在第二輪觸發“新意圖”的時候,可以通過不含有任何“槽位信息”的句式觸發新意圖,但系統如果要在觸發意圖之后去請求服務,則必須保證“意圖服務必要要素”的完整,但這時候是不可能強制讓用戶在Query里體現“槽位信息”。
那么問題就變成了:在第二輪用戶發起的對話中,必須保證在不含有任何“槽位信息”的情況下,Query是可以觸發某個意圖。觸發這個意圖后又不能去通過“線性多輪”這個模塊去獲取觸發意圖后的“服務必要要素”,那么只能通過另一種形式去獲取“必填槽位”,即上一輪的槽位繼承。
這也就限定了“跨意圖非線性多輪”所能解決的問題的邊界:只有在兩個意圖的“服務必要要素”(必填槽位)完全相同的情況下,才可以保證在用戶在不提供任何槽位信息的Query中;你是可以通過槽位繼承的方式,滿足此意圖的“服務必要要素”的槽位信息。否則第二輪中“觸發意圖”和“意圖服務”之間的GAP,在不借用“線性多輪”能力的情況下,是沒有辦法完美彌補上的。
可一旦你借用了“線性多輪”追問補槽的能力,那么這個問題也就不再是一個“多輪對話”的問題——因為它已經超出了“需要聯系上文才能獲得完整意圖”這個邊界。
所以,在“跨意圖非線性多倫”這個問題邊界內,需要去人為定義哪些意圖之間是可以進行跨意圖多倫對話的。
現在普遍的實現方式,是去配置一個意圖的“輸入前置語境”和“輸出語境”,來限定某個意圖在第二輪的觸發,即時句式完全相同,也必須在符合配置好的“輸入前置語境”條件下,才能觸發。
確定好一個“跨意圖非線性多倫”意圖可觸發的前置條件后,下面的工作就和“配置意圖句式”模塊流程相似了,配置這個意圖的可能“意圖表達類型”和其中的“意圖觸發必要要素”
比如在“查天氣”這個場景中,兩個intent分別為“查溫度”和“查空氣質量”。那么在“查空氣質量”這個“跨意圖非線性多倫”的配置中,前置輸入語境條件就是“查溫度”這個Intent,觸發“查空氣質量”的這個意圖必要要素就是“空氣質量”這四個字(不含任何槽位信息),比如“那空氣質量呢”。
完整過程如下:
QA:北京今天溫度多少 (獲取【城市】與【日期】必填槽位)
AN:氣溫XX度
QA(二輪):那空氣質量呢
AN:今天PM2.5XXXXX…..
可以看到,在第一輪的句式Query里,如果用戶僅僅說“那空氣質量呢”要么是不會觸發意圖,或即時可以觸發也需要“線性多倫”或其他方式去補槽。而“查空氣質量”這個意圖,通過“跨意圖非線性多倫”的配置,“那空氣質量呢”這個句式,在符合前置語境條件的情況下,是可以匹配上“查空氣質量”這個意圖,并且后續通過槽位繼承的方式形成“完整用戶意圖”去請求后續的服務
4.5多輪槽位解決方式
在邊界問題之后,就是如何獲取用戶完整意圖的問題。這個在反而是比較簡單的了,操作的方式無非是槽位的“繼承、替換和新增”上,并且這樣的操作方式是可以直接在邏輯上得以證明的。
當然,還有一些比較特殊的Query進行槽位的特殊處理。
比如用戶第一輪“我想聽《愛我別走》”,系統隨機放了一首張震岳唱的愛我別走,用戶聽著聽著第二輪“換別人唱的”。這種情況下用戶的完整意圖是“我不想聽張震岳版本的《愛我別走》”(原諒我是個周杰倫粉….),但你會驚人地發現,兩輪Query的槽位只有一個“愛我別走”(歌曲名稱槽位),但用戶的完整意圖是“我想聽不是張震岳唱的《愛我別走》”,你怎么破!
這樣的特殊情況,也是有一套通用的方法,是可以通過特殊句式匹配和槽位處理方式,以及后續的搜索手段去解決的。
在“非線性多倫”這個模塊,我更多是提出了自己的問題,而沒有在解決思路和方法論的層面上做過的的闡述,因為就像我在最開始說的,我更希望通過這篇文章,去思考在整個BOT對話中,在每一模塊,我們要解決的是什么問題。
到這里,我大概論述了我對整個BOT產品的框架的認知,其中涉及到最多的關鍵字,就是“邊界”。隨著了解和思考的深入,越來越體會到邊界對BOT產品極為重要,因為每一個模塊要么是為了解決一個邊界問題,要么是在某個邊界內去解決某類問題。
當然,以上僅是基于個人的一些思考和想法,也并沒有在上面過多提及方法論層面上的東西,也希望之后會能分享出來。
本文由 @free 原創發布于人人都是產品經理。未經許可,禁止轉載。
題圖來自 Unsplash ,基于 CC0 協議
寫的很好,很有幫助,謝謝分享~
寫的太好了,我之前有開發經驗,覺得描述的很棒,很貼切。棒棒的
能個聯系方式私下交流一下嗎?
對AI相關的東西不是很懂,表示崇拜
講的挺好,但是把要素抽象成槽位卻沒有說明,讓我暈眩了好久。
用各種很像的名詞和概念把這個事情復雜化了
看不懂就對了,我也看不懂。 ??
我都看不懂 ??