Alan Tsai 的學習筆記


學而不思則罔,思而不學則殆,不思不學則“網貸” 為現任微軟最有價值專家 (MVP)、微軟認證講師 (MCT) 、Blogger、Youtuber:記錄軟體開發的點點滴滴 著重於微軟技術、C#、ASP .NET、Azure、DevOps、Docker、AI、Chatbot、Data Science

[chatbot + AI = 下一代操作模式][19]把LUIS和Bot Builder SDK整合

[chatbot + AI = 下一代操作模式][19]把LUIS和Bot Builder SDK整合.jpg
圖片來源:https://pixabay.com/en/books-spine-colors-pastel-1099067/ 

在上一篇([18]在LUIS建立app - 概念變成實作)看完如何建立一個app,然後定義intent以及utterance。

這篇將來看看如何把上篇建立好的model發佈出去,并且用在實際的程式裡面。這篇將整合LUIS建立出來的Model到目前的chatbot裡面,讓chatbot的判斷不再是呆板的if else。

這篇的程式碼github頁面是alantsai-samples/mhat-hotelbot:blog/chapter-19

如何讓LUIS和Bot Builder SDK結合?

有兩個動作需要做:

  1. 上篇雖然把model建立出來了,但是沒有發佈,因此需要先發佈了之後,外界才可以透過REST Api調用
  2. 調整chatbot的程式 - 目前是在RootDialog裡面透過if else來切換觸發那個Dialog。這個工作將轉交給LUIS來做這個意圖識別

發佈LUIS app

登入到luis.ai的網站上面,并且進入到上篇所建立的app裡面,在上面的menu選擇PUBLISH

chrome_2018-07-24_17-07-45.png
切換到Publish app的畫面

從上圖可以看到,目前的Published Version顯示的是尚未發佈過。

在按下Publish按鈕之前,有一些設定介紹一下:

  1. Select Slot可以選擇發佈到那個slot裡面。好習慣是會有個Staging/UAT環境測試好了才會上Production。而LUIS有提供這個機制可以方便測試好了再上正式
  2. Timezone的部分不太確定作用,不過估計是和分析資料呈現的日期有關。如果有清楚的歡迎更正
  3. Include All Predicted intent scores - 由於識別的時候不同的intent會有不同的分數 - 如果想看到所有的intent分數就打勾,如果只需要最高分的就不打勾。這個影響到回傳的json大小
  4. Enable Bing Spell checker - Bing spell checker是另外一個服務,用來檢測有沒有打錯字。不過這個估計只有英文語系有作用,如果要使用需要加入 Bing spell checker的key
  5. key string - 這個要收好,驗證權限用的key
  6. Endpoint - 這個是服務的地址,由於區域的不同,地址也是不同的。這個是REST API的end point
chrome_2018-07-24_17-10-22.png
一些發佈相關的設定
題外話,免費版本只能夠放在北美,如果想要放在亞洲,需要收費版本。設定很簡單,只需要在Azure上面先建立好LUIS的服務,然後按下按鈕Add Key裡面加入建立的那個服務即可。

設定確認好了之後,就按下Publish,然後會看到之前Published Version會變成0.1。

題外話,看到版號應該會想到版本控制對吧。LUIS設計還蠻好,除了staging和production切換之外,還有把版號這個事情考慮進去。這都是影響服務品質應該有的管控。

發佈完了要測試一下有沒有問題,這個時候直接點下End Point,然後在最後一個參數q輸入想要查詢的,將會得到結果:

chrome_2018-07-24_17-22-54.png
測試發佈的model是否有問題

整合LUIS到Bot Builder SDK

接下來就是把LUIS整合到Bot Builder SDK裡面。

從上面知道,其實LUIS最後提供的就是一個REST API而已,所以可以自己做一個class專門處理溝通然後返回結果, 不過不用那麽麻煩,Bot Builder SDK已經有包好Dialog可以直接使用。

題外話:還蠻驚訝沒找到有現成的C# Library獨立在做和LUIS溝通的這個事情,不過Bot Builder SDK裡面有包含,如果非chatbot的程式需要和LUIS溝通,可以參考一下Bot Builder SDK的原始碼,省的自己寫。

接下來,改造一下現行程式來用LUIS判斷使用者的意圖,總共有幾個部分:

  1. 建立一個RootLuisDialog繼承LuisDialog
  2. 調整每一個intent對應需要發生的事情
  3. 調整進入的起始Dialog
  4. 測試結果

建立一個Dialog繼承LuisDialog

首先,在Dialogs資料夾下面,在建立另外一個class叫做RootLuisDialog.cs

這個新的Dialog將會繼承LuisDialog,并且透過LuisModelAttribute來設定使用的app id,以及key

因此,整個class内容如下:

[LuisModel("<app id>", "<key>")]
[Serializable]
public class RootLuisDialog : LuisDialog<object>
{
}
app idkey最快的取得方式是從Luis那邊不是有透過endpoint做測試,網址的末端是app id,subscription-key則是需要的key:
chrome_2018-07-24_17-52-47.png
取得app id 以及 key的方式
注意一下,key要保存好,避免被人濫用您的服務。
注意:如果不是使用預設的key(在美國的region),那麽endpoint會不同,這個時候把對應endpoint的domain name輸入到參數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來測試剛剛的修改。

botframework-emulator_2018-07-24_22-58-27.png
測試結果

接下來就是把其他的intent也加進去即可。

結語

這篇介紹了如何把建立出來的LUIS app發佈成爲服務,并且如何和Bot Builder SDK結合,讓chatbot能夠使用LUIS的威力來識別使用者的意圖。

到目前爲止,對於LUIS的基本概念以及使用已經有了基本概念,不過裡面還有蠻多的細節,例如entities的使用、持續維護LUIS app等,下一篇([20]LUIS深入使用 - 定義Entities來截取參數)先從entities開始介紹。


如果文章對您有幫助,就請我喝杯飲料吧
街口支付QR Code
街口支付QR Code
台灣 Pay QR Code
台灣 Pay QR Code
Line Pay 一卡通 QR Code
Line Pay 一卡通 QR Code
街口支付QR Code
支付寶QR Code
街口支付QR Code
微信支付QR Code
comments powered by Disqus