Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
APLICA-SE A: SDK v4
Uma conversa entre um bot e um usuário geralmente envolve pedir (solicitar) informações ao usuário, analisar a resposta do usuário e, em seguida, agir com base nessas informações. Seu bot deve acompanhar o contexto de uma conversa, para que possa gerenciar seu comportamento e lembrar as respostas a perguntas anteriores. O estado de um bot é a informação que ele rastreia para responder adequadamente às mensagens recebidas.
Gorjeta
A biblioteca de diálogos fornece prompts integrados que oferecem mais funcionalidades que os utilizadores podem aproveitar. Exemplos desses prompts podem ser encontrados no artigo Implementar o fluxo de conversa sequencial.
Nota
Para criar agentes com sua escolha de serviços, orquestração e conhecimento de IA, considere usar o SDK de agentes do Microsoft 365. O SDK de agentes tem suporte para C#, JavaScript ou Python. Você pode saber mais sobre o SDK de agentes em aka.ms/agents. Se você estiver procurando por uma plataforma de agente baseada em SaaS, considere o Microsoft Copilot Studio. Se você tiver um bot existente criado com o SDK do Bot Framework, poderá atualizar seu bot para o SDK de agentes. Você pode revisar as principais alterações e atualizações nas diretrizes de migração do SDK do Bot Framework para o SDK de agentes. Os tíquetes de suporte para o SDK do Bot Framework não serão mais atendidos a partir de 31 de dezembro de 2025.
Pré-requisitos
- O código neste artigo é baseado no exemplo Prompt Users for Input. Você precisará de uma cópia do exemplo C#, JavaScript, Java ou Python.
- Conhecimento de gestão de estado e como guardar dados de utilizador e de conversa.
Sobre o código de exemplo
O bot de exemplo faz ao usuário uma série de perguntas, valida algumas de suas respostas e salva suas entradas. O diagrama a seguir mostra a relação entre o bot, o perfil de usuário e as classes de fluxo de conversa.
- Uma
UserProfile
classe para as informações do usuário que o bot coletará. - Uma
ConversationFlow
classe para controlar nosso estado de conversação enquanto coleta informações do usuário. - Uma enumeração interna
ConversationFlow.Question
para rastrear onde você está na conversa.
O estado do usuário rastreará o nome, a idade e a data escolhida do usuário, e o estado da conversa rastreará o que você perguntou pela última vez ao usuário. Dado que não planeias implantar esse bot, vais configurar o estado do utilizador e da conversa para usar armazenamento de memória.
Você usa o manipulador de turno de mensagens do bot mais as propriedades de estado de usuário e conversa para gerenciar o fluxo da conversa e a coleta de entrada. Em seu bot, você registrará as informações de propriedade de estado recebidas durante cada iteração do manipulador de turno de mensagem.
Criar objetos de conversação e de utilizador
Crie os objetos de estado de usuário e conversação na inicialização e consuma-os por meio da injeção de dependência no construtor de 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>();
Bots/CustomPromptBot.cs
private readonly BotState _userState;
private readonly BotState _conversationState;
public CustomPromptBot(ConversationState conversationState, UserState userState)
{
_conversationState = conversationState;
_userState = userState;
}
Criar acessos a propriedades
Crie acessores para as propriedades do perfil de utilizador e do fluxo de conversa e, em seguida, chame GetAsync
para recuperar o valor da propriedade do estado.
Bots/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);
Antes que o turno termine, ligue SaveChangesAsync
para gravar quaisquer alterações de estado no armazenamento.
await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}
Gestor de turno de mensagens
Ao manipular atividades de mensagem, o manipulador de mensagens usa um método auxiliar para gerenciar a conversa e avisar o usuário. O método auxiliar é descrito na seção a seguir.
Bots/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);
}
Preenchimento do perfil de utilizador
O bot solicita informações ao usuário, com base em qual pergunta, se houver, que o bot fez no turno anterior. A entrada é analisada usando um método de validação.
Cada método de validação segue um desenho semelhante:
- O valor de retorno indica se a entrada é uma resposta válida para essa pergunta.
- Se a validação for aprovada, ela produzirá um valor analisado e normalizado para salvar.
- Se a validação falhar, ele produzirá uma mensagem com a qual o bot pode pedir as informações novamente.
Os métodos de validação são descritos na seção a seguir.
Bots/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;
}
}
}
Analise e valide a entrada
O bot usa os seguintes critérios para validar a entrada.
- O nome deve ser uma cadeia de caracteres não vazia. É normalizado cortando espaços em branco.
- A idade deve ter entre 18 e 120 anos . É normalizado retornando um inteiro.
- A data deve ser qualquer data ou hora pelo menos uma hora à frente. Ele é normalizado retornando apenas a parte de data da entrada analisada.
Nota
Para a entrada de idade e data, o exemplo usa as bibliotecas Microsoft/Recognizers-Text para executar a análise inicial. Esta é apenas uma maneira de analisar a entrada. Para obter mais informações sobre essas bibliotecas, consulte o README do projeto.
Bots/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;
}
Teste o bot localmente
Baixe e instale o Bot Framework Emulator para testar o bot localmente.
- Execute a amostra localmente na sua máquina. Se você precisar de instruções, consulte o
README
arquivo para o exemplo C#, o exemplo JS ou o exemplo Python. - Teste-o usando o emulador.
Recursos adicionais
A biblioteca Diálogos fornece classes que automatizam muitos aspetos do gerenciamento de conversas.