Udostępnij za pośrednictwem


Zapisywanie danych dotyczących użytkownika i konwersacji

DOTYCZY: ZESTAW SDK w wersji 4

Bot jest z natury bezstanowy. Po wdrożeniu bota może nie działać w tym samym procesie lub na tej samej maszynie z jednej kolei do następnej. 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ą zarządzania stanem i obiektów magazynu do zarządzania stanem i ich utrwalania. 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

Zestawy SDK języka JavaScript, C# i Python platformy Bot Framework będą nadal obsługiwane, jednak zestaw SDK języka Java jest wycofywany z ostatecznym długoterminowym wsparciem kończącym się w listopadzie 2023 r.

Istniejące boty utworzone za pomocą zestawu JAVA SDK będą nadal działać.

W przypadku tworzenia nowych botów rozważ użycie programu Microsoft Copilot Studio i przeczytaj o wyborze odpowiedniego rozwiązania copilot.

Aby uzyskać więcej informacji, zobacz Przyszłość tworzenia botów.

Wymagania wstępne

  • Znajomość podstaw bota i sposobu, w jaki boty zarządzają stanem jest wymagany.
  • 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, nazwa użytkownika jest żądana i dane wejściowe są przechowywane w stanie użytkownika. Jeśli tak, nazwa przechowywana w stanie użytkownika jest używana do komunikacji z użytkownikiem i ich danymi wejściowymi, wraz z czasem odebranym i identyfikatorem kanału wejściowego, zostanie zwrócona użytkownikowi. 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;
}

Tworzenie obiektów stanu konwersacji i użytkownika

Następnie należy zarejestrować MemoryStorage obiekt , który jest używany do tworzenia UserState obiektów i ConversationState . Obiekty stanu użytkownika i konwersacji są tworzone w Startup obiekcie i są wstrzykiwane do konstruktora bota. Inne usługi dla zarejestrowanego bota to: dostawca poświadczeń, karta 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 CreateProperty metody, która zapewnia uchwyt do BotState obiektu. Każda funkcja dostępu właściwości stanu umożliwia uzyskanie lub ustawienie wartości skojarzonej właściwości stanu. Przed użyciem właściwości stanu użyj poszczególnych metod dostępu, aby załadować właściwość z magazynu i 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 inicjowania w czasie dodawania metod dostępu właściwości stanu do bota. Teraz możesz użyć tych metod dostępu 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 wartość jest pusta i conversationData.PromptedUserForName ma wartość true, należy pobrać podaną nazwę użytkownika i zapisać tę nazwę 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 wcześniej były przechowywane, pobierasz czas komunikatu i identyfikator kanału z danych wejściowych użytkownika, echo wszystkich danych z powrotem do użytkownika 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 kolei należy użyć metody SaveChangesAsync() obiektów zarządzania stanami, aby zapisać wszystkie zmiany stanu z powrotem do magazynu.

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);
}

Testowanie bota

  1. Pobierz i zainstaluj najnowszą wersję emulatora platformy Bot Framework
  2. Uruchom przykład lokalnie na maszynie. 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 ostatni składnik zapisywania wygrywa domyślnie. W praktyce należy uzyskać, ustawić i zapisać stan tak blisko siebie w botze, jak to możliwe. Aby zapoznać się z omówieniem sposobu implementowania optymistycznej blokady, zobacz Implementowanie magazynu niestandardowego dla bota.
Krytyczne dane biznesowe Użyj stanu bota do przechowywania preferencji, nazwy użytkownika lub ostatniej uporządkowanej rzeczy, ale nie używaj go do przechowywania krytycznych danych biznesowych. W przypadku danych krytycznych utwórz własne składniki magazynu lub zapisz bezpośrednio w magazynie.
Rozpoznawanie tekstu 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.