接受知識庫中主動式學習建議的問題
注意
QnA Maker 服務即將於 2025 年 3 月 31 日淘汰。 較新版的問題和解答功能現在隨附於 Azure AI 語言。 如需瞭解語言服務內的問題解答功能,請參閱問題解答。 從 2022 年 10 月 1 日開始,您將無法建立新的 QnA Maker 資源。 如需將現有的 QnA Maker 知識庫移轉至問題解答的相關資訊,請參閱移轉指南。
主動式學習會在您核准建議之後改變知識庫或搜尋服務,然後儲存並訓練。 如果您核准建議,則系統會將其新增為替代問題。
開啟主動式學習
為了查看建議的問題,您必須針對 QnA Maker 資源開啟主動式學習。
檢視建議的問題
為了查看建議的問題,請在 [編輯知識庫] 頁面上選取 [檢視選項],然後選取 [顯示主動式學習建議]。 如果沒有針對任何問答配對的建議,則會停用此選項。
選取 [依建議篩選],將包含問答配對的知識庫篩選成僅顯示建議。
每個 QnA 配對都會建議新的問題替代方式,附有核取記號
✔
(用以接受問題) 和x
(用以拒絕建議)。 選取核取記號可新增問題。您可以在內容工具列中選取 [全部新增] 或 [全部拒絕] 來新增或刪除「所有建議」。
選取 [儲存並訓練],以儲存對知識庫所做的變更。
選取 [發佈],以允許可從 GenerateAnswer API 取得變更。
當您將 5 個以上的查詢叢集化時,每隔 30 分鐘 QnA Maker 便會建議替代問題,讓您接受或拒絕它們。
主動式學習建議會儲存在匯出的知識庫中
當您的應用程式已啟用主動式學習,且您匯出應用程式時,tsv 檔案中的 SuggestedQuestions
資料行會保留主動式學習資料。
SuggestedQuestions
資料行是隱含 autosuggested
和明確 usersuggested
意見反應資訊的 JSON 物件。 針對單一使用者提交的 help
問題,此 JSON 物件的範例為:
[
{
"clusterHead": "help",
"totalAutoSuggestedCount": 1,
"totalUserSuggestedCount": 0,
"alternateQuestionList": [
{
"question": "help",
"autoSuggestedCount": 1,
"userSuggestedCount": 0
}
]
}
]
當您重新匯入此應用程式時,主動式學習會繼續為您的知識庫收集資訊和提供建議。
從 Bot 使用 GenerateAnswer 和訓練 API 的架構流程
Bot 或其他用戶端應用程式應該使用下列架構流程來使用主動式學習:
Bot 會使用 GenerateAnswer API 從知識庫取得答案,也會使用
top
屬性取得一些答案。Bot 會判定明確的意見反應:
- 使用您自己的自訂商務邏輯,篩選出低分數。
- 在 Bot 或用戶端應用程式中,顯示使用者的可能答案清單,並取得使用者選取的答案。
Bot 會使用訓練 API,將選取的答案送回 QnA Maker。
在 GenerateAnswer 要求中使用 top 屬性來取得數個相符的答案
將問題提交給 QnA Maker 以取得答案時,JSON 主體的 top
屬性會設定要傳回的答案數目。
{
"question": "wi-fi",
"isTest": false,
"top": 3
}
使用 score 屬性以及商務邏輯,取得要向使用者顯示的答案清單
當用戶端應用程式 (例如聊天機器人) 收到回應時,系統會傳回前 3 個問題。 使用 score
屬性來分析分數之間的鄰近性。 這個鄰近性範圍是由您自己的商務邏輯決定。
{
"answers": [
{
"questions": [
"Wi-Fi Direct Status Indicator"
],
"answer": "**Wi-Fi Direct Status Indicator**\n\nStatus bar icons indicate your current Wi-Fi Direct connection status: \n\nWhen your device is connected to another device using Wi-Fi Direct, '$ \n\n+ *+ ' Wi-Fi Direct is displayed in the Status bar.",
"score": 74.21,
"id": 607,
"source": "Bugbash KB.pdf",
"metadata": []
},
{
"questions": [
"Wi-Fi - Connections"
],
"answer": "**Wi-Fi**\n\nWi-Fi is a term used for certain types of Wireless Local Area Networks (WLAN). Wi-Fi communication requires access to a wireless Access Point (AP).",
"score": 74.15,
"id": 599,
"source": "Bugbash KB.pdf",
"metadata": []
},
{
"questions": [
"Turn Wi-Fi On or Off"
],
"answer": "**Turn Wi-Fi On or Off**\n\nTurning Wi-Fi on makes your device able to discover and connect to compatible in-range wireless APs. \n\n1. From a Home screen, tap ::: Apps > e Settings .\n2. Tap Connections > Wi-Fi , and then tap On/Off to turn Wi-Fi on or off.",
"score": 69.99,
"id": 600,
"source": "Bugbash KB.pdf",
"metadata": []
}
]
}
用戶端應用程式在問題具有類似分數時的後續動作
您的用戶端應用程式會顯示所有問題,並且讓使用者可以選取最能代表其意圖的「單一問題」。
一旦使用者選取了其中一個現有問題,用戶端應用程式就會使用 QnA Maker 訓練 API,將使用者的選擇當作意見反應傳送。 此意見反應會完成主動式學習意見反應迴圈。
將 API 定型
主動式學習意見反應會隨著訓練 API POST 要求傳送至 QnA Maker。 API 簽章為:
POST https://<QnA-Maker-resource-name>.azurewebsites.net/qnamaker/knowledgebases/<knowledge-base-ID>/train
Authorization: EndpointKey <endpoint-key>
Content-Type: application/json
{"feedbackRecords": [{"userId": "1","userQuestion": "<question-text>","qnaId": 1}]}
HTTP 要求屬性 | 名稱 | 類型 | 用途 |
---|---|---|---|
URL 路由參數 | 知識庫識別碼 | string | 測試您知識庫的 GUID。 |
自訂子網域 | QnAMaker 資源名稱 | string | 資源名稱會用作 QnA Maker 的自訂子網域。 在您發佈知識庫之後,可以在 [設定] 頁面上使用此項。 其會列示為 host 。 |
頁首 | 內容-類型 | string | 傳送至 API 的本文媒體類型。 預設值為:application/json |
頁首 | 授權 | string | 您的端點金鑰 (EndpointKey xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。 |
張貼本文 | JSON 物件 | JSON | 訓練意見反應 |
JSON 主體有數個設定:
JSON 主體屬性 | 類型 | 用途 |
---|---|---|
feedbackRecords |
陣列 | 意見反應清單。 |
userId |
string | 接受所建議問題的人員的使用者識別碼。 使用者識別碼格式是由您決定。 例如,電子郵件地址可以是您架構中的有效使用者識別碼。 選擇性。 |
userQuestion |
string | 使用者查詢的確切文字。 必要。 |
qnaID |
數值 | 問題的識別碼,可在 GenerateAnswer 回應中找到。 |
範例 JSON 主體看起來像這樣:
{
"feedbackRecords": [
{
"userId": "1",
"userQuestion": "<question-text>",
"qnaId": 1
}
]
}
成功回應會傳回狀態 204 且沒有 JSON 回應主體。
將許多意見反應記錄批次成單一呼叫
在用戶端應用程式 (例如 Bot) 中,您可以儲存資料,然後在 feedbackRecords
陣列的單一 JSON 主體中傳送許多記錄。
範例 JSON 主體看起來像這樣:
{
"feedbackRecords": [
{
"userId": "1",
"userQuestion": "How do I ...",
"qnaId": 1
},
{
"userId": "2",
"userQuestion": "Where is ...",
"qnaId": 40
},
{
"userId": "3",
"userQuestion": "When do I ...",
"qnaId": 33
}
]
}
Bot Framework 範例程式碼
如果使用者的查詢應該用於主動式學習,則您的 Bot Framework 程式碼必須呼叫訓練 API。 有兩段要撰寫的程式碼:
- 判斷是否應該使用查詢來進行主動式學習
- 將查詢送回 QnA Maker 訓練 API,以進行主動式學習
在 Azure Bot 範例中,這兩個活動都是以程式設計的。
訓練 API 的範例 C# 程式碼,搭配 Bot Framework 4.x
下列程式碼說明如何使用訓練 API,將資訊送回 QnA Maker。
public class FeedbackRecords
{
// <summary>
/// List of feedback records
/// </summary>
[JsonProperty("feedbackRecords")]
public FeedbackRecord[] Records { get; set; }
}
/// <summary>
/// Active learning feedback record
/// </summary>
public class FeedbackRecord
{
/// <summary>
/// User id
/// </summary>
public string UserId { get; set; }
/// <summary>
/// User question
/// </summary>
public string UserQuestion { get; set; }
/// <summary>
/// QnA Id
/// </summary>
public int QnaId { get; set; }
}
/// <summary>
/// Method to call REST-based QnAMaker Train API for Active Learning
/// </summary>
/// <param name="endpoint">Endpoint URI of the runtime</param>
/// <param name="FeedbackRecords">Feedback records train API</param>
/// <param name="kbId">Knowledgebase Id</param>
/// <param name="key">Endpoint key</param>
/// <param name="cancellationToken"> Cancellation token</param>
public async static void CallTrain(string endpoint, FeedbackRecords feedbackRecords, string kbId, string key, CancellationToken cancellationToken)
{
var uri = endpoint + "/knowledgebases/" + kbId + "/train/";
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage())
{
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(uri);
request.Content = new StringContent(JsonConvert.SerializeObject(feedbackRecords), Encoding.UTF8, "application/json");
request.Headers.Add("Authorization", "EndpointKey " + key);
var response = await client.SendAsync(request, cancellationToken);
await response.Content.ReadAsStringAsync();
}
}
}
訓練 API 的範例 Node.js 程式碼,搭配 Bot Framework 4.x
下列程式碼說明如何使用訓練 API,將資訊送回 QnA Maker。
async callTrain(stepContext){
var trainResponses = stepContext.values[this.qnaData];
var currentQuery = stepContext.values[this.currentQuery];
if(trainResponses.length > 1){
var reply = stepContext.context.activity.text;
var qnaResults = trainResponses.filter(r => r.questions[0] == reply);
if(qnaResults.length > 0){
stepContext.values[this.qnaData] = qnaResults;
var feedbackRecords = {
FeedbackRecords:[
{
UserId:stepContext.context.activity.id,
UserQuestion: currentQuery,
QnaId: qnaResults[0].id
}
]
};
// Call Active Learning Train API
this.activeLearningHelper.callTrain(this.qnaMaker.endpoint.host, feedbackRecords, this.qnaMaker.endpoint.knowledgeBaseId, this.qnaMaker.endpoint.endpointKey);
return await stepContext.next(qnaResults);
}
else{
return await stepContext.endDialog();
}
}
return await stepContext.next(stepContext.result);
}
最佳作法
如需使用主動式學習時的最佳做法,請參閱最佳做法。