你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

接受知识库中的主动学习建议的问题

注意

QnA Maker 服务将于 2025 年 3 月 31 日停用。 问答功能的较新版本现已作为 Azure AI 语言的一部分提供。 有关语言服务中的问答功能,请参阅问答。 从 2022 年 10 月 1 日开始,你将无法创建新的 QnA Maker 资源。 有关将现有 QnA Maker 知识库迁移到问题解答的信息,请参阅迁移指南

主动学习在批准建议后更改知识库或搜索服务,然后进行保存和训练。 如果你批准此建议,则它将被添加为备选问题。

启用主动学习

为了查看建议的问题,必须为 QnA Maker 资源启动主动学习

查看建议的问题

  1. 为了查看建议的问题,请在“编辑”知识库页面上,依次选择“查看选项”和“显示主动学习建议”。 如果没有针对任何问题和答案对的建议,则将禁用此选项。

    在门户的“编辑”部分中,选择“显示建议”,以查看主动学习的新问题备选项。

  2. 通过选择“按建议筛选”,将包含问题和答案对的知识库筛选为仅显示建议。

    使用“按建议筛选”切换,以仅查看主动学习的建议的问题备选项。

  3. 每个 QnA 对都会建议提供复选标记的新问题备选项, 表示接受问题,x 表示拒绝建议。 选中复选标记可以添加问题。

    通过选择绿色的复选标记或红色的删除标记,选择或拒绝主动学习的建议的问题备选项。

    可以通过在上下文工具栏中选择“全部添加”或“全部拒绝”来添加或删除“所有建议”。

  4. 选择“保存并训练”,将所做的更改保存到知识库。

  5. 选择“发布”,允许通过 GenerateAnswer API 进行更改。

    如果集中 5 个或以上的相似查询,每 30 分钟 QnA Maker 会提供备选问题建议,供你接受或拒绝。

主动学习建议保存在导出的知识库中

当你的应用启用了主动学习并导出应用后,tsv 文件中的 SuggestedQuestions 列将保留主动学习数据。

SuggestedQuestions 列是隐式 autosuggested 和显式 usersuggested 反馈信息的 JSON 对象。 此 JSON 对象针对单个用户提交的 help 问题示例如下:

[
    {
        "clusterHead": "help",
        "totalAutoSuggestedCount": 1,
        "totalUserSuggestedCount": 0,
        "alternateQuestionList": [
            {
                "question": "help",
                "autoSuggestedCount": 1,
                "userSuggestedCount": 0
            }
        ]
    }
]

当你重新导入此应用时,主动学习将继续收集相关信息并为你的知识库提出建议。

从机器人中使用 GenerateAnswer 和训练 API 的体系结构流

机器人或其他客户端应用程序应通过以下体系结构流来使用主动学习:

  1. 机器人借助 GenerateAnswer API 并使用 top 属性来指定获取的答案数量,从知识库中获取答案

  2. 机器人确定显式反馈:

    • 使用你自己的自定义业务逻辑,筛除低分数。
    • 在机器人或客户端应用程序中,向用户显示可能答案列表并获取用户选定的答案。
  3. 机器人会通过训练 API将选定的答案发回 QnA Maker

使用 GenerateAnswer 请求中的 top 属性获取几个匹配的答案

向 QnA Maker 提交问题以获取答案时,JSON 正文的 top 属性会设置要返回的答案数量。

{
    "question": "wi-fi",
    "isTest": false,
    "top": 3
}

使用分数属性以及业务逻辑获取要向用户显示的答案列表

当客户端应用程序(例如聊天机器人)收到响应时,返回排名靠前的 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 路由参数 知识库 ID 字符串 知识库的 GUID。
自定义子域 QnAMaker 资源名称 字符串 资源名称将用作 QnA Maker 的自定义子域。 发布知识库后,可以在“设置”页面上找到该属性。 它作为 host 列出。
标头 Content-Type 字符串 发送到 API 的正文的媒体类型。 默认值为:application/json
标头 授权 字符串 终结点密钥 (EndpointKey xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。
POST 正文 JSON 对象 JSON 训练反馈

JSON 正文有几个设置:

JSON 正文属性 类型 用途
feedbackRecords array 反馈列表。
userId 字符串 接受建议问题的人员的用户 ID。 采用何种用户 ID 格式取决于你。 例如,电子邮件地址可以是体系结构中的有效用户 ID。 可选。
userQuestion 字符串 用户查询的全字匹配。 必需。
qnaID 数字 问题的 ID,位于 GenerateAnswer response 之中。

示例 JSON 正文如下所示:

{
    "feedbackRecords": [
        {
            "userId": "1",
            "userQuestion": "<question-text>",
            "qnaId": 1
        }
    ]
}

成功的响应将返回状态 204,并且没有 JSON 响应正文。

将多个反馈记录批处理到单个调用中

在客户端应用程序(如机器人)中,你可以保存数据,然后在 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 Framework 4.x 训练 API 的示例 C# 代码

下列代码说明了如何使用训练 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();
        }
    }
}

使用 Bot Framework 4.x 训练 API 的示例 Node.js 代码

下列代码说明了如何使用训练 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);
}

最佳做法

有关使用主动学习的最佳做法,请参阅最佳做法

后续步骤