####好好好####談多輪對話(填槽方面)

序言

以一週前的一條微博作爲開始。一週前我講:相對的,自然語言解析技術已經逐漸不再成爲各家廣義智能助理產品的核心競爭力,識別用戶意圖之後所提供的服務開始成爲對話機器人差異化的核心。

百度:對話系統的組成

對於一個對話系統而言,我微博中所指的『後續服務』,就是上圖中的 DST(對話狀態維護)以及 Policy(動作候選排序),或者統一的稱其爲 DM(Dialogue Mannagement,對話管理)。也即,當接收到 NLU 模塊的輸出、其他場景及用戶特徵信息之後,判斷系統應該跳轉到什麼狀態,以及執行什麼樣的動作。

從產品的角度,DM 是對話機器人封閉域多輪對話體驗的核心,正是一次次 DST + Policy 形成了人機間的多輪對話體驗。(我個人傾向於將識別用戶意圖之後,爲了獲取必要信息,與用戶進行的有目的的多輪對話稱爲封閉域多輪對話,區別於識別用戶意圖之前,爲了利用上文信息,所採用的『上下文替換』、『主體補全』等技術,aka 開放域多輪對話。下文提到的『多輪對話』,均指封閉域多輪對話。)

既然多輪對話在對話機器人類產品體驗中扮演着如此重要的角色,我便傾向於開始思考:一個架構完備的多輪對話體系應該是什麼樣的。也即多輪對話系統中需要至少包含哪些模塊,才能爲用戶提供一種與人人對話相去不遠的人機對話體驗。

多輪對話定義

我有個習慣,就是在構造一個複雜系統之前,先從紛繁的細節之中跳出,嘗試抽象的描述整個系統,及系統中的各個模塊,也即爲它們『下定義』。這能幫助你在多種可行方案中做出選擇,也即幫你明確:什麼該做,什麼不該做,什麼該誰做

基於以上思想,我嘗試先給出幾個我個人對於多輪對話體系定義問題的回答:

基本定義:什麼是多輪對話?
(封閉域)多輪對話是一種,在人機對話中,初步明確用戶意圖之後,獲取必要信息以最終得到明確用戶指令的方式。多輪對話與一件事情的處理相對應。

補充說明:所謂『必要信息』一定要通過與用戶的對話獲取嗎?
不一定,即便是人與人之間的交流,對話本身所包含的信息也只佔總傳遞信息量的一小部分,更多信息來源於說話人的身份、當前的時間/地點等一系列場景信息。所以多輪對話的信息獲取方式也不應當只侷限於用戶所說的話。

補充說明:多輪對話一定在形式上表現爲與用戶的多次對話交互嗎?
不一定,如果用戶的話語中已經提供了充足的信息,或者其它來源的補充信息已經足夠將用戶的初步意圖轉化爲一條明確的用戶指令,那就不會存在與用戶的多次對話交互。

以上是針對多輪對話整體定義問題的回答,每個模塊的相關定義會在下文各個模塊的講解中嘗試給出。

基本定義:什麼是槽?
槽是多輪對話過程中將初步用戶意圖轉化爲明確用戶指令所需要補全的信息。一個槽與一件事情的處理中所需要獲取的一種信息相對應。

補充說明:多輪對話中的所有的槽位都需要被填充完整嗎?
不一定,以如下對話爲例:

我:『去蕭山機場多少錢』
出租車司機:『70』

對話中的『70』,應當被理解爲70元人民幣,而不必再去追問:『你說的是人民幣、美元、日元還是港幣?』。這類信息應當以默認值的形式存在,也即槽有必填非必填之分,與上文所說的『信息未必需要通過與用戶的對話獲取』相對應。

詞槽與接口槽

上文反覆的提到,對話內容並不是獲取信息的唯一方式,用戶身份以及當前場景也包含着大量值得被利用的隱含信息。所以,與此相對的,一個完備的多輪對話體系應當同時具備從用戶話裏以及話外獲取信息的能力。

我個人將利用用戶話中關鍵詞填寫的槽叫做詞槽,利用用戶畫像以及其他場景信息填寫的槽叫做接口槽

舉個例子,我講『我明天要坐火車去上海』。其中,分別將『明天』、『上海』填入名爲『出發時間』、『目的地』的詞槽中,而我當前所在的位置,則填入到了名爲『出發地』的接口槽中。

槽組與槽位

我個人將利用用戶話中關鍵詞填寫的槽叫做詞槽,利用用戶畫像以及其他場景信息填寫的槽叫做接口槽

