【问题标题】:Is the best practice alwayas to start a dialog in bot?最好的做法总是在机器人中开始对话吗?
【发布时间】:2019-12-30 15:49:53
【问题描述】:

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

其中一个规则在调用 Luis 后开始对话,在此 Luis 认识到需要。

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

PS:在我看来,如果有必要我必须开始,但我有疑问。

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

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

【问题讨论】:

  • 虽然当前的 Bot Builder 示例严重倾向于始终使用对话框,但 v4 SDK 使您可以轻松选择何时使用对话框,甚至可以让机器人不使用任何对话框一点也不。你能通过在对话类之外获取对话文本来解释你的意思吗?你说的是对话框发送给用户的文本还是对话框从用户那里收到的文本?
  • 嗨@KyleDelaney,我说的是从用户那里收到的文本。你能解释一下当对话框不在启动类时如何启动对话框吗?

标签: c# dependency-injection botframework asp.net-core-2.1 azure-language-understanding


【解决方案1】:

对话使用对话上下文开始、继续和结束,这是一个回合上下文和对话集的组合。对话框集是从 对话框状态 属性访问器创建的。请熟悉dialogs 文档。当谈到使用机器人状态和创建属性访问器时,我认为您会对this 特别感兴趣。 This 还包含一些使用对话框的代码示例。

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

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

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);

【讨论】:

  • 谢谢。这正是我要找的!
猜你喜欢
  • 1970-01-01
  • 2015-11-27
  • 1970-01-01
  • 2016-11-07
  • 2011-07-19
  • 2011-09-26
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
相关资源
最近更新 更多