作者:段清華
個人首頁:http://qhduan.com
Github連結: https://github.com/qhduan/
原文連結,點選文末閱讀全文直達:https://github.com/qhduan/ConversationalRobotDesign
這篇文章包括 Dialogue System, QA System, Chatbot 簡述。下面大部分文字是整體的介紹,當然要完全把這三個部分都詳細說完,可能就夠一本書了,沒幾百篇論文的閱讀出不來。主要是因為每個系統的每個實作方法經常都是獨立的一個領域,而很少有介紹完整成品的東西,也幾乎沒有完整的書籍。
Conversational Robot 的來曆
主要是為了避免dialogue和chat這兩個詞。
Dialogue System 和 Chatbot 都有其比較特定的含義,這裡避開他們。然後使用了 Conversational 這個詞。
簡單的來說
我所定義的
Conversational Robot = Dialogue System + QA System + Chabot + Other Needed Support Components
其中Dialogue System是骨架,其他部分是血肉。
其實單獨來說,每個系統都可以獨立存在。例如一般的百科全書,如果不嚴格的讨論,我們可以認為它是一個QA System。它本身是很有用的,也可以獨立存在。
甚至說Chatbot本身,如果應用在心理輔導、嬰幼兒陪伴等領域,也可以單獨的作為一個應用。
而我之是以把Dialogue System作為主要部分,主要是因為我認為機器人存在的目标最主要是完成任務,我認為傳統意義上的Dialogue System,本質就是一個Task-Oriented System。這符合我對于 Robot 的哲學了解,即執行任務是第一要務。
從人機互動的角度看Conversational Robot

從人機互動的角度看ConversationalRobot
人與機器有很多互動方式,而語音、語言互動是一項重要的互動方式。
自然語言處理(NLP)包括了語音識别,語音合成,文本了解,文本生成等等範疇,可以說從人機互動的角度來說,Conversational Robot 在這裡特指語言的了解、生成這一過程的相關部件。
從機器人的角度來看Conversational Robot
從機器人的角度來看ConversationalRobot
從機器人的角度來講,一個智能體(Intelligent Agent),從外界環境接受資訊,這個資訊主要的一個資訊來源就是人。而人能提供例如語音(說話),語言(微信打字),視訊(機器視覺),動作(動作、手勢識别)等資訊。
Conversational Robot 特指接受語言,或者經過轉換的語音資料,根據對文本的了解,産生一些執行操作。執行操作可以由其他部件完成。最終把執行結果傳回給人的這一個過程的相關部件。
内部元件,從Dialogue System的主要骨架說起
一個傳統的Dialogue System如下圖所示
Principal components of a spoken dialog system
(Jason D. Williams, The Dialog State Tracking Challenge Series: A Review, 2016)
一個更簡單的圖例如:
Traditional Pipeline for Task-oriented Systems
(Hongshen Chen, A Survey on Dialogue Systems:Recent Advances and New Frontiers, 2017)
語音識别(ASR)
圖中ASR負責識别語音,對于一條使用者的語音輸入可能有多個結果
例如不同識别到的文本和對應的可信度
例如使用者說(注意是語音):“我要去上海”
結果可能是
[
{
"sentence": "我要去上海",
"score": 0.4
},
{
"sentence": "我要去商海",
"score": 0.3
},
{
"sentence": "我要去傷害",
"score": 0.1
}
]
複制
實際上很多關于對話系統的文章都沒有仔細說這部分,這也是顯而易見的,因為語音識别有更專門的領域專家去研究。絕大部分系統的假設都是能拿到比較準确的識别結果,至少是像上面那樣的的結果清單,之後的工作。類似的,圖中的TTS也是一般被忽略。
自然語言了解(NLU or SLU or LU)
這部分在有些資料被稱為
SLU
(Spoken Language Understanding), 有的資料也稱為
NLU
(Natual Language Understanding),甚至
LU
(Language Understanding)。也有一些文獻稱之為
Semantic Decoding
,因為它的結果也被稱為
Semantic Frame
, 也就是把使用者輸入的句子(utterance)轉換為了一種Semantic Frame,即抽象出了使用者所期望行為的語義。
這部分主要根據語音輸入的結果,判斷使用者意圖。
從含義角度來說,輸出的是,三個部分内容:
SLOT(S): 問題所需要的資料參數
INTENT: 使用者意圖
DOMAIN: 問題領域
如(Yun-Nung Chen, SYNTAX OR SEMANTICS? KNOWLEDGE-GUIDED JOINT SEMANTIC FRAME PARSING)的例子:
W: tell vivian to be quiet
S: contact=vivian, message=be quiet
D: communication
I: send_text
複制
也就是使用者輸入了
tell vivian to be quiet
之後, 或者這句話的DOMAIN(D)是
communication
, INTENT是
send_text
, 有兩個slot, 分别是聯系人
contact=vivian
還有資訊内容
message=be quiet
這些内容會被後續的部件處理。
從一些實際應用的角度來說,這部分LU在一些系統裡也被描述為會産生潛在的
user-action
清單。也就是“使用者想做什麼”的行為清單和每種行為的可能性
例如使用者輸入:“明天晚上的電影”,結果可能是
[
{
"user_action": "request(movie_name, date=tomorrow_night)",
"score": 0.5
},
{
"user_action": "request(movie_name, date=tomorrow)",
"score": 0.3
},
{
"user_action": "inform(date=tomorrow_night)",
"score": 0.1
}
]
複制
這些清單可能類似下面的行為,其中
Usr
列打對号的就是使用者可能産生的行為清單,我們以後會在單獨的
NLU
相關章節詳細探讨這部分内容。(Steve Young, The Hidden Information State model: A practical framework for POMDP-based spoken dialogue management, 2010)

