如何留在机器人对话框中(机器人框架,C#)

时间:2021-05-27 19:39:04

标签: c# asp.net azure botframework chatbot

我目前计划在我的 C# 机器人中使用对话框。我已经设计了一个 完成对话框并将其实现到我当前的解决方案中,但是当我对其进行测试时,我只能触发它的第一部分。

我的机器人配置如下:

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    string[] PostCodeDialogStartTrigger = new string[] { "trigger1", "trigger2", "trigger3" };
    if (PostCodeDialogStartTrigger.Contains(turnContext.Activity.Text) /* Maybe || ConversationState != null */)
    {
        await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
    }
    else
    {
        // First, we use the dispatch model to determine which cognitive service (LUIS or QnA) to use.
        var recognizerResult = await BotServices.Dispatch.RecognizeAsync(turnContext, cancellationToken);

        // Top intent tell us which cognitive service to use.
        var topIntent = recognizerResult.GetTopScoringIntent();

        // Next, we call the dispatcher with the top intent.
        await DispatchToTopIntentAsync(turnContext, topIntent.intent, recognizerResult, cancellationToken);
    }
}

我在 PostCodeDialogStartTrigger 中有一组字符串。我希望对话框在用户消息与触发器之一匹配时启动。否则我的常规流程应该开始,其中包括用于一维对话的 LUIS 和 QnA Maker。问题是我不能留在对话框中,因为下一条消息显然不会再次触发对话框。

有没有办法检查 ConversationState 或 UserState,如果它已经取得进展,对话会继续吗?

1 个答案:

答案 0 :(得分:1)

你想要的是中断https://docs.microsoft.com/azure/bot-service/bot-builder-howto-handle-user-interrupt

核心机器人示例通过创建一个使任何对话“可中断”的基本 CancelAndHelpDialog 类,包括一种处理中断的稍微复杂的方法,但有一种更简单的方法。关键是默认每回合都调用ContinueDialogAsync,只有在该回合发生中断时才调用它。您可以将每个回合视为三种情况:

  1. 发生中断
  2. 没有中断,但有一个活跃的对话
  3. 没有中断,也没有活动对话

逻辑可能是这样的:

string[] PostCodeDialogStartTrigger = new string[] { "trigger1", "trigger2", "trigger3" };

if (PostCodeDialogStartTrigger.Contains(turnContext.Activity.Text))
{
    // Case 1: Handle interruptions by starting a dialog
    await dialogContext.BeginDialogAsync(DIALOG_ID);
}
else
{
    // Case 2: Try to continue the dialog in case there is one
    var result = await dialogContext.ContinueDialogAsync();

    if (result.Status == DialogTurnStatus.Empty)
    {
        // Case 3: If there aren't any dialogs on the stack

        // First, we use the dispatch model to determine
        // which cognitive service (LUIS or QnA) to use.
        // . . .
    }
}

您可能会注意到我在这里没有使用 RunAsyncRunAsync 与您的机器人的“主对话框”配合使用时效果最好,它意味着始终在堆栈中,如果您没有真正的主对话框,它就不会那么好用。 RunAsync 的最初目的是将几个方法调用合并为一个,因为机器人调用 ContinueDialogAsync 然后检查结果然后启动主对话框是一种常见的模式,如果对话框堆栈是空的。您想做类似的事情,但不是在对话堆栈为空的情况下开始主对话,而是只想调用 dispatch。

如果您好奇,这里有一些其他 Stack Overflow 帖子,您可以在其中阅读有关中断的信息:

我应该提到您正在尝试以一种过时的方式做事。您可能已经注意到 Dispatch 已被 Orchestrator 取代,因此您确实应该改用 Orchestrator。此外,Composer 还简化了诸如中断之类的操作,无论如何,建议每个人现在都使用 Composer。