Verwalten des ZustandsManaging state

gilt für: SDK v4APPLIES TO: SDK v4

Der Zustand in einem Bot basiert auf den gleichen Paradigmen wie bei modernen Webanwendungen, und über das Bot Framework SDK werden einige Abstraktionen bereitgestellt, um die Verwaltung des Zustands zu vereinfachen.State within a bot follows the same paradigms as modern web applications, and the Bot Framework SDK provides some abstractions to make state management easier.

Wie bei Web-Apps auch, ist ein Bot grundsätzlich zustandslos. Jedes einzelne Segment der Konversation kann auch von einer anderen Instanz Ihres Bots verarbeitet werden.As with web apps, a bot is inherently stateless; a different instance of your bot may handle any given turn of the conversation. Für einige Bots wird diese Einfachheit bevorzugt, wenn der Bot entweder ohne zusätzliche Informationen arbeiten kann, oder die erforderlichen Informationen sind garantiert innerhalb der — eingehenden Nachricht enthalten.For some bots, this simplicity is preferred—the bot can either operate without additional information, or the information required is guaranteed to be within the incoming message. Für andere Benutzer ist der Zustand (z. B. der Ort, an dem die Konversation aufgelassen wurde, oder daten, die zuvor über den Benutzer empfangen wurden) erforderlich, damit der Bot eine nützliche Konversation hat.For others, state (such as where the conversation left off or data previously received about the user) is necessary for the bot to have a useful conversation.

Warum benötige ich den Zustand?Why do I need state?

Wenn der Zustand verwaltet wird, kann Ihr Bot aussagekräftigere Konversationen durchführen, indem bestimmte Punkte zu einem Benutzer oder einer Konversation gespeichert werden.Maintaining state allows your bot to have more meaningful conversations by remembering certain things about a user or conversation. Wenn mit einem Benutzer beispielsweise schon einmal eine Konversation erfolgt ist, können Sie die bereits erhaltenen Informationen zum Benutzer speichern, damit Sie nicht noch einmal danach fragen müssen.For example, if you've talked to a user previously, you can save previous information about them, so that you don't have to ask for it again. Bei der Zustandsspeicherung werden Daten auch länger als nur für den aktuellen Durchlauf (Turn) gespeichert, damit Informationen auch im Verlauf einer Konversation mit mehreren Durchläufen erhalten bleiben.State also keeps data for longer than the current turn, so that your bot keeps information over the course of a multi-turn conversation.

Im Zusammenhang mit Bots gibt es einige Ebenen für die Verwendung des Zustands: speicherebene, Zustandsverwaltung (im Botzustand im folgenden Diagramm enthalten) und Zustandseigenschaftszugriffe.As it pertains to bots, there are a few layers to using state: the storage layer, state management (contained in the bot state in the diagram below), and state property accessors. Das Diagramm zeigt Teile der Interaktionssequenz zwischen diesen Ebenen. Die durchgezogenen Pfeile stellen einen Methodenaufruf dar, und die gestrichelten Pfeile stellen die Antwort dar (mit oder ohne Rückgabewert).This diagram illustrates parts of the interaction sequence between these layers, with the solid arrows representing a method call, and the dashed arrows representing the response (with or without a return value).

Botzustand

Der im Diagramm dargestellte Fluss wird in den folgenden Abschnitten mit Details zu jeder dieser Ebenen erläutert.The flow of this diagram is explained in following sections with details each of these layers.

SpeicherebeneStorage layer

Ab dem Back-End, wo die Zustandsinformationen tatsächlich gespeichert werden, ist die Speicherebene.Starting at the backend, where the state information is actually stored, is the storage layer. Dies kann man sich als Ihren physischen Speicher wie In-Memory, Azure oder einen Server eines Drittanbieters bzw. eines Drittanbieters bzw. eines Drittanbieterservers bzw. eines Drittanbieters bzw. eines Drittanbieters bzw.This can be thought of as your physical storage, such as in-memory, Azure, or a third party server.

