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
Una conversazione tra un bot e un utente spesso include la richiesta all'utente di informazioni, l'analisi della risposta e quindi un'azione in base a tali informazioni. Il bot deve tenere traccia del contesto di una conversazione, in modo che possa gestirne il comportamento e ricordare le risposte alle domande precedenti. Lo stato di un bot è un'informazione di cui il bot tiene traccia per rispondere in modo appropriato ai messaggi in arrivo.
Suggerimento
La libreria dialogs fornisce richieste predefinite che forniscono più funzionalità che gli utenti possono usare. Esempi di tali richieste sono disponibili nell'articolo Implementare un flusso di conversazione sequenziale.
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
- Il codice in questo articolo è basato sull'esempio relativo alla richiesta di input agli utenti. È necessaria una copia dell'esempio C#, dell'esempio JavaScript, dell'esempio Java o di Python.
- Conoscenza della gestione dello stato e del salvataggio dei dati relativi a utenti e conversazioni.
Informazioni sul codice di esempio
Il bot di esempio pone all'utente una serie di domande, convalida alcune risposte e salva l'input. Il diagramma seguente illustra la relazione tra il bot, il profilo utente e le classi del flusso di conversazione.
- Una classe
UserProfile
per le informazioni dell'utente che verranno raccolte dal bot. - Una classe
ConversationFlow
per controllare lo stato della conversazione durante la raccolta delle informazioni dell'utente. - Enumerazione interna
ConversationFlow.Question
per tenere traccia della posizione in cui ci si trova nella conversazione.
Lo stato utente tiene traccia del nome, dell'età e della data scelta dell'utente e lo stato della conversazione tengono traccia dell'ultima richiesta all'utente. Poiché non si prevede di distribuire questo bot, configurerai lo stato utente e lo stato della conversazione per utilizzare la memoria.
Per gestire il flusso della conversazione e la raccolta di input, si usano le proprietà dello stato utente e della conversazione e il gestore dei turni dei messaggi del bot. Nel tuo bot, verranno registrate le informazioni sulle proprietà dello stato ricevute durante ogni iterazione del gestore di turni del messaggio.
Creare gli oggetti della conversazione e dell'utente
Creare gli oggetti di stato dell'utente e della conversazione all'avvio e utilizzarli tramite l'inserimento della dipendenza nel costruttore del bot.
Startup.cs
// 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.
services.AddSingleton<UserState>();
// Create the Conversation state.
services.AddSingleton<ConversationState>();
Bot/CustomPromptBot.cs
private readonly BotState _userState;
private readonly BotState _conversationState;
public CustomPromptBot(ConversationState conversationState, UserState userState)
{
_conversationState = conversationState;
_userState = userState;
}
Creare le funzioni di accesso alle proprietà
Creare le funzioni di accesso alle proprietà per le proprietà del flusso di conversazione e del profilo utente e quindi chiamare GetAsync
per recuperare il valore della proprietà dallo stato.
Bot/CustomPromptBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var conversationStateAccessors = _conversationState.CreateProperty<ConversationFlow>(nameof(ConversationFlow));
var flow = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationFlow(), cancellationToken);
var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
var profile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile(), cancellationToken);
Prima della fine del turno, chiamare SaveChangesAsync
per scrivere eventuali modifiche di stato nell'archivio.
await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}
Gestore dei turni di messaggi
Quando si gestiscono le attività dei messaggi, il gestore di messaggi usa un metodo helper per gestire la conversazione e richiedere input all'utente. Il metodo helper è descritto nella sezione seguente.
Bot/CustomPromptBot.cs
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var conversationStateAccessors = _conversationState.CreateProperty<ConversationFlow>(nameof(ConversationFlow));
var flow = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationFlow(), cancellationToken);
var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
var profile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile(), cancellationToken);
await FillOutUserProfileAsync(flow, profile, turnContext, cancellationToken);
// Save changes.
await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}
Compilazione del profilo utente
Il bot richiede informazioni all'utente sulla base della eventuale domanda posta dal bot durante il turno precedente. L'input viene analizzato con un metodo di convalida.
Ogni metodo di convalida è strutturato in modo simile:
- Il valore restituito indica se l'input è una risposta valida per questa domanda.
- Se la convalida ha esito positivo, produce un valore analizzato e normalizzato da salvare.
- Se la convalida non riesce, produce un messaggio con il quale il bot può chiedere nuovamente l'informazione.
I metodi di convalida sono descritti nella sezione seguente.
Bot/CustomPromptBot.cs
{
var input = turnContext.Activity.Text?.Trim();
string message;
switch (flow.LastQuestionAsked)
{
case ConversationFlow.Question.None:
await turnContext.SendActivityAsync("Let's get started. What is your name?", null, null, cancellationToken);
flow.LastQuestionAsked = ConversationFlow.Question.Name;
break;
case ConversationFlow.Question.Name:
if (ValidateName(input, out var name, out message))
{
profile.Name = name;
await turnContext.SendActivityAsync($"Hi {profile.Name}.", null, null, cancellationToken);
await turnContext.SendActivityAsync("How old are you?", null, null, cancellationToken);
flow.LastQuestionAsked = ConversationFlow.Question.Age;
break;
}
else
{
await turnContext.SendActivityAsync(message ?? "I'm sorry, I didn't understand that.", null, null, cancellationToken);
break;
}
case ConversationFlow.Question.Age:
if (ValidateAge(input, out var age, out message))
{
profile.Age = age;
await turnContext.SendActivityAsync($"I have your age as {profile.Age}.", null, null, cancellationToken);
await turnContext.SendActivityAsync("When is your flight?", null, null, cancellationToken);
flow.LastQuestionAsked = ConversationFlow.Question.Date;
break;
}
else
{
await turnContext.SendActivityAsync(message ?? "I'm sorry, I didn't understand that.", null, null, cancellationToken);
break;
}
case ConversationFlow.Question.Date:
if (ValidateDate(input, out var date, out message))
{
profile.Date = date;
await turnContext.SendActivityAsync($"Your cab ride to the airport is scheduled for {profile.Date}.");
await turnContext.SendActivityAsync($"Thanks for completing the booking {profile.Name}.");
await turnContext.SendActivityAsync($"Type anything to run the bot again.");
flow.LastQuestionAsked = ConversationFlow.Question.None;
profile = new UserProfile();
break;
}
else
{
await turnContext.SendActivityAsync(message ?? "I'm sorry, I didn't understand that.", null, null, cancellationToken);
break;
}
}
}
Analizzare e convalidare l'input
Per convalidare l'input, il bot usa i criteri seguenti.
- Il nome deve essere una stringa non vuota. Questo elemento verrà normalizzato tagliando lo spazio vuoto.
- L'età deve essere compresa tra 18 e 120. Questo elemento verrà normalizzato restituendo un numero intero.
- La data deve essere qualsiasi data o ora di almeno un'ora avanti nel futuro. Questo elemento verrà normalizzato restituendo solo la parte dell'input analizzato relativa alla data.
Nota
Per l'input di età e data, l'esempio usa le librerie Microsoft/Recognizers-Text per eseguire l'analisi iniziale. Questo è solo un modo per analizzare l'input. Per altre informazioni su queste librerie, vedere README del progetto.
Bot/CustomPromptBot.cs
private static bool ValidateName(string input, out string name, out string message)
{
name = null;
message = null;
if (string.IsNullOrWhiteSpace(input))
{
message = "Please enter a name that contains at least one character.";
}
else
{
name = input.Trim();
}
return message is null;
}
private static bool ValidateAge(string input, out int age, out string message)
{
age = 0;
message = null;
// Try to recognize the input as a number. This works for responses such as "twelve" as well as "12".
try
{
// Attempt to convert the Recognizer result to an integer. This works for "a dozen", "twelve", "12", and so on.
// The recognizer returns a list of potential recognition results, if any.
var results = NumberRecognizer.RecognizeNumber(input, Culture.English);
foreach (var result in results)
{
// The result resolution is a dictionary, where the "value" entry contains the processed string.
if (result.Resolution.TryGetValue("value", out var value))
{
age = Convert.ToInt32(value);
if (age >= 18 && age <= 120)
{
return true;
}
}
}
message = "Please enter an age between 18 and 120.";
}
catch
{
message = "I'm sorry, I could not interpret that as an age. Please enter an age between 18 and 120.";
}
return message is null;
}
private static bool ValidateDate(string input, out string date, out string message)
{
date = null;
message = null;
// Try to recognize the input as a date-time. This works for responses such as "11/14/2018", "9pm", "tomorrow", "Sunday at 5pm", and so on.
// The recognizer returns a list of potential recognition results, if any.
try
{
var results = DateTimeRecognizer.RecognizeDateTime(input, Culture.English);
// Check whether any of the recognized date-times are appropriate,
// and if so, return the first appropriate date-time. We're checking for a value at least an hour in the future.
var earliest = DateTime.Now.AddHours(1.0);
foreach (var result in results)
{
// The result resolution is a dictionary, where the "values" entry contains the processed input.
var resolutions = result.Resolution["values"] as List<Dictionary<string, string>>;
foreach (var resolution in resolutions)
{
// The processed input contains a "value" entry if it is a date-time value, or "start" and
// "end" entries if it is a date-time range.
if (resolution.TryGetValue("value", out var dateString)
|| resolution.TryGetValue("start", out dateString))
{
if (DateTime.TryParse(dateString, out var candidate)
&& earliest < candidate)
{
date = candidate.ToShortDateString();
return true;
}
}
}
}
message = "I'm sorry, please enter a date at least an hour out.";
}
catch
{
message = "I'm sorry, I could not interpret that as an appropriate date. Please enter a date at least an hour out.";
}
return false;
}
Testare il bot nell'ambiente locale
Scaricare e installare Bot Framework Emulator per testare il bot in locale.
- Esegui l'esempio localmente sul tuo computer. Se hai bisogno di istruzioni, consulta il file per l'esempio
README
di C#, l'esempio di JS, o l'esempio di Python. - Testarlo usando l'Emulator.
Risorse aggiuntive
La libreria Dialogs fornisce classi che automatizzano molti aspetti della gestione delle conversazioni.