Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
SI APPLICA A: SDK v4
È possibile creare flussi di conversazione semplici e complessi usando la libreria di dialoghi. Questo articolo illustra come gestire conversazioni complesse con rami e cicli e come passare argomenti tra parti diverse del dialogo.
Nota
Per creare agenti con la scelta di servizi di intelligenza artificiale, orchestrazione e conoscenze, è consigliabile usare Microsoft 365 Agents SDK. Agents SDK supporta C#, JavaScript o Python. Per altre informazioni su Agents SDK , vedere aka.ms/agents. Se si sta cercando una piattaforma agente basata su SaaS, prendere in considerazione Microsoft Copilot Studio. Se si dispone di un bot esistente compilato con Bot Framework SDK, è possibile aggiornare il bot ad Agents SDK. È possibile esaminare le modifiche e gli aggiornamenti principali in Bot Framework SDK per le linee guida per la migrazione di Agents SDK. I ticket di supporto per Bot Framework SDK non verranno più gestiti a partire dal 31 dicembre 2025.
Prerequisiti
- Conoscenza delle nozioni di base sui bot, della gestione dello stato, della libreria di dialoghi e di come implementare un flusso di conversazione sequenziale.
- Copia dell'esempio di dialogo complesso in C#, JavaScript, Java o Python.
Informazioni sull'esempio
Questo esempio rappresenta un bot che può consentire agli utenti di accedere per recensire fino a due aziende da un elenco. Il bot usa tre dialoghi componenti per gestire il flusso di conversazione. Ogni dialogo componente include un dialogo a cascata ed eventuali prompt necessari per raccogliere l'input dell'utente. Questi dialoghi vengono descritti in maggior dettaglio nelle sezioni seguenti. Il bot usa lo stato della conversazione per gestire i dialoghi e lo stato dell'utente per salvare informazioni sull'utente e sulle aziende che vuole recensire.
Il bot si basa sul gestore di attività. Come molti bot di esempio, saluta l'utente, usa i dialoghi per gestire i messaggi che invia e salva il suo stato e quello della conversazione prima che termini in turno.
Per usare i dialoghi, installare il pacchetto NuGet Microsoft.Bot.Builder.Dialogs.
Definire il profilo utente
Il profilo utente conterrà le informazioni raccolte dai dialoghi, il nome e l'età dell'utente, nonché le aziende selezionate per la recensione.
UserProfile.cs
/// <summary>Contains information about a user.</summary>
public class UserProfile
{
public string Name { get; set; }
public int Age { get; set; }
// The list of companies the user wants to review.
public List<string> CompaniesToReview { get; set; } = new List<string>();
Crea i dialoghi
Questo bot contiene tre dialoghi:
- Il dialogo principale avvia il processo generale e quindi riepiloga le informazioni raccolte.
- Il dialogo di primo livello raccoglie le informazioni dell'utente e include la logica di diramazione, in base all'età dell'utente.
- Il dialogo di selezione della recensione consente all'utente di scegliere le aziende in modo iterativo. A tale scopo, usa la logica di ciclo.
Il dialogo principale
Il dialogo principale prevede due passaggi:
- Avviare il dialogo di primo livello.
- Recuperare e riepilogare il profilo utente raccolto dal dialogo di primo livello, salvare le informazioni nello stato dell'utente e quindi segnalare la fine del dialogo principale.
Dialogs\MainDialog.cs
private async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.BeginDialogAsync(nameof(TopLevelDialog), null, cancellationToken);
}
private async Task<DialogTurnResult> FinalStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
var userInfo = (UserProfile)stepContext.Result;
string status = "You are signed up to review "
+ (userInfo.CompaniesToReview.Count is 0 ? "no companies" : string.Join(" and ", userInfo.CompaniesToReview))
+ ".";
await stepContext.Context.SendActivityAsync(status);
var accessor = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
await accessor.SetAsync(stepContext.Context, userInfo, cancellationToken);
return await stepContext.EndDialogAsync(null, cancellationToken);
}
Dialogo di primo livello
Il dialogo di primo livello prevede quattro passaggi:
- Chiedere il nome dell'utente.
- Chiedere l'età dell'utente.
- Avviare il dialogo di selezione della recensione o procedere con il passaggio successivo, in base all'età dell'utente.
- Ringraziare infine l'utente per aver partecipato e restituire le informazioni raccolte.
Il primo passaggio consiste nella creazione di un profilo utente vuoto come parte dello stato del dialogo. Il dialogo inizia con un profilo vuoto e vi aggiunge informazioni man mano che prosegue. Al termine, l'ultimo passaggio restituisce le informazioni raccolte.
Nel terzo passaggio (avvio della selezione), il flusso della conversazione si dirama, in base all'età dell'utente.
Dialogs\TopLevelDialog.cs
stepContext.Values[UserInfo] = new UserProfile();
var promptOptions = new PromptOptions { Prompt = MessageFactory.Text("Please enter your name.") };
// Ask the user to enter their name.
return await stepContext.PromptAsync(nameof(TextPrompt), promptOptions, cancellationToken);
}
private async Task<DialogTurnResult> AgeStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Set the user's name to what they entered in response to the name prompt.
var userProfile = (UserProfile)stepContext.Values[UserInfo];
userProfile.Name = (string)stepContext.Result;
var promptOptions = new PromptOptions { Prompt = MessageFactory.Text("Please enter your age.") };
// Ask the user to enter their age.
return await stepContext.PromptAsync(nameof(NumberPrompt<int>), promptOptions, cancellationToken);
}
private async Task<DialogTurnResult> StartSelectionStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Set the user's age to what they entered in response to the age prompt.
var userProfile = (UserProfile)stepContext.Values[UserInfo];
userProfile.Age = (int)stepContext.Result;
if (userProfile.Age < 25)
{
// If they are too young, skip the review selection dialog, and pass an empty list to the next step.
await stepContext.Context.SendActivityAsync(
MessageFactory.Text("You must be 25 or older to participate."),
cancellationToken);
return await stepContext.NextAsync(new List<string>(), cancellationToken);
}
else
{
// Otherwise, start the review selection dialog.
return await stepContext.BeginDialogAsync(nameof(ReviewSelectionDialog), null, cancellationToken);
}
}
private async Task<DialogTurnResult> AcknowledgementStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Set the user's company selection to what they entered in the review-selection dialog.
var userProfile = (UserProfile)stepContext.Values[UserInfo];
userProfile.CompaniesToReview = stepContext.Result as List<string> ?? new List<string>();
// Thank them for participating.
await stepContext.Context.SendActivityAsync(
MessageFactory.Text($"Thanks for participating, {((UserProfile)stepContext.Values[UserInfo]).Name}."),
cancellationToken);
// Exit the dialog, returning the collected user information.
return await stepContext.EndDialogAsync(stepContext.Values[UserInfo], cancellationToken);
}
}
}
Dialogo di selezione della recensione
Il dialogo di selezione della recensione prevede due passaggi:
- Chiedere all'utente di scegliere un'azienda da recensire o scegliere
done
per terminare.- Se il dialogo è stato avviato con informazioni iniziali, tali informazioni sono disponibili tramite la proprietà options del contesto del passaggio a cascata. Il dialogo di selezione della recensione può riavviarsi automaticamente e in questo modo consente all'utente di scegliere più di un'azienda da recensire.
- Se l'utente ha già selezionato un'azienda da recensire, quest'ultima viene rimossa dalle opzioni disponibili.
- Viene aggiunta un'opzione
done
per consentire all'utente di uscire prima dal ciclo.
- Ripetere questo dialogo o uscire, a seconda dei casi.
- Se l'utente sceglie un'azienda da recensire, aggiungerla al suo elenco.
- Se l'utente ha scelto due società o ha scelto di uscire, terminare la finestra di dialogo e restituire l'elenco raccolto.
- In caso contrario, riavviare il dialogo, inizializzandolo con il contenuto dell'elenco.
Dialogs\ReviewSelectionDialog.cs
private async Task<DialogTurnResult> SelectionStepAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
// Continue using the same selection list, if any, from the previous iteration of this dialog.
var list = stepContext.Options as List<string> ?? new List<string>();
stepContext.Values[CompaniesSelected] = list;
// Create a prompt message.
string message;
if (list.Count is 0)
{
message = $"Please choose a company to review, or `{DoneOption}` to finish.";
}
else
{
message = $"You have selected **{list[0]}**. You can review an additional company, " +
$"or choose `{DoneOption}` to finish.";
}
// Create the list of options to choose from.
var options = _companyOptions.ToList();
options.Add(DoneOption);
if (list.Count > 0)
{
options.Remove(list[0]);
}
var promptOptions = new PromptOptions
{
Prompt = MessageFactory.Text(message),
RetryPrompt = MessageFactory.Text("Please choose an option from the list."),
Choices = ChoiceFactory.ToChoices(options),
};
// Prompt the user for a choice.
return await stepContext.PromptAsync(nameof(ChoicePrompt), promptOptions, cancellationToken);
}
private async Task<DialogTurnResult> LoopStepAsync(
WaterfallStepContext stepContext,
CancellationToken cancellationToken)
{
// Retrieve their selection list, the choice they made, and whether they chose to finish.
var list = stepContext.Values[CompaniesSelected] as List<string>;
var choice = (FoundChoice)stepContext.Result;
var done = choice.Value == DoneOption;
if (!done)
{
// If they chose a company, add it to the list.
list.Add(choice.Value);
}
if (done || list.Count >= 2)
{
// If they're done, exit and return their list.
return await stepContext.EndDialogAsync(list, cancellationToken);
}
else
{
// Otherwise, repeat this dialog, passing in the list from this iteration.
return await stepContext.ReplaceDialogAsync(InitialDialogId, list, cancellationToken);
}
}
Eseguire i dialoghi
La classe dialog bot estende il gestore attività e contiene la logica per l'esecuzione dei dialoghi. La classe dialog and welcome bot classe estende la classe dialog bot per aggiungere anche un messaggio di benvenuto all'utente quando si aggiunge alla conversazione.
Il gestore dei turni del bot ripete il flusso di conversazione definito dai tre dialoghi. Quando riceve un messaggio dall'utente:
- Esegue il dialogo principale.
- Se lo stack del dialogo è vuoto, viene avviato il dialogo principale.
- In caso contrario, i dialoghi sono ancora in corso e verrà continuato il dialogo attivo.
- Lo stato viene salvato, per cui eventuali aggiornamenti apportati allo stato dell'utente, della conversazione e del dialogo vengono resi persistenti.
Bots\DialogBot.cs
public override async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
{
await base.OnTurnAsync(turnContext, cancellationToken);
// Save any state changes that might have occurred during the turn.
await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
}
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);
}
Registrare i servizi per il bot
Creare e registrare i servizi in base alle esigenze:
- Servizi di base per un bot: un adattatore e l'implementazione del bot.
- Servizi per la gestione dello stato: archiviazione, stato utente e stato conversazione.
- Il dialogo principale che verrà usato dal bot.
Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient().AddControllers().AddNewtonsoftJson(options =>
{
options.SerializerSettings.MaxDepth = HttpHelper.BotMessageSerializerSettings.MaxDepth;
});
// Create the Bot Framework Authentication to be used with the Bot Adapter.
services.AddSingleton<BotFrameworkAuthentication, ConfigurationBotFrameworkAuthentication>();
// Create the Bot Adapter with error handling enabled.
services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
// Create the storage we'll be using for User and Conversation state. (Memory is great for testing purposes.)
services.AddSingleton<IStorage, MemoryStorage>();
// Create the User state. (Used in this bot's Dialog implementation.)
services.AddSingleton<UserState>();
Nota
L'archiviazione di memoria viene usata solo a scopo di test e non è destinata all'uso in produzione. Assicurarsi di usare un tipo di archiviazione permanente per un bot di produzione.
Test del bot
Se non è già stato fatto, installare Bot Framework Emulator.
Eseguire l'esempio in locale sul proprio computer.
Avviare l'emulatore, connettersi al bot e inviare messaggi come mostrato di seguito.
Risorse aggiuntive
Per un'introduzione su come implementare un dialogo, vedere Implementare un flusso di conversazione sequenziale, che usa un singolo dialogo a cascata e alcune richieste per porre all'utente una serie di domande.
La libreria Dialogs include una convalida di base per i prompt. È anche possibile aggiungere una convalida personalizzata. Per altre informazioni, vedere Raccogliere l'input degli utenti con una richiesta di dialogo.
Per semplificare il codice del dialogo e riusarlo per più bot, è possibile definire parti di un set di dialoghi come classe separata. Per altre informazioni, vedere riutilizzare le finestre di dialogo.