Das Bot Framework SDK enthält einige Implementierungen für die Speicherebene:The Bot Framework SDK includes some implementations for the storage layer:

  • Bei Arbeitsspeicher wird zu Testzwecken In-Memory-Speicher implementiert.Memory storage implements in-memory storage for testing purposes. In-Memory-Datenspeicher ist nur für lokale Tests bestimmt, da er flüchtig und temporär ist.In-memory data storage is intended for local testing only as this storage is volatile and temporary. Die Daten werden jedes Mal gelöscht, wenn der Bot neu gestartet wird.The data is cleared each time the bot is restarted.
  • Bei Azure Blob Storage wird eine Verbindung mit einer Azure Blob Storage-Objektdatenbank hergestellt.Azure Blob Storage connects to an Azure Blob Storage object database.
  • Bei partitioniertem Azure Cosmos DB-Speicher wird eine Verbindung mit einer partitionierten Cosmos DB-NoSQL-Datenbank hergestellt.Azure Cosmos DB partitioned storage connects to a partitioned Cosmos DB NoSQL database.

Wichtig

Die Klasse Cosmos DB-Speicher wurde als veraltet gekennzeichnet.The Cosmos DB storage class has been deprecated. Container, die ursprünglich mit CosmosDbStorage erstellt wurden, hatten keinen Partitionsschlüssel festgelegt und erhalten den Standardpartitionsschlüssel / "_partitionKey".Containers originally created with CosmosDbStorage had no partition key set, and were given the default partition key of "/_partitionKey".

Container, die mit Cosmos DB-Speicher erstellt wurden, können mit Cosmos DB partitionierten Speicher verwendet werden.Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. Weitere Informationen finden Sie unter Partitionierung in Azure Cosmos DB.Read Partitioning in Azure Cosmos DB for more information.

Beachten Sie auch, dass im Gegensatz zum legacy-Cosmos DB-Speicher der Cosmos DB partitionierte Speicher nicht automatisch eine Datenbank in Ihrem Cosmos DB erstellt.Also note that, unlike the legacy Cosmos DB storage, the Cosmos DB partitioned storage does not automatically create a database within your Cosmos DB account. Sie müssen manuell eine neueDatenbank erstellen, aber das manuelle Erstellen eines Containers überspringen, da CosmosDbPartitionedStorage den Container für Sie erstellt.You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

Eine Anleitung zum Herstellen einer Verbindung für andere Speicheroptionen finden Sie unter Direktes Schreiben in den Speicher.For instructions on how to connect to other storage options, see write directly to storage.

ZustandsverwaltungState management

Mit der Zustandsverwaltung wird das Lesen und Schreiben des Zustands Ihres Bots auf die zugrunde liegende Speicherebene automatisiert.State management automates the reading and writing of your bot's state to the underlying storage layer. Der Zustand wird in Form von Zustandseigenschaften gespeichert. Hierbei handelt es sich im Wesentlichen um Schlüssel-Wert-Paare, die von Ihrem Bot über das Zustandsverwaltungsobjekt gelesen und geschrieben werden können, ohne sich um die zugrunde liegenden Implementierungen kümmern zu müssen.State is stored as state properties, which are effectively key-value pairs that your bot can read and write through the state management object without worrying about the specific underlying implementation. Mit diesen Zustandseigenschaften wird definiert, wie diese Informationen gespeichert werden.Those state properties define how that information is stored. Wenn Sie beispielsweise eine Eigenschaft abrufen, die Sie als spezifische Klasse oder Objekt definiert haben, wissen Sie, wie diese Daten strukturiert werden.For example, when you retrieve a property that you defined as a specific class or object, you know how that data will be structured.

