最佳实践是否总是在bot中启动对话框?

时间:2019-08-26 12:43:17

标签: c# dependency-injection botframework asp.net-core-2.1 luis

我正在将机器人V3迁移到V4,并且运行良好,但是该机器人有一些规则,并且在实施这些规则时遇到了一些困难。

其中一个规则会在致电Luis之后启动对话框,因为Luis意识到了这一需求。

我的疑问是:机器人最佳实践是什么?总是启动对话框还是仅在必要时启动?

PS:在我看来,如有必要,我必须重新开始,但我对此表示怀疑。

if (Luis.CheckDialogNeed)
{
   await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken)
}

如果答案是在必要时启动对话框,那么如何在对话框类之外获取对话框的文本。例如,在机器人课程中?

1 个答案:

答案 0 :(得分:0)

对话框是使用对话框上下文启动,继续和结束的,该上下文是转弯上下文和对话框设置的组合。通过对话框状态属性访问器创建一个对话框集。请熟悉dialogs文档。我想在使用机器人状态和创建属性访问器时,您对this会特别感兴趣。 This还包含一些使用对话框的代码示例。

就像我说过的那样,当前Bot Builder samples中的大多数都是以这样一种方式构建的,即所有机器人逻辑都可以在对话框中执行。从一个对话框中开始一个新对话框很容易,因为新对话框刚刚被添加到对话框堆栈中。如果您使用的是组件对话框,则甚至可以在对话框中包含对话框。

旧样本和模板的工作方式略有不同。 Bot状态对象(如对话状态和用户状态)使用依赖项注入传递给bot类,并且这些bot状态对象用于创建状态属性访问器,然后创建对话框集。然后,bot类将在其OnTurnAsync处理程序中创建一个对话框上下文,并尝试继续当前对话框或开始一个新对话框,或者仅发送一个单向消息,具体取决于对话框堆栈和传入消息。您可以在git repo中检出较早的提交以查看实际操作,也可以检出新的active learning sample,因为尚未进行更新以匹配其他示例的模式。机器人的构造函数如下:

public ActiveLearningBot(ConversationState conversationState, UserState userState, IBotServices botServices)
{
    botServices = botServices ?? throw new ArgumentNullException(nameof(botServices));
    if (botServices.QnAMakerService == null)
    {
        throw new ArgumentException($"Invalid configuration. Please check your '.bot' file for a QnA service.");
    }

    ConversationState = conversationState;
    UserState = userState;

    // QnA Maker dialog options
    QnaMakerOptions = new QnAMakerOptions
    {
        Top = 3,
        ScoreThreshold = 0.03F,
    };

    _dialogs = new DialogSet(ConversationState.CreateProperty<DialogState>(nameof(DialogState)));

    _dialogHelper = new DialogHelper(botServices);

    _dialogs.Add(_dialogHelper.QnAMakerActiveLearningDialog);
}

这是OnTurnAsync中的相关代码:

var dialogContext = await _dialogs.CreateContextAsync(turnContext, cancellationToken);
var results = await dialogContext.ContinueDialogAsync(cancellationToken);
switch (results.Status)
{
    case DialogTurnStatus.Cancelled:
    case DialogTurnStatus.Empty:
        await dialogContext.BeginDialogAsync(_dialogHelper.ActiveLearningDialogName, QnaMakerOptions, cancellationToken);
        break;
    case DialogTurnStatus.Complete:
        break;
    case DialogTurnStatus.Waiting:
        // If there is an active dialog, we don't need to do anything here.
        break;
}

// Save any state changes that might have occured during the turn.
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken);