管理对话复杂性

适用于:SDK v4

可以通过组件对话创建独立的对话来处理特定的方案,将大型对话集分解成更易于管理的片段。 其中的每个片段有自身的对话集,可避免与其外的对话集发生名称冲突。 组件对话可重复使用,因为它们可以:

  • 已添加到您的机器人中的另一个 ComponentDialogDialogSet
  • 作为软件包的一部分导出。
  • 在其他机器人中使用。

重要

Bot Framework SDK 和 Bot Framework Emulator 已在 GitHub 上存档。 项目不再更新或维护。 自 2025 年 12 月 31 日起,Bot Framework SDK 的支持票证将不再提供服务。

若要使用所选的 AI 服务、业务流程和知识生成代理,请考虑使用 Microsoft 365 代理 SDK。 代理 SDK 对 C#、JavaScript 或 Python 具有语言支持。 可以在 aka.ms/agents 了解有关代理 SDK 的详细信息。 如果现有的机器人是使用 Bot Framework SDK 生成的,则可以将机器人更新到代理 SDK。 查看 Bot Framework SDK 到代理 SDK 迁移指南的核心更改和更新。

如果要构建设计为在 Microsoft Teams 中工作的协作代理,请考虑使用 Teams SDK。 它为在 Teams 环境中运行的代理提供 Teams 特定的 API、自适应卡支持和内置 AI 协同调度功能。 可以在 Teams SDK(Teams AI 库)中了解详细信息。

如果要查找基于 SaaS 的代理平台,请考虑 Microsoft Copilot Studio

先决条件

关于本示例

在多轮次提示示例中,我们将使用一个瀑布对话、几个提示和一个组件对话来创建交互,向用户提出一系列问题。 代码使用对话来循环执行以下步骤:

步骤 提示类型
请求用户提供其交通方式 选择提示
请求用户输入其姓名 文本提示
询问用户是否愿意提供其年龄 确认提示
如果他们回答“是”,则请求他们提供年龄 带有验证的数字提示,仅接受大于 0 且小于 150 的年龄输入。
询问收集的信息是否“正确” 重复使用确认提示

最后,如果用户回答“是”,则显示收集的信息;否则,告知用户他们的信息不会保留。

实现你的组件对话框

在多轮次提示示例中,我们将使用一个瀑布对话、几个提示和一个组件对话来创建交互,向用户提出一系列问题。

组件对话可封装一个或多个对话。 组件对话有一个内部对话集,而添加到此内部对话集的对话和提示有其自己的 ID,这些 ID 只能在组件对话内部查看。

若要使用对话,请安装 Microsoft.Bot.Builder.Dialogs NuGet 包。

Dialogs\UserProfileDialog.cs

在这里,UserProfileDialog 类派生自 ComponentDialog 类。

public class UserProfileDialog : ComponentDialog

在构造函数中,AddDialog 方法会将对话和提示添加到组件对话。 使用此方法添加的第一项设置为初始对话。 可以通过显式设置 InitialDialogId 属性来更改初始对话。 启动组件对话框时,它会启动其 初始对话框

public UserProfileDialog(UserState userState)
    : base(nameof(UserProfileDialog))
{
    _userProfileAccessor = userState.CreateProperty<UserProfile>("UserProfile");

    // This array defines how the Waterfall will execute.
    var waterfallSteps = new WaterfallStep[]
    {
        TransportStepAsync,
        NameStepAsync,
        NameConfirmStepAsync,
        AgeStepAsync,
        PictureStepAsync,
        SummaryStepAsync,
        ConfirmStepAsync,
    };

    // Add named dialogs to the DialogSet. These names are saved in the dialog state.
    AddDialog(new WaterfallDialog(nameof(WaterfallDialog), waterfallSteps));
    AddDialog(new TextPrompt(nameof(TextPrompt)));
    AddDialog(new NumberPrompt<int>(nameof(NumberPrompt<int>), AgePromptValidatorAsync));
    AddDialog(new ChoicePrompt(nameof(ChoicePrompt)));
    AddDialog(new ConfirmPrompt(nameof(ConfirmPrompt)));
    AddDialog(new AttachmentPrompt(nameof(AttachmentPrompt), PicturePromptValidatorAsync));

    // The initial child Dialog to run.
    InitialDialogId = nameof(WaterfallDialog);
}

以下代码表示瀑布对话的第一步。

private static async Task<DialogTurnResult> NameStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    stepContext.Values["transport"] = ((FoundChoice)stepContext.Result).Value;

    return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Please enter your name.") }, cancellationToken);
}

若要详细了解如何实现瀑布对话,请参阅如何实现顺序聊天流

在运行时,组件对话保留其自己的对话堆栈。 启动组件对话时:

  • 会创建一个实例并将其添加到外部对话堆栈
  • 它会创建一个内部对话框堆栈,并将其加入自身状态中
  • 它会启动初始对话并将其添加到内部对话堆栈。

父上下文将组件视为活动对话。 但是,从组件内部的上下文来看,初始对话框似乎就是当前活动的对话框。

从你的机器人中调用对话框

在外层对话集中,即你向其中添加了组件对话的那个对话集,组件对话具有你在创建它时使用的 ID。 在外层集合中,该组件看起来像一个单独的对话框,就像提示框一样。

若要使用组件对话,请将该组件对话的实例添加到机器人的对话集中。

Bots\DialogBot.cs

在该示例中,这是通过从机器人的 OnMessageActivityAsync 方法中调用的 RunAsync 方法完成的。

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    Logger.LogInformation("Running dialog with Message Activity.");

    // Run the Dialog with the new message Activity.
    await Dialog.RunAsync(turnContext, ConversationState.CreateProperty<DialogState>(nameof(DialogState)), cancellationToken);
}

测试你的机器人

  1. 安装 Bot Framework Emulator(如果尚未安装)。

  2. 在计算机本地运行示例。

  3. 按如下所示启动 Emulator,连接到机器人,然后发送消息。

多轮提示词对话的示例文本记录。

其他信息

组件对话框的取消机制如何工作

如果从组件对话的上下文调用“取消所有对话”,组件对话会取消其内部堆栈上的所有对话,然后结束,将控制返回给外部堆栈上的下一对话。

如果从外部上下文调用“取消所有对话”,则会取消该组件以及外部上下文中的其余对话。

后续步骤

了解如何创建支持分支和循环的复杂对话。