【问题标题】:Microsoft Bot Framework, LUIS, take some action when the message dont have a intentMicrosoft Bot Framework,LUIS,当消息没有意图时采取一些措施
【发布时间】:2016-12-26 13:51:55
【问题描述】:

我最近开始学习 Microsoft Bot Framework,所以我开始制作一个聊天机器人,我想我做错了

我是这样制作聊天机器人的:

--> 我得到消息的用户
--> 发送到 LUIS
--> 获取意图和实体
--> 选择我的答案并发送。

没关系,但是得到以下情况:

用户:我想更改我的电子邮件。 --> 意图:ChangeInfo 实体: 电子邮件/价值:电子邮件

CHATBOT:请告诉我你的新邮箱。 --> 意图:无意图 实体:无实体

用户:email@email.com --> 意图:IDon'tKnow 实体: 电子邮件/价值:email@email.com

我采取这种情况,当用户发送他的电子邮件时,我发送到 LUI,但是电子邮件没有意图,只是有一个实体,但是电子邮件可以在很多不同的情况下使用,我的问题是,如何我的机器人知道对话的上下文来理解这封电子邮件是为了更改电子邮件而不是发送电子邮件,或者更新这封电子邮件或其他事情。

我在 gitHub here 上的代码,我知道这是一个丑陋的代码,但我这样做只是为了理解 bot 框架,之后我会让这段代码更漂亮

【问题讨论】:

  • 您不使用 LuisDialog 的任何原因?在这种情况下,您不应该将电子邮件发送回 Luis,您应该触发 PromptDialog.Text 来询问电子邮件并在用户输入后做任何您想做的事情。

标签: c# botframework azure-language-understanding


【解决方案1】:

这应该像使用 LuisDialog 和一组提示来管理用户流一样简单。您将在下面找到我整理的一些快速代码,以向您展示如何做到这一点。您不需要额外的步骤或添加额外的实体,或者使用用户提供的电子邮件去 Luis。

我建议您阅读更多有关 LuisDialog 和一般对话框的信息,因为您在控制器中使用 Luis 的方式我不认为是要走的路。

Here 是一个很好的 Luis 样本,这里是 multi-dialogs 周围的一个很好的样本。

示例代码

namespace MyNamespace
{
    using System;
    using System.Threading.Tasks;
    using Microsoft.Bot.Builder.Dialogs;
    using Microsoft.Bot.Builder.Internals.Fibers;
    using Microsoft.Bot.Builder.Luis;
    using Microsoft.Bot.Builder.Luis.Models;
    using Microsoft.Bot.Connector;

    [Serializable]
    [LuisModel("YourModelId", "YourSubscriptionKey")]
    public class MyLuisDialog : LuisDialog<object>
    {
        [LuisIntent("")]
        [LuisIntent("None")]
        public async Task None(IDialogContext context, LuisResult result)
        {
            string message = "Não entendi, me diga com outras palavras!";

            await context.PostAsync(message);
            context.Wait(this.MessageReceived);
        }

        [LuisIntent("ChangeInfo")]
        public async Task ChangeInfo(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            // no need to go to luis again..
            PromptDialog.Text(context, AfterEmailProvided, "Tell me your new email please?");
        }

        private async Task AfterEmailProvided(IDialogContext context, IAwaitable<string> result)
        {
            try
            {
                var email = await result;

                // logic to store your email...
            }
            catch
            {
                // here handle your errors in case the user doesn't not provide an email
            }

          context.Wait(this.MessageReceived);
        }

        [LuisIntent("PaymentInfo")]
        public async Task Payment(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
        {
            // logic to retrieve the current payment info..
            var email = "test@email.com";

            PromptDialog.Confirm(context, AfterEmailConfirmation, $"Is it {email} your current email?");
        }

        private async Task AfterEmailConfirmation(IDialogContext context, IAwaitable<bool> result)
        {
            try
            {
                var response = await result;

                // if the way to store the payment email is the same as the one used to store the email when going through the ChangeInfo intent, then you can use the same After... method; otherwise create a new one
                PromptDialog.Text(context, AfterEmailProvided, "What's your current email?");
            }
            catch
            {
                // here handle your errors in case the user doesn't not provide an email
            }

            context.Wait(this.MessageReceived);
        }
    }
}

【讨论】:

