[chatbot + AI = 下一代操作模式][21]LUIS深入使用 - 如何在BotBuilder使用entities @ Alan Tsai 的學習筆記|An Asp .Net Mvc Web Developer Blog

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)先從如何持續完善開始。

comments powered by Disqus