Diese Zustandseigenschaften werden in bereichsbezogenen „Buckets“ zusammengefasst, wobei es sich lediglich um Sammlungen für die Organisation dieser Eigenschaften handelt.These state properties are lumped into scoped "buckets", which are just collections to help organize those properties. Das SDK enthält drei dieser Buckets:The SDK includes three of these "buckets":

  • BenutzerzustandUser state
  • KonversationszustandConversation state
  • Zustand der privaten KonversationPrivate conversation state

Alle diese Buckets sind Unterklassen der Bot State-Klasse, von der Ableitungen erstellt werden können, um andere Arten von Buckets mit anderen Bereichen zu definieren.All of these buckets are subclasses of the bot state class, which can be derived to define other types of buckets with different scopes.

Diese vordefinierten Buckets beziehen sich jeweils auf eine bestimmte Sichtbarkeit:These predefined buckets are scoped to a certain visibility, depending on the bucket:

  • Der Benutzerzustand ist für jeden Durchlauf verfügbar, den der Bot unabhängig von der Konversation mit dem Benutzer über den Kanal durchführt.User state is available in any turn that the bot is conversing with that user on that channel, regardless of the conversation
  • Der Konversationszustand ist für jeden Durchlauf einer bestimmten Konversation unabhängig vom Benutzer (also den Gruppenkonversationen) verfügbar.Conversation state is available in any turn in a specific conversation, regardless of user (i.e. group conversations)
  • Der Zustand der privaten Konversation bezieht sich auf die jeweilige Konversation und den jeweiligen Benutzer.Private conversation state is scoped to both the specific conversation and to that specific user

Tipp

Sowohl der Benutzerzustand als auch der Konversationszustand bezieht sich jeweils auf den Kanal.Both user and conversation state are scoped by channel. Wenn eine Person unterschiedliche Kanäle nutzt, um auf Ihren Bot zuzugreifen, wird sie jeweils als ein anderer Benutzer angezeigt (einer für jeden Kanal), der jeweils einen eigenen Benutzerzustand aufweist.The same person using different channels to access your bot appears as different users, one for each channel, and each with a distinct user state.

