Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
DOTYCZY: SDK w wersji 4
Rozmowa między botem a użytkownikiem często wiąże się z monitowaniem (monitowaniem) użytkownika o informacje, analizowaniem odpowiedzi użytkownika, a następnie działaniem na tych informacjach. Bot powinien śledzić kontekst konwersacji, aby mógł zarządzać swoim zachowaniem i pamiętać odpowiedzi na poprzednie pytania. Stan bota to informacje, które śledzi, aby odpowiednio reagować na przychodzące komunikaty.
Napiwek
Biblioteka dialogów zawiera wbudowane podpowiedzi, które zapewniają większą funkcjonalność, z której mogą korzystać użytkownicy. Przykłady tych monitów można znaleźć w artykule Implementowanie sekwencyjnego przepływu konwersacji.
Uwaga
Aby tworzyć agentów z wybranymi usługami sztucznej inteligencji, orkiestracją i wiedzą, rozważ użycie zestawu SDK agentów platformy Microsoft 365. Zestaw SDK agentów obsługuje języki C#, JavaScript lub Python. Więcej informacji na temat zestawu SDK agentów można uzyskać na stronie aka.ms/agents. Jeśli szukasz platformy agenta opartej na modelu SaaS, rozważ microsoft Copilot Studio. Jeśli masz istniejącego bota utworzonego przy użyciu zestawu Bot Framework SDK, możesz zaktualizować bota do zestawu SDK agentów. Wskazówki dotyczące migracji z Bot Framework SDK do Agents SDK znajdziesz pod Bot Framework SDK to Agents SDK migration guidance, które omawiają podstawowe zmiany i aktualizacje. Zgłoszenia do pomocy technicznej dla zestawu Bot Framework SDK nie będą już obsługiwane od 31 grudnia 2025 r.
Wymagania wstępne
- Kod w tym artykule jest oparty na przykładzie "Zachęcanie użytkowników do wprowadzenia danych". Będziesz potrzebować kopii przykładu języka C#, przykładu JavaScript, przykładu Java Lub przykładu języka Python.
- Znajomość zarządzania stanem i sposobu zapisywania danych użytkownika i konwersacji.
Informacje o przykładowym kodzie
Przykładowy bot zadaje użytkownikowi serię pytań, weryfikuje niektóre odpowiedzi i zapisuje swoje dane wejściowe. Na poniższym diagramie przedstawiono relację między klasami bota, profilu użytkownika i przepływu konwersacji.
-
UserProfile
Klasa informacji o użytkowniku zbieranych przez bota. -
ConversationFlow
Klasa do kontrolowania stanu konwersacji podczas zbierania informacji o użytkowniku. - Wewnętrzne
ConversationFlow.Question
wyliczenie do śledzenia punktu, w którym jesteś w konwersacji.
Stan użytkownika będzie śledzić imię użytkownika, wiek i wybraną datę, a stan konwersacji będzie śledzić, co użytkownik zapytał ostatnio. Ponieważ nie planujesz wdrożenia tego bota, skonfigurujesz stan użytkownika i konwersacji, aby korzystać z pamięciowego magazynu.
Aby zarządzać przepływem rozmowy i zbieraniem danych wejściowych, należy użyć obsługi kolejek wiadomości bota oraz właściwości stanu użytkownika i konwersacji. W swoim bocie zapiszesz informacje o właściwości stanu otrzymane podczas każdej iteracji obsługującego obieg wiadomości.
Tworzenie konwersacji i obiektów użytkownika
Utwórz obiekty stanu użytkownika i konwersacji na etapie uruchamiania i korzystaj z nich za pośrednictwem wstrzykiwania zależności w konstruktorze bota.
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>();
Boty/CustomPromptBot.cs
private readonly BotState _userState;
private readonly BotState _conversationState;
public CustomPromptBot(ConversationState conversationState, UserState userState)
{
_conversationState = conversationState;
_userState = userState;
}
Tworzenie metod dostępu do właściwości
Utwórz akcesory właściwości dla właściwości profilu użytkownika i przebiegu konwersacji, a następnie wywołaj metodę GetAsync
, aby pobrać wartość właściwości ze stanu.
Boty/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);
Przed zakończeniem kolei wywołaj metodę SaveChangesAsync
, aby zapisać zmiany stanu w pamięci.
await _conversationState.SaveChangesAsync(turnContext, false, cancellationToken);
await _userState.SaveChangesAsync(turnContext, false, cancellationToken);
}
Obsługa sekwencji komunikatów
Podczas obsługi działań związanych z komunikatami program obsługi komunikatów używa metody pomocniczej do zarządzania konwersacją i monitowania użytkownika. Metoda pomocnika została opisana w poniższej sekcji.
Boty/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);
}
Wypełnianie profilu użytkownika
Bot prosi użytkownika o podanie informacji na podstawie tego, które pytanie, jeśli jakieś, zadał w poprzednim kroku. Dane wejściowe są analizowane przy użyciu metody weryfikacji.
Każda metoda walidacji jest zgodna z podobnym projektem:
- Wartość zwracana wskazuje, czy dane wejściowe są prawidłową odpowiedzią na to pytanie.
- Jeśli walidacja przebiegnie pomyślnie, generuje przeanalizowaną i znormalizowaną wartość do zapisania.
- Jeśli walidacja zakończy się niepowodzeniem, zostanie wyświetlony komunikat, za pomocą którego bot może ponownie poprosić o podanie informacji.
Metody weryfikacji opisano w poniższej sekcji.
Boty/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;
}
}
}
Analizowanie i weryfikowanie danych wejściowych
Bot używa następujących kryteriów do weryfikowania danych wejściowych.
- Nazwa musi być ciągiem niepustym. Jest znormalizowany poprzez usuwanie białych znaków.
- Wiek musi należeć do przedziału od 18 do 120 lat. Jest normalizowany przez zwracanie liczby całkowitej.
- data musi być dowolną datą lub godziną co najmniej godzinę do przodu. Jest znormalizowany przez zwrócenie tylko części daty przeanalizowanych danych wejściowych.
Uwaga
W przypadku danych wejściowych dotyczących wieku i daty przykład używa bibliotek Microsoft/Recognizers-Text do wykonywania początkowej analizy. Jest to tylko jeden ze sposobów analizowania danych wejściowych. Aby uzyskać więcej informacji na temat tych bibliotek, zobacz plik README projektu.
Boty/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;
}
Testowanie bota lokalnie
Pobierz i zainstaluj program Bot Framework Emulator , aby przetestować bota lokalnie.
- Uruchom przykład lokalnie na swoim komputerze. Jeśli potrzebujesz instrukcji, zapoznaj się z plikiem przykładu
README
języka C#, przykładu JS lub przykładu języka Python. - Przetestuj go przy użyciu emulatora.
Dodatkowe zasoby
Biblioteka Dialogs udostępnia klasy, które automatyzują wiele aspektów zarządzania konwersacjami.