舉個例子,我講『我後天要坐火車去上海』。其中,分別將『後天』、『上海』填入名爲『出發時間』、『目的地』的詞槽中,而我當前所在的位置,則填入到了名爲『出發地』的接口槽中。

不知道上文錯的如此離譜的結論有沒有引起你的注意 :)

仔細讀一遍上面舉的例子,就會發現一個很嚴重的矛盾點:難道『出發地』這個槽不能由用戶指定?用戶完全可以說『我後天要坐火車從北京去上海』,那它是詞槽還是接口槽?而且更進一步的,難道只能用『我當前所在的位置』來填入『出發地』這個槽中?比如,如果能讀到我的日程表,發現我明天會去杭州,那是不是就應該用『杭州』而不是『我現在所在的位置』來填『出發地』這個槽了?

從中我們能發現什麼呢?同一個槽,可能會存在多種填槽方式

我將可能包含多種填槽方式的稱爲槽組,槽組下面可能存在任意多個槽位,也即任意多種填槽方式,而每個槽位又都對應着『詞槽』與『接口槽』兩種槽位類型之一。

本質上來講,槽組(也即上文中提到的『槽』),對應着一種信息,而幾乎不會有哪種信息的獲取方式只有一種。所以一個『槽』會同時對應多種填槽方式也就是自然而然的了。

依照上文,同一種信息會有多種獲取方式,也即同一個槽組會對應多種填槽方式(槽位)。那不同填槽方式之間必然會存在優先級的概念。

就如同上文『訂票』的例子,『出發地』槽包含三種填寫方式,一種詞槽、兩種接口槽,自然的,詞槽的優先級最高,『日程表中隱含的出發地』次之,『我當前所在的位置』再次。

如果將其與前文提到過的必填/非必填結合起來,其填槽過程應當遵循以下步驟:

  • 嘗試填寫詞槽
  • 若失敗,嘗試填寫第一接口槽『用戶日程表中隱含的出發地』
  • 若失敗,嘗試填寫第二接口槽『用戶當前所在位置』
  • 若失敗,判斷是否該槽必填
  • 若必填,反問用戶,重填詞槽
    *若非必填,則針對該槽組的填槽過程結束

我們需要知道,必填/非必填在邏輯上與槽組而不是槽位平級,只有信息纔會分爲必要/非必要,填槽方式不做這種區分。而且是否必填實際上與接口槽無關,只取決於是否需要與用戶進行交互。

澄清話術

槽組也即與一種信息平級的概念還有一個,叫做澄清話術

澄清話術是對話機器人希望獲取某種信息時所使用的問句。比如『目的地』對應的澄清話術就是『您想從哪出發呢?』,『出發時間』對應的澄清話術就是『您想什麼時間出發呢?』。

顯而易見的,澄清話術與槽組而不是槽位平級。

槽的填寫

上文講到,一個槽組可能會有多個槽位,槽位存在詞槽接口槽之分。

先說詞槽。

詞槽信息的抽取其實還是有些麻煩的,不過這屬於解析的問題,不在本文探討的範圍內,這裏只是簡單提一下,舉兩個例子:

  • 用戶表達『不』,可能會有『不行』、『不是』、『算了』、『沒有』等一系列說法。
  • 用戶話中有多個符合條件的關鍵詞,我們整套多輪對話中有多個槽,每個槽填一個還是多個值?哪個槽與哪個詞對應?

同義詞典、規則、雙向LSTM+CRF,各有各的方法。

再說接口槽。

接口槽與詞槽相比,額外存在一個問題,就是:接口返回的結果就是用戶需要的結果嗎?

這裏需要分成兩種情況來討論,一種是:我們明確知道接口的返回值可以直接填入槽位(不是槽/槽組)中,不需要向用戶確認

特別的,這裏還要明確一點,即便是上述情況,也並不意味着當前槽/槽組只有該特定接口槽這一個槽位。有兩種情況存在:一種是該槽組下只有這一個槽位,該接口的返回值直接填入槽位中,也相當於填入了槽/槽組中;或者該槽位下有多個槽位,接口槽的填入值並不一定最終作爲槽/槽組的填入值。

另一種是:我們知道接口的返回值只能作爲參考,需要用戶的協助才能進行槽位的填寫

這種情況下,需要提供選項,讓用戶最終決定該槽位的填入值,與詞槽一樣,這裏同樣需要處理單值/多值的問題。單值/多值在邏輯上與槽組平級。

此外,這裏還要注意一個否認選項的問題,比如我對阿里小蜜說,我忘記密碼了,它會通過接口拿到我的當前賬號,然後將其提供選項給我,問『你是忘記了哪個賬號的密碼?』,不過,除了我當前賬號之外,還有一個選項也被提供出來了,就是『不,不是這個賬號』。

這代表了一類問題的存在,用戶的意圖並不一定包含在接口的全部返回值之中。所以就必然會有這樣一種類似『不要/不是/不』的選項,我將其叫做否認選項

用戶選擇否認選項後,即意味着該槽位的填寫失敗了,需要填入一個特殊值代表失敗。用戶選擇否認選項的失敗,可以與接口調用失敗等其它意外情況合併處理,因爲這都意味着該槽位填寫失敗,意味着該種信息獲取方式未能成功獲取信息

如果該槽組下只有這一個槽位,這個特殊的失敗表徵值就應當作爲整個槽組的填入值,如果還有其他槽位值,則根據槽位間優先級最終確定槽組填入值。

平級槽和依賴槽

上面說到底都在講一個槽組的填寫,也即一種信息的獲取,但多輪對話的目的是將初步用戶意圖轉化爲明確用戶指令,這其中所需要的信息通常都不只有一種。

談完了槽組與槽位之間的關係,接下來談一下槽組與槽組之間的關係,也即信息與信息之間的關係。

爲了便於理解,我先舉兩個例子來代表兩種多輪對話中所包含的極端情況。

第一種:訂車票,你需要知道用戶出發的時間、地點、目的地、座位種類。這四個槽組之間,沒有任何依賴關係。換言之,你只需要確定好這四個槽組中必填槽組之間的澄清順序,接收到用戶問句後,對還未填充完成的必填槽組依次進行澄清即可。我將這四個槽組之間的關係稱爲平級槽關係

另一種,不知道讀者玩沒玩過橙光,或者其它多結局的劇情類遊戲。它們的特點是什麼呢?每一個選擇都會有影響到後續劇情發展也即 每個槽組的填寫結果會影響其它槽組的填寫。換言之,部分槽組依賴前序槽組的填寫結果,在其依賴的前序槽組填寫完成之前,該槽組都無法進行填寫。我將槽組間的這種關係稱爲依賴槽關係

這種情況下,整個多輪對話過程就形成了一棵樹,極端情況下,這棵樹是滿的。樹上的每個節點放置着一個會對後續對話走向產生影響的槽組

槽關係的選擇要根據實際業務場景來確定。

如果錯將平級槽採用依賴槽關係來管理,就會出現信息的丟失。比如 A、B、C,三者本爲平級槽關係,但卻將其用 A->B->C 的依賴槽關係來管理,那即便用戶問句中包含填寫 B、C 槽組的信息,也可能會由於 A 槽組的未填寫而造成 B、C 槽組的填寫失敗。

如果錯將依賴槽採用平級槽的關係來管理,就會出現信息的冗餘,比如 A、B、C三者的關係爲 A、A1->B、A2->C,那即便用戶將值 A1 填入槽組 A 後,卻仍然需要向用戶詢問本不需要的 C 槽組的填寫信息。

上述兩種情況屬於全平級槽關係全依賴槽關係的特殊情況,在實際的業務場景中,這兩種關係會是同時存在的,不同槽組間,既有平級槽關係,又有依賴槽關係。

實際業務場景中,完整的多輪對話過程通常會以的形式存在,每個節點存在一個或多個槽組,用於獲取一種或多種信息,節點間的槽組爲依賴關係,節點內的槽組爲平級關係

上文將多輪對話定義爲一件事情的處理,槽組/槽定義爲一種信息的獲取,槽位定義爲信息的一種獲取方式。這裏我傾向於將多輪對話樹結構中的一個節點定義爲處理事情的一個步驟

一件事情的處理包含多個步驟,每個步驟中需要補全一種或多種信息,每種信息存在一種或多種獲取方式。

上述定義和組裏算法大佬的定義有些分歧,不過誰讓這是我的文章呢 :) 就按我的來。

填槽意義

結合上文,我們需要瞭解到,填槽的意義有兩個:作條件分支多輪對話作信息補全用戶意圖。換言之,填槽不僅是補全用戶意圖的方式,而且前序槽位的填寫還會起到指導後續信息補全走向的作用。

准入條件

上文我們講到,完整的多輪對話過程通常會以的形式存在,樹中包含多個節點,代表處理這件事情的一個步驟