Die Schlüssel, die für diese einzelnen vordefinierten Buckets verwendet werden, gelten spezifisch für den Benutzer oder die Konversation (oder beides).The keys used for each of these predefined buckets are specific to the user and conversation, or both. Beim Festlegen des Werts Ihrer Zustandseigenschaft wird der Schlüssel für Sie intern definiert und umfasst die im Durchlaufkontext enthaltenen Informationen, um sicherzustellen, dass die einzelnen Benutzer bzw. Konversationen im richtigen Bucket und unter der richtigen Eigenschaft angeordnet werden.When setting the value of your state property, the key is defined for you internally with information contained on the turn context to ensure that each user or conversation gets placed in the correct bucket and property. Die Schlüssel werden wie folgt definiert:Specifically, the keys are defined as follows:

  • Vom Benutzerzustand wird ein Schlüssel erstellt, indem die Kanal-ID und die Von-ID (Channel ID/From ID) verwendet werden.The user state creates a key using the channel ID and from ID. Beispiel: {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName.For example, {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
  • Mit dem Konversationszustand wird ein Schlüssel erstellt, indem die Kanal-ID und die Konversations-ID (Channel ID/Conversation ID) verwendet werden.The conversation state creates a key using the channel ID and the conversation ID. Beispiel: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName.For example, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
  • Mit dem Zustand der privaten Konversation wird ein Schlüssel erstellt, indem die Kanal-ID, die Von-ID und die Konversations-ID verwendet werden.The private conversation state creates a key using the channel ID, from ID and the conversation ID. Beispiel: {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName.For example, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName

Verwenden der einzelnen ZustandsartenWhen to use each type of state

Der Konversationszustand ist gut für die Nachverfolgung des Konversationskontexts, z.B.:Conversation state is good for tracking the context of the conversation, such as:

  • Ob der Bot dem Benutzer eine Frage gestellt hat und welche Frage dies warWhether the bot asked the user a question, and which question that was
  • Was das aktuelle Thema der Konversation ist oder das vorherige Thema warWhat the current topic of conversation is, or what the last one was

Der Benutzerzustand ist gut für Nachverfolgungsinformationen zum Benutzer, z.B.:User state is good for tracking information about the user, such as:

  • Nicht kritische Benutzerinformationen, z.B. Name und Präferenzen, eine Alarmeinstellung oder eine AlarmpräferenzNon-critical user information, such as name and preferences, an alarm setting, or an alert preference
  • Informationen zur letzten Konversation des Benutzers mit dem BotInformation about the last conversation they had with the bot
    • Ein Bot für die Produktunterstützung kann beispielsweise verfolgen, nach welchen Produkten der Benutzer gefragt hat.For instance, a product-support bot might track which products the user has asked about.

Der private Konversationszustand ist gut für Kanäle, die Gruppenkonversationen unterstützen, bei denen Sie aber sowohl benutzer- als auch konversationsspezifische Informationen nachverfolgen möchten.Private conversation state is good for channels that support group conversations, but where you want to track both user and conversation specific information. Beispielsweise bei einem Clicker-Bot für ein Klassenzimmer:For example, if you had a classroom clicker bot:

  • Der Bot kann Antworten der Kursteilnehmer auf eine bestimmte Frage aggregieren und anzeigen.The bot could aggregate and display student responses for a given question.
  • Der Bot kann die Leistung jedes Kursteilnehmers aggregieren und am Ende der Stunde für jeden Kursteilnehmer jeweils „privat“ bereitstellen.The bot could aggregate each student's performance and privately relay that back to them at the end of the session.

Weitere Informationen zur Verwendung dieser vordefinierten Buckets finden Sie im Gewusst-wie-Artikel zum Zustand.For details on using these predefined buckets, see the state how-to article.

Herstellen einer Verbindung mit mehreren DatenbankenConnecting to multiple databases

Wenn Ihr Bot eine Verbindung mit mehreren Datenbanken herstellen muss, können Sie eine Speicherebene für jede Datenbank erstellen.If your bot needs to connect to multiple databases, create a storage layer for each database. Sie können mehrere Datenbanken verwenden, wenn Ihr Bot Informationen sammelt, die unterschiedliche Anforderungen an Sicherheit, Parallelität oder Datenspeicherort erfüllen.You might choose to use multiple databases if your bot collects information that has different security, concurrency, or data location needs.

Erstellen Sie für jede Speicherebene die Objekte für die Zustandsverwaltung, die Sie zum Unterstützen Ihrer Zustandseigenschaften benötigen.For each storage layer, create the state management objects you need to support your state properties.

ZustandseigenschaftenaccessorenState property accessors

Zustandseigenschaftenaccessoren werden verwendet, um das eigentliche Lesen bzw. Schreiben für eine Ihrer Zustandseigenschaften durchzuführen und get-, set- und delete-Methoden für den Zugriff auf Ihre Zustandseigenschaften aus einem Durchlauf bereitzustellen.State property accessors are used to actually read or write one of your state properties, and provide get, set, and delete methods for accessing your state properties from within a turn. Für die Erstellung eines Accessors müssen Sie den Eigenschaftennamen angeben (normalerweise beim Initialisieren Ihres Bots).To create an accessor, you must provide the property name, which usually takes place when you're initializing your bot. Anschließend können Sie diesen Accessor verwenden, um diese Eigenschaft für den Zustand Ihres Bots abzurufen und zu ändern.Then, you can use that accessor to get and manipulate that property of your bot's state.

Mit den Accessoren kann das SDK den Zustand aus dem zugrunde liegenden Speicher abrufen und den Zustandscache für Sie aktualisieren.The accessors allow the SDK to get state from the underlying storage, and update the bot's state cache for you. Der Zustandscache ist ein lokaler Cache, der von Ihrem Bot verwaltet und in dem das Zustandsobjekt für Sie gespeichert wird. Auf diese Weise werden Lese- und Schreibvorgänge ermöglicht, ohne dass auf den zugrunde liegenden Speicher zugegriffen werden muss.The state cache is a local cache maintained by your bot that stores the state object for you, allowing read and write operations without accessing the underlying storage. Wenn er nicht bereits im Cache vorhanden ist, wird durch das Aufrufen der get-Methode des Accessors der Zustand abgerufen und im Cache abgelegt.If it isn't already in the cache, calling the accessor's get method retrieves state and also places it in the cache. Nach dem Abruf kann die Zustandseigenschaft genau wie jede andere lokale Variable geändert werden.Once retrieved, the state property can be manipulated just like a local variable.

Mit der delete-Methode des Accessors wird die Eigenschaft aus dem Cache entfernt und aus dem zugrunde liegenden Speicher gelöscht.The accessor's delete method removes the property from the cache, and also deletes it from the underlying storage.

Wichtig

Für den ersten Aufruf der get-Methode eines Accessors müssen Sie eine Factorymethode für die Erstellung des Objekts bereitstellen, falls es in Ihrem Zustand noch nicht enthalten ist.For the first call to an accessor's get method, you must provide a factory method to create the object if it doesn't yet exist in your state. Wenn keine Factorymethode angegeben ist, tritt eine Ausnahme auf.If no factory method is given, you will get an exception. Ausführliche Informationen zur Nutzung einer Factorymethode finden Sie im Gewusst wie-Artikel zum Zustand.Details on how to use a factory method can be found in the state how-to article.

Damit die Änderungen beibehalten werden, die Sie an der vom Accessor erhaltenen Zustandseigenschaft vornehmen, muss die Eigenschaft im Zustandscache aktualisiert werden.To persist any changes you make to the state property you get from the accessor, the property in the state cache must be updated. Hierfür können Sie die set-Methode des Accessors aufrufen. Mit dieser Methode wird der Wert Ihrer Eigenschaft im Cache festgelegt, damit er verfügbar ist, wenn zu einem späteren Zeitpunkt des Durchlaufs das Lesen oder Aktualisieren erforderlich ist.You can do so via a call the accessors set method, which sets the value of your property in the cache, and is available if that needs to be read or updated later in that turn. Sie müssen dann den Zustand speichern, um diese Daten dauerhaft im zugrunde liegenden Speicher abzulegen (damit sie auch nach dem aktuellen Durchlauf verfügbar sind).To actually persist that data to the underlying storage (and thus make it available after the current turn), you must then save your state.

Funktionsweise der Zustandseigenschaftenaccessor-MethodenHow the state property accessor methods work

Die Accessormethoden stellen den Hauptansatz für die Interaktion Ihres Bots mit dem Zustand dar.The accessor methods are the primary way for your bot to interact with state. Hier sind die einzelnen Funktionsweisen und zugrunde liegenden Ebenen beschrieben:How each work, and how the underlying layers interact, are as follows:

  • Die get-Methode des Accessors:The accessor's get method:
    • Der Accessor fordert die Eigenschaft vom Zustandscache an.Accessor requests property from the state cache.
    • Wenn die Eigenschaft im Cache enthalten ist, wird sie zurückgegeben.If the property is in the cache, return it. Andernfalls wird sie aus dem Zustandsverwaltungsobjekt abgerufen.Otherwise, get it from the state management object. (Falls sie im Zustand noch nicht verfügbar ist, können Sie die Factorymethode im get-Aufruf des Accessors verwenden.)(If it is not yet in state, use the factory method provided in the accessors get call.)
  • Die set-Methode des Accessors:The accessor's set method:
    • Aktualisiert den Zustandscache mit dem neuen Eigenschaftswert.Update the state cache with the new property value.
  • Die save changes-Methode des Objekts für die Zustandsverwaltung:The state management object's save changes method:
    • Überprüfen Sie die Änderungen an der Eigenschaft im Zustandscache.Check the changes to the property in the state cache.
    • Schreiben Sie diese Eigenschaft in den Speicher.Write that property to storage.

Status in DialogfeldernState in dialogs

Die Dialogbibliothek verwendet einen Dialogzustandseigenschaften-Accessor, der für den Konversationszustand des Bots definiert ist, um die Stelle eines Dialogs in der Konversation zu behalten.The dialogs library uses a dialog state property accessor, defined on the bot's conversation state, to retain a dialog's place in the conversation. Die Dialogzustandseigenschaft ermöglicht es jedem Dialog auch, vorübergehende Informationen zwischendurch zu speichern.The dialog state property also allows each dialog to store transient information in between turns.

Adaptive Dialoge verfügen über eine komplexere Speicherbereichsstruktur, die unter anderem den Zugriff auf Konfigurations- und Erkennungsergebnisse erleichtert.Adaptive dialogs have a more elaborate memory scope structure, which makes it easier to access configuration and recognition results, among other things. Der Dialog-Manager verwendet die Benutzer- und Konversationszustandsverwaltungsobjekte, um diese Speicherbereiche bereitzustellen.The dialog manager uses the user and conversation state management objects to provide these memory scopes.

Informationen zur Dialogbibliothek finden Sie im Artikel Dialogbibliothek.For information about the dialogs library, see the dialogs library article.

Speichern des ZustandsSaving state

Wenn Sie die set-Methode des Accessors aufrufen, um den aktualisierten Zustand aufzuzeichnen, wurde diese Zustandseigenschaft noch nicht in Ihrem permanenten Speicher abgelegt, sondern nur im Zustandscache Ihres Bots.When you call the accessor's set method to record the updated state, that state property has not yet been saved to your persisted storage, and instead is only saved to your bot's state cache. Um die im Zustandscache befindlichen Änderungen im permanenten Speicher abzulegen, müssen Sie die save changes-Methode des Zustandsverwaltungsobjekts aufrufen. Sie ist unter der oben erwähnten Implementierung der Botzustandsklasse verfügbar (z.B. Benutzerzustand oder Konversationszustand).To save any changes in the state cache to your persisted state, you must call the state management object's save changes method, which is available on the implementation of the bot state class mentioned above (such as user state or conversation state).

Durch das Aufrufen der „save changes“-Methode für ein Zustandsverwaltungsobjekt (also die oben erwähnten Buckets) werden alle Eigenschaften, die Sie für den jeweiligen Bucket bisher eingerichtet haben, im Zustandscache gespeichert. Dies gilt aber nicht für die anderen Buckets, über die Sie unter dem Zustand Ihres Bots ggf. verfügen.Calling the save changes method for a state management object (i.e. the buckets mentioned above) saves all properties in the state cache that you have set up to that point for that bucket, but not for any of the other buckets you may have in your bot's state.

Tipp

Anhand des Botzustands wird das Verhalten „letzter Schreibvorgang gewinnt“ implementiert, bei dem der letzte Schreibvorgang den vorherigen Schreibzustand außer Kraft setzt.Bot state implements a "last write wins" behavior, where the last write will stamp over the previously written state. Dieses Verhalten ist ggf. für viele Anwendungen geeignet, aber es sind einige Aspekte zu beachten. Dies gilt vor allem für Szenarien mit horizontaler Skalierung, bei denen bestimmte Parallelitäts- oder Latenzebenen zu berücksichtigen sind.This may work for many applications but has implications, particularly in scaled-out scenarios, where there may be some level of concurrency or latency in play.

Falls Sie über benutzerdefinierte Middleware verfügen, über die der Zustand nach Abschluss Ihres Turn-Handlers aktualisiert wird, helfen Ihnen ggf. die Informationen unter Verarbeiten des Zustands in Middleware weiter.If you have some custom middleware that might update state after your turn handler completes, consider handling state in middleware.

Zusätzliche RessourcenAdditional resources