Botmaker 解决 Qnamaker 后续问题

2023-12-03

对于我当前的项目,我尝试使用仅上下文的后续提示。

My problem is now, that some of the questions from the follow-up prompts are the same. qna example

在 qna ui 中,上下文的分离工作正常,但是当用户回答我在应用程序中实现的聊天中的问题时,qna 返回错误的答案。

代码: 机器人构建器版本:4.5.3 NodeJS:12.10.0

onMessage(){.....

let results = qna.getAnswer(context);
if(results[0].context.prompts.length){ //  Answer with Follow-up
      return context.sendActivity(CardHelper.GetHeroCard(results[0].answer, results[0].context.prompts))
   }else{ // normal answer
      return context.sendActivity(results[0].answer)
   }
}
Sample Questions:

Expected Answer:
I want to learn programming => java => here is our guide
Real Answer:
I want to learn programming => java => that is the java test

Expected Answer:
I want to do a test => java => that is the java test
Real Answer:
I want to do a test => java => that is the java test

如何才能在代码中实现这些后续提示,并且不丢失后续上下文呢?


首先要明白的是多轮对话和后续提示处于预览状态。这通常意味着人们应该预料到错误和缺失的功能。在这种情况下,这意味着 SDK 不仅缺少该功能,API 参考中甚至没有它。您可以在生成答案参考打电话给generateAnswer端点包括一个context属性在其主体中,但该对象的类型未记录。它链接到Context在响应中返回的对象类型,而不是您应该放入请求中的对象类型。

既然你的问题提到了CardHelper.GetHeroCard,我想你已经熟悉了QnA Maker 提示示例。如果您不熟悉该示例,那么当涉及 QnA Maker 中的多轮对话时,它是最终的事实来源。该示例包含您问题的完整答案,因此我不确定您为什么不使用它。但是,您还应该看到您需要做什么您应该遵循的文档:

返回非初始答案和后续提示的 JSON 请求

填补context对象包含先前的上下文。

在以下 JSON 请求中,当前问题是使用 Windows Hello 登录上一个问题是帐户和登录.

{
  "question": "Use Windows Hello to sign in",
  "top": 10,
  "userId": "Default",
  "isTest": false,
  "qnaId": 17,
  "context": {
    "previousQnAId": 15,
    "previousUserQuery": "accounts and signing in"
  }
}

QnA Maker 本身不会保存任何状态,因此它取决于您的机器人为其提供上一轮的上下文。你的机器人没有这样做,这就是它不起作用的原因。以下是示例代码的简化版本,可帮助您了解需要执行的操作:

async testQnAMaker(turnContext) {
    var qna = new QnAMaker({
        knowledgeBaseId: '<GUID>',
        endpointKey: '<GUID>',
        host: 'https://<APPNAME>.azurewebsites.net/qnamaker'
    });

    var context = await this.qnaState.get(turnContext) || {
        PreviousQnaId: 0,
        PreviousUserQuery: null
    };

    // We're passing a context property into the QnAMakerOptions
    // even though it's not part of the interface yet
    var results = await qna.getAnswers(turnContext, { context });
    var firstResult = results[0];

    if (firstResult) {
        var answer = firstResult.answer;
        var resultContext = firstResult.context;
        var prompts = resultContext && resultContext.prompts;

        if (prompts && prompts.length) {
            await this.qnaState.set(turnContext, {
                PreviousQnaId: firstResult.id,
                PreviousUserQuery: turnContext.activity.text
            });

            answer = ChoiceFactory.forChannel(
                turnContext,
                prompts.map(prompt => prompt.displayText),
                answer);
        }

        await turnContext.sendActivity(answer);
    } else {
        await turnContext.sendActivity("I can't answer that");
    }
}

由于您使用的功能目前处于预览状态,因此您需要发挥自己的聪明才智来弄清楚如何使用它。我只是使用状态属性访问器来保存每轮上一个问题的上下文,但您可能希望将其构建到对话框中并将每个用户查询保存在对话框状态中。关键是,如果您希望后续提示起作用,则必须保存 QnA Maker 状态。

EDIT:事实证明,如果您将上下文放入操作本身,则有一种方法可以在没有机器人状态的情况下使用后续提示,但这只有在用户单击按钮而不是输入内容时才有效:显示 QnAMaker 后续提示的文本

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Botmaker 解决 Qnamaker 后续问题 的相关文章

随机推荐