Botframework Microsoft Bot Framework-用户被重定向到错误的对话框

Botframework Microsoft Bot Framework-用户被重定向到错误的对话框,botframework,direct-line-botframework,qnamaker,Botframework,Direct Line Botframework,Qnamaker,我正在使用Microsoft Bot Framework(用于.NET)、QnA Maker和QnAMakerDialog()开发聊天机器人。托管聊天盒控件的bot和web项目部署在Azure中。我是 使用直达线路作为通道 对话流程非常简单。用户从主分支开始。根据用户输入,对话将继续使用QnAMakerDialog或用于反馈的自定义对话框 问题如下: 用户从主分支开始。只要用户不键入“end”,我就将对话转发到QnA对话框,并尝试回答他的问题。在某些情况下,用户键入“end”。因此,我启动反馈对

我正在使用Microsoft Bot Framework(用于.NET)、QnA Maker和QnAMakerDialog()开发聊天机器人。托管聊天盒控件的bot和web项目部署在Azure中。我是 使用直达线路作为通道

对话流程非常简单。用户从主分支开始。根据用户输入,对话将继续使用QnAMakerDialog或用于反馈的自定义对话框

问题如下:

用户从主分支开始。只要用户不键入“end”,我就将对话转发到QnA对话框,并尝试回答他的问题。在某些情况下,用户键入“end”。因此,我启动反馈对话框。用户输入反馈。现在,应该感谢他的反馈,并将其发送回QnA对话。相反,他得到的答复是,在QnA知识数据库中没有找到好的答案。这意味着,不知何故,他发现自己走错了路!机器人认为他在QnA分支上,但事实上他应该在反馈分支上

按照相同的步骤,无法始终再现此错误。它随机发生,没有模式。更重要的是,它只发生在某些环境中。它从来不会发生在我的开发机器上,它很少发生在一个环境中,而且经常发生在第三个环境中。(这两个环境的配置几乎相同,因此不会出现问题)。此外,问题不可能来自QnAMakerDialog–我使用自定义QnADialog进行了测试,该QnADialog始终返回静态消息,而不是来自QnAMaker的答案,并且问题仍然存在

这是密码。任何想法都是非常受欢迎的

[BotAuthentication]
public class MessagesController : ApiController
{
    private readonly ILog log;
    public MessagesController(ILog log)
    {
        this.log = log;
    }

    internal static IDialog<object> MakeRoot()
    {
        return Chain.From(() => new HomeDialog());
    }

    public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
    {
        var client = new ConnectorClient(new Uri(activity.ServiceUrl));
        try
        {
            switch (activity.GetActivityType())
            {
                case ActivityTypes.Message:
                    var typingReply = activity.CreateReply();
                    typingReply.Type = ActivityTypes.Typing;
                    await client.Conversations.ReplyToActivityAsync(typingReply);
                    await Conversation.SendAsync(activity, MakeRoot);
                    break;

                default:
                    HandleSystemMessage(activity);
                    break;
            }
        }
        catch (Exception ex)
        {
            var errorReply = activity.CreateReply();
            errorReply.Type = ActivityTypes.Message;
            errorReply.Text ="I'm sorry, I'm having issues understanding you. Let's try again.";

            await client.Conversations.ReplyToActivityAsync(errorReply);

            log.Error("Issue in the bot.", ex);
        }

        return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
    }

    private Activity HandleSystemMessage(Activity message)
    {

        if (message.Type == ActivityTypes.DeleteUserData)
        {
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
        }
        else if (message.Type == ActivityTypes.Typing)
        {
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }
        return null;
    }
}

[Serializable]
public class HomeDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
            context.Wait(MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
            await RedirectToQnaDialog(context);
    }

    private async Task RedirectToQnaDialog(IDialogContext context)
    {
            await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
    }

    private async Task QnaDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
    {
            var message = await result;

            PromptDialog.Text(context,
                ResumeAfterQuestionTyped,
                "Type your question or 'end' to end this conversation.",
                "Please retry", 3);
    }

    private async Task ResumeAfterQuestionTyped(IDialogContext context, IAwaitable<string> inputFromUser)
    {
            var question = await inputFromUser;

            if (question.ToLower().Equals("end"))
            {
                await context.PostAsync("You would really help me out by giving feedback. " +
                                        "What subjects should we include to provide answers for your questions?");
                context.Call(new FeedbackDialog(), FeedbackDialogResumeAfter);
            }
            else
            {
                await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
            }
    }

    private async Task FeedbackDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
    {
            await context.PostAsync("Thank you for your feedback. You can now continue to ask me more questions.");

            context.Wait(MessageReceivedAsync);
    }


[Serializable]
public class QnaDialog : QnAMakerDialog
{
    public QnaDialog() : base(new QnAMakerService
    (new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey"],
        ConfigurationManager.AppSettings["QnaKnownledgeBaseKey"],
        ConfigurationManager.AppSettings["QnaNotFoundReply"],
        Convert.ToDouble(ConfigurationManager.AppSettings["QnaPrecentageMatch"]), 5)))
    {
    }

    protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message,
        QnAMakerResults results)
    {
            if (results.Answers.Count > 0)
            {
                var response = results.Answers.First().Answer;

                await context.PostAsync(response);
            }
    }

    protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message,
        QnAMakerResults result)
    {
            context.Done<IMessageActivity>(null);
    }


[Serializable]
public class FeedbackDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
            context.Wait(MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
            var message = await result;

            context.Done(message);
    }
  }
