如何在 LUIS 对话框中调用 LUIS 对话框?

How to call LUIS Dialog inside LUIS Dialog?

我的机器人有带有几个意图的 LUIS 对话。我从 MessageController 调用 LUIS 对话框。如果检测到意图,我将启动一个子对话。子对话框完成后,我调用 context.Done("response from user"). 之后调用 ChlildDialogDone 任务。

ChildDialogDone 任务中我想再次调用 LUIS 对话框来检测用户消息的意图(到达 ChildDialogDone )。现在在 ChildDialogDone 我有 context.Wait(MessageReceived). 执行这行代码时,没有任何反应,我的机器人正在等待来自用户的下一条消息。

代码如下:

    [Serializable]
        public partial class DefiningIntentDialog : LuisDialog<object>
        {

            [LuisIntent("")]
            public async Task NoIntent(IDialogContext context, LuisResult result)
            {        
                var dialog = new GreetingsDialog();
                dialog.InitialMessage = result.Query;
                context.Call(dialog, GreetingDialogDone);      
            }

            [LuisIntent("Email")]
            public virtual async Task ConfirmationEmail(IDialogContext context, LuisResult result)
            {
                await context.Forward(new EmailDialog, EmailDialogDone, "message", CancellationToken.None);
            }

            private async Task EmailDialogDone(IDialogContext context, IAwaitable<string> argument)
            {
                var messageHandled = await argument;

                context.Wait(MessageReceived);
            }
      }

因此在 EmailDialogDone 中,我收到了一些来自用户的消息,我想再次使用此消息执行 DefiningIntent 对话框。我该怎么做?

您可以重复 LUIS 对话框的 MessegaReceived 上的逻辑,以实现您想要执行的操作。基本上,这段代码应该非常符合您的需要:

var tasks = this.services.Select(s => s.QueryAsync(messageHandled, CancellationToken.None)).ToArray();
var winner = this.BestResultFrom(await Task.WhenAll(tasks));

IntentActivityHandler handler = null;
if (winner == null || !this.handlerByIntent.TryGetValue(winner.BestIntent.Intent, out handler))
{
    handler = this.handlerByIntent[string.Empty];
}

if (handler != null)
{
    await handler(context, null, winner?.Result);
}

引用 "this" 的代码片段是您继承自的 LUIS 对话框的一部分。

  • 服务,是基于您的 LuisModel 属性实例化的 LuisServices 的集合。
  • IntentActivityHandler 是 LuisIntent 装饰方法 "implementing" 与方法签名的处理程序。
  • handlerbyIntent 是一个字典,键是对话的意图名称,处理程序是需要为该意图调用的方法。

查看 this 了解更多详情,并确保您使用的是最新版本的 BotBuilder SDK(目前 post:v3.2.1)

无需从 MessegaReceived 复制逻辑。 您可以直接调用 MessegaReceived:

private async Task EmailDialogDone(IDialogContext context, IAwaitable<string> argument)
{
   await MessageReceived(context, new AwaitableFromItem<IMessageActivity>((IMessageActivity)context.Activity));
}