從谷歌收購的api.ai,來看構建簡單場景chatbot的方法
雷鋒按:本文作者張俊,文章主要介紹了1)谷歌收購的api.ai的發展歷史;2)構建簡單chatbot的一般原理。
chatbot無疑是當前非?;鸬囊粋€研究領域和產品方向,簡單地可以分為兩類,開放域bot和封閉域bot,開放域bot傾向于解決所有的事情,而封閉域bot傾向于解決某一個細分領域中的事情,旨在用AI技術提高效率,提高生產力?,F階段的開放域bot我個人感覺更像是多個常用封閉域bot的疊加,當用戶發起一個請求,系統會判斷出屬于哪個細分領域,然后轉到相應的程序中去執行并給出反饋,順著這個邏輯來看,研究簡單場景下的chatbot是個重要的基礎工作,這類研究或者產品的質量直接決定了復雜場景或者開放域bot的質量。當然逗樂型的bot并不屬于本文討論的范圍。
圖片來自paper?- The Dialog State Tracking Challenge Series- A Review
chatbot是場交互革命,也是一個多技術融合的平臺。上圖給出了構建一個chatbot需要具備的組件,簡單地說chatbot = NLU(Natural Language Understanding) + NLG(Natural Language Generation)。(本文只關注NLP相關的技術,對語音識別并無討論)
對于封閉域的chatbot,NLU的工作就是DST(Dialog State Tracker),用戶給出輸入之后,系統可以給出下面的形式作為state:
Act(Slot=Value)
Act表示用戶行為的類型,比如請求、查詢、打招呼等等;Slot表示用戶輸入中包含的某種Act下的Entity,比如查詢酒店的位置、價格這些實體;Value是指Slot中Entity對應的值,比如位置在北邊,價格在500-800之間等等。每一句話中可能包括多個Act-Slot-Value對,chatbot需要做的事情就是準確地識別出Act,并且抽取出相應的Slot和Value。
緊接著是NLG的部分,前幾天在PaperWeekly第二期中分享了三篇paper,其中兩篇正是研究基于DST的NLG問題。
本文首先從api.ai這家企業提供的服務說起,通過研究其提供的封閉域bot構建技術,來提煉構建簡單場景chatbot的一般方法,為構建復雜場景或者找出現有chatbot存在的技術問題和面臨的技術難點打下基礎。
api.ai
api.ai公司介紹
Api.ai provides developers and companies with the advanced tools they need to build conversational user interfaces for apps and hardware devices.
這家公司是一家典型的B2D公司,提供了一些工具幫助開發者輕松地開發一款bot,并且可以輕松地發布到各種message平臺上。商業模式也非常簡單,免費用戶有一定次數的調用權限,需要大量調用的話,則付費購買,不同的權限有不同的價格,該公司也提供高級定制化服務。
api.ai公司成立于2010年(數據來自CrunchBase),其早期業務不清楚,但可以從提供的服務中推斷出早期攢了大量的用戶數據,而且涉及的領域非常多,比如:
每個領域都有一個知識庫,如果你要開發某個常用領域內的chatbot,那么這個知識庫將會非常有用。
重要概念和工作原理
重要概念
1、Agents。 這個是一個對外接口,與其他應用程序或你的app進行整合的部分。如下圖:
2、Entities。 這里的實體和引言中提到的Slot類似,是指某個特定領域內的實體,是一類東西的抽象概括,比如HotelName這一實體,對應著很多的酒店名字,凱賓斯基、如家等等。有Entity,就一定有value,chatbot中重要的一步正是從user input中抽取出對應預先設定好entity的value,是一個典型的Named Entity Recognition任務。
這里經典的NER任務是識別出user input中的person、time、place等等幾個基本元素,api.ai將這些常見的entity定義為system級的,即默認提供了訓練好的識別器,當然不僅僅限于這幾類基本的;而特定領域知識庫的重要作用也正是在于識別該領域內的entity。除了system level的NER之外,需要developer自定義一些entity,比如菜名,而且要給定具體的菜名和相似的表達作為samples進行訓練。
3、Intents。 這個相當于是從user input到chatbot執行某個action之間的一個映射關系,用戶輸入一句話之后,chatbot就可以理解其意圖,是在打招呼,還是查詢,還是做些別的事情。這部分api.ai提供了訓練器,但是需要developer定義一些標注好的examples,標注的形式如下:
這里用戶輸入是book a ticket to Los Angeles on Monday,所謂標注包括兩個level,一個是entity標注,一個是intent標注,前一個是為了訓練NER工具,后一個是為了識別intent。這里因為LA是地名,Monday是時間,所以都會被api.ai的系統自動標注出來。
4、Actions。 這個是由intents進行trigger的,actions就和引言中的Act類似,是一個具體的動作,比如說查詢,但執行動作的時候一般都要帶上具體的參數value,用戶輸入:“三里屯最近的阿迪達斯店在什么位置?”,chatbot首先會提取出place->三里屯,query->阿迪達斯店,然后轉換為json丟給后臺的查詢服務,查詢到結果后給出答案。這里的value抽取其實就是第二個概念提到的entity value。
5、Contexts。 上下文是一個非常重要但卻解決不是很好的點,api.ai提供的方式是自定義一些context condition,當condition滿足時,自動trigger出context關聯內容template,然后filling slots,生成response。
工作原理
以RSarXiv chatbot為例,簡單介紹下工作原理。(注:RSarXiv是我之前寫的一個arxiv paper推薦系統)
step 1 自定義Entity ,這里我定義了兩個entities,一個是keywords和subject。keywords是為search功能提供value,而subject是為update new papers功能提供value。
定義好subject entity之后,我給出了幾個examples,同時也包括其synonyms,keywords entity類似。
step 2 自定義Intents ,這里我定義了兩個Intents,分別是update和search。下圖是update的examples,是我自定義的幾個例子。api.ai會根據我定義好的entity進行自動標注,比如cs.CL,today是系統默認的entity所以也進行了自動標注。自動標注是為了后臺的機器學習算法對標注好的examples進行學習,以提高chatbot的NLU準確率。
接下來,我需要定義下Actions,如下圖:
Action被稱為update,必須包含的參數是subject,也就是我們上面講到的一個entity,date參數并不是必須的。所以,這里如果用戶的input被識別出是update intents的話,就必須包括subject參數,否則chatbot會trigger一個response,類似“請用戶輸入subject”這樣的話。
step 3 簡單測試 ,在界面的右側有一個console,用來測試當前chatbot的效果,我輸入update cs.CL,得到下面的效果:
chatbot識別出Intent是Update,Action是update,Parameter是date和subject,并且subject的值是cs.CL,下面的Show JSON是api.ai為developer生成的,用來與developer自己的web service進行數據交換。
step 4 訓練 。訓練包括兩個部分,一是訓練NER,二是訓練Intent Classification。訓練器是api.ai提供的,但是標注數據是developer自己提供的,當然訓練數據越多,標注越準,分類器的準確率就越高,chatbot的NLU準確率越高。至于訓練方法,docs中沒有細說,我簡單猜測一下,NER可以當做Sequence Labeling任務,和Intent Recognition類似,都可以看作是多分類問題,不管是傳統的分類方法還是當下流行的deep learning方法都能得到不錯的準確率。隨著user logs的增多,訓練數據會越來越多,chatbot通過學習就會變得越來越“聰明”。但這里有個問題,training data越多,需要標注或者修改標注的數據就會越多,也是一個麻煩事兒。
step 5 整合、發布 。api.ai支持的平臺非常多,包括當下流行的message平臺,還有各種操作系統平臺。在message平臺上提供了一鍵整合的功能,在操作系統上提供了SDK。這里我用了slack平臺,api.ai打通了和slack的接口,也提供了webhook,連接了我之前寫好的web service,只需要按照它給定的消息接口進行定義即可。
demo
目前RSarXiv只提供兩個簡單的功能,一個是update今天最新的arxiv paper,你可以通過show me new papers in cs.CL等類似的話來獲取cs.CL這個領域中最新的paper;一個是search功能,你可以通過search LSTM等類似的話來獲取包括LSTM這個關鍵詞的paper。由于是一個測試用的demo,就沒做什么復雜的功能。
大家如果感興趣的話,可以留言給我或者發郵件給我(mcgrady150318@ Gmail .com),我邀請大家到這個slack team中。
簡單場景chatbot構建方法
介紹了下api.ai提供的服務,下面簡單地提煉一下。
chatbot = NLU + NLG
api.ai解決的重點問題是NLU的問題,NLU也是Dialogue State Tracker(DST)的核心和基礎,而DST是chatbot的核心。這里的NLU包括兩個問題:
1、從user inputs中識別出user intent和對應的action。
2、從user inputs中抽取出預先設定好的entity value,作為action的parameter。
NLG在api.ai這里基本上通過developer在Intent中設定response,當識別出是哪個intent之后,response自然就有了,最多空一些slot,用結果進行填充。如果developer選擇了webhook,即需要從自定義的web service中給定response。如下圖:
跑了一個簡單場景的chatbot demo之后,簡單歸納下構建方法:
1、從特定任務中歸納出Intents、Actions、Entities。
2、分別編寫Intents、Entities的examples,兩類examples是做DST的基礎,用來訓練chatbot準確地識別user intents和entity parameters,至于算法,自己寫也可以,用api.ai也可以。
3、做好DST之后,chatbot就知道用戶的意圖和相應的參數,丟給后臺的web service去執行,并得到執行的結果,然后填充預先定義好的templates,生成response,返回給用戶。
結束語
簡單場景的chatbot關鍵之處在于做好DST,有一個叫Dialogue State Tracking Challenge的比賽正式為了解決這個問題而舉辦的。我們說,封閉域的chatbot涉及兩個方面,一是NLU,一是NLG,前者通過大量的examples來學習一個分類器和抽取器,得到Dialogue State,而后者根據Dialogue State,生成合適的response。
NLU不是一個簡單的事情,尤其是標注大量的examples不是那么容易;NLG同樣也不是一個好解決的問題,預先定義的template會讓chatbot受限制于template的多少,手工痕跡太重,需要一種更牛的解決方案來代替。(其實挺多paper都在做這件事情,PaperWeekly也分享過幾篇相關的paper,data driven的NLG方案同樣需要大量的examples做訓練。)
Context是個挺難的事情,現有的、成熟的解決方案仍是手工來定義條件,然后根據條件來trigger。我在想,能否構建一個動態的DST,可以是一張動態hash table,也可以是一個動態graph,記錄著某一個user方方面面的狀態,而不僅僅是某一輪對話中抽取出的信息,而是多輪對話中的信息,不僅在intent識別中可以用到context,在生成response時也可以用到,多輪對話和個性化對話都將不是什么問題了?;蛘撸矛F在流行的表示學習思維來想這個問題的話,也許context可以是一個分布式表示,user profile也是一個表示,NLG時以context distribution為condition來做generatation。
本文介紹了構建簡單場景下chatbot的一般方法,用api.ai確實很容易做一個chatbot,而對于復雜場景,我覺得用api.ai來開發也沒有太大問題,最費時的可能是構建context trigger。api.ai因為是面向developer的,所以對于普通的用戶并不適合,但對于有一定經驗的developer來說,使用起來就非常簡單,提供的web界面也很好用,如果說chatbot是一個平臺的話,那么api.ai正像是一個開發工具,提高了開發chatbot的效率,雖然NLG和context這兩個問題可以做的更好,但整體來說降低了開發chatbot的門檻,是個很有意義和錢景的服務。
雷鋒網 (搜索“雷鋒網”公眾號關注) 注:本文由clickstone授權雷鋒網發布,如需轉載請聯系原作者,并注明作者和出處,不得刪減內容。
相關閱讀:
谷歌收購語音識別開放平臺?API.ai,或將其整合在 Allo 中