[BotAuthentication]
公共类消息控制器:ApiController
{
私有只读ILog日志;
公共消息控制器(ILog日志)
{
this.log=log;
}
内部静态IDialog MakeRoot()
{
返回链。从(()=>新建HomeDialog());
}
公共虚拟异步任务发布([FromBody]活动)
{
var client=newconnectorclient(新Uri(activity.ServiceUrl));
尝试
{
开关(activity.GetActivityType())
{
案例活动类型。消息:
var typingReply=activity.CreateReply();
typingReply.Type=ActivityTypes.Typing;
等待client.Conversations.ReplyToActivityAsync(键入Reply);
wait Conversation.sendaync(活动,MakeRoot);
打破
违约:
HandleSystemMessage(活动);
打破
}
}
捕获(例外情况除外)
{
var errorReply=activity.CreateReply();
errorReply.Type=ActivityTypes.Message;
errorReply.Text=“对不起,我在理解您时遇到问题。让我们再试一次。”;
等待client.Conversations.ReplyToActivityAsync(errorReply);
日志错误(“bot中的问题”,例如);
}
返回新的HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
私有活动HandleSystemMessage(活动消息)
{
if(message.Type==ActivityTypes.DeleteUserData)
{
}
else if(message.Type==ActivityTypes.ConversationUpdate)
{
}
else if(message.Type==ActivityTypes.ContactRelationUpdate)
{
}
else if(message.Type==ActivityTypes.Typing)
{
}
else if(message.Type==ActivityTypes.Ping)
{
}
返回null;
}
}
[可序列化]
公共类HomeDialog:IDialog
{
公共异步任务StartAsync(IDialogContext上下文)
{
Wait(MessageReceivedAsync);
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
等待重定向到qnadialog(上下文);
}
专用异步任务重定向到QNADialog(IDialogContext上下文)
{
wait context.Forward(new QnaDialog(),qnadialogresumefafter,context.Activity,CancellationToken.None);
}
专用异步任务QnaDialogResumeAfter(IDialogContext上下文,IAwaitable结果)
{
var消息=等待结果;
PromptDialog.Text(上下文,
简历输入后,
“键入您的问题或“结束”以结束此对话。”,
“请重试”,3);
}
私有异步任务ResumeAfterQuestionTyped(IDialogContext上下文,IAwaitable inputFromUser)
{
var问题=等待用户输入;
如果(question.ToLower().Equals(“end”))
{
wait context.PostAsync(“你会通过提供反馈来帮助我的。”+
“我们应该包括哪些主题来回答您的问题?”);
调用(new FeedbackDialog(),FeedbackDialogResumeAfter);
}
其他的
{
wait context.Forward(new QnaDialog(),qnadialogresumefafter,context.Activity,CancellationToken.None);
}
}
专用异步任务反馈对话框ResumeAfter(IDialogContext上下文,IAwaitable结果)
{
wait context.PostAsync(“谢谢你的反馈。你现在可以继续问我更多问题了。”);
Wait(MessageReceivedAsync);
}
[可序列化]
公共类QnaDialog:QnAMakerDialog
{
public QnaDialog():基本(新的QnAMakerService
(新的QnAMakerAttribute(ConfigurationManager.AppSettings[“QnaSubscriptionKey”],
ConfigurationManager.AppSettings[“QnaKnownledgeBaseKey”],
ConfigurationManager.AppSettings[“QnanoFoundReply”],
Convert.ToDouble(ConfigurationManager.AppSettings[“QnaPrecentageMatch”]),5)
{
}
受保护的重写异步任务RespondFromQnAMakerResultAs
[Serializable]
public class HomeDialog : IDialog<object>
{
    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(MessageReceivedAsync);
    }

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
    {
        await QnaDialogResumeAfter(context, result);
    }

    private async Task QnaDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
    {
        var message = await result;

        PromptDialog.Text(context,
            ResumeAfterQuestionTyped,
            "Type your question or 'end' to end this conversation.",
            "Please retry", 3);
    }

    private async Task ResumeAfterQuestionTyped(IDialogContext context, IAwaitable<string> inputFromUser)
    {
        var question = await inputFromUser;

        if (question.ToLower().Equals("end"))
        {
            await context.PostAsync("You would really help me out by giving feedback. " +
                                    "What subjects should we include to provide answers for your questions?");
            context.Call(new QnaDialog.FeedbackDialog(), FeedbackDialogResumeAfter);
        }
        else
        {
            await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
        }
    }

    private async Task FeedbackDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
    {
        PromptDialog.Text(context,
            ResumeAfterQuestionTyped,
            "Thank you for your feedback. You can now continue to ask me more questions.",
            "Please retry", 3);
    }


    [Serializable]
    public class QnaDialog : QnAMakerDialog
    {
        public QnaDialog() : base(new QnAMakerService
        (new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey"],
            ConfigurationManager.AppSettings["QnaKnownledgeBaseKey"],
            ConfigurationManager.AppSettings["QnaNotFoundReply"],
            Convert.ToDouble(ConfigurationManager.AppSettings["QnaPrecentageMatch"]), 5)))
        {
        }

        protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message,
            QnAMakerResults results)
        {
            if (results.Answers.Count > 0)
            {
                var response = results.Answers.First().Answer;

                await context.PostAsync(response);
            }
        }

        protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
        {
            context.Done<IMessageActivity>(null);
        }


        [Serializable]
        public class FeedbackDialog : IDialog<object>
        {
            public async Task StartAsync(IDialogContext context)
            {
                context.Wait(MessageReceivedAsync);
            }

            private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
            {
                var message = await result;

                context.Done(message);
            }
        }
    }
}
 var store = new InMemoryDataStore(); // volatile in-memory store

 builder.Register(c => store)
     .Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
     .AsSelf()
     .SingleInstance();