Speichern von Benutzer- und Konversationsdaten

GILT FÜR: SDK v4

Ein Bot ist grundsätzlich zustandslos. Nachdem Ihr Bot bereitgestellt wurde, kann es sein, dass er für die einzelnen Durchläufe nicht als Teil desselben Prozesses oder auf demselben Computer ausgeführt wird. Unter Umständen muss Ihr Bot aber den Kontext einer Konversation nachverfolgen, damit er das Verhalten verwalten und Antworten auf vorherige Fragen speichern kann. Mit den Zustands- und Speicherfeatures des Bot Framework SDK können Sie Ihrem Bot den Zustand hinzufügen. Bots verwenden Zustandsverwaltungs- und Speicherobjekte, um den Zustand zu verwalten und zu speichern. Der Zustands-Manager bietet eine Abstraktionsebene, mit der Sie unabhängig von der Art des zugrunde liegenden Speichers mithilfe von Eigenschaftenaccessoren auf Zustandseigenschaften zugreifen können.

Hinweis

Die JavaScript-, C#- und Python-SDKs für Bot Framework werden weiterhin unterstützt, das Java-SDK wird jedoch eingestellt und der langfristige Support endet im November 2023.

Bestehende Bots, die mit dem Java SDK erstellt wurden, werden weiterhin funktionieren.

Wenn Sie einen neuen Bot erstellen möchten, sollten Sie den Einsatz von Power Virtual Agents in Betracht ziehen und sich über die Auswahl der richtigen Chatbot-Lösung informieren.

Weitere Informationen finden Sie unter Die Zukunft des Bot-Design.

Voraussetzungen

Informationen zu diesem Beispiel

Nach dem Empfang der Benutzereingabe überprüft das Beispiel den gespeicherten Konversationszustand, um festzustellen, ob der Benutzer bereits zur Eingabe seines Namens aufgefordert wurde. Wenn dies nicht der Fall ist, wird der Name des Benutzers angefordert, und die Eingabe wird im Benutzerzustand gespeichert. Ist dies der Fall, wird der im Benutzerzustand gespeicherte Name zur Konversation mit dem Benutzer verwendet, und die Eingabedaten werden zusammen mit der Empfangszeit und der ID des Eingabekanals an den Benutzer zurückgegeben. Die Werte für die Uhrzeit und die Kanal-ID werden aus den Benutzerkonversationsdaten abgerufen und dann im Konversationszustand gespeichert. Das folgende Diagramm zeigt die Beziehung zwischen dem Bot, dem Benutzerprofil und den Konversationsdatenklassen.

Definieren von Klassen

Der erste Schritt beim Einrichten der Zustandsverwaltung ist das Definieren der Klassen, die die Informationen enthalten, die im Benutzer- und Konversationszustand verwaltet werden sollen. In dem in diesem Artikel verwendeten Beispiel werden die folgenden Klassen definiert:

  • In UserProfile.cs definieren Sie eine UserProfile-Klasse für die Benutzerinformationen, die vom Bot erfasst werden.
  • In ConversationData.cs definieren Sie eine ConversationData-Klasse, um den Konversationszustand während der Erfassung von Benutzerinformationen zu steuern.

Die folgenden Codebeispiele zeigen die Definitionen für die Klassen UserProfile und 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;
}

Erstellen von Konversations- und Benutzerzustandsobjekten

Als Nächstes registrieren Sie die MemoryStorage-Klasse, die zum Erstellen von UserState- und ConversationState-Objekten verwendet wird. Die Benutzer- und Konversationszustandsobjekte werden beim Startup erstellt, und Abhängigkeiten werden in den Botkonstruktor injiziert. Weitere Dienste, die für einen Bot registriert werden, sind ein Anmeldeinformationsanbieter, ein Adapter und die Botimplementierung.

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 */

Bots/StateManagementBot.cs

private BotState _conversationState;
private BotState _userState;

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

Hinzufügen von Zustandseigenschaftenaccessoren