  • 非常感谢,这是最好的答案。但是知道我有一个新问题,这是一个简单的问题。在方法 AfterEmailProvided 中,我需要将用户的答案发送给 LIUS 还是没有必要?因为用户可以以多种不同的形式回答“真”或“假”。我知道,我也可以使用选项,但我的聊天机器人是用于短信的,所以我不能在短信中发送两个带有“是或否”的按钮和我的老板想让这个聊天机器人看起来像一个真正的人,而且真正的人不要问是或否,知道吗?!
  • 您无需将电子邮件发回给 Luis。流程应该是:用户请求更改他的电子邮件,机器人请求新电子邮件,用户提供电子邮件(这里是调用 AfterEmailProvided 的时间),您的机器人刚刚收到电子邮件,并将其存储在某个地方。无需向用户询问其他任何内容。在付款的情况下,电子邮件的确认是一个是/否的问题。当然,用户可以回答任何问题,但这是一个是/否的问题;最坏的情况下,他们将收到 PromptDialog.Confirm 的重试消息,该消息也可以更改。
  • 我找到了一种做是/否问题的方法,只需使用 PromptDialog.Confirm(context, yourMethod, $"your message");并且您的“IAwaitable”将是一个布尔值,因此用户可以响应是(1)或否(0)。这是文档。 (docs.botframework.com/en-us/csharp/builder/sdkreference/dd/d7e/…)
  • 这正是我在代码中所做的(查看付款方式)以及我在之前的评论中所说的......我错过了什么吗?
  • 对不起,你是对的,我没有在你的代码中注意到这一点
【解决方案2】:

在我的机器人流程中,我使用了从前端更改的 step 变量。我从机器人更改的另一个step 变量。这有助于我确定我在对话中的哪一步。您可以执行相同的操作来识别您的机器人正在询问用户的内容。

var data = {step: "asked_email"};
var msg = builder.Message(session).addEntity(data).text("Your message.");
session.send(msg);

如果您不想将特定步骤发送到 LUIS 进行识别,您可以在 onBeginDialog 处理程序中进行处理:

intents.onBegin(function (session, args, next) {
  if (session.message.step !== "email") {
    next();
  } else {
    //Do something else and not go to LUIS.
    session.endDialog();
  }
});

您可以在此处找到对 LUIS onBeginDialog 的引用: https://docs.botframework.com/en-us/node/builder/chat/IntentDialog/#onbegin--ondefault-handlers

可以在此处找到有关消息数据的详细信息: https://docs.botframework.com/en-us/node/builder/chat-reference/classes/_botbuilder_d_.message.html#entities

【讨论】:

  • 它在 c# 中有吗?我看到文档在 nodeJs 中,但我在 c# 中开发]
  • 在 C# 中处理起来更加容易。您可以在var responseLuis = Luis.GetResponse(activity.Text); 上方添加条件以检查消息步骤。如果消息步骤不是电子邮件,请不要执行此命令并在没有 LUIS 的情况下直接发送响应。 step 数据是这里的关键,如果你知道你的机器人在哪一步,你可以管理你想对消息做什么。
  • 我已经尝试过了,但这里的问题是当我们需要在两种不同的情况下更改电子邮件时。示例:(1) > 用户: 我想更改我的电子邮件 > 聊天机器人: 你是新电子邮件吗? > 用户:email@email.com > 聊天机器人:电子邮件已更改 (2) - > 用户:我想在我的电子邮件中收到付款 > 聊天机器人: 是您的电子邮箱:emai222@email.com 吗? > 用户:没有 > 聊天机器人:你现在的邮箱是什么? > 用户: email@email.com > 聊天机器人:我更新您的电子邮件并发送您的付款人
  • 这只是 2 个不同的意图,我认为您会因为使用 Luis 的方式以及控制器中的所有内容而感到困惑。如果您使用对话框重新排序项目,您应该如何使用它会变得更加清晰。您不需要管理步骤等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2018-11-22
  • 1970-01-01
  • 2018-03-11
相关资源
最近更新 更多