Met onderdeeldialoogvensters kunt u onafhankelijke dialoogvensters maken voor het afhandelen van specifieke scenario's, waarbij een grote dialoogvensterset wordt opgesplitst in beheerbare onderdelen. Elk van deze onderdelen heeft een eigen dialoogvensterset en voorkomt naamconflicten met de dialoogvensters erbuiten. Dialoogvensters voor onderdelen kunnen opnieuw worden gebruikt:
Toegevoegd aan een andere ComponentDialog of DialogSet in uw bot.
Geëxporteerd als onderdeel van een pakket.
Wordt gebruikt in andere bots.
Notitie
De Sdk's voor Bot Framework JavaScript, C# en Python blijven ondersteund, maar de Java SDK wordt buiten gebruik gesteld met definitieve langetermijnondersteuning die eindigt op november 2023.
Bestaande bots die zijn gebouwd met de Java SDK blijven functioneren.
In het voorbeeld met meerdere prompts gebruiken we een watervaldialoogvenster, een paar prompts en een onderdeeldialoogvenster om een interactie te maken die de gebruiker een reeks vragen stelt. In de code wordt een dialoogvenster gebruikt om deze stappen te doorlopen:
Stappen
Type prompt
Vraag de gebruiker om hun transportmodus
Keuzeprompt
Vraag de gebruiker om zijn of haar naam
Tekstprompt
Vraag de gebruiker of ze hun leeftijd willen opgeven
Prompt bevestigen
Als ze ja hebben beantwoord, vraagt u om hun leeftijd
Nummerprompt met validatie om alleen leeftijden van meer dan 0 en minder dan 150 te accepteren.
Vraag of de verzamelde informatie 'ok' is
Prompt bevestigen opnieuw gebruiken
Ten slotte, als ze ja hebben beantwoord, geeft u de verzamelde informatie weer; laat de gebruiker anders weten dat de gegevens niet worden bewaard.
Dialoogvenster Uw onderdeel implementeren
In het voorbeeld met meerdere prompts gebruiken we een watervaldialoogvenster, een paar prompts en een onderdeeldialoogvenster om een interactie te maken die de gebruiker een reeks vragen stelt.
Een onderdeeldialoogvenster bevat een of meer dialoogvensters. Het onderdeeldialoogvenster bevat een interne dialoogvensterset en de dialoogvensters en aanwijzingen die u aan deze binnenste dialoogvensterset toevoegt, hebben hun eigen id's, die alleen zichtbaar zijn vanuit het onderdeeldialoogvenster.
Als u dialoogvensters wilt gebruiken, installeert u het NuGet-pakket Microsoft.Bot.Builder.Dialogs .
Dialoogvensters\UserProfileDialog.cs
Hier is de UserProfileDialog klasse afgeleid van de ComponentDialog klasse.
public class UserProfileDialog : ComponentDialog
Binnen de constructor voegt de AddDialog methode dialoogvensters en prompts toe aan het onderdeeldialoogvenster. Het eerste item dat u met deze methode toevoegt, wordt ingesteld als het eerste dialoogvenster. U kunt het eerste dialoogvenster wijzigen door de InitialDialogId eigenschap expliciet in te stellen. Wanneer u een dialoogvenster voor een onderdeel start, wordt het eerste dialoogvenster gestart.
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);
}
De volgende code vertegenwoordigt de eerste stap van het watervaldialoogvenster.
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);
}
Als u dialoogvensters wilt gebruiken, moet uw project het npm-pakket botbuilder-dialogs installeren.
dialoogvensters/userProfileDialog.js
Hier breidt de UserProfileDialog klasse zich uit ComponentDialog.
class UserProfileDialog extends ComponentDialog {
Binnen de constructor voegt de AddDialog methode dialoogvensters en prompts toe aan het onderdeeldialoogvenster. Het eerste item dat u met deze methode toevoegt, wordt ingesteld als het eerste dialoogvenster. U kunt het eerste dialoogvenster wijzigen door de InitialDialogId eigenschap expliciet in te stellen. Wanneer u een dialoogvenster voor een onderdeel start, wordt het eerste dialoogvenster gestart.
De volgende code vertegenwoordigt de eerste stap van het watervaldialoogvenster.
async transportStep(step) {
// WaterfallStep always finishes with the end of the Waterfall or with another dialog; here it is a Prompt Dialog.
// Running a prompt here means the next WaterfallStep will be run when the user's response is received.
return await step.prompt(CHOICE_PROMPT, {
prompt: 'Please enter your mode of transport.',
choices: ChoiceFactory.toChoices(['Car', 'Bus', 'Bicycle'])
});
}
Hier is de UserProfileDialog klasse afgeleid van de ComponentDialog klasse.
public class UserProfileDialog extends ComponentDialog {
Binnen de constructor voegt de addDialog methode dialoogvensters en prompts toe aan het onderdeeldialoogvenster. Het eerste item dat u met deze methode toevoegt, wordt ingesteld als het eerste dialoogvenster. U kunt het eerste dialoogvenster wijzigen door de setInitialDialogId methode aan te roepen en de naam van het eerste dialoogvenster op te geven. Wanneer u een dialoogvenster voor een onderdeel start, wordt het eerste dialoogvenster gestart.
public UserProfileDialog(UserState withUserState) {
super("UserProfileDialog");
userProfileAccessor = withUserState.createProperty("UserProfile");
WaterfallStep[] waterfallSteps = {
UserProfileDialog::transportStep,
UserProfileDialog::nameStep,
this::nameConfirmStep,
this::ageStep,
UserProfileDialog::pictureStep,
this::confirmStep,
this::summaryStep
};
// Add named dialogs to the DialogSet. These names are saved in the dialog state.
addDialog(new WaterfallDialog("WaterfallDialog", Arrays.asList(waterfallSteps)));
addDialog(new TextPrompt("TextPrompt"));
addDialog(new NumberPrompt<Integer>("NumberPrompt", UserProfileDialog::agePromptValidator, Integer.class));
addDialog(new ChoicePrompt("ChoicePrompt"));
addDialog(new ConfirmPrompt("ConfirmPrompt"));
addDialog(new AttachmentPrompt("AttachmentPrompt", UserProfileDialog::picturePromptValidator));
// The initial child Dialog to run.
setInitialDialogId("WaterfallDialog");
}
De volgende code vertegenwoordigt de eerste stap van het watervaldialoogvenster.
private static CompletableFuture<DialogTurnResult> nameStep(WaterfallStepContext stepContext) {
stepContext.getValues().put("transport", ((FoundChoice) stepContext.getResult()).getValue());
PromptOptions promptOptions = new PromptOptions();
promptOptions.setPrompt(MessageFactory.text("Please enter your name."));
return stepContext.prompt("TextPrompt", promptOptions);
}
Als u dialoogvensters wilt gebruiken, installeert u de botbuilder-dialogs en botbuilder-ai PyPI-pakketten door deze uit te voeren pip install botbuilder-dialogs en pip install botbuilder-ai vanuit een terminal.
dialoogvensters/user_profile_dialog.py
Hier breidt de UserProfileDialog klasse zich uit ComponentDialog.
class UserProfileDialog(ComponentDialog):
Binnen de constructor voegt de add_dialog methode dialoogvensters en prompts toe aan het onderdeeldialoogvenster. Het eerste item dat u met deze methode toevoegt, wordt ingesteld als het eerste dialoogvenster. U kunt het eerste dialoogvenster wijzigen door de initial_dialog_id eigenschap expliciet in te stellen. Wanneer u een dialoogvenster voor een onderdeel start, wordt het eerste dialoogvenster gestart.
De volgende code vertegenwoordigt de eerste stap van het watervaldialoogvenster.
async def transport_step(
self, step_context: WaterfallStepContext
) -> DialogTurnResult:
# WaterfallStep always finishes with the end of the Waterfall or with another dialog;
# here it is a Prompt Dialog. Running a prompt here means the next WaterfallStep will
# be run when the users response is received.
return await step_context.prompt(
ChoicePrompt.__name__,
PromptOptions(
prompt=MessageFactory.text("Please enter your mode of transport."),
choices=[Choice("Car"), Choice("Bus"), Choice("Bicycle")],
),
)
Tijdens de uitvoering onderhoudt het dialoogvenster van het onderdeel een eigen dialoogvensterstack. Wanneer het onderdeeldialoogvenster wordt gestart:
Er wordt een exemplaar gemaakt en toegevoegd aan de buitenste dialoogvensterstack
Er wordt een interne dialoogvensterstack gemaakt die wordt toegevoegd aan de status
Het eerste dialoogvenster wordt gestart en voegt dit toe aan de binnenste dialoogvensterstack.
De bovenliggende context ziet het onderdeel als het actieve dialoogvenster. Voor de context in het onderdeel ziet het er echter uit dat het eerste dialoogvenster het actieve dialoogvenster is.
Het dialoogvenster aanroepen vanuit uw bot
In de buitenste dialoogvensterset, de dialoogvenster waarmee u het onderdeeldialoogvenster hebt toegevoegd, heeft het onderdeeldialoogvenster de id waarmee u het hebt gemaakt. In de buitenste set ziet het onderdeel eruit als één dialoogvenster, net als bij prompts.
Als u een onderdeeldialoogvenster wilt gebruiken, voegt u er een exemplaar van toe aan de dialoogvensterset van de bot.
In het voorbeeld wordt dit gedaan met behulp van de RunAsync methode die wordt aangeroepen vanuit de methode van OnMessageActivityAsync de bot.
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);
}
dialoogvensters/userProfileDialog.js
In het voorbeeld hebben we een run methode toegevoegd aan het dialoogvenster gebruikersprofiel.
De run methode wordt aangeroepen vanuit de methode van onMessage de bot.
this.onMessage(async (context, next) => {
console.log('Running dialog with Message Activity.');
// Run the Dialog with the new message Activity.
await this.dialog.run(context, this.dialogState);
await next();
});
DialogBot.java
In het voorbeeld wordt dit gedaan met behulp van de run methode die wordt aangeroepen vanuit de methode van onMessageActivity de bot.
@Override
protected CompletableFuture<Void> onMessageActivity(
TurnContext turnContext
) {
LoggerFactory.getLogger(DialogBot.class).info("Running dialog with Message Activity.");
// Run the Dialog with the new message Activity.
return Dialog.run(dialog, turnContext, conversationState.createProperty("DialogState"));
}
helpers/dialog_helper.py
In het voorbeeld hebben we een run_dialog methode toegevoegd aan het dialoogvenster gebruikersprofiel.
Start de emulator, maak verbinding met uw bot en verzend berichten zoals hieronder wordt weergegeven.
Aanvullende informatie
Hoe annulering werkt voor onderdeeldialoogvensters
Als u alle dialoogvensters annuleert vanuit de context van het onderdeeldialoogvenster, worden alle dialoogvensters op de binnenste stack geannuleerd en wordt vervolgens het besturingselement geretourneerd naar het volgende dialoogvenster op de buitenste stack.
Als u alle dialoogvensters vanuit de buitenste context annuleert, wordt het onderdeel geannuleerd, samen met de rest van de dialoogvensters in de buitenste context.
Volgende stappen
Leer hoe u complexe gesprekken maakt die vertakking en lus vormen.