Avec les dialogues composants, vous pouvez créer des dialogues indépendants pour gérer des scénarios spécifiques, en divisant un jeu de dialogues en éléments plus petits et donc plus faciles à gérer. Chacun de ces éléments a son propre jeu de dialogues, ce qui permet d’éviter toute collision de nom avec les jeux de dialogues externes. Les dialogues composants sont réutilisables dans la mesure où ils peuvent être :
Ajoutés à un autre ComponentDialog ou DialogSet dans votre bot.
Exportés dans le cadre d’un package.
Utilisés dans d’autres bots.
Remarque
Les kits SDK JavaScript, C# et Python Bot Framework continueront d’être pris en charge. Toutefois, le kit de développement logiciel (SDK) Java est mis hors service avec une prise en charge finale à long terme se terminant en novembre 2023.
Les bots existants créés avec le kit de développement logiciel (SDK) Java continueront de fonctionner.
Dans l'échantillon d'invite multitour, nous utilisons un dialogue en cascade, quelques invites et un dialogue de composant pour créer une interaction qui pose à l'utilisateur une série de questions. Le code utilise un dialogue pour suivre ces étapes :
Étapes
Type d’invite
Demander à l’utilisateur son mode de transport
Invite de choix
Demander son nom à l’utilisateur
Invite de texte
Demander à l’utilisateur s’il souhaite indiquer son âge
Invite de confirmation
S'ils ont répondu oui, demander leur âge
Invite de nombre avec validation pour accepter uniquement des âges compris entre 0 et 150.
Demander si les informations collectées sont « ok »
Invite de réutilisation de la confirmation
Enfin, si l'utilisateur a répondu oui, affichez les informations collectées ; dans le cas contraire, indiquez-lui que ses informations ne seront pas conservées.
Mise en œuvre de votre dialogue de composant
Dans l'échantillon d'invite multitour, nous utilisons un dialogue en cascade, quelques invites et un dialogue de composant pour créer une interaction qui pose à l'utilisateur une série de questions.
Un dialogue composant encapsule un ou plusieurs dialogues. Le dialogue composant possède un jeu de dialogues interne défini ; les dialogues et les invites que vous ajoutez à ce jeu de dialogues interne possèdent leurs propres ID, visibles uniquement à partir du dialogue composant.
Pour utiliser les dialogues, installez le package NuGet Microsoft.Bot.Builder.Dialogs.
Dialogs\UserProfileDialog.cs
Ici, la classe UserProfileDialog dérive de la classe ComponentDialog.
public class UserProfileDialog : ComponentDialog
Dans le constructeur, la méthode AddDialog ajoute des dialogues et des invites au dialogue composant. Le premier article que vous ajoutez avec cette méthode est défini comme boîte de dialogue initiale. Vous pouvez changer la boîte de dialogue initiale en définissant explicitement la propriété InitialDialogId. Quand vous démarrez un dialogue composant, celui-ci démarre son dialogue initial.
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);
}
Le code suivant représente la première étape du dialogue en cascade.
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);
}
Pour utiliser des dialogues, votre projet doit installer le package npm botbuilder-dialogs.
dialogs/userProfileDialog.js
Ici la classe UserProfileDialog étend ComponentDialog.
class UserProfileDialog extends ComponentDialog {
Dans le constructeur, la méthode AddDialog ajoute des dialogues et des invites au dialogue composant. Le premier article que vous ajoutez avec cette méthode est défini comme boîte de dialogue initiale. Vous pouvez changer la boîte de dialogue initiale en définissant explicitement la propriété InitialDialogId. Quand vous démarrez un dialogue composant, celui-ci démarre son dialogue initial.
Le code suivant représente la première étape du dialogue en cascade.
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'])
});
}
Ici, la classe UserProfileDialog dérive de la classe ComponentDialog.
public class UserProfileDialog extends ComponentDialog {
Dans le constructeur, la méthode addDialog ajoute des dialogues et des invites au dialogue composant. Le premier article que vous ajoutez avec cette méthode est défini comme boîte de dialogue initiale. Vous pouvez changer la boîte de dialogue initiale en appelant la méthode setInitialDialogId et en fournissant le nom de la boîte de dialogue initiale. Quand vous démarrez un dialogue composant, celui-ci démarre son dialogue initial.
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");
}
Le code suivant représente la première étape du dialogue en cascade.
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);
}
Pour utiliser les dialogues, installez les packages PyPI botbuilder-dialogs et botbuilder-ai en exécutant pip install botbuilder-dialogs et pip install botbuilder-ai à partir d’un terminal.
dialogs/user_profile_dialog.py
Ici la classe UserProfileDialog étend ComponentDialog.
class UserProfileDialog(ComponentDialog):
Dans le constructeur, la méthode add_dialog ajoute des dialogues et des invites au dialogue composant. Le premier article que vous ajoutez avec cette méthode est défini comme boîte de dialogue initiale. Vous pouvez changer la boîte de dialogue initiale en définissant explicitement la propriété initial_dialog_id. Quand vous démarrez un dialogue composant, celui-ci démarre son dialogue initial.
Le code suivant représente la première étape du dialogue en cascade.
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")],
),
)
Au moment de l’exécution, le dialogue composant gère sa propre pile de dialogues. Au démarrage du dialogue composant :
Une instance est créée et ajoutée à la pile de dialogues externe
Il crée une pile de dialogues interne qu’il ajoute à son état
Il démarre son dialogue initial et l’ajoute à la pile de dialogues interne.
Le contexte parent voit le composant comme dialogue actif. Cependant, dans le contexte du composant, il semble que la boîte de dialogue initiale soit la boîte de dialogue active.
Appelez le dialogue à partir de votre bot
Dans le jeu de dialogues externe, celui auquel vous ajoutez le dialogue composant, ce dialogue composant est doté de l'ID avec lequel vous l'avez créé. Dans le jeu externe, le composant ressemble à un dialogue unique, de façon très similaire aux invites.
Pour utiliser un dialogue de composant, ajoutez-en une instance au jeu de dialogues du bot.
Dans l’exemple, c’est fait en utilisant la méthode RunAsync qui est appelée à partir de la méthode OnMessageActivityAsync du 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);
}
dialogs/userProfileDialog.js
Dans l’exemple, nous avons ajouté une méthode run au dialogue du profil utilisateur.
La méthode run est appelée depuis la méthode onMessage du 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
Dans l’exemple, c’est fait en utilisant la méthode run qui est appelée à partir de la méthode onMessageActivity du 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
Dans l’exemple, nous avons ajouté une méthode run_dialog au dialogue du profil utilisateur.
Démarrez l’émulateur, connectez-vous à votre bot et envoyez des messages, comme indiqué ci-dessous.
Informations supplémentaires
Fonctionnement de l’annulation pour les dialogues composants
Si vous appelez cancel all dialogs à partir du contexte du dialogue composant, le dialogue composant annule tous les dialogues sur sa pile interne, puis se termine en retournant le contrôle au dialogue suivant sur la pile externe.
Si vous appelez cancel all dialogs à partir du contexte externe, le composant est annulé, ainsi que le reste des dialogues sur le contexte externe.
Étapes suivantes
Découvrez comment créer des conversations complexes qui forment des branches et des boucles.