Mit Komponentendialogen können Sie unabhängige Dialoge für bestimmte Szenarien erstellen, indem ein umfangreicher Dialogsatz in besser verwaltbare Teile unterteilt wird. Jeder dieser Teile verfügt über einen eigenen Dialogsatz, wodurch Namenskonflikte mit anderen Dialogsätzen vermieden werden. Komponentendialoge können wie folgt wiederverwendet werden:
Sie können in Ihrem Bot einem anderen ComponentDialog- oder DialogSet-Element hinzugefügt werden.
Sie können als Teil eines Pakets exportiert werden.
Sie können in anderen Bots verwendet werden.
Hinweis
Die JavaScript-, C#- und Python-SDKs für Bot Framework werden weiterhin unterstützt, das Java-SDK wird jedoch eingestellt und der langfristige Support endet im November 2023.
Bestehende Bots, die mit dem Java SDK erstellt wurden, werden weiterhin funktionieren.
Sie benötigen eine Kopie des Beispiels für Eingabeaufforderungen mit mehreren Durchläufen in C#, JavaScript, Java oder Python.
Über das Beispiel
In diesem Beispiel für Eingabeaufforderungen mit mehreren Turns verwenden wir einen Wasserfalldialog, einige Eingabeaufforderungen und einen Komponentendialog, um eine Interaktion zu erstellen, bei der dem Benutzer eine Reihe von Fragen gestellt wird. Der Code durchläuft die folgenden Schritte in Form eines Dialogs:
Schritte
Art der Eingabeaufforderung
Transportmittel des Benutzers erfragen
Auswahleingabeaufforderung
Name des Benutzers erfragen
Texteingabeaufforderung
Benutzer fragen, ob er sein Alter angeben möchte
Bestätigungseingabeaufforderung
Falls ja, Alter des Benutzers erfragen
Zahleneingabeaufforderung mit Überprüfung, damit nur Altersangaben zwischen Null und 150 (jeweils ausschließlich) akzeptiert werden.
Fragen, ob die erfassten Informationen korrekt sind
Erneute Bestätigungseingabeaufforderung
Falls ja, werden die erfassten Informationen angezeigt. Falls nicht, wird dem Benutzer mitgeteilt, dass seine Informationen nicht gespeichert werden.
Komponentendialog implementieren
In diesem Beispiel für Eingabeaufforderungen mit mehreren Turns verwenden wir einen Wasserfalldialog, einige Eingabeaufforderungen und einen Komponentendialog, um eine Interaktion zu erstellen, bei der dem Benutzer eine Reihe von Fragen gestellt wird.
Ein Komponentendialog umfasst einen oder mehrere Dialoge. Der Komponentendialog verfügt über einen inneren Dialogsatz, und die Dialoge und Eingabeaufforderungen, die Sie diesem inneren Dialogsatz hinzufügen, haben ihre eigenen IDs, die nur über den Komponentendialog sichtbar sind.
Installieren Sie das NuGet-Paket Microsoft.Bot.Builder.Dialogs, um Dialoge verwenden zu können.
Dialogs\UserProfileDialog.cs
Hier wird die UserProfileDialog-Klasse von der ComponentDialog-Klasse abgeleitet.
public class UserProfileDialog : ComponentDialog
Innerhalb des Konstruktors werden dem Komponentendialog mit der AddDialog-Methode Dialoge und Eingabeaufforderungen hinzugefügt. Das erste Element, das Sie mit dieser Methode hinzufügen, wird als erster Dialog festgelegt. Sie können den anfänglichen Dialog ändern, indem Sie die InitialDialogId-Eigenschaft explizit festlegen. Wenn Sie einen Komponentendialog starten, wird sein erster Dialog gestartet.
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);
}
Der folgende Code stellt den ersten Schritt des Wasserfalldialogs dar.
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);
}
In Ihrem Projekt muss das npm-Paket botbuilder-dialogs installiert werden, damit Dialoge verwendet werden können.
dialogs/userProfileDialog.js
Hier wird ComponentDialog mit der UserProfileDialog-Klasse erweitert.
class UserProfileDialog extends ComponentDialog {
Innerhalb des Konstruktors werden dem Komponentendialog mit der AddDialog-Methode Dialoge und Eingabeaufforderungen hinzugefügt. Das erste Element, das Sie mit dieser Methode hinzufügen, wird als erster Dialog festgelegt. Sie können den anfänglichen Dialog ändern, indem Sie die InitialDialogId-Eigenschaft explizit festlegen. Wenn Sie einen Komponentendialog starten, wird sein erster Dialog gestartet.
Der folgende Code stellt den ersten Schritt des Wasserfalldialogs dar.
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 wird die UserProfileDialog-Klasse von der ComponentDialog-Klasse abgeleitet.
public class UserProfileDialog extends ComponentDialog {
Innerhalb des Konstruktors werden dem Komponentendialog mit der addDialog-Methode Dialoge und Eingabeaufforderungen hinzugefügt. Das erste Element, das Sie mit dieser Methode hinzufügen, wird als erster Dialog festgelegt. Sie können den anfänglichen Dialog ändern, indem Sie die setInitialDialogId-Methode aufrufen und den Namen des anfänglichen Dialogs angeben. Wenn Sie einen Komponentendialog starten, wird sein erster Dialog gestartet.
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");
}
Der folgende Code stellt den ersten Schritt des Wasserfalldialogs dar.
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);
}
Um Dialoge zu verwenden, installieren Sie die PyPI-Pakete botbuilder-dialogs und botbuilder-ai, indem Sie über ein Terminal pip install botbuilder-dialogs und pip install botbuilder-ai ausführen.
dialogs/user_profile_dialog.py
Hier wird ComponentDialog mit der UserProfileDialog-Klasse erweitert.
class UserProfileDialog(ComponentDialog):
Innerhalb des Konstruktors werden dem Komponentendialog mit der add_dialog-Methode Dialoge und Eingabeaufforderungen hinzugefügt. Das erste Element, das Sie mit dieser Methode hinzufügen, wird als erster Dialog festgelegt. Sie können den anfänglichen Dialog ändern, indem Sie die initial_dialog_id-Eigenschaft explizit festlegen. Wenn Sie einen Komponentendialog starten, wird sein erster Dialog gestartet.
Der folgende Code stellt den ersten Schritt des Wasserfalldialogs dar.
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")],
),
)
Zur Laufzeit wird im Komponentendialog ein eigener Dialogstapel verwaltet. Wenn der Komponentendialog gestartet wird, wird Folgendes durchgeführt:
Eine Instanz wird erstellt und dem äußeren Dialogstapel hinzugefügt.
Es wird ein innerer Dialogstapel erstellt, der dem Zustand hinzugefügt wird.
Der erste Dialog wird gestartet und dem inneren Dialogstapel hinzugefügt.
Der übergeordnete Kontext sieht die Komponente als aktiven Dialog. Für den Kontext innerhalb der Komponente sieht es jedoch so aus, als sei der erste Dialog der aktive Dialog.
Rufen Sie den Dialog von Ihrem Bot aus auf
Im äußeren Dialogsatz (der Dialogsatz, dem Sie den Komponentendialog hinzufügen) verfügt der Komponentendialog über die ID, die Sie für die Erstellung verwendet haben. Im äußeren Satz sieht die Komponente wie ein einzelner Dialog aus (ähnlich wie bei Eingabeaufforderungen).
Um einen Komponentendialog zu verwenden, müssen Sie eine Instance davon dem Dialogsatz des Bots hinzufügen.
Im Beispiel erfolgt dies mit der RunAsync-Methode, die von der OnMessageActivityAsync-Methode des Bots aufgerufen wird.
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);
}
dialogs/userProfileDialog.js
In diesem Beispiel haben wir dem Benutzerprofildialog eine run-Methode hinzugefügt.
Die run-Methode wird über die onMessage-Methode des Bots aufgerufen.
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
Im Beispiel erfolgt dies mit der run-Methode, die von der onMessageActivity-Methode des Bots aufgerufen wird.
@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 diesem Beispiel haben wir dem Benutzerprofildialog eine run_dialog-Methode hinzugefügt.
Führen Sie das Beispiel lokal auf Ihrem Computer aus.
Starten Sie den Emulator, stellen Sie eine Verbindung mit Ihrem Bot her, und senden Sie Nachrichten wie unten dargestellt.
Weitere Informationen
Funktionsweise des Abbruchs für Komponentendialoge
Wenn Sie im Kontext des Komponentendialogs cancel all dialogs aufrufen, bricht der Komponentendialog alle Dialoge seines inneren Stapels ab und wird anschließend beendet. Die Steuerung wird dann wieder an den nächsten Dialog des äußeren Stapels übergeben.
Wenn Sie cancel all dialogs über den äußeren Kontext aufrufen, wird die Komponente genauso wie die restlichen Dialoge des äußeren Kontexts abgebrochen.
Nächste Schritte
Informieren Sie sich darüber, wie Sie komplexe Konversationen mit Verzweigungen und Schleifen erstellen.