面向接口/協議?看DuerOS的技能開發
一般地,開發一個對話系統或者機器人問答系統會涉及諸多領域的技術,除了硬件系統之外,還包括語言識別,自然語言處理/識別,知識圖譜的搭建,自然語言生成及TTS播報等等,這對于企業及開發者個人而言,幾乎是難以完成的任務。
有幸的是,對話式AI操作系統例如DuerOS的誕生,使我們可以直面業務邏輯,相對輕松地完成語音類服務的開發與實現。在過去的研發中,經常使用的往往是面向接口的設計方法,那么,面向對話式操作系統的開發,是如何實現的呢?
接口
在OO的時候,通常會講到SOLID原則:
- 單一職責
- 開閉原則
- 里氏替換
- 接口隔離
- 依賴反轉
其中接口隔離是其中的一項重要原則。接口的概念外延較廣泛,wiki上的解釋是這樣的:
- An interface is a shared boundary across which two or more separate components of a computer system exchange information. The exchange can be between software, computer hardware, peripheral devices, humans, and combinations of these.
接口大體上從載體上分為硬件接口和軟件接口,從交互上可以分為人機接口和機-機(M2M)接口。軟件中的接口為組件可以提供了常量、數據類型、過程類型、異常規范和方法簽名等。有時,公共變量也被定義為接口的一部分。接口是一種很高的抽象,很多時候都會涉及到接口,因此要注意上下文和具體的應用場景。
在面向對象的編程語言中,尤其是不支持多繼承的編程語言,往往有著特殊的具體含義,interface 一詞成為了關鍵字,例如Java。Java接口中所用的方法一般都是抽象方法和常量,但是在Java8及以后的版本中,開始支持靜態成員以及默認的函數實現,例如:
- public interface MyTestInterface {
- int MAX_STORAGE_SIZE = 1024;
- default void doTest() {
- System.out.println("Hello, Test!");
- }
- }
盡管如此,作為一個從Java 1.2 開始使用的老程序員而言,Java的發展還是略顯遲緩。
關于接口描述語言(IDL),大約最早出現在是CORBA的規范中,自己在1999年初次使用IDL的時候,非常感嘆它的神奇,在當時簡直就是跨平臺開發的基礎。實際上,OMG IDL不是作為程序設計語言體現在CORBA體系結構中的,而是用來描述產生對象調用請求的客戶對象和服務對象之間的接口的語言。IDL文件描述數據類型和方法框架,而服務對象則為一個指定的對象實現提供上述數據和方法。一般地,IDL文件描述了服務器提供的服務功能,客戶機可以根據該接口文件描述的方法向服務器提出業務請求。在大多數CORBA產品中都提供了IDL到相關編程語言的編譯器。 在Android的應用開發中,AIDL實際上就是IDL的一個領域應用而已。
那么接口和協議有什么聯系和區別呢?
協議
協議,一般是指通信協議,例如大家熟知的互聯網協議——TCP/IP。
在編程語言中,協議指示的是調用方和目標對象之間的交互鏈。一般描述為:
- 對象可以理解的消息。
- 這些消息可能附帶的參數。
- 這些消息返回的結果類型。
- 盡管修改了對象的狀態,但仍然保留的不變量。
- 需要由客戶端處理到對象的異常情況。
- 對于通信而言,還包括方法的調用序列和決策點,例如在UML交互圖中的表示:通信圖、序列圖、交互概述圖/活動圖等。
在面向對象的編程語言中,同樣地,也有把protocol作為關鍵字的編程語言,例如Objective-C。在Objective-C中,同樣不支持多繼承,即不允許一個類有多個父類,于是Objective-C提供了類似的實現方法,也就是協議。協議有點類似于Java里的接口,不同點就是在協議里,可以提供可選的方法,不要求全部繼承。例如:
- @protocol myprotocolName
- - (void)requiredMethod;
- @optional
- - (void)anOptionalMethod1;
- - (void)anOptionalMethodn;
- - (void)otherOptionalMethod;
- @required
- - (void)anotherRequiredMethod;
- @end
Objective-C的協議包括正式協議和非正式協議,這里不再贅述。
協議和接口在很多時候是交疊的,但視角不同,接口面向的是實體對象,而協議聚焦在交互上。本質上,任何的協議都是有字典和語法兩部分組成,從而形成通信上的共識。
對程序員而言,往往更關注傳輸協議和應用協議。傳輸協議主要完成數據裝配,多路復用,差錯檢測和流量控制。應用協議才是具體業務的數據和狀態描述及內容交互。
那么,對話系統的應用開發是如何面向接口和協議的呢?
對話系統的應用技能開發
DuerOS 是對話式人工智能交互系統,簡稱對話式AI系統。應用DuerOS的典型產品之一就是智能音箱。
談到在智能音箱上的應用開發,往往讓人聯想到使用音箱提供的SDK,例如Android SDK 或者 Linux的SDK,然后將應用下載到音箱上。這種理解還停留在多年前的APP開發階段,對人工智能操作系統存在著極大的誤區,可以參見感知人工智能操作系統。
在基于DuerOS的設備例如智能音箱上,應用的開發和Web服務的開發沒什么區別。 簡單地,可以把智能音箱理解成瀏覽器,只是原來的鼠標點擊和鍵盤輸入換成了語音交互即可。在智能設備上開發應用是通過DuerOS Bot Platform(簡稱DBP)實現的,交互協議稱為DuerOS Conversation Service(簡稱DCS),包括了智能終端與DuerOS之間的協議,和DuerOS與應用服務(Bot)之間的協議。
作為開發者, 我們主要實現DuerOS與應用服務(Bot)之間的協議,方便起見,把它也叫做DBP協議。
DBP 協議淺析
DBP協議把HTTP/HTTPS 作為傳輸協議,關于http的相關內容可以參見溫故知新,HTTP/2。 DBP協議中應用協議的數據是通過JSON來表述。
請求與響應
智能音箱上的應用實際上就是對DBP協議中的請求作出響應的Web服務。 一個典型的request 結構示例如下:
- {
- "version": "2.0",
- "session": {
- },
- "context": {
- "System": {
- "user": {
- },
- "application": {
- },
- "device": {
- "deviceId": "{{STRING}}",
- "supportedInterfaces": {
- "VoiceInput": {},
- "VoiceOutput": {},
- "AudioPlayer": {},
- "VideoPlayer": {},
- "Display": {}
- }
- }
- },
- "AudioPlayer": {},
- "VideoPlayer": {}
- },
- "request": {}
- }
session表示用戶會話信息,一次session過程是從開始用戶調起技能到結束,表示用戶與技能的一次會話。
Context描述了設備端的狀態數據,能力配置參數以及用戶相關信息,包括System即系統參數和播放器的狀態。
request 才是具體的payload, 是經DuerOS 經過AI處理后的用戶請求。
Response 是開發者實現的主要內容, 結構示例如下:
- {
- "version" : "2.0",
- "context" : {
- "intent" : {
- "name" : "{{STRING}}",
- "slots" : {
- "{{STRING}}" : {
- }
- }
- },
- "expectResponse" : [
- {}
- ],
- },
- "session" : {
- "attributes" : {
- "{{STRING}}": "{{STRING}}"
- },
- },
- "response" : {
- "outputSpeech" : {
- "type" : "{{STRING}}",
- "text" : "{{STRING}}",
- "ssml" : "{{STRING}}",
- },
- "reprompt" : {
- "outputSpeech" : {
- "type" : "{{STRING}}",
- "text" : "{{STRING}}",
- "ssml" : "{{STRING}}",
- }
- },
- "card" : {}
- "directives" : [],
- "expectSpeech": {{BOOLEAN}},
- "shouldEndSession" : {{BOOLEAN}}
- }
- }
Context用于反饋給DuerOS的intent結果;Intent是技能應用認為對本次query更加合理的意圖解析,expectResponse用于推測用戶可能的回復,DuerOS會在后續的query中優化意圖解析模型。關于意圖和槽位,可以參見感知自然語言理解(NLU)。
session存儲了在DuerOS 會話的屬性數據,如果本次session不結束,那么在下一個發送給技能的請求中,在session.attributes字段會攜帶這些屬性給到至技能應用,相當于數據到終端上繞了一圈。
response是技能應用回復給DuerOS的payload,包括語音播報的內容和風格,展現輸出和技能指令等。
一對Request/Response構成了DBP協議的主體。
事件和指令
事件和指令是DBP協議中的重要消息形式,從智能終端和DuerOS發往我們開發的技能應用的消息稱為事件,從技能應應用發往智能終端和DuerOS的消息稱為指令。
在用戶通過語音輸入后,DuerOS會對語音請求進行識別和理解,并將理解結果發送給技能應用。有三個事件相當于定義了應用技能的生命周期:
- LaunchRequest:代表開啟技能應用
- IntentRequest:相當于進入技能應用的消息處理循環
- SessionEndedRequest:相當于被動結束技能應用,當然,技能應用可以主動退出。
智能終端上的處理狀態事件是通過DuerOS透傳給技能應用的,主要包括音頻播放器audioplayer的音頻播放事件集和視頻播放器videoplayer的視頻播放事件集,對于有屏終端而言,還包括form事件,即用戶屏幕上的點擊事件等。
具體地,音頻事件包括:
- AudioPlayer.PlaybackStarted事件
- AudioPlayer.PlaybackStopped事件
- AudioPlayer.PlaybackFinished事件
- AudioPlayer.PlaybackNearlyFinished事件
- AudioPlayer.ProgressReportIntervalElapsed事件
視頻播放事件包括:
- VideoPlayer.PlaybackStarted事件
- VideoPlayer.PlaybackStopped事件
- VideoPlayer.PlaybackFinished事件
- VideoPlayer.PlaybackNearlyFinished事件
- VideoPlayer.ProgressReportIntervalElapsed事件
- VideoPlayer.ProgressReportDelayElapsed事件
- VideoPlayer.PlaybackStutterStarted事件
- VideoPlayer.PlaybackStutterFinished事件
- VideoPlayer.PlaybackPaused事件
- VideoPlayer.PlaybackResumed事件
- VideoPlayer.PlaybackQueueCleared事件
- PlaybackScheduledStopReached事件
Form事件包括顯示控件的點擊事件,主要包括Form.ButtonClicked和Form.RadioButtonClicked事件等。為了方便開發,增強展示形式的表現力,DBP協議還提供了展現卡片和展現模版,對于的事件包括Display.ElementSelected事件和Display.ButtonClicked事件。
對這些事件的處理,技能應用相當于得到了用戶、智能設備狀態和DuerOS數據的輸入,然后通過指令(directive)的形式完成交互。
在對話過程中,技能應用可以發出的指令有Dialog.ElicitSlot, Dialog.ConfirmSlot,Dialog.ConfirmIntent和Dialog.Delegate,分別用于槽位的填充和確認,意圖的確認,以及通知DuerOS來處理NLU。
在音/視頻播放中,技能應用可以發出的指令有AudioPlayer.Play和AudioPlayer.Stop 來通知音頻播放器開始和停止播放,VideoPlayer.Play和 VideoPlayer.Stop來通知視頻播放器開始和停止播放 VideoPlayer.ClearQueue用來清除播放的資源隊列。
在有屏的智能設備上,Form的事件處理可以理解成一般的HTML表單處理,而展示模版的指令只有一個Hint,用于展現技能應用的引導詞。技能引導詞是技能展現的提示信息,引導用戶與技能應用進行交互。每個技能都可以設計引導詞,讓用戶更快速的使用技能。
由此可見,DBP協議的主要部分相對簡單,清晰明了。
小結
即使理解了協議的格式和內容,自己實現整個DBP協議也是需要一定的工作量的。所幸的是,DBP平臺提供了多種編程語言的SDK,對DBP協議的實現進行了封裝,基于這些SDK(Java/JavaScript/Go/PHP/Python),我們的開發變得相對簡單,使我們可以聚焦于應用的業務邏輯。
DBP平臺還提供了大量的技能開發模版,相當于簡化的開發框架,使對話式AI系統的技能應用開發更為簡單。另外,DBP平臺提供的小技能開發,更是無需編程即可實現一些簡單技能應用的開發。
參考資料
https://dueros.baidu.com/dbp
Pugh Ken,“Interface-Oriented Design”,Pragmatic Bookshelf,2006
威廉·斯托林斯,《數據與計算機通信(第十版)》,電子工業出版社,2015
【本文來自51CTO專欄作者“老曹”的原創文章,作者微信公眾號:喔家ArchiSelf,id:wrieless-com】