The principal dialogue acts used by the HIS System
關于這個清單的詳細意義與探讨,會在後續的章節進行。
Dialogue State Tracker & Dialogue Policy
在某些系統上,這兩部分是分離的,在而在很多系統上,實際就是一個部分。也有一些資料把這部分稱為Dialogue Management。這部分也被稱為Belief Tracking & Policy Optimization / Policy Learning。
需要狀态管理是因為對話并不僅僅是單輪的,而是需要多輪進行,或者說完成一個任務很可能需要跟使用者反複互動。使用者很可能修改之前的意圖、提供的參數等等内容。如果對話隻是一問一答,即目前問題和以前的問題、回答都沒關系的話,那實際上就不算Dialogue System,而是QA System了(Question & Answer)
系統需要儲存之前使用者的問題,也要儲存自己回答的結果,例如:
request的格式:
request(a, b=x, c=y,...)
即請求參數
a
,并且提供(可選的)參數
b=x
等。
inform的格式:
inform(a=x, b=y)
即提供資訊,使用者可以向系統提供資訊,系統也可以向使用者提供資訊(答案或查詢結果)。
舉例如下:
使用者:我想找北京去上海的火車
-> user_action: request(車票清單, 起始地=北京, 目的地=上海)
-> sys_action: inform(車票清單=執行部件的答案, 起始地=北京, 目的地=上海)
系統回答執行個體:從北京去上海的車票有xx趟,如下:xxxxx
使用者:從杭州去的呢?
-> user_action: request(車票清單, 起始地=杭州)
-> sys_action: inform(車票清單=執行部件的答案, 起始地=杭州, 目的地=上海)
系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy
複制
假設上面兩條是連續的問題,那麼系統在回答第二條的時候,使用者是沒直接提示目的地的(這裡是符合自然語言習慣的),那麼目的地這個狀态,就應該由DST部件存儲下來(相當于機器的短期記憶),在一定假設下,補全并猜測到使用者的完整意圖。
在第二次回答中,如果系統并不确定目的地是上海(例如根據某個機率值),那麼可能就會産生下面的情況:
使用者:我想找北京去上海的火車
-> user_action: request(車票清單, 起始地=北京, 目的地=上海)
-> sys_action: inform(車票清單=執行部件的答案, 起始地=北京, 目的地=上海)
系統回答執行個體:從北京去上海的車票有xx趟,如下:xxxxx
## 以上部分和上面的例子一樣
使用者:從杭州去的呢?
-> user_action: request(車票清單, 起始地=杭州)
-> sys_action: confirm(起始地=杭州,目的地=上海)
## confirm是确認操作,期待使用者回答諸如是/否,yes/no的回答
系統回答示例:您是說從杭州去上海的車票嗎?
使用者:是的
-> user_action: confirm()
-> sys_action: inform(車票清單=執行部件的答案, 起始地=杭州, 目的地=上海)
系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy
複制
或者如果系統實在不确定,或者比較愚蠢,甚至可能是:
使用者:我想找北京去上海的火車
-> user_action: request(車票清單, 起始地=北京, 目的地=上海)
-> sys_action: inform(車票清單=執行部件的答案, 起始地=北京, 目的地=上海)
系統回答執行個體:從北京去上海的車票有xx趟,如下:xxxxx
## 以上部分和上面的例子一樣
使用者:從杭州去的呢?
-> user_action: request(車票清單, 起始地=杭州)
-> sys_action: request(目的地=上海)
## 上面最後一行代表,機器也可以向使用者請求資訊
系統回答示例:請告訴我目的地是哪裡?
使用者:是上海
-> user_action: inform(目的地=上海)
-> sys_action: inform(車票清單=執行部件的答案, 起始地=杭州, 目的地=上海)
系統回答示例:從杭州去上海的車票有yy趟,如下:yyyyy
複制
這些不同的操作,最終都成功引導到了結果。當然理論上第一次最好,因為使用者操作最少,但是如果ASR部件、NLU部件甚至DST部件産生了錯誤(例如聽錯了、了解錯誤、管理失誤等等),那麼是有可能産生後兩次的對話。
是以DST和DP部件,主要是管理曆史狀态,并且根據狀态生成一個
sys_action
,系統所要應對的行為。
自然語言生成 NLG
自然語言生成部件的主要目的是根據系統的相應類型,生成自然語言回答。
一般來說這部分主要是套模闆。
當然現在也有一些使用如seq2seq模型等等産生的NLG方法。這些方法的出現一來是為了提高系統的魯棒性,另一方面是希望系統說話更接近人類說話方式,最終提高使用者體驗。
語音合成 TTS
這部分是指從文字到語音合成的部分,并不在我所定義的Conversational Robot的範疇内。絕大部分Dialogue System或其他相關文獻也都會忽略,因為子產品本身可以獨立運作,并且有比較成熟的解決方案。
問答系統 QA System
這裡簡單探讨QA系統的幾種形式
問答比對
問答比對包括Question & Answer Selection/Matching/Searching。
假設我們有一堆問答對
(q_1, a_1, q_2, a_2, ..., q_n, a_n)
如果這個時候新來了一個問題,最樸素的想法就是去這些問答對裡面搜尋,找到答案(假設有的話)。
問題是,問題本身的形式可能多種多樣,例如:
- 你從哪來?
- 你哪來的?
- 你從哪裡來?
- 你來自哪裡?
這些問題本身都代表一樣的含義,或者說他們有相似的語義(Semantic)。
那麼問題來了,如何确定答案?
假設我們有一個函數
f(x, y)
,當兩個問題相似的時候
f(q_1, q_2)
趨近于1,當兩個問題不相似的時候
f(q_1, q_3)
趨近于0。
那麼使用者隻要輸入一個新問題
q_user
,那麼我們隻要從資料庫裡面計算
argmax{q_i} f(q_i, q_user)
就好了。也就是從資料庫中找到與問題
q_user
最相似的問題。
當然還有另一種類似的做法,假設一個函數
g(x, y)
,當一個問題
q
和答案
a
是一對的時候(也就是
a
是
q
的正确答案),那麼
g(q, a)
趨近于1,如果不是一對,則趨近于0。
當使用者來了新問題
q_user
,那麼我們隻要周遊資料庫裡面的所有答案尋找
argmax{a_i} g(q_user, a_i)
,則可以找到,最符合使用者問題的答案
當然實際應用的時候,我們不可能真的周遊資料庫的所有問題(可能有幾百萬條資料,時間性能不允許),這個時候我們可以通過其他手段。
例如我們有一個函數
vec(x)
,它可以把一個問題或者答案轉換成一個有限長度的實數向量。然後我們還有一個函數
similarity(x, y)
,用來判斷兩個向量是否相似。那麼當使用者來了一個問題
q_user
的時候,我們可以先把它向量化得到
vec(q_user)
,然後再去比對我們已經
預先
向量化好的其他問題。即
argmax{vec(q_i)} similarity(vec(q_user), vec(q_i))
因為向量相似比對的算法,可能遠快于周遊所有問題(或答案)。(例如用K-neighbour相關算法如BallTree等)
用深度學習解決此類問題的論文比較多,例如:
(Ming Tan, LSTM-BASED DEEPLEARNING MODELS FOR NON-FACTOID ANSWER SELECTION, 2016)
IR-based
利用搜尋引擎,或者類似搜尋引擎的技術
假設我們問“愛因斯坦出生于哪一年?”
然後把這個問題直接丢給搜尋引擎,或者經過某種轉換到某個形式(例如把問題修改為文本“愛因斯坦 出生 年份”)
假設去搜尋,第一條結果可能如下:
阿爾伯特·愛因斯坦- 維基百科,自由的百科全書
https://zh.wikipedia.org/zh-hant/阿爾伯特·愛因斯坦
阿爾伯特·愛因斯坦,或譯亞伯特·愛因斯坦(德語:Albert Einstein,1879年3月14日-1955年4月18日),猶太裔理論實體學家,創立了現代實體學的兩大支柱之一的相對論 :274,也是質能等價公式(E = mc2)的發現者。他在科學哲學領域頗具影響力。因為“對理論實體的貢獻,特別是發現了光電效應的原理”,他榮獲1921年諾貝爾實體學獎 ...
複制
而我們根據問題可以判斷使用者的意圖是希望結果是“哪一年”,也就是問題答案很可能是(18xx年, 19xx年, 18xx-xx-xx, 19xx-xx-xx)之類的形式。
我們獲得了潛在的答案類型,和潛在包含答案的資料條目。我們再從中搜尋我們的答案。
這個方法的方法與條件:
- 答案比較短(一個詞或一個短語)的時候
- 把問題轉換為可能更容易搜尋到答案的形式
- 猜測使用者所希望的答案類型(是人?地點?時間?其他?)
Knowledge-based (KB QA)
當然也可以說語義網、知識圖譜等based
這個角度解決QA問題首先我們需要有一堆資料庫,常見使用三元組(triples)的形式儲存,例如:
- (愛因斯坦,出生于,1879)
- (愛因斯坦,職業,實體學家)
- (愛因斯坦,死于,1955)
- (中國,首都,北京)
- (美國,首都,華盛頓)
類似這樣,一般來說三元組中間那是一個關系(relation),而兩邊是兩個實體(entity),我們也可以寫作
出生于(愛因斯坦,1879)
,
出生于(這篇文章的作者,2020)
,類似這樣的形式
假設我們有很多這樣的三元組資料,那麼我們解決:“愛因斯坦出生在哪年”這樣的問題方法,是把問題轉換為一種邏輯形式,例如:
愛因斯坦出生在哪年 => 出生于(愛因斯坦, ?x)
中國的首都 => 首都(中國, ?y)
複制
其中
出生于
和
首都
都是關系,而
中國
和
愛因斯坦
都是實體,而
?x
和
?y
都是自由變量,這裡代指我們想要尋求的答案。
從這個角度解決QA問題有一套比較完整的方法論,如RDF,Semantic Web,SPARQL等技術和方法
也有一些文獻使用了結合deep learning與sequence-to-sequence等技術的的Knowledge-based解決方案,具體内容我們後續會讨論。
Chatbot
這裡Chatbot特指中文的閑聊機器人
閑聊機器人是帶有一定“娛樂”意味的機器人。當然也可以用作例如心理輔導,心理幫助,嬰幼兒教育,兒童陪伴等等内容。
這部分就不是完成一個任務,不是需要答案,而更多的是陪伴、娛樂、放松。一個Chatbot最簡單的成功名額就是,本質是鼓勵使用者多和Chatbot交流,使用者使用時長和使用者下次繼續使用的意願,如果使用者願意一直陪着Chatbot聊天,那就成功了。
一般來說Chatbot隻有兩種技術,template-based和neural-based
template-based
也就是根據模闆來選擇回答
最簡單的模闆例如:
使用者:你喜歡 * 嗎?
系統:我喜歡 * 啊,你喜歡嗎?
系統:我喜歡 * 啊,你還喜歡什麼别的嗎?
使用者:你吃過 * 嗎?
系統:我是機器人,不吃 *
系統:* 好吃嗎?你告訴我呗
使用者:你覺得 * 怎麼樣?
系統:這取決于你對 * 的了解,我不好回答啊
系統:我覺得 * 還不錯吧,你怎麼看?
複制
可以看出,上面模闆的
*
可以代指很多東西
當然實際應用上,模闆可能比上面複雜的多,可以解決更多問題,設定算術題,計算,遞歸等等
這方面比較完整的研究是AIML語言,即 Artificial Intelligence Markup Language 語言。
是一種XML格式的标記語言,這部分方法也曾經是試圖解決圖靈測試的主力研究方法。
更多内容可以參考:
Wikipedia AIML
AIML tutorial
neural-based
是以神經機器翻譯模型為參考,用來生成對話的模型。即基于深度學習的 sequence-to-sequence 模型(或變種),來生成對話。
這類模型直接訓練對話,得到端到端的結果。訓練資料大部分來自于電影字幕、社交媒體,或者其他已有的對話資料。
這友善比較前沿的研究如
(Jiwei Li, Adversarial Learning for Neural Dialogue Generation, 2017)
(Jiwei Li, Deep Reinforcement Learning for Dialogue Generation, 2016)
更多 Template-based 和 Neural-Based 的實作,我們後續張章節會讨論。