ダイアログの複雑さを管理するManage dialog complexity

適用対象: SDK v4APPLIES TO: SDK v4

コンポーネント ダイアログを使用すると、大規模なダイアログ セットをより管理しやすい要素に分割して、特定のシナリオを処理する独立したダイアログを作成できます。With component dialogs, you can create independent dialogs to handle specific scenarios, breaking a large dialog set into more manageable pieces. 各要素には独自のダイアログ セットがあり、その要素外にあるダイアログ セットとの名前の競合を回避しています。Each of these pieces has its own dialog set, and avoids any name collisions with the dialog sets outside of it. コンポーネント ダイアログは、次のことができるという点で再利用可能です。Component dialogs are reusable in that they can be:

  • ボット内の別の ComponentDialog または DialogSet へ追加。Added to another ComponentDialog or DialogSet in your bot.
  • パッケージの一部としてエクスポート。Exported as a part of a package.
  • 他のボット内で使用。Used within other bots.

前提条件Prerequisites

サンプルについてAbout the sample

マルチターン プロンプト サンプルでは、ウォーターフォール ダイアログ、いくつかのプロンプト、およびコンポーネント ダイアログを使用して、ユーザーに一連の質問を行う単純なインタラクションを作成します。In the multi-turn prompt sample, we use a waterfall dialog, a few prompts, and a component dialog to create a simple interaction that asks the user a series of questions. コードはダイアログを使用して、これらの手順を順番に切り替えます。The code uses a dialog to cycle through these steps:

手順Steps プロンプトの種類Prompt type
移動手段をユーザーに聞きますAsk the user for their mode of transportation 選択プロンプトChoice prompt
名前をユーザーに聞きますAsk the user for their name テキスト プロンプトText prompt
年齢を指定するかどうかをユーザーに聞きますAsk the user if they want to provide their age 確認プロンプトConfirm prompt
"はい" と回答した場合は、年齢を聞きますIf they answered yes, asks for their age 数値プロンプト。数値を検証し、0 より大きく 150 未満の場合のみ受け入れます。Number prompt with validation to only accept ages greater than 0 and less than 150.
収集された情報が正しいかどうかを聞きますAsks if the collected information is "ok" 再利用確認プロンプトReuse Confirm prompt

最後に、"はい" と答えたら、収集された情報を表示します。それ以外の場合は、ユーザー情報が保持されないことをユーザーに通知します。Finally, if they answered yes, display the collected information; otherwise, tell the user that their information will not be kept.

コンポーネント ダイアログを実装するImplement the component dialog

マルチターン プロンプト サンプルでは、ウォーターフォール ダイアログ、いくつかの プロンプト、および コンポーネント ダイアログ を使用して、ユーザーに一連の質問を行う単純なインタラクションを作成します。In the multi-turn prompt sample, we use a waterfall dialog, a few prompts, and a component dialog to create a simple interaction that asks the user a series of questions.

コンポーネント ダイアログによって 1 つ以上のダイアログがカプセル化されます。A component dialog encapsulates one or more dialogs. コンポーネント ダイアログには内部ダイアログ セットがあり、この内部ダイアログ セットに追加したダイアログとプロンプトは独自の ID を持っています。これらの ID は、コンポーネント ダイアログ内からのみ表示できます。The component dialog has an inner dialog set, and the dialogs and prompts that you add to this inner dialog set have their own IDs, visible only from within the component dialog.

ダイアログを使用するには、Microsoft.Bot.Builder.Dialogs NuGet パッケージをインストールします。To use dialogs, install the Microsoft.Bot.Builder.Dialogs NuGet package.

Dialogs\UserProfileDialog.csDialogs\UserProfileDialog.cs

ここでは UserProfileDialog クラスは、ComponentDialog クラスから派生しています。Here the UserProfileDialog class derives from the ComponentDialog class.

public class UserProfileDialog : ComponentDialog

