如何在两个不同语言的luis.ai对话框之间切换

时间:2017-06-16 15:06:09

标签: c# facebook azure botframework luis

我使用luis.ai在bot框架中创建了一个bot。

在我的luis帐户中,我创建了两个具有不同语言文化的应用程序。一个英语和其他法语应用程序。两者都有他们的意图。

在我的代码中,我打电话给一次英语对话,其他时间用法语luis对话。

我的问题是,当我在英语facebook频道(信使)开始对话时,我得到了正确的答案。当我输入法语时,在这个机器人和频道内部,我的机器人不会调用法语对话框。

当我在法语版的facebook中开始对话时...机器人无法识别正确的对话框...但是发现错误:“哎呀!我们的系统存在一些问题

我尝试输入英语话语然后我得到:哎呀!太多的尝试:(。但不要担心,我正在处理该异常,你可以再试一次!

我的想法是:当我在英语语言中使用facebook时,点击:开始...我的对话以英语对话开始(AlltheBot.cs)。如果我输入法语单词:salut,demarrer,bot可以转发到法语对话框(FrenchLuis.cs)。反过来说,当我在法语版的facebook中,当我点击Demarrer以法语开始,然后如果我在英语对话框中键入你好来转发时我的谈话。

我的代码在这里:

MessageController.cs

namespace MultiDialogsBot
 {
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using FirstBotApplication.Dialogs;
using System.Linq;
using System;

[BotAuthentication]
public class MessagesController : ApiController
{
    /// <summary>
    /// POST: api/Messages
    /// Receive a message from a user and reply to it
    /// </summary>
    public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
    {
        if (activity.Type == ActivityTypes.Message)
        {
            await Conversation.SendAsync(activity, () => new RootDialog());
        }
        else
        {
            this.HandleSystemMessage(activity);
        }

        var response = Request.CreateResponse(HttpStatusCode.OK);
        return response;
      }

     private Activity HandleSystemMessage(Activity message)
     {
        if (message.Type == ActivityTypes.DeleteUserData)
        {
            // Implement user deletion here
            // If we handle user deletion, return a real message
        }
        else if (message.Type == ActivityTypes.ConversationUpdate)
        {
            // Handle conversation state changes, like members being added 
       and removed
            // Use Activity.MembersAdded and Activity.MembersRemoved and 
         Activity.Action for info

            IConversationUpdateActivity update = message;
            var client = new ConnectorClient(new Uri(message.ServiceUrl), 
           new MicrosoftAppCredentials());
            if (update.MembersAdded != null && update.MembersAdded.Any())
            {
                foreach (var newMember in update.MembersAdded)
                {
                    if (newMember.Id != message.Recipient.Id && newMember.Id 
             != message.Conversation.Id)
                    {
                        var reply = message.CreateReply();
                        reply.Text = $"Welcome" + " " + 
      message.Recipient.Name + " ! You are a new member! If you want to see 
                   help menu , type : help";
                        client.Conversations.ReplyToActivityAsync(reply);
                    }
                }
            }
            // Not available in all channels
        }
        else if (message.Type == ActivityTypes.ContactRelationUpdate)
        {
            // Handle add/remove from contact lists
            // Activity.From + Activity.Action represent what happened
        }
        else if (message.Type == ActivityTypes.Typing)
        {
            // Handle knowing tha the user is typing
        }
        else if (message.Type == ActivityTypes.Ping)
        {
        }

        return null;
    }


}

}

RootDialog.cs

namespace FirstBotApplication.Dialogs
 {
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;

[Serializable]
public class RootDialog : IDialog<object>
{


    public async Task StartAsync(IDialogContext context)
    {
        context.Wait(this.MessageReceivedAsync);
    }

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

        if (message.Text.ToLower().Contains("Get Started") || 
       message.Text.ToLower().Contains("hello") || 
         message.Text.ToLower().Contains("hi"))
        {
            context.Call(new AllTheBot (), this.ResumeAfterOptionDialog);

        }

        else if (message.Text.ToLower().Contains("Démarrer") || 
     message.Text.ToLower().Contains("salut") || 
        message.Text.ToLower().Contains("french"))
        {
            context.Call(new FrenchLuis(), this.ResumeAfterOptionDialog);

        }
        else
        {
            await context.PostAsync($"Ooops! There are some problems with our system");
        }

    }

    private async Task ResumeAfterOptionDialog(IDialogContext context, 
     IAwaitable<object> result)
    {
        await context.PostAsync($"Ooops! Too many attemps :(. But don't 
   worry, I'm handling that exception and you can try again!");
    }

      }
    }

FrenchLuis.cs

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Luis;
using Microsoft.Bot.Builder.Luis.Models;
 using Microsoft.Bot.Connector;
 using System;
  using System.Collections.Generic;
   using System.IO;
    using System.Linq;
 using System.Threading.Tasks;
using System.Web;


   namespace FirstBotApplication
    {
    //  [LuisModel("Please Enter Your LUIS Model ID", "Please Enter Your 
     LUIS 
     Subscription Key")]

  [Serializable]

 [LuisModel("aaaaaaa", "xxxxxxxxx")]



public class FrenchLuis : LuisDialog<object>
{
    internal static string results;

    // internal static string results;
    [LuisIntent("None")]
    [LuisIntent("")]
    public async Task None(IDialogContext context, LuisResult result)
    {
        string message = $"Désolé je n'ai pas compris '{result.Query}'. 
     Veuillez reformuler votre question";

        await context.PostAsync(message);

        context.Wait(this.MessageReceived);
        context.Done(true);

    }



    //french luis.ai
    [LuisIntent("demarrerintent")]
    public async Task demarrerintent(IDialogContext context, 
   IAwaitable<IMessageActivity> activity, LuisResult result)
    {

        await context.PostAsync("Bienvenue :) ");

         context.Done(true);


    }

    [LuisIntent("denous")]
    public async Task denous(IDialogContext context, 
   IAwaitable<IMessageActivity> activity, LuisResult result)
    {

        await context.PostAsync(" Nous sommes .....");

        context.Done(true);
    }

    [LuisIntent("quisommes")]
    public async Task quisommes(IDialogContext context, IAwaitable<IMessageActivity> activity, LuisResult result)
    {

        await context.PostAsync("Je suis un robot");
        context.Done(true);
        // context.Wait(MessageReceived);

    }
  }}

AllTheBot.cs

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.Luis;
using Microsoft.Bot.Builder.Luis.Models;
using Microsoft.Bot.Connector;
   using System;
  using System.Collections.Generic;
  using System.IO;
using System.Linq;
  using System.Threading.Tasks;
 using System.Web;


  namespace FirstBotApplication
     {

    [LuisModel("bbbbbb", "xxxxxxx")]

   [Serializable]


  public class AllTheBot : LuisDialog<object>
   {
    internal static string results;

    // internal static string results;
    [LuisIntent("None")]
    [LuisIntent("")]
    public async Task None(IDialogContext context, LuisResult result)
    {
        string message = $"Sorry, I did not understand '{result.Query}'. 
       Please reformulate your question";

        await context.PostAsync(message);
        context.Done(true);

        //  context.Wait(this.MessageReceived);

    }


    [LuisIntent("grettings")]
    [LuisIntent("intentfr")]
    public async Task Greeting(IDialogContext context, 
    IAwaitable<IMessageActivity> activity, LuisResult result)
    {


            await context.PostAsync("Welcome ");

        context.Done(true);

    }



    [LuisIntent("test")]
    public async Task test(IDialogContext context, 
    IAwaitable<IMessageActivity> activity, LuisResult result)
    {
        await context.PostAsync("Do you want to test our bot ? We suggest to 
    type : hi or who are you, help etc..");
        context.Wait(MessageReceived);
    }
    }}

2 个答案:

答案 0 :(得分:3)

我查看了你的项目并遇到了一些问题。您应该一步一步地消除问题,因为您混合了很多东西(对话管理,LUIS调用等)。

<强> RootDialog.cs

第一点:

message.Text.ToLower().Contains("Démarrer") 

message.Text.ToLower().Contains("Get Started")

这两个测试无效,因为您要比较小写的单词和大写的单词。

此外,还有更聪明的方法来点击Facebook Messenger“Get Started”按钮的事件,但这不是重点。

第二点:

private async Task ResumeAfterOptionDialog(IDialogContext context, IAwaitable<object> result)
{
    await context.PostAsync($"Ooops! Too many attemps :(. But don't worry, I'm handling that exception and you can try again!");
}

这里的文字对于对话简历非常奇怪!

AllTheBot.cs和FrenchLuis.cs

当您调用2 LuisDialog时,您永远不会将消息的值传递给这些对话框,这是正常的吗?

您应该使用context.Forward代替context.Call:这样您的邮件就会自动转发到子对话框。

全球行为

我认为你没有采用正确的方式来管理语言。为什么不使用有效的语言检测系统来检查您从用户收到的内容是哪种语言?

Microsoft Cognitive Services提供的Text Analytics API就是为此:https://azure.microsoft.com/en-gb/services/cognitive-services/text-analytics/

您的案例中的对话管理

我制作了2个对话框管理实现的示例(此处没有LUIS),以向您展示工作原理:

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

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

        if (message.Text.ToLower().Contains("Get Started") ||
            message.Text.ToLower().Contains("hello") ||
            message.Text.ToLower().Contains("hi"))
        {
            await context.Forward(new Dialog44592511_EN(), this.ResumeAfterOptionDialog, message);
        }
        else if (message.Text.ToLower().Contains("Démarrer") || message.Text.ToLower().Contains("salut") || message.Text.ToLower().Contains("french"))
        {
            await context.Forward(new Dialog44592511_FR(), this.ResumeAfterOptionDialog, message);
        }
        else
        {
            await context.PostAsync($"Ooops! There are some problems with our system");
        }
    }

    private async Task ResumeAfterOptionDialog(IDialogContext context, IAwaitable<object> result)
    {
        await context.PostAsync($"Resume!");
    }
}

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

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;
        await context.PostAsync($"Vous êtes dans le dialogue FR");
        context.Done<object>(null);
    }
}

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

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
    {
        var activity = await result as Activity;
        await context.PostAsync($"You are in the EN dialog");
        context.Done<object>(null);
    }
}

Test

不要犹豫,编辑您的问题以获取更多详情

答案 1 :(得分:0)

您应该使用context.Call而不是context.Forward,这会将消息转发到对话框。

使用context.Call,您只需调用对话框并准备好接收新消息。

您应该查看启动对话框的不同方法,解释here