【问题标题】:Calling back LUIS from a dialog [duplicate]从对话框中回调 LUIS [重复]
【发布时间】:2018-01-23 19:52:27
【问题描述】:

我正在使用 Microsoft 和 C# 开发聊天机器人。我的机器人基本上从 LUIS 获得意图,并基于该意图回复静态字符串或转发到包含多个问题的新对话框。在新对话框中,用户发送的消息直接在代码中处理,无需通过 LUIS。

我的代码:

MainLUISDialog.cs:

[LuisIntent("Greetings")]
public async Task Greetings(IDialogContext context, IAwaitable<IMessageActivity> argument, LuisResult result)
{
    await context.PostAsync(@"Hello user!");
    context.Wait(MessageReceived);
}

[LuisIntent("NearbyRestaurants")]
public async Task NearbyRestaurants(IDialogContext context, IAwaitable<IMessageActivity> argument, LuisResult result)
{
    var msg = await argument;
    await context.Forward(new LocationDialog(), ResumeAfterLocationReceived, msg, CancellationToken.None);
}

LocationDialog.cs:

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

public virtual async Task MessageReceivedAsync(IDialogCOntext context, IAwaitable<IMessageActivity> argument)
{
    var msg = await argument;
    var reply = context.MakeMessage();
    reply.Type = ActivityTypes.Message;
    reply.Text = "would you like to share your location?";
    reply.TextFormat = TextFormatTypes.Plain;
    reply.SuggestedActions = new SuggetedActions()
    {
        Actions = new List<CardAction>()
        {
            new CardAction(){ Title="Yes", Type=ActionTypes.ImBack, Value="yes"},
            new CardAction(){ Title="No", Type=ActionTypes.ImBack, Value="no"}
        }
    };
    await context.PostAsync(reply);
    context.Wait(ReplyReceivedAsync);
}

public virtual async Task ReplyReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
    var msg = await argument;
    if(msg.Text.Equals("yes"))
    {
        //forward to function for handling location
    }
    else if (msg.Text.Equals("no"))
    {
        context.Done("no location")
    }
    else
    {
        context.Done(msg.Text)
    }
}

MainLUISDialog.cs (ResumeAfterLocationReceived):

public async Task ResumeAfterLocationReceived(IDialogContext context, IAwaitable<String> result)
{
    if(result.Equals("no"))
    {
        await context.PostAsync(@"Sorry can't search");
        context.Wait(MessageReceived);
    }
    else
    {
        //in this case i need to forward the message directly to LUIS to get the user's intent
    }
}

当询问用户是否要共享他的位置并且用户通过不同的消息回答是/否时,我需要将该消息直接转发回 LUIS 以获得用户的意图。我怎么做?我知道如果我使用 context.Wait(MessageReceived) 这将使代码忘记用户发送的消息,用户将不得不再次输入。

【问题讨论】:

  • 为澄清起见,您想将“是”这个词发送给 LUIS?
  • @JasonSowers 否,如果是/否,我不需要返回 LUIS,以防用户回答是/否以外的其他问题,例如“你好吗”我需要将此消息发送回 LUIS。谢谢:)
  • 谢谢,我看错了:)
  • 查看我刚刚添加的副本。在你的情况下,因为你在 LuisDialog 而不是 MessageReceivedAsync 你只需要使用 MessageReceived
  • @EzequielJadib 谢谢你:) 你链接的帖子解决了我的问题,我会在这里发布我的案例的完整答案。

标签: c# bots botframework chatbot azure-language-understanding


【解决方案1】:

您可能需要考虑在此处更改您的逻辑。让您的按钮 ImBack 值类似于“是,使用我的位置”或“不,不要使用我的位置”或类似的变体。然后,您可以将整个字符串发送给 Luis,就像在您的问候语或附近的餐馆意图中(或者不是您当前所做的那样)作为位置意图。这样您就不必担心处理其他意图。另外,你不会把“是”和“不是”这两个词绑起来

【讨论】:

  • 这不是我的确切情况,在我的情况下,我有多个对话框,每个可能包含多达 30 个问题,我不能每次都返回 LUIS 的主对话框,我需要在用户输入的文本不是选项之一。无论如何,我在 Ezequiel 的评论中找到了我的答案,我将在下面发布。谢谢你:)
【解决方案2】:

我以同样的方式解决了这个问题,Ezequel Jadib 在下面的帖子中添加了几行: How to forward result of Prompt.Choice() to current dialog?

在我的 MainLUISDialog.cs(ResumeAfterLocationReceived)中:

public async Task ResumeAfterLocationReceived(IDialogContext context, IAwaitable<String> result)
{
    if(result.Equals("no"))
    {
        await context.PostAsync(@"Sorry can't search");
        context.Wait(MessageReceived);
    }
    else
    {
        //added code here:
        var userSearchString = result.Text;
        Activity myActivity = new Activity();
        myActivity.Text = userSearchString ;
        await MessageReceived(context, Awaitable.FromItem(myActivity));
    }
}

秘诀是获取用户输入的文本,创建一个新活动,将文本添加到活动中,然后将其传递给 LUIS 对话框的 messageReceived 任务。

【讨论】:

  • 在我的回答here中添加了一些关于活动的更多细节@
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 1970-01-01
相关资源
最近更新 更多