Nun erstellen Sie Eigenschaftenaccessoren mit der CreateProperty-Methode, die ein Handle für das BotState-Objekt bereitstellt. Mit jedem Zustandseigenschaftenaccessor können Sie den Wert der zugeordneten Zustandseigenschaft abrufen oder festlegen. Bevor Sie die Zustandseigenschaften verwenden, nutzen Sie jeden Accessor, um die Eigenschaft aus dem Speicher zu laden und aus dem Zustandscache abzurufen. Um den korrekt zugeordneten Schlüssel für die Zustandseigenschaft abzurufen, rufen Sie die GetAsync-Methode auf.

Bots/StateManagementBot.cs

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

Zugreifen auf den Zustand von Ihrem Bot aus

Im vorherigen Abschnitt wurden die Schritte erläutert, die während der Initialisierung ausgeführt werden, um dem Bot Zustandseigenschaftenaccessoren hinzuzufügen. Jetzt können Sie diese Accessoren zur Laufzeit verwenden, um Zustandsinformationen zu lesen und zu schreiben. Der folgende Beispielcode verwendet den unten dargestellten Logikflow:

  • Wenn userProfile.Name leer ist und conversationData.PromptedUserForNametrue ist, rufen Sie den angegebenen Benutzernamen ab und speichern ihn im Benutzerzustand.
  • Wenn userProfile.Name leer ist und conversationData.PromptedUserForNamefalse ist, fragen Sie nach dem Namen des Benutzers.
  • Wenn userProfile.Name zuvor gespeichert wurde, gehen Sie wie folgt vor: Sie rufen die Uhrzeit der Nachricht und die Kanal-ID aus der Benutzereingabe ab, geben alle Daten an den Benutzer zurück und speichern die abgerufenen Daten im Konversationszustand.

Bots/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}");
    }
}

Bevor Sie den Turn-Handler beenden, schreiben Sie mit der SaveChangesAsync()-Methode der Zustandsverwaltungsobjekte alle Zustandsänderungen zurück in den Speicher.

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

Bot testen

  1. Laden Sie die aktuelle Version von Bot Framework Emulator herunter, und installieren Sie sie.
  2. Führen Sie das Beispiel lokal auf Ihrem Computer aus. Wenn Sie eine Anleitung benötigen, lesen Se die Infodateien für C#, JavaScript, Java oder Python.
  3. Verwenden des Emulators zum Testen des Beispiel-Bots.

Weitere Informationen

In diesem Artikel wird beschrieben, wie Sie Ihrem Bot Status hinzufügen können. In der folgenden Tabelle finden Sie weitere Informationen zu verwandten Themen.

Thema Hinweise
Datenschutz Wenn Sie persönliche Daten von Benutzern speichern möchten, müssen Sie sicherstellen, dass die Anforderungen der Datenschutz-Grundverordnung erfüllt sind.
Zustandsverwaltung Alle Aufrufe der Zustandsverwaltung sind asynchron, und standardmäßig gilt der Konfliktauflösungsmodus „Letzter Schreiber gewinnt“. In der Praxis sollten Sie das Abrufen, Festlegen und Speichern des Zustands in Ihrem Bot möglichst nah beieinander anordnen. Eine Erläuterung zur Implementierung optimistischer Sperren finden Sie unter Implementieren des benutzerdefinierten Speichers für Ihren Bot.
Kritische Geschäftsdaten Verwenden Sie den Botzustand zum Speichern von Einstellungen, des Benutzernamens oder der letzten Bestellung, aber nicht zum Speichern von kritischen Geschäftsdaten. Erstellen Sie für kritische Daten eigene Speicherkomponenten, oder schreiben Sie direkt in den Speicher.
Recognizer-Text In diesem Beispiel werden die Microsoft/Recognizers-Text-Bibliotheken verwendet, um Benutzereingaben zu analysieren und zu überprüfen. Weitere Informationen finden Sie auf der Seite mit der Übersicht.

Nächste Schritte

Lernen Sie, wie Sie dem Benutzer eine Reihe von Fragen stellen, seine Antworten überprüfen und seine Eingaben speichern können.