Botframework 使用上下文的QnA生成器调用不是';行不通

Botframework 使用上下文的QnA生成器调用不是';行不通,botframework,qnamaker,Botframework,Qnamaker,我无法使QnA Maker提示按钮正常工作。我正在拨打标准的QnA Maker REST电话,如下所示: if(qnAcontext==null){ qnAcontext={ 以前的qnaid:0, PreviousUserQuery:null } } console.log(qnAcontext); const qnaResult=等待请求({ url:url, 方法:“POST”, 标题:标题, json:{ 问题:质询:, 排名:3, 上下文:qnAcontext } }); bot正在

我无法使QnA Maker提示按钮正常工作。我正在拨打标准的QnA Maker REST电话,如下所示:

if(qnAcontext==null){
qnAcontext={
以前的qnaid:0,
PreviousUserQuery:null
}
}
console.log(qnAcontext);
const qnaResult=等待请求({
url:url,
方法:“POST”,
标题:标题,
json:{
问题:质询:,
排名:3,
上下文:qnAcontext
}
});
bot正在正确获取qnAcontext并将其包含在POST请求中。我可以看到这些值略有不同。例如,如果我在没有上下文的情况下输入提示,它会以32.2%的置信度返回,如果我添加上下文,它会更高,但只有38.64%。这远低于向用户显示答案所需的分数

如果我在QnA Maker测试面板中执行此操作,后续操作将返回到100%。根据中的注释,这似乎是通过在服务中传递提示符的qnaId来实现的。但是,如果用户尚未选择该ID,我如何知道该ID?这些提示会生成一张英雄卡,我在生成卡时确实有qnaId,但我不知道这有什么用处。以下是我如何生成提示按钮:

var按钮=[];
prompts.forEach(元素=>{
按钮({
值:element.displayText,
类型:ActionTypes.ImBack,
标题:element.displayText
});
});
var heroCard=CardFactory.heroCard(
名片,
卡片文本,
[],
CardFactory.操作(按钮));
我想我可以用前面的问题单独打个电话,找到提交的查询的qnaId,但这似乎是不必要的开销。当然,只需文本和前面的问题就可以从QnA Maker获得正确的结果

编辑:我确实通过以下代码实现了这一点,但延迟是显而易见的。我不得不想象有一个更好的方法来实现这一点

if(qnAcontext==null){
var qnaResult=等待请求({
url:url,
方法:“POST”,
标题:标题,
json:{
问题:质询:,
排名:3,
上下文:qnAcontext
}
});
}否则{
var firstResult=等待请求({
url:url,
方法:“POST”,
标题:标题,
json:{
问题:qnAcontext.PreviousUserQuery
}
});
var prompt=firstResult.answers[0].context.prompts.find(e=>{return e.displayText==query});
var qnaResult=等待请求({
url:url,
方法:“POST”,
标题:标题,
json:{
qnaId:prompt.qnaId
}
});
}

实际上并不需要QnaContext。您只需要传递随后续提示一起提供的qnaId。只要做一些小的调整,你就快到了

假设您使用团队作为通道,则使用messageBack功能,而不是imBack

messageBack允许您通过以下方式发送附加数据:

  • 将一组文本回显到屏幕和
  • 将单独的数据发送到bot进行处理(前端不可见),其中可能包括后续问题的qnaid
  • 根据上面的代码示例,假设您已经有了提示的句柄,则只需进行一点小的更改:

            prompts.forEach(element => {
                buttons.push({
                    type: ActionTypes.messageBack,
                    title: element.displayText
                    displayText: "<optional - echo text to conversation>",
                    text: "User just clicked the MessageBack button",
                    value: {
                        "qnaId": element.qnaid
                    }
                });
            });
    
    因此,假设我们将activity.value.qnaId中的qnaId分配给一个名为followUpQnaId的属性

                var qnaResult = await request({
                    url: url,
                    method: 'POST',
                    headers: headers,
                    json: {
                        qnaId: followUpQnaId
                    }
                });
    
    请看这里:


    这意味着您只有一个电话向每个提示的用户发送带有嵌入式qnaid的卡,然后当用户应答时,您使用qnaid请求精确匹配的后续信息。它可以减少您看到的延迟。

    我熟悉自适应卡。我仍然有点不清楚您如何建议助手的逻辑应该起作用。现在我把它称为
    var processResult=wait this.qnaDialog.processAsync(userDialog.qnaState,context.activity)。我考虑过检查qnaState是否为null,并在这种情况下使用qnaId,但使用可能会问一个无关的问题。如果我这样做,我是否能够从activity.value访问qnaId?我只是想弄清楚如何根据按键(可能发生也可能不发生)使用文本或qnaId拨打正确的电话。我已经更新了答案,专门针对您最初的问题。希望这更清楚。谢谢,这更清楚。我会试一试,如果我有任何问题,会告诉你的。
    
                var qnaResult = await request({
                    url: url,
                    method: 'POST',
                    headers: headers,
                    json: {
                        qnaId: followUpQnaId
                    }
                });