而每個節點,都應當有其特別的准入條件。樹的根節點往往需要限制 NLU 模塊的輸出,也即明確什麼樣的用戶意圖將會由該棵多輪對話樹來處理;樹的中間及葉子節點往往需要根據前序槽組的填槽結果以及其他背景信息進行條件限制。(如果將所有信息,比如 NLU 模塊輸出,或是其他背景信息都看做前序槽組的填寫結果,那就能得到統一的槽組-條件-槽組-條件······形式,槽組用於獲取信息,條件用於信息限制

我嘗試從兩個角度來描述一套完備的准入條件體系。

一個是多條件的組織形式,准入條件在邏輯上應該支持條件間的與或非,百度的 UNIT 平臺提供了一種相對成熟的組織形式,將准入條件整體劃分爲條件條件組,條件包含在條件組中,組內條件間是關係,條件組之間是關係(當然這裏的且與或可以根據自身業務情況對調),條件本身支持關係。

一個是單條件的限制能力,准入條件應當同時支持對前序槽組填寫值、填寫方式、填寫狀態進行限制。也即需要有針對值的條件針對類型的條件針對狀態的條件。簡單的講,狀態就是『填了嗎』,類型就是『誰填的』,值就是『填了什麼』。

不同業務場景下我們會需要不同角度的限制條件。比如,上文中提到填槽的意義包含兩種:作條件分支多輪對話作信息補全用戶意圖,如果僅僅作信息,那我們通常就只關心『填了嗎』,只要填寫完成就進行後續步驟,並不關係『誰填的』以及『填了什麼』;但是如果槽組內的填入值會影響後續多輪對話走向,那我們就傾向於通過槽組的填入方式填入值來作多輪對話的分支。

答案系統

先明確一個觀點,多輪對話樹的節點屬於對話節點而不是答案節點同一份答案可能會出現在多個對話節點中

答案系統和多輪過程應當是解耦的,答案系統中的每份答案都應當設置好自己的觸發條件。舉個例子,若存在 ABC 三個槽,A=A1、B=B3、C=C1 提供答案一,A=A2、B=B1、C=C2 或 A=A3、B=B2、C=C1 提供答案二。

另外,答案的種類也不應僅侷限於文本,富文本、接口、話題切換,都可以視爲合理的答案形式。

話題切換

話題切換指用戶與用戶的對話從一個多輪過程切換至另一個多輪過程,話題切換有主動切換被動切換之分。

上文提到的作爲答案的話題切換,就可以理解爲主動的話題切換

被動的話題切換是指,系統發現無法從用戶的問句中抽取信息以繼續當前的多輪對話,只好將其作爲一條全新的問句重新進行解析和話題識別

話題切換,尤其是主動的話題切換會涉及到一個新問題:槽繼承

舉個例子:

我:『我明天要坐高鐵從杭州到北京』
我:『算了,還是坐飛機吧』

這種情況下,機器人不應當重複詢問『出發地』、『出發時間』和『目的地』。

除了槽繼承,還有一個與之相對的問題叫做槽記憶,這通常適用在被動式的話題切換中。由於解析失誤,或者其他原因,使得用戶跳出了原話題,當用戶在一定時間內重新回到原話題時,不應讓用戶重複進行填槽,該技術已被用於阿里小蜜,不過他們似乎稱之爲『多輪狀態記憶』。

舉個例子:

我:幫我訂張從杭州到北京的機票。
VPA:請問您希望哪天出發呢?
我:明天杭州下雨嗎?
VPA:明天杭州有雷陣雨。
我:後天呢?
VPA:後天杭州天氣晴。
我:機票訂後天的。
VPA:好的,已幫你預定後天從杭州到北京的機票。

狀態切換

我們還需要思考這樣一個問題,既然話題可以切換,也即一個多輪過程可以切換到另一個多輪過程,那多輪過程中的對話狀態是否可以切換?

我舉兩個例子:

第一個:

我:幫我訂張機票,從杭州出發。
VPA:請問你想去哪呢?
我:(發現明天杭州有雷陣雨)換出發地。
VPA:請問你想從哪出發呢?
我:上海。

多輪對話應當允許回到前序節點

第二個:

我:我想買個杯子。
VPA:以下是爲您推薦的杯子。(展示結果一)
我:換一換。
VPA:以下是爲您推薦的杯子。(展示結果二)

多輪對話應當允許重複進入同一節點

結語

就先這麼多吧 :)



作者:我偏笑_NSNirvana
鏈接:https://www.jianshu.com/p/b0aa00f7095e
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章