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

戴安娜

我正在使用 Microsoft Bot Framework(用于 .NET)、QnA Maker 和 QnAMakerDialog(https://github.com/garypretty/botframework/tree/master/QnAMakerDialog开发聊天机器人机器人和托管聊天框控件的 Web 项目部署在 Azure 中。我使用 Direct Line 作为通道。

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

问题如下:

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

按照相同的步骤,无法一直重现此错误。它随机发生,没有模式。甚至更多 - 它只发生在某些环境中。它从未发生在我的开发机器上,它很少发生在一个环境中,它经常发生在第三个环境中。(这两个环境的配置几乎相同,问题不会从那里出现)。此外,问题不可能来自 QnAMakerDialog – 我使用自定义 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);
    }
  }

}

戴安娜

我发布了答案,因为这可能会在未来对其他人有所帮助:

问题是我使用的是内存中的机器人状态,而这在 Microsoft 文档中明确记录,这应该仅用于测试目的。

 var store = new InMemoryDataStore(); // volatile in-memory store

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

内置的 Azure 负载均衡器将 DirectLine 的请求随机转发到其中一个实例,这就是 API 完全丢失的原因,因为 API 的每个实例在内存中都有自己的“状态”。

因此,基本上解决方法是为机器人实现状态管理,而不是使用默认的内存中状态。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Microsoft Bot Framework中的FormFlow与对话框

来自分类Dev

Microsoft Bot Framework 多用户

来自分类Dev

Microsoft Bot Framework未经授权的错误

来自分类Dev

使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项

来自分类Dev

Microsoft Bot Framework-在多个对话框中使用变量(node.js)

来自分类Dev

Microsoft Bot Framework转发到对话框无法正常工作

来自分类Dev

Microsoft Bot Framework-在对话期间发送消息

来自分类Dev

Microsoft Bot Framework Client SDK

来自分类Dev

在Microsoft Bot Framework网络聊天中唯一标识用户

来自分类Dev

在 Microsoft bot Framework 中跨渠道验证用户身份

来自分类Dev

Microsoft Bot Framework 和 Microsoft Teams

来自分类Dev

如何解决Microsoft Bot Framework中的内容类型错误?

来自分类Dev

如何解决Microsoft Bot Framework中的内容类型错误?

来自分类Dev

Microsoft Bot Framework (WebChat) - 500 内部服务器错误

来自分类Dev

Microsoft Bot Framework OAuth 卡返回错误请求

来自分类Dev

结合使用Microsoft Bot框架和动态对话框

来自分类Dev

在Microsoft Bot框架中处理多个对话框

来自分类Dev

结合使用Microsoft Bot框架和动态对话框

来自分类Dev

Microsoft Bot Framework上的Skype Bot-无响应

来自分类Dev

当用户键入“退出”,“退出”等时,终止所有对话框并退出MS Bot Framework中的对话

来自分类Dev

在Microsoft Bot Framework中创建对话时找不到404资源

来自分类Dev

在Microsoft Bot Framework中难以访问现有对话中的消息

来自分类Dev

Microsoft Bot Framework-Facebook集成-Net Framework

来自分类Dev

如何通过Microsoft Bot Framework将记录插入到Azure表存储中?

来自分类Dev

MS团队| Microsoft Bot Framework-在任务/提取上返回502错误

来自分类Dev

如何存储用户信息以在另一个对话框中访问 - Bot framework V3

来自分类Dev

如何在Microsoft Bot Framework + C#中安排任务?

来自分类Dev

带Facebook Messenger中按钮的Microsoft Bot Framework消息

来自分类Dev

适用于Facebook Messenger的Microsoft Bot Framework附件

Related 相关文章

  1. 1

    Microsoft Bot Framework中的FormFlow与对话框

  2. 2

    Microsoft Bot Framework 多用户

  3. 3

    Microsoft Bot Framework未经授权的错误

  4. 4

    使用Autofac在Microsoft Bot Framework对话框中注入外部依赖项

  5. 5

    Microsoft Bot Framework-在多个对话框中使用变量(node.js)

  6. 6

    Microsoft Bot Framework转发到对话框无法正常工作

  7. 7

    Microsoft Bot Framework-在对话期间发送消息

  8. 8

    Microsoft Bot Framework Client SDK

  9. 9

    在Microsoft Bot Framework网络聊天中唯一标识用户

  10. 10

    在 Microsoft bot Framework 中跨渠道验证用户身份

  11. 11

    Microsoft Bot Framework 和 Microsoft Teams

  12. 12

    如何解决Microsoft Bot Framework中的内容类型错误?

  13. 13

    如何解决Microsoft Bot Framework中的内容类型错误?

  14. 14

    Microsoft Bot Framework (WebChat) - 500 内部服务器错误

  15. 15

    Microsoft Bot Framework OAuth 卡返回错误请求

  16. 16

    结合使用Microsoft Bot框架和动态对话框

  17. 17

    在Microsoft Bot框架中处理多个对话框

  18. 18

    结合使用Microsoft Bot框架和动态对话框

  19. 19

    Microsoft Bot Framework上的Skype Bot-无响应

  20. 20

    当用户键入“退出”,“退出”等时,终止所有对话框并退出MS Bot Framework中的对话

  21. 21

    在Microsoft Bot Framework中创建对话时找不到404资源

  22. 22

    在Microsoft Bot Framework中难以访问现有对话中的消息

  23. 23

    Microsoft Bot Framework-Facebook集成-Net Framework

  24. 24

    如何通过Microsoft Bot Framework将记录插入到Azure表存储中?

  25. 25

    MS团队| Microsoft Bot Framework-在任务/提取上返回502错误

  26. 26

    如何存储用户信息以在另一个对话框中访问 - Bot framework V3

  27. 27

    如何在Microsoft Bot Framework + C#中安排任务?

  28. 28

    带Facebook Messenger中按钮的Microsoft Bot Framework消息

  29. 29

    适用于Facebook Messenger的Microsoft Bot Framework附件

热门标签

归档