最好的做法总是在机器人中开始对话吗?

Is the best practice alwayas to start a dialog in bot?

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

这些规则之一在调用 Luis 后启动对话,在此 Luis 认识到需要。

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

PS:在我看来,必要的时候我必须开始,但我有疑问。

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

如果答案是在必要时启动对话框,如何在对话框外获取对话框的文本class。例如,在 bot class?

Dialogs 使用 dialog context 开始、继续和结束,它是 turn context 和 对话集。对话集是从 dialog state 属性 访问器创建的。请熟悉 dialogs documentation. I think you'll be particularly interested in this when it comes to using bot state and creating property accessors. This 还包含一些使用对话框的代码示例。

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

旧示例和模板的工作方式略有不同。机器人状态对象(如对话状态和用户状态)使用依赖注入传递给机器人 class,这些机器人状态对象用于创建状态 属性 访问器,然后是对话集。然后,机器人 class 将在其 OnTurnAsync 处理程序中创建一个对话上下文,并尝试继续当前对话或开始一个新的对话,或者根据对话堆栈和传入消息仅发送一个回合的消息.您可以查看 git 存储库中的旧提交以查看实际效果,或者您可以查看新的 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);