C# Bot Framework V4多回合提示功能问题QnaMaker

C# Bot Framework V4多回合提示功能问题QnaMaker,c#,botframework,qnamaker,C#,Botframework,Qnamaker,我有一个直连机器人连接到QnaMaker,并测试如何响应用户的新提示功能,下面是QnaMaker的示例Qna 1) q) How to get New York Printer details(QnAID: 13) a) details are below NY73889-B0 2) q) How to get Dallas printer details (QnAID: 14) a) details are below DL093883-B1 3) q) printer location

我有一个直连机器人连接到QnaMaker,并测试如何响应用户的新提示功能,下面是QnaMaker的示例Qna

1) 
q) How to get New York Printer details(QnAID: 13)
a) details are below NY73889-B0

2)
q) How to get Dallas printer details (QnAID: 14)
a) details are below DL093883-B1

3)
q) printer location 
a) please chose from the 2 options below
   Dallas(QnAID: 13)  New York(QnAID: 14)    (Prompts)
4)
q)Dallas
a) Dallas is a beautiful city

5)
q)New York
a) City of lights
问题:用户询问一个问题“打印机位置”,并在纽约和达拉斯得到提示。然后,当用户选择一个位置(比如达拉斯)时,理想情况下,它应该给出答案

(二) q) 如何获取达拉斯打印机详细信息(QnAID:14) a) 详细信息在DL093883-B1下方因为我们有与问题4相关的提示,并且我们使用了旧州,该州为达拉斯选择了QnaID选项。。但它给出了下面的答案,因为它只与用户响应的dallas提示文本匹配,而不考虑旧状态,因此非常感谢您的帮助

(四) q) 达拉斯 达拉斯是一座美丽的城市

protected override async Task<(object newState, IEnumerable<Activity> output, object result)> ProcessAsync(object oldState, Activity inputActivity)
{
    Activity outputActivity = null;
    QnABotState newState = null;
    var query = inputActivity.Text; ;


    //Step 4) We Build the json based on the value selected user so we make a call to the Qna Maker using the response from the user on the button click and the previous state
    //here we check if there was a prompt  from the previous question and update the state to send to the bot for response based on the option selected
    if (((QnAPrompting.Models.QnABotState)oldState) != null)
    {
        for (int i = 0; i < ((QnABotState)oldState).PreviousPromptValues.Length; i++)
        {
            if (((QnABotState)oldState).PreviousPromptValues[i].DisplayText == query)
            {
                ((QnABotState)oldState).qnaId = ((QnABotState)oldState).PreviousPromptValues[i].QnaId;
                ((QnABotState)oldState).question = query;
            }
        }
    } //Step5). when we get the response from the user after the choosing an option from the prompt, it queries the qnamaker and filters based on the old state as well
    //Step1). we get the prompts based on the question asked for the first time the old state is empty
    var qnaResult = await _qnaService.QueryQnAServiceAsync(query, (QnABotState)oldState);
    var qnaAnswer = qnaResult[0].Answer;
    var prompts = qnaResult[0].Context?.Prompts;

    if (prompts == null || prompts.Length < 1)
    {

        if (((QnAPrompting.Models.QnABotState)oldState) != null)
        {
            if (((QnAPrompting.Models.QnABotState)oldState).IsPreviousPrompt)
            {
                string method = "/knowledgebases/{0}/{1}/qna/";
                var method_with_id = String.Format(method, "KBID", "prod");
                var uri = "https://westus.api.cognitive.microsoft.com" + "/qnamaker/v4.0" + method_with_id;
                Console.WriteLine("Calling " + uri + ".");
                var response = await Get(uri);
            }
        }
        outputActivity = MessageFactory.Text(qnaAnswer);
    }
    else //Step 2.)prompt parameters are stored in the state
    {

        ContextValues ctx = new ContextValues();
        ctx.PreviousQnaId = qnaResult[0].Id;
        ctx.PreviousUserQuery = query;
        //store here in azure table
        newState = new QnABotState
        {
            question = string.Empty,
            top=10,
            userId = "Default",
            context = ctx,
            PreviousPromptValues = prompts,
        };

        outputActivity = CardHelper.GetHeroCard(qnaAnswer, prompts);
    }
    //Step 3) Prompt is displayed to the user
    return (newState, new Activity[] { outputActivity }, null);
}
protectedoverride async Task ProcessAsync(对象旧状态、活动输入活动)
{
活动输出活动=空;
QnABotState newState=null;
var query=inputActivity.Text;
//步骤4)我们基于所选用户的值构建json,因此我们使用用户在单击按钮时的响应和之前的状态调用Qna生成器
//在这里,我们检查是否有来自上一个问题的提示,并根据所选选项更新要发送给bot进行响应的状态
if(((QnAPrompting.Models.QnABotState)oldState)!=null)
{
对于(int i=0;i<((QnABotState)oldState).PreviousPromptValues.Length;i++)
{
if(((QnABotState)oldState).PreviousPromptValues[i].DisplayText==query)
{
((QnABotState)oldState.qnaId=((QnABotState)oldState.PreviousPromptValues[i].qnaId;
((QnABotState)oldState.question=query;
}
}
}//步骤5).当我们从提示中选择一个选项后收到用户的响应时,它会查询qnamaker并根据旧状态进行筛选
//步骤1).我们根据第一次询问的问题得到提示,旧状态为空
var qnaResult=await_qnaService.queryqnaservicecasync(query,(QnABotState)oldState);
var qnaAnswer=qnaResult[0]。答案;
var prompts=qnaResult[0]。上下文?。提示;
if(prompts==null | | prompts.Length<1)
{
if(((QnAPrompting.Models.QnABotState)oldState)!=null)
{
if(((QnAPrompting.Models.QnABotState)oldState).IsPreviousPrompt)
{
string method=“/knowledgebase/{0}/{1}/qna/”;
var方法_,_id=String.Format(方法“KBID”、“prod”);
var uri=”https://westus.api.cognitive.microsoft.com“+”/qnamaker/v4.0“+带有\u id的方法\u;
WriteLine(“调用“+uri+”);
var响应=等待获取(uri);
}
}
outputActivity=MessageFactory.Text(qnaAnswer);
}
else//步骤2.)提示参数存储在状态
{
ContextValues ctx=新的ContextValues();
ctx.PreviousQnaId=qnaResult[0].Id;
ctx.PreviousUserQuery=查询;
//存储在azure表中
newState=新的QnABotState
{
question=string.Empty,
top=10,
userId=“默认”,
上下文=ctx,
PreviousPromptValues=提示,
};
outputActivity=CardHelper.GetHeroCard(qnaAnswer,提示);
}
//步骤3)向用户显示提示
返回(newState,新活动[]{outputActivity},null);
}

我从源代码重新下载了代码。只需修改机器人的设置,我就运行了代码,并按预期工作。正如Kyle指出的,问题是我修改了QueryQnAServiceAsync,这导致了问题。现在它按预期工作。

我从源代码重新下载了代码。只需修改机器人的设置,我就运行了代码,并按预期工作。正如Kyle指出的,问题是我修改了QueryQnAServiceAsync,这导致了问题。现在,它正按预期工作。

如果您的代码基于一个示例(可能是这样),那么在您的问题中链接到它是一件好事,因为这将帮助我们回答这个问题。在任何情况下,我们都需要更多信息。显然,您已经修改了
QnABotState
,因此必须修改
QueryQnAServiceAsync
才能使用它,但您忽略了该代码。问题还可能是,您实际上没有正确保存状态,但您也遗漏了该代码。您可能对和感兴趣,尽管他们使用节点SDKI,但在QnA提示实验示例中也遇到了相同的问题。提示响应不考虑上下文,只是将提示文本与答案匹配(在您的案例中,提示输入回答了一个单独的问题)。还没有找到解决方案…@spStacker-你还在研究这个吗?(因为有很多人在评论,如果你想让我们看到你的回复,你必须标记我们。)@KyleDelaney这是QueryQnAServiceAsync谢谢你的回复。。现在开始工作了…很抱歉延迟了响应如果你的代码基于一个样本(比如可能),那么在你的问题中链接到它是一件好事,因为这将帮助我们回答这个问题。在任何情况下,我们都需要更多的信息。显然,您已经修改了
QnABotState
,因此必须修改
QueryQnAServiceAsync
才能使用它,但您忽略了该代码。问题还可能是,您实际上没有正确保存状态,但您也遗漏了该代码。您可能对和感兴趣,尽管他们使用节点SDKI,但在QnA提示实验示例中也遇到了相同的问题。提示响应不考虑上下文,只是将提示文本与答案匹配