Alan Tsai 的學習筆記


學而不思則罔,思而不學則殆,不思不學則“網貸” 記錄軟體開發的點點滴滴 著重於微軟技術、網頁開發、DevOps、C#, Asp .net Mvc、Azure、AI、Chatbot、Docker、Data Science

[chatbot + AI = 下一代操作模式][21]LUIS深入使用 - 如何在BotBuilder使用entities

[chatbot + AI = 下一代操作模式][21]LUIS深入使用 - 如何在BotBuilder使用entities.jpg
圖片來源:https://pixabay.com/en/books-spine-colors-pastel-1099067/ 

在上一篇([20]LUIS深入使用 - 定義Entities來截取參數)看完了如何定義entities之後,在這篇將來看看如何把定義的entities在程式裡面使用起來。

這一篇將先從加入訂房的intent,并且會依照使用者輸入的内容解析出來的entities作爲初始的表單值。

一起來看看如何在程式使用entities。

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

調整程式使用entities

將來調整現有的程式碼,會經過一下幾個動作:

  1. 調整RootLuisDialog - 加入ReserveRoom intent的方法
  2. 把本來RootDialog和訂房有關的邏輯搬入
  3. 修正FormFlow建立方式 - 允許傳入預設值
  4. 調整邏輯加入entities的值
  5. 測試結果

調整RootLuisDialog - 加入ReserveRoom intent的方法

首先,要在RootLuisDialog裡面增加一個新的方法,這個方法用來處理ReserveRoom intent相關的邏輯

[LuisIntent("ReserveRoom")]
public Task ReserveRoom
	(IDialogContext context, LuisResult result)
{
	return Task.CompletedTask;
}

把本來和訂房有關的邏輯搬入

接下來從RootDialog把呼叫ReserveRoomDialog那段邏輯搬進來到ReserveRoom方法裡面:

[LuisIntent("ReserveRoom")]
public Task ReserveRoom
	(IDialogContext context, LuisResult result)
{
	context.Call(new ReserveRoomDialog(), ReserverRoomAfterAsync);

	return Task.CompletedTask;
}
....

總共還有兩個callback需要搬動,不過爲了節省篇幅,所以這邊就不列出來了。詳細可以參考github上面的檔案。

修正FormFlow建立方式 - 允許傳入預設值

目前的FormFlow預設都是空值,但是如果有去的entities的話,這個值可以作爲預設值。因此,先調整FormFlow的建立方式。

修改ReserveRoomDialog

public ReserveRoomDialog(RoomReservation inRoomReservation)
{
	RoomReservationState = inRoomReservation;
}

public ReserveRoomDialog()
	:this(new RoomReservation())
{

}

public RoomReservation RoomReservationState { get; }

public Task StartAsync(IDialogContext context)
{
	var reserveRoomForm =
		new FormDialog<RoomReservation>
			(RoomReservationState,
				RoomReservation.BuildForm, 
				FormOptions.PromptInStart);
...

調整邏輯加入entities的值

這邊要把entities截取出來并且傳入到處理FormFlow的Dialog。

LuisResult.Entities裡面可以取得所有被截取出來的entities,這邊用個簡單邏輯,如果有unit表示也有數字,依照這個概念取得要住幾晚

[LuisIntent("ReserveRoom")]
public Task ReserveRoom
	(IDialogContext context, LuisResult result)
{

	var roomReservation = new RoomReservation();

	// 取得unit的entity
	var unitEntity = result.Entities
		.FirstOrDefault(x => x.Type == "unit");

	// 有表示會給預設住多久
	if(unitEntity != null)
	{
		var numberEntity = result.Entities
			.FirstOrDefault(x => x.Type == "builtin.number");

		var number = int.Parse(numberEntity.Entity);

		// 如果單位是 天,表示實際住的晚上天數會減少1
		if(unitEntity.Entity == "天")
		{
			number = number - 1;
		}

		roomReservation.NumberOfNightToStay = number;
	}

	context.Call(new ReserveRoomDialog(roomReservation),
		ReserverRoomAfterAsync);

	return Task.CompletedTask;
}

測試結果

以上是整個需要做調整的修改,接下來就可以進行測試了,這邊有三種情景:

我要住
botframework-emulator_2018-07-27_23-10-38.png
沒有說要住幾天的情況下,給的是預設天數0
題外話,上篇在training的時候沒有train過我要住,但是LUIS判別正確。這就是LUIS强大的地方,定義的越多,沒定義的語句也能夠判斷的出來。這個不是簡單if else可以做到的功能。
我要住3晚
botframework-emulator_2018-07-27_23-07-27.png
可以看到預設已經輸入了3晚
我要住5天
botframework-emulator_2018-07-27_23-08-01.png
可以看到,天數的邏輯是-1,幾晚正確的放進去

結語

這篇看了如何在程式裡面取得LUIS判斷出來的entities,并且使用這些entities來給表單預設值。

entities定義的好會讓整個使用體驗非常好,因爲使用者可以用自然的語言做出填寫表單的動作。

當然,entities不止可用在定義表單的預設值,可以用的地方非常多,這就要看工程師們的想象力啦。

到目前爲止,LUIS的使用以及程式對接都清楚了,不過有些上綫之後管理層面的部分還沒介紹,例如怎麽持續完善這個LUIS的app,怎麽備份,怎麽對LUIS app做備份等等。

下一篇([22]LUIS管理及維護 - 持續加强app、多人維護、備份以及加入別的region key)先從如何持續完善開始。


如果文章對您有幫助,就請我喝杯飲料吧
街口支付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