第12 屆iT邦幫忙鐵人賽系列文章 (Day16)
QnA Maker 是微軟提供一個雲端的自然語言處理 (NLP) 處理服務,可輕鬆透過網站後台建立自己的知識庫,並能從使用者所輸入的語句,理解他的意圖,提供可能對應的知識庫答案。QnA Maker提供了免費的方案,但限制就是只能有3份知識庫、每秒只能調用Api 3次,每月50,000筆Request,對於一般使用或技術評估來講很夠用了。要在 Line 串接大概分為以下步驟:
[ ] 在Azure註冊 QnA Maker
[ ] 新增一個 knowledge base
[ ] 增加題目與回答
[ ] 完成訓練 & 發佈
[ ] 取得 Endpoint、EndpointKey,來讓程式串接
照著 https://www.qnamaker.ai/Create Step By Step 步驟,因為QnA Maker是Azure的服務,故您可以需要Azure的訂閱,由此註冊試用
Step 1 在 Azure 新增 QnA Maker 服務
Step 2 選取剛剛建立的QnA Maker服務,並選擇繁體中文
Step 3 knowledge base 名稱
步驟四可以匯入現有的資料集,來源可以是文件或者是線上的網站,這樣就不用重新建檔了,是不是很酷啊 :D
Step 4 匯入資料集 (本次先跳過)
開始瘋狂建題目吧!我們來試試建立:"新人怎麼認識的?" 回答我們設定 "我們是在打工餐廳認識的喔,那時的同事 put your hands up ??",並點選Save And Train
可以透過旁邊的模擬器測試,嘗試打類似的問話,都會對應的相同的回答
在串接之前,記得要先點選 Publish
又是得到一個熟悉的 curl 指令,可以繼續用 https://curl.olsh.me/ 來轉 C# 啦
QnAMakerUtility.cs
新增一個 Utility 來處理 QnA Maker,裡面的 Key 應該要移到appsetting.json比較好替換,最初幾篇有提到可以用 IOption 來注入,這邊就不再多提了。QnA Maker判斷出來會有個分數值,我們篩選最高的當作答案,另也定義一個選擇新參數為分數,如果有值的話,要大於這個分數我們才會回傳。
public class QnAMakerUtility
{
public async Task<QnAMakterAnswer> Get(string question, int? scope = null)
{
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://qna-maker-lab.azurewebsites.net/qnamaker/knowledgebases/OOOOO-2d0e-4512-ba3f-a58fdc4c37e1/generateAnswer"))
{
request.Headers.TryAddWithoutValidation("Authorization", "EndpointKey 5fdcf6c7-eb76-4a53-9e3b-74570645bOOO");
request.Content = new StringContent("{'question':'" + question + "'}");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();
var qnaResponse = JsonConvert.DeserializeObject<QnAMakerResponse>(result);
// 取得分數最高的回答
var answers = qnaResponse.answers;
// 選擇性參數,大於多少分數才回傳,這樣看起來會比較準
if(scope.HasValue)
{
answers = answers.Where(c => c.score >= scope.Value);
}
var answer = answers.OrderByDescending(c => c.score).FirstOrDefault();
// 無法辨識
if (answer == null || answer.id == -1) return null;
return answer;
}
}
}
}
QnAMakerResponse
public class QnAMakerResponse
{
public IEnumerable<QnAMakterAnswer> answers { get; set; }
public bool activeLearningEnabled { get; set; }
}
public class QnAMakterAnswer
{
public object[] questions { get; set; }
public string answer { get; set; }
public float score { get; set; }
public int id { get; set; }
public object[] metadata { get; set; }
}
調整一下 IntenFactory.cs
我們先判斷 Rule Base 的回覆 (字串完整比對),有比對到就回傳了,如果沒有比對到,則丟到 AI Base (QnA Maker) 來判斷
傳送 "新人怎麼認識的?" 分數是 100 分
傳送 “當初怎麼交往的?” 分數是 26.53 分
所以對話模型是要逐步訓練的,我們調整一下,提升交往關鍵字的分數,要記得重新訓練和發佈
傳送 "交往的過程",得到重新訓練後的分數 99 分了
本篇就是 .NET Core 串接 QnA Maker 的過程,透過這種雲端語意辨識服務,我們再也不用在程式擴增一堆 Intent 實作,並且讓 Chatbot 聰明一點,使用者為什麼都可以知道它想問的意圖是什麼。如果要更聰明一點訓練,可以考慮使用微軟的 LUIS 服務,在 LUIS 可以針對使用者所傳的資訊拆解 Entity / Intent,透過訊息的收集,透過自行定義的訓練語意讓 Chatbot 理解且更準的內容,但本系列文章應該不會介紹到這塊 (後續還是介紹一些好玩的 Line服務)
QnA Maker 服務
https://azure.microsoft.com/zh-tw/services/cognitive-services/qna-maker/
Rule Base vs AI Base
https://www.tricentis.com/artificial-intelligence-software-testing/ai-approaches-rule-based-testing-vs-learning/
如何在 Line 串接 QnA Maker
https://docs.microsoft.com/en-us/azure/cognitive-services/qnamaker/quickstarts/quickstart-rest-curl
本篇文章同步發佈於我的 Medium 如果這篇文章對你有幫助,就大力追蹤和拍手鼓掌下去吧 !!