コンストラクター内で、AddDialog メソッドによって、ダイアログとプロンプトがコンポーネント ダイアログに追加されます。Within the constructor, the AddDialog method adds dialogs and prompts to the component dialog. このメソッドを使用して追加した最初の項目が初期ダイアログとして設定されますが、これは、InitialDialogId プロパティを明示的に設定することで変更できます。The first item you add with this method is set as the initial dialog, but you can change this by explicitly setting the InitialDialogId property. コンポーネント ダイアログを開始すると、その initial dialog が開始されます。When you start a component dialog, it will start its initial dialog.

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,
        ConfirmStepAsync,
        SummaryStepAsync,
    };

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

これは、ウォーターフォール ダイアログの最初のステップの実装です。This is the implementation of the first step of the waterfall dialog.

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

ウォーターフォール ダイアログの実装の詳細については、連続して行われる会話フローを実装する方法をご覧ください。For more information on implementing waterfall dialogs, see how to implement sequential conversation flow.

実行時、コンポーネント ダイアログに独自のダイアログ スタックが保持されます。At run-time, the component dialog maintains its own dialog stack. コンポーネント ダイアログが開始すると、以下が行われます。When the component dialog is started:

  • インスタンスが作成され、外部ダイアログ スタックに追加されますAn instance is created and added to the outer dialog stack
  • 内部ダイアログ スタックが作成され、その状態が追加されますIt creates an inner dialog stack that it adds to its state
  • 初期ダイアログが開始され、内部ダイアログ スタックに追加されます。It starts its initial dialog and adds that to the inner dialog stack.

親コンテキストからは、コンポーネントがアクティブなダイアログのように見えます。From the parent context, it will look like the component is the active dialog. コンポーネント内からは、初期ダイアログがアクティブなダイアログのように見えます。From inside the component, it will look like the initial dialog is the active dialog.

ダイアログの残りの部分を実装し、ボットに追加するImplement the rest of the dialog and add it to the bot

コンポーネント ダイアログの追加先の外部ダイアログ セットでは、コンポーネント ダイアログの ID は、それを作成したときに使用したものです。In the outer dialog set, the one to which you add the component dialog, the component dialog has the ID that you created it with. 外部セットでは、コンポーネントは 1 つのダイアログのように見えます。これはプロンプトの動作と似ています。In the outer set, the component looks like a single dialog, much like prompts do.

コンポーネント ダイアログを使用するには、そのインスタンスをボットのダイアログ セットに追加します。これが外部ダイアログ セットです。To use a component dialog, add an instance of it to the bot's dialog set - this is the outer dialog set.

Bots\DialogBot.csBots\DialogBot.cs

サンプルでは、これはボットの OnMessageActivityAsync メソッドから呼び出される RunAsync メソッドを使用して行います。In the sample, this is done using the RunAsync method that is called from the bot's OnMessageActivityAsync method.

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

ボットをテストするTo test the bot

  1. Bot Framework Emulator をインストールします (まだインストールしていない場合)。If you have not done so already, install the Bot Framework Emulator.
  2. ご自身のマシンを使ってローカルでサンプルを実行します。Run the sample locally on your machine.
  3. 以下に示すように、エミュレーターを起動し、お使いのボットに接続して、メッセージを送信します。Start the Emulator, connect to your bot, and send messages as shown below.

マルチターン プロンプト ダイアログの実行サンプル

関連情報Additional information

コンポーネント ダイアログのキャンセルのしくみHow cancellation works for component dialogs

コンポーネント ダイアログのコンテキストから cancel all dialogs を呼び出すと、コンポーネント ダイアログによって、その内部スタックのすべてのダイアログがキャンセルされた後、終了します。そして外部スタックの次のダイアログに制御が戻ります。If you call cancel all dialogs from the component dialog's context, the component dialog will cancel all of the dialogs on its inner stack and then end, returning control to the next dialog on the outer stack.

外部コンテキストから cancel all dialogs を呼び出すと、コンポーネントは、外部コンテキストの残りのダイアログとともにがキャンセルされます。If you call cancel all dialogs from the outer context, the component is cancelled, along with the rest of the dialogs on the outer context.

ボットで入れ子になったコンポーネント ダイアログを管理するときは、この点に注意してください。Keep this in mind when managing nested component dialogs in your bot.

次のステップNext steps

分岐とループを行う複雑な会話を作成する方法について説明します。Learn how to create complex conversations that branch and loop.