大家好,很久沒有更新網誌了!

今天要來教大家一個非常重要的東西

就是watson裡面的dialog功能拉

那dialog到底是什麼?而且要怎麼用呢?

其實dialog就是一套有階層式的key word mapping工具

想想看

現今的機器人是不是往往都只能跟你做一問一答的對話

譬如你今天講說,我要一杯"拿鐵"

機器人就會反問你,"請問你要冰的還是熱的?"

你:"我要冰的"

結果這時候機器人已經忘記你是要點"拿鐵"了

因為機器人都只支援一問一答

那有人就說,我可以用if else去判斷並且使用var把東西記下來啊!

是得這樣是行得通的

但是你想想看如果今天機器人是要放置在一些銀行或是郵局,一些問題比較複雜的地方

你的if else 不就要寫道你的屁股開花嗎?~

所以watson針對了這樣的需求,開發出了一套整合型服務就是 

好的那我們切入正題,來看看這個dialog要怎麼使用吧!

首先dialog所使用的為xml文件

大家可以先去以下這個網址去下載他基本的example

以及我自己打的一份鬧鐘or碼表的對話文件

還有這個連結是一概述性的介紹  LINK

接著來一個一個看這些XML的標籤怎麼運作吧!

<folder label="Main">
<output>
<prompt selectionType="RANDOM">
<item>Hello, welcome to Mike’s Pizza</item>
</prompt>
<goto ref="getUserInput_2449614"/>
</output>
<getUserInput id="getUserInput_2449614">
<search ref="folder_2449611"/>
<default>
<output>
<prompt selectionType="RANDOM">
<item>
I am sorry, I did not understand your question. Please try asking another one.
</item>
</prompt>
</output>
</default>
</getUserInput>
</folder>

首先就是這個folder Main

這個資料夾是我們開啟對話時第一個先進入的地方

接著我們看到第一個重要的標籤

output

<output>

    <prompt>

       <item></item>  

    </prompt>

</output>

這樣子的寫法大家可以把它看成是一整組的方式

在output裡面必須要有這兩個標籤<prompt>以及<item>

output顧名思義就是輸出,基本上我們在裡面放置的就是機器人要說出來的東西

item

被用到的地方有兩個input以及output

在output中代表的是確切要說出的結果

prompt

而prompt就是定義你的輸出答案方式為何

<prompt selectionType="RANDOM">的意思就是

item是以random方式輸出

所以在這個程式的一開始

機器人就會對你說出

Hello, welcome to Mike’s Pizza

這句話

那如果你的item是多數像是這樣

<output>
<prompt selectionType="RANDOM">
<item>Hello, welcome to Mike’s Pizza</item>
<item>Do you want a pizza?</item>
<item>what kinds of pizza you want to have</item>
</prompt>
<goto ref="getUserInput_2449614"/>
</output>
 
 
因為在prompt的地方是random的
所以機器人在程式開始時會隨機的從三個輸出裡面選一個講
 
那output的講解就先到這邊
接著是另一個關鍵
 
goto
<goto ref="getUserInput_2449614"/>
 
這個就是要讓對話進行到某一個階段的refer
有點像C語言中的goto可以直接跳至程式的另外一個地方
而裡面必須要有 ref這個變數,並且指向某一個標籤的id
所以在範例中我們會跑到這裡
 
<getUserInput id="getUserInput_2449614">
<search ref="folder_2449611"/>
<default>
<output>
<prompt selectionType="RANDOM">
<item>
I am sorry, I did not understand your question. Please try asking another one.
</item>
</prompt>
</output>
</default>
</getUserInput>
 

因為這個label的 id="getUserInput_2449614"

getuserinput

getUserInput 這個label的功用就是讓使用者輸入你想對機器人講的話了

那輸入完之後就會到下一個label

search

<search ref="folder_2449611"/>

search label就是用來將使用者輸入做match的功能

而你必須跟他指定要到哪一個資料夾進行答案的尋找

所以裡面也要有一個ref的變數

並且指到某一個資料夾

那接下來的

desfault

<default>
<output>
<prompt selectionType="RANDOM">
<item>
I am sorry, I did not understand your question. Please try asking another one.
</item>
</prompt>
</output>
</default>

功用就是當你的input沒辦法搜尋到任何對應的輸出時

機器人必須要說的話或是要做的事

所以在這個例子

當你說了機器人聽不懂的話時

機器人就會回

I am sorry, I did not understand your question. Please try asking another one.

 

 

 

那根據剛剛我們的search標籤

我們會開始搜索以下的資料夾

<folder label="Live Content" id="folder_2449611">
<input>
<grammar>
<item>What type of toppings do you have?</item>
<item>$ What type of toppings do you have?</item>
<item>$ list of toppings</item>
<item>What * toppings * have</item>
<item>$ list toppings * available</item>
<item>$ what toppings do you have</item>
</grammar>
<output>
<prompt selectionType="RANDOM">
<item>We have Pepperoni, Mushrooms, and Sausage</item>
</prompt>
</output>
</input>
</folder>
 
input
接下來就是整個dialog的重頭戲了'
 
也就是input標籤
 
input其實就是if的意思
 
如果你有符合這個條件他就會做內部的事情
 
大家可以以這樣去思考會比較容易理解
 
那他的條件就是在grammar標籤裡面的每個item
 
item
 
在這邊代表的就是條件們
 
大家可以把他想成是if的條件
 
所以使用者的輸入如果有符合
 
<item>What type of toppings do you have?</item>
<item>$ What type of toppings do you have?</item>
<item>$ list of toppings</item>
<item>What * toppings * have</item>
<item>$ list toppings * available</item>
<item>$ what toppings do you have</item>
 
任何之一的話
 
我們就會做在input標籤裡從</grammar>到</input>以內的所有事情
 
在這個例子
 
我們將會執行以下段落
 
<output>
<prompt selectionType="RANDOM">
<item>We have Pepperoni, Mushrooms, and Sausage</item>
</prompt>
</output>
 
所以機器人將會回答
 
We have Pepperoni, Mushrooms, and Sausage
 
在item裡面的*以及$要做什麼的?
 
*所代表的意思即為有任何字在其中
 
所以如果今天我們設定
 
* your name *
 
what your name ?  O
your name              X
what your name     X
hey! what your name boy? O
 
也就是說*字號中必須要字存在
 
那如果我們只要有我們要的字元出現在其中就符合呢?
 
那就是使用 $字號
 
$your name
 
what your name ?  O
your name              O
what your name     O
hey! what your name boy? O
your bad name X
 
這就是兩個主要的input用法
 
那如果直接寫上
 
<item> your name </item>呢?
 
這樣就只有
 
your name可以符合這個輸入喔!
 
那以上這些基本的功能我都介紹完了
 
用以上這幾個元件基本上就已經可以完成一個簡單的對話了
 
有一個重要的觀念給大家
 
因為這個dialog的設計最一開始是給英文使用的
 
所以當中文要使用這個服務的時候
 
要把所有input的item中每個字元加上空格
 
先看一個普通的用法
 
ex:
<item>$天氣</item>
在比對"今天天氣真好"是不能符合條件的
只有在"今天 天氣 真好"才可以符合條件
 
 
 
所以我們今天只要把從使用者的輸入以及input的item加上空成以下形式
 
<item>$天 氣</item>
今 天 天 氣 真 好
 
如此才會進入這個input當中喔!
 
 
 
 
 
 
接下來要介紹幾個比較進階用的元件
 
 
----------------------------------------------------------------------------------進階----------------------------------------------------------------------------------------------------
 
Concepts
 
Concept標籤是要放在
<folder label="Concepts"/>
</flow>

內部的

寫法如下

<folder label="Concepts"/>

<concept>
                <grammar>
                    <item>怎 樣</item>
                    <item>如 何</item>
                    <item>好 嗎</item>
                    <item>怎 麼 樣</item>
                    <item>怎 麼</item>
                </grammar>

 </concept>

<concept>
                <grammar>
                    <item>搬 上</item>
                    <item>搬 到</item>
                    <item>上</item>
                    <item>放</item>
                    <item>放 置</item>
                    <item>放 來</item>
                    <item>弄 到</item>
                </grammar>
  </concept>

</flow>

在同一個concept內部的每個item

在dialog中將會被視為一樣的東西

舉個例子

如果我在input grammar中寫上

<item> 你 們 雲 端 的 效 能 如 何</item>

若我的輸入為 "你 們 雲 端 的 效 能 怎 麼 樣"

依然會被判定為進入這個input當中

因為在concept當中

"如何"以及"怎麼樣"是同樣的字

 

variables

variables就是所謂的變數功能

使要放在<variables></variables>之中

功能是讓dialog服務可以記得使用者的一些資訊

用法如下

<variables>
        <var_folder name="User_info">
            <var name="drink" type="TEXT"/>
            <var name="time" type="NUMBER" />
            <var name="time_scope" type="TEXT"/>
            <var name="time_min" type="TEXT"/>
            <var name="s_hour" type="TEXT"/>
            <var name="s_min" type="TEXT"/>
            <var name="s_sec" type="TEXT"/>
        </var_folder>
    </variables>

這些邊數必須要放在variables的標籤內部

那要怎麼使用呢?

我們必須要搭配

action

我們以下做個例子

如果使用者今天向機器人點了一杯拿鐵

機器人要把拿鐵記錄在

drink當中

我們會這樣寫

<input>

 <grammar>

  <item>$ 拿 鐵 </item>

</grammar>

    <action varName="drink" operator="SET_TO">拿鐵</action>

    <output>

            <prompt selectionType="RANDOM">

                    <item>您點的飲料為{drink}</item>

           </prompt>

       </output>

</input>

所以當今天使用者的輸入中有任何拿鐵

我們的drink變數就會被設定成拿鐵

並且在output當中可以輸出用法是將打上      {變數名稱}

但是要這樣一個一個打可能會有點勞累

所以dialog有另外一個功能

entities

功能是一個封閉是選擇的概念

首先我們必須要先定義有哪些選項可以使用

寫法如下

<entities>
        <entity name="DYNAMIC_DATA">
            <value name="DataCapture" value="DataCapture">
                <grammar>
                    <item>*</item>
                </grammar>
            </value>
        </entity>
        <entity name="clock_chose">
            <value name="早 上" value="早 上"/>
            <value name="中 午" value="中 午"/>
            <value name="下 午" value="下 午"/>
            <value name="晚 上" value="晚 上"/>
            <value name="半 夜" value="半 夜"/>
            <value name="凌 晨" value="凌 晨"/>
        </entity>
        <entity name="clock_time">
            <value name="十 一" value="十 一"/>
            <value name="十 二" value="十 二"/>
            <value name="一" value="一"/>
            <value name="二" value="二"/>
            <value name="兩" value="二"/>
            <value name="三" value="三"/>
            <value name="四" value="四"/>
            <value name="五" value="五"/>
            <value name="六" value="六"/>
            <value name="七" value="七"/>
            <value name="八" value="八"/>
            <value name="九" value="九"/>
            <value name="十" value="十"/>
            
        </entity>
    </entities>

那要如何搭配使用呢

請參考以下範例

 

<input>
                                    <grammar>
                                           <item>$ (clock_chose)* (clock_time) 點</item>
                                    </grammar>
                                    <goto ref="clock_final_output"/>
</input>

 

在entity中有出現的選項可以被當作選擇題的選樣一樣

並且放在input當中讓我們來看以下的例子

     <item>$ (clock_chose)* (clock_time) 點</item>

若要符合這行item

使用者必須輸入以下格式

早上/中午/下午/晚上/半夜/凌晨 * 一/二/三/四/五/六/七/八/九/十/十一/十二 點

也就是說可以以這種方式去限定使用者的輸入

將entities搭配variable使用

讓我們來看以下範例

<input>
                                    <grammar>
                                        <item>$ (clock_chose)={time_scope} * (clock_time)={time} 點</item>
                                      </grammar>
                                    <action varName="time" operator="SET_TO">{time.source}</action>
                                    <action varName="time_scope" operator="SET_TO">{time_scope.value:main}</action>
                                    <goto ref="clock_final_output"/>
</input>

在這邊$ (clock_chose)={time_scope} 

我們會將符合clock_chose的變數放置在time_scope當中

但是光只有這樣只完成一半的功能

還要搭配

<action varName="time_scope" operator="SET_TO">{time_scope.value:main}</action>

才會把變數真正記錄下來

這是固定用法請大家直接記下來就好

 

DYNAMIC_DATA動態資料抓取

 

想必大家有看到DYNAMIC_DATA了吧

這是一個專門抓取隨機的變數的方式

例如名子我們無法窮盡所有名子在entity當中吧!

所以我們使用了DYNAMIC_DATA來方便抓取資料

以下是使用DYNAMIC_DATA的例子

<input>
                        <grammar>
                            <item>$ 我 叫 (DYNAMIC_DATA)={User_Name} </item>
                            <item>$ 我 是 (DYNAMIC_DATA)={User_Name} </item>
                            <item>$ my name is (DYNAMIC_DATA)={User_Name} </item>
                            <item>$ I'm (DYNAMIC_DATA)={User_Name} </item>
                            <item>$ I am (DYNAMIC_DATA)={User_Name} </item>
                            <item>$ (DYNAMIC_DATA)={User_Name} </item>
                            
                        </grammar>
                        <action varName="User_Name" operator="SET_TO">{User_Name.source}</action>
                        <output>
                            <prompt>
                                <item>你好 {User_Name} 請問你需要什麼幫忙?</item>
                            </prompt>
                            <goto ref="first_input"/>
                        </output>
 </input>

<action varName="User_Name" operator="SET_TO">{User_Name.source}</action>

在這邊也是固定用法

請大家直接記起來

將變數的source的值放到變數當中

-----------------------------------------------------------------------------------------------------------------------------------

那大家到底要怎麼樣測試自己的xml編輯的成功與否呢?

請大家將以下專案clone下來並且push上自己的雲端

專案位置

成功之後就可以在專案的URL看到以下畫面

接著就可以點下左邊的加號

將xml檔案往上傳送

取一個獨特的名子

成功之後就可以看到剛剛輸入的檔名

 

接著點下去之後

就可以看到對話視窗

就可以開始跟他聊天了!!!

那在這邊還是要提醒一下大家

在對話窗輸入的時候必須都加上空白鍵如下

 

那我來示範一下由我的鬧鐘碼表服務所製作出來的結果吧

可以看到右手邊一直不斷有變數被記錄下來

那如果可以考慮到好幾種可能並寫寫入到dialog當中的話就可以達成更人性化的對話

像是以下我直接在第一次的輸入就跟她說我想要在早上的七點五十分設定鬧鐘

對話就不會再重複問我一次我要那個時段了

這次的解說就到這邊結束

下個部份我們會講解到如何搭配NLC做一個更接近人性化更有效率的對話系統

 

arrow
arrow
    文章標籤
    Watson bluemix 超級剛蛋
    全站熱搜

    C牛(norman kung) 發表在 痞客邦 留言(0) 人氣()