在上一篇([18]在LUIS建立app - 概念變成實作)看完如何建立一個app,然後定義intent以及utterance。
這篇將來看看如何把上篇建立好的model發佈出去,并且用在實際的程式裡面。這篇將整合LUIS建立出來的Model到目前的chatbot裡面,讓chatbot的判斷不再是呆板的if else。
如何讓LUIS和Bot Builder SDK結合?
有兩個動作需要做:
- 上篇雖然把model建立出來了,但是沒有發佈,因此需要先發佈了之後,外界才可以透過REST Api調用
- 調整chatbot的程式 - 目前是在RootDialog裡面透過if else來切換觸發那個Dialog。這個工作將轉交給LUIS來做這個意圖識別
發佈LUIS app
登入到luis.ai的網站上面,并且進入到上篇所建立的app裡面,在上面的menu選擇PUBLISH
從上圖可以看到,目前的Published Version顯示的是尚未發佈過。
在按下Publish
按鈕之前,有一些設定介紹一下:
- Select Slot可以選擇發佈到那個slot裡面。好習慣是會有個Staging/UAT環境測試好了才會上Production。而LUIS有提供這個機制可以方便測試好了再上正式
- Timezone的部分不太確定作用,不過估計是和分析資料呈現的日期有關。如果有清楚的歡迎更正
- Include All Predicted intent scores - 由於識別的時候不同的intent會有不同的分數 - 如果想看到所有的intent分數就打勾,如果只需要最高分的就不打勾。這個影響到回傳的json大小
- Enable Bing Spell checker - Bing spell checker是另外一個服務,用來檢測有沒有打錯字。不過這個估計只有英文語系有作用,如果要使用需要加入 Bing spell checker的key
- key string - 這個要收好,驗證權限用的key
- Endpoint - 這個是服務的地址,由於區域的不同,地址也是不同的。這個是REST API的end point
Add Key
裡面加入建立的那個服務即可。
設定確認好了之後,就按下Publish
,然後會看到之前Published Version會變成0.1。
發佈完了要測試一下有沒有問題,這個時候直接點下End Point,然後在最後一個參數q
輸入想要查詢的,將會得到結果:
整合LUIS到Bot Builder SDK
接下來就是把LUIS整合到Bot Builder SDK裡面。
從上面知道,其實LUIS最後提供的就是一個REST API而已,所以可以自己做一個class專門處理溝通然後返回結果, 不過不用那麽麻煩,Bot Builder SDK已經有包好Dialog可以直接使用。
接下來,改造一下現行程式來用LUIS判斷使用者的意圖,總共有幾個部分:
- 建立一個
RootLuisDialog
繼承LuisDialog
- 調整每一個intent對應需要發生的事情
- 調整進入的起始Dialog
- 測試結果
建立一個Dialog繼承LuisDialog
首先,在Dialogs
資料夾下面,在建立另外一個class叫做RootLuisDialog.cs
這個新的Dialog將會繼承LuisDialog
,并且透過LuisModelAttribute
來設定使用的app id,以及key
因此,整個class内容如下:
[LuisModel("<app id>", "<key>")]
[Serializable]
public class RootLuisDialog : LuisDialog<object>
{
}
app id
和key
最快的取得方式是從Luis那邊不是有透過endpoint做測試,網址的末端是app id,subscription-key
則是需要的key:
domain
這個參數即可。
調整每一個intent對應需要發生的事情
透過使用LuisIntentAttribute
,設定intent的名稱作爲參數,只要當LUIS判斷的intent和那個名字對應上的話,那個方法就會被執行。
如果LuisIntentAttribute
的名稱為空,表示所有沒match到都會由這個方法來處理。
有了這個概念之後,調整程式碼如下:
...
public class RootLuisDialog : LuisDialog<object>
{
[LuisIntent("")]
public async Task None
(IDialogContext context, LuisResult result)
{
await context.PostAsync("無法理解您的請求");
context.Wait(MessageReceived);
}
[LuisIntent("SearchHotel")]
public Task SearchHotel
(IDialogContext context, LuisResult result)
{
context.Call(new SearchHotelDialog(), async (ctx, r) =>
{
var imessageActivity = ctx.Activity as Activity;
var returnMessage = imessageActivity.CreateReply();
var attachments = await r;
returnMessage.Attachments = attachments;
await context.PostAsync(returnMessage);
context.Wait(MessageReceived);
});
return Task.CompletedTask;
}
}
調整初始進入的Dialog
上面設定好了Dialog了之後,接下來就是調整讓RootLuisDialog
替代RootDialog
。
因此進入MessagesController
調整如下:
...
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.GetActivityType() == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, MakeLuisDialog);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private IDialog<object> MakeLuisDialog()
{
return Chain.From(() => new RootLuisDialog());
}
...
對應的調整有標黃了,基本上,這邊建立了一個方法,MakeLuisDialog
避免整個inline呼叫看起來很亂。
測試結果
最後,使用bot emulator來測試剛剛的修改。
接下來就是把其他的intent也加進去即可。
結語
這篇介紹了如何把建立出來的LUIS app發佈成爲服務,并且如何和Bot Builder SDK結合,讓chatbot能夠使用LUIS的威力來識別使用者的意圖。
到目前爲止,對於LUIS的基本概念以及使用已經有了基本概念,不過裡面還有蠻多的細節,例如entities的使用、持續維護LUIS app等,下一篇([20]LUIS深入使用 - 定義Entities來截取參數)先從entities開始介紹。