Udostępnij za pośrednictwem


Zapisywanie danych dotyczących użytkownika i konwersacji

DOTYCZY: SDK w wersji 4

Bot jest z natury bezstanowy. Po wdrożeniu bota, może on nie działać w tym samym procesie lub na tej samej maszynie przy każdym uruchomieniu. Jednak bot może wymagać śledzenia kontekstu konwersacji, aby mógł zarządzać swoim zachowaniem i pamiętać odpowiedzi na poprzednie pytania. Funkcje stanu i przechowywania zestawu Bot Framework SDK umożliwiają dodawanie stanu do bota. Boty używają obiektów zarządzania stanem i magazynowania do przechowywania i utrwalania stanu. Menedżer stanu udostępnia warstwę abstrakcji, która umożliwia dostęp do właściwości stanu przy użyciu metod dostępu do właściwości niezależnie od typu magazynu bazowego.

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

  • Znajomość podstaw bota i sposobu, w jaki boty zarządzają stanem są wymagane.
  • Kod w tym artykule jest oparty na przykładzie bota zarządzania stanem. Będziesz potrzebować kopii przykładu w języku C#, JavaScript, Java lub Python.

Informacje o tym przykładzie

Po otrzymaniu danych wejściowych użytkownika ten przykład sprawdza stan przechowywanej konwersacji, aby sprawdzić, czy ten użytkownik został wcześniej poproszony o podanie ich nazwy. Jeśli nie, użytkownik zostaje poproszony o podanie swojej nazwy, a te dane są przechowywane w stanie użytkownika. Jeśli tak, nazwa przechowywana w stanie użytkownika jest używana do rozmowy z użytkownikiem, a ich dane wejściowe, wraz z czasem otrzymania i identyfikatorem kanału wejściowego, są zwracane do użytkownika. Wartości czasu i identyfikatora kanału są pobierane z danych konwersacji użytkownika, a następnie zapisywane w stanie konwersacji. Na poniższym diagramie przedstawiono relację między klasami danych bota, profilu użytkownika i konwersacji.

Definiowanie klas

Pierwszym krokiem konfigurowania zarządzania stanem jest zdefiniowanie klas zawierających informacje do zarządzania w stanie użytkownika i konwersacji. W przykładzie użytym w tym artykule zdefiniowano następujące klasy:

  • W UserProfile.cs zdefiniujesz klasę UserProfile dla informacji o użytkowniku, które będzie zbierać bot.
  • W ConversationData.cs należy zdefiniować klasę ConversationData do kontrolowania stanu konwersacji podczas zbierania informacji o użytkowniku.

W poniższych przykładach kodu przedstawiono definicje klas UserProfile i ConversationData .

UserProfile.cs

public class UserProfile
{
    public string Name { get; set; }
}

ConversationData.cs

public class ConversationData
{
    // The time-stamp of the most recent incoming message.
    public string Timestamp { get; set; }

    // The ID of the user's channel.
    public string ChannelId { get; set; }

    // Track whether we have already asked the user's name
    public bool PromptedUserForName { get; set; } = false;
}

Utwórz obiekty stanu konwersacji i użytkownika

Następnie należy zarejestrować MemoryStorage, które są używane do tworzenia UserState i ConversationState obiektów. Obiekty stanu użytkownika i konwersacji są tworzone w Startup i wstrzykiwane jako zależności do konstruktora bota. Inne usługi zarejestrowane dla bota to: dostawca poświadczeń, adapter i implementacja bota.

Startup.cs

// {
//     TypeNameHandling = TypeNameHandling.All,
// var storage = new BlobsStorage("<blob-storage-connection-string>", "bot-state");

// With a custom JSON SERIALIZER, use this instead.
// var storage = new BlobsStorage("<blob-storage-connection-string>", "bot-state", jsonSerializer);

/* END AZURE BLOB STORAGE */

Boty/StateManagementBot.cs

private BotState _conversationState;
private BotState _userState;

public StateManagementBot(ConversationState conversationState, UserState userState)
{
    _conversationState = conversationState;
    _userState = userState;
}

Dodawanie metod dostępu właściwości stanu

Teraz utworzysz metody dostępu do właściwości, przy użyciu metody CreateProperty, która zapewnia dostęp do obiektu BotState. Każdy akcesor właściwości stanu umożliwia pobranie lub ustawienie wartości powiązanej właściwości stanu. Przed użyciem właściwości stanu, użyj każdego akcesora, aby najpierw załadować właściwość z magazynu, a następnie pobrać ją z pamięci podręcznej stanu. Aby uzyskać prawidłowy klucz o określonym zakresie skojarzony z właściwością stanu, należy wywołać metodę GetAsync .

Boty/StateManagementBot.cs

var conversationStateAccessors = _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));

Stan dostępu z bota

W poprzedniej sekcji omówiono kroki wykonywane podczas inicjalizacji, aby dodać akcesory właściwości stanu do naszego bota. Teraz możesz użyć tych akcesorów w czasie wykonywania, aby odczytywać i zapisywać informacje o stanie. Poniższy przykładowy kod używa następującego przepływu logiki:

  • Jeśli userProfile.Name jest pusty i conversationData.PromptedUserForName ma wartość true, trzeba pobrać podaną nazwę użytkownika i zapisać ją w stanie użytkownika.
  • Jeśli userProfile.Name wartość jest pusta i conversationData.PromptedUserForName ma wartość false, należy poprosić o podanie nazwy użytkownika.
  • Jeśli userProfile.Name były wcześniej przechowywane, pobierasz czas wiadomości i identyfikator kanału z danych wejściowych użytkownika, wyświetlasz wszystkie te dane użytkownikowi i przechowujesz pobrane dane w stanie konwersacji.

Boty/StateManagementBot.cs

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
    // Get the state properties from the turn context.

    var conversationStateAccessors = _conversationState.CreateProperty<ConversationData>(nameof(ConversationData));
    var conversationData = await conversationStateAccessors.GetAsync(turnContext, () => new ConversationData());

    var userStateAccessors = _userState.CreateProperty<UserProfile>(nameof(UserProfile));
    var userProfile = await userStateAccessors.GetAsync(turnContext, () => new UserProfile());

    if (string.IsNullOrEmpty(userProfile.Name))
    {
        // First time around this is set to false, so we will prompt user for name.
        if (conversationData.PromptedUserForName)
        {
            // Set the name to what the user provided.
            userProfile.Name = turnContext.Activity.Text?.Trim();

            // Acknowledge that we got their name.
            await turnContext.SendActivityAsync($"Thanks {userProfile.Name}. To see conversation data, type anything.");

            // Reset the flag to allow the bot to go through the cycle again.
            conversationData.PromptedUserForName = false;
        }
        else
        {
            // Prompt the user for their name.
            await turnContext.SendActivityAsync($"What is your name?");

            // Set the flag to true, so we don't prompt in the next turn.
            conversationData.PromptedUserForName = true;
        }
    }
    else
    {
        // Add message details to the conversation data.
        // Convert saved Timestamp to local DateTimeOffset, then to string for display.
        var messageTimeOffset = (DateTimeOffset)turnContext.Activity.Timestamp;
        var localMessageTime = messageTimeOffset.ToLocalTime();
        conversationData.Timestamp = localMessageTime.ToString();
        conversationData.ChannelId = turnContext.Activity.ChannelId.ToString();

        // Display state data.
        await turnContext.SendActivityAsync($"{userProfile.Name} sent: {turnContext.Activity.Text}");
        await turnContext.SendActivityAsync($"Message received at: {conversationData.Timestamp}");
        await turnContext.SendActivityAsync($"Message received from: {conversationData.ChannelId}");
    }
}

Przed zakończeniem procedury obsługi zdarzeń należy użyć metody SaveChangesAsync() obiektów zarządzania stanem, aby zapisać wszystkie zmiany stanu z powrotem do pamięci.

Boty/StateManagementBot.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);
}

Przetestuj swojego bota

  1. Pobierz i zainstaluj najnowszą wersję emulatora platformy Bot Framework
  2. Uruchom przykład lokalnie na swoim komputerze. Jeśli potrzebujesz instrukcji, zapoznaj się z plikiem README dla języków C#, JavaScript, Java lub Python.
  3. Użyj emulatora, aby przetestować przykładowego bota.

Dodatkowe informacje

W tym artykule opisano sposób dodawania stanu do bota. Aby uzyskać więcej informacji na temat tematów pokrewnych, zobacz poniższą tabelę.

Temat Uwagi
Prywatność Jeśli zamierzasz przechowywać dane osobowe użytkownika, należy zapewnić zgodność z ogólnym rozporządzeniem o ochronie danych.
Zarządzanie stanem Wszystkie wywołania zarządzania stanem są asynchroniczne, a domyślnie zwycięża ostatni piszący. W praktyce należy pobrać, ustawić i zapisać stan tak blisko siebie w bocie, jak to tylko możliwe. Aby zapoznać się z opisem implementacji optymistycznej blokady, zobacz także Implementowanie magazynu niestandardowego dla bota.
Krytyczne dane biznesowe Użyj stanu bota do przechowywania preferencji, nazwy użytkownika lub ostatniej rzeczy, którą zamówili, ale nie używaj go do przechowywania krytycznych danych biznesowych. W przypadku danych krytycznych utwórz własne komponenty przechowywania lub zapisz bezpośrednio w magazynie.
Recognizer-Tekst W przykładzie użyto bibliotek Microsoft/Recognizers-Text do analizowania i weryfikowania danych wejściowych użytkownika. Aby uzyskać więcej informacji, zobacz stronę przeglądu .

Następne kroki

Dowiedz się, jak zadać użytkownikowi serię pytań, zweryfikować odpowiedzi i zapisać swoje dane wejściowe.