Administración de estadosManaging state

se aplica a: SDK V4APPLIES TO: SDK v4

El estado dentro de un bot sigue los mismos paradigmas que las aplicaciones web modernas, y Bot Framework SDK proporciona algunas abstracciones para facilitar la administración de estados.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.

Al igual que con las aplicaciones web, un bot intrínsecamente carece de estado; una instancia diferente del puede controlar cualquier turno determinado de la conversación.As with web apps, a bot is inherently stateless; a different instance of your bot may handle any given turn of the conversation. Para algunos bots, se prefiere esta simplicidad: el bot puede funcionar sin información adicional o se garantiza que la información necesaria esté dentro — del mensaje entrante.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. Para otros, el estado (por ejemplo, dónde dejó la conversación o los datos recibidos previamente sobre el usuario) es necesario para que el bot tenga una conversación útil.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.

¿Por qué necesito el estado?Why do I need state?

Mantener el estado permite que el bot mantenga conversaciones más significativas al recordar ciertas cosas sobre un usuario o una conversación.Maintaining state allows your bot to have more meaningful conversations by remembering certain things about a user or conversation. Por ejemplo, si ha hablado con un usuario anteriormente, puede guardar información previa sobre él, para no tener que volver a pedirla.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. El estado también mantiene los datos durante más tiempo que el turno actual, de modo que el bot conserva la información en el transcurso de una conversación de varios turnos.State also keeps data for longer than the current turn, so that your bot keeps information over the course of a multi-turn conversation.

En lo que se refiere a los bots, hay algunas capas para usar el estado: la capa de almacenamiento, la administración de estado (incluida en el estado del bot en el diagrama siguiente) y los accessors de propiedad de estado.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. Este diagrama muestra las partes de la secuencia de interacción entre estas capas. Las flechas de línea continua representan una llamada al método, mientras que las flechas de línea discontinua representan la respuesta (con o sin un valor devuelto).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).

estado del bot

El flujo de este diagrama se explica en las siguientes secciones y se incluyen detalles de cada capa.The flow of this diagram is explained in following sections with details each of these layers.

Capa de almacenamientoStorage layer

A partir del back-end, donde se almacena realmente la información de estado, es la capa de almacenamiento.Starting at the backend, where the state information is actually stored, is the storage layer. Esto se puede pensar como el almacenamiento físico, como en memoria, Azure o un servidor de terceros.This can be thought of as your physical storage, such as in-memory, Azure, or a third party server.

Bot Framework SDK incluye algunas implementaciones de la capa de almacenamiento:The Bot Framework SDK includes some implementations for the storage layer:

  • Almacenamiento en memoria implementa el almacenamiento en memoria con fines de prueba.Memory storage implements in-memory storage for testing purposes. El almacenamiento de datos en memoria está destinado únicamente a pruebas locales, ya que este almacenamiento es volátil y temporal.In-memory data storage is intended for local testing only as this storage is volatile and temporary. Los datos se borran cada vez que se reinicia el bot.The data is cleared each time the bot is restarted.
  • Azure Blob Storage se conecta a una base de datos de objetos Azure Blob Storage.Azure Blob Storage connects to an Azure Blob Storage object database.
  • El almacenamiento con particiones de Azure Cosmos DB se conecta a una base de datos NoSQL de Cosmos DB.Azure Cosmos DB partitioned storage connects to a partitioned Cosmos DB NoSQL database.

Importante

La clase almacenamiento de Cosmos DB está en desuso.The Cosmos DB storage class has been deprecated. Los contenedores creados originalmente con CosmosDbStorage no tenían ningún conjunto de claves de partición y se les dio la clave de partición predeterminada / de "_partitionKey".Containers originally created with CosmosDbStorage had no partition key set, and were given the default partition key of "/_partitionKey".

Los contenedores creados Cosmos DB almacenamiento se pueden usar con Cosmos DB con particiones.Containers created with Cosmos DB storage can be used with Cosmos DB partitioned storage. Para más información, consulte Creación de particiones en Azure Cosmos DB.Read Partitioning in Azure Cosmos DB for more information.

Tenga en cuenta también que, a diferencia del almacenamiento de Cosmos DB heredado, el Cosmos DB con particiones no crea automáticamente una base de datos dentro de Cosmos DB cuenta.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. Debe crear manualmente una basede datos, pero omitir la creación manual de un contenedor, ya que CosmosDbPartitionedStorage creará el contenedor automáticamente.You need to create a new database manually, but skip manually creating a container since CosmosDbPartitionedStorage will create the container for you.

Para obtener instrucciones sobre cómo conectarse a otras opciones de almacenamiento, consulte Escritura directa en el almacenamiento.For instructions on how to connect to other storage options, see write directly to storage.

Administración de estadosState management

La administración de estados automatiza la lectura y escritura de estado del bot a la capa de almacenamiento subyacente.State management automates the reading and writing of your bot's state to the underlying storage layer. El estado se almacena como propiedades de estado, que son pares clave-valor que el bot puede leer y escribir mediante el objeto de administración de estados sin preocuparse por la implementación subyacente específica.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. Las propiedades de estado definen cómo se almacena esa información.Those state properties define how that information is stored. Por ejemplo, cuando se recupera una propiedad que se ha definido como una clase u objeto específico, se sabe cómo se estructurarán los datos.For example, when you retrieve a property that you defined as a specific class or object, you know how that data will be structured.

Estas propiedades de estado se agrupan en el ámbito de "cubos", que son solo colecciones para ayudar a organizar esas propiedades.These state properties are lumped into scoped "buckets", which are just collections to help organize those properties. El SDK incluye tres de estos "cubos":The SDK includes three of these "buckets":

  • Estado de usuarioUser state
  • Estado de conversaciónConversation state
  • Estado de conversación privadaPrivate conversation state

Todos estos cubos son subclases de la clase estado de bot, que se puede derivar para definir otros tipos de cubos con ámbitos diferentes.All of these buckets are subclasses of the bot state class, which can be derived to define other types of buckets with different scopes.

Estos cubos predefinidos tienen una cierta visibilidad, dependiendo del cubo:These predefined buckets are scoped to a certain visibility, depending on the bucket:

  • El estado de usuario está disponible en cualquier momento que el bot esté conversando con ese usuario en ese canal, independientemente de la conversación.User state is available in any turn that the bot is conversing with that user on that channel, regardless of the conversation
  • El estado de conversación está disponible en cualquier momento de una conversación específica, independientemente del usuario (es decir, conversaciones de grupo).Conversation state is available in any turn in a specific conversation, regardless of user (i.e. group conversations)
  • El estado de conversación privada se extiende tanto a la conversación específica como a ese usuario específico.Private conversation state is scoped to both the specific conversation and to that specific user

Sugerencia

Tanto el estado del usuario como el de la conversación están delimitados por canal.Both user and conversation state are scoped by channel. La misma persona que utiliza diferentes canales para acceder al bot aparece como usuarios diferentes, uno para cada canal y cada uno con un estado de usuario distinto.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.

Las claves utilizadas para cada uno de estos cubos predefinidos son específicas para el usuario y la conversación, o para ambos.The keys used for each of these predefined buckets are specific to the user and conversation, or both. Al establecer el valor de su propiedad de estado, la clave se define internamente con información contenida en el contexto del turno para asegurar que cada usuario o conversación se coloca en el cubo y la propiedad correctos.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. En concreto, las claves se definen de la manera siguiente:Specifically, the keys are defined as follows:

  • El estado de usuario crea una clave con el identificador de canal y el identificador de procedencia.The user state creates a key using the channel ID and from ID. Por ejemplo, {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyNameFor example, {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
  • El estado de conversación crea una clave con el identificador de canal y el identificador de conversación.The conversation state creates a key using the channel ID and the conversation ID. Por ejemplo, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyNameFor example, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
  • El estado de conversación privada crea una clave con el identificador de canal, el identificador de procedencia y el identificador de conversación.The private conversation state creates a key using the channel ID, from ID and the conversation ID. Por ejemplo, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyNameFor example, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName

Cuándo usar cada tipo de estadoWhen to use each type of state

El estado de conversación es bueno para realizar el seguimiento del contexto de la conversación, como por ejemplo:Conversation state is good for tracking the context of the conversation, such as:

  • Si el bot le formula una pregunta al usuario, y cuál fue la preguntaWhether the bot asked the user a question, and which question that was
  • Cuál es el tema actual de conversación o cuál fue el últimoWhat the current topic of conversation is, or what the last one was

El estado de usuario es bueno para realizar el seguimiento de la información sobre el usuario, como por ejemplo:User state is good for tracking information about the user, such as:

  • Información de usuario no crítica, como el nombre y las preferencias, una configuración de alarma o una preferencia de alertaNon-critical user information, such as name and preferences, an alarm setting, or an alert preference
  • Información sobre la última conversación que tuvieron con el botInformation about the last conversation they had with the bot
    • Por ejemplo, un bot de soporte técnico de productos puede realizar el seguimiento de los productos sobre los que el usuario ha preguntado.For instance, a product-support bot might track which products the user has asked about.

El estado de conversación privada es bueno para los canales que admiten conversaciones de grupo, pero en los que se desea realizar un seguimiento de la información específica del usuario y de la conversación.Private conversation state is good for channels that support group conversations, but where you want to track both user and conversation specific information. Por ejemplo, si tiene un bot de sistema de respuesta en el aula:For example, if you had a classroom clicker bot:

  • El bot puede agregar y mostrar las respuestas de los alumnos para una pregunta dada.The bot could aggregate and display student responses for a given question.
  • El bot puede agregar el rendimiento de cada alumno y transmitirlo en privado al final de la sesión.The bot could aggregate each student's performance and privately relay that back to them at the end of the session.

Para más información sobre el uso de estos cubos predefinidos, consulte el artículo de procedimientos de estado.For details on using these predefined buckets, see the state how-to article.

Conexión a varias bases de datosConnecting to multiple databases

Si el bot necesita conectarse a varias bases de datos, cree una capa de almacenamiento para cada base de datos.If your bot needs to connect to multiple databases, create a storage layer for each database. Puede optar por usar varias bases de datos si el bot recopila información que tiene diferentes necesidades de seguridad, simultaneidad o ubicación de datos.You might choose to use multiple databases if your bot collects information that has different security, concurrency, or data location needs.

Para cada capa de almacenamiento, cree los objetos de administración de estado que necesita para admitir las propiedades de estado.For each storage layer, create the state management objects you need to support your state properties.

Descriptores de acceso de propiedad de estadoState property accessors

Los descriptores de acceso de la propiedad de estado se usan para leer o escribir una de las propiedades de estado y proporcionan los métodos para obtener, establecer y eliminar con el fin de acceder a las propiedades de estado desde dentro de un turno.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. Para crear un descriptor de acceso, debe proporcionar el nombre de la propiedad, que normalmente tiene lugar cuando se inicializa el bot.To create an accessor, you must provide the property name, which usually takes place when you're initializing your bot. Entonces, puede usar ese descriptor de acceso para obtener y manipular esa propiedad de estado del bot.Then, you can use that accessor to get and manipulate that property of your bot's state.

Los descriptores de acceso permiten que el SDK obtenga el estado del almacenamiento subyacente y actualice la caché de estado del bot para el usuario.The accessors allow the SDK to get state from the underlying storage, and update the bot's state cache for you. La caché de estado es una caché local mantenida por el bot que almacena el objeto de estado por el usuario, lo que permite operaciones de lectura y escritura sin acceder al almacenamiento subyacente.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. Si aún no está en la memoria caché, una llamada al método para obtener el descriptor de acceso recupera el estado y también lo coloca en la memoria caché.If it isn't already in the cache, calling the accessor's get method retrieves state and also places it in the cache. Una vez recuperada, la propiedad de estado puede manipularse como una variable local.Once retrieved, the state property can be manipulated just like a local variable.

El método para eliminar el descriptor de acceso quita la propiedad de la memoria caché y también la elimina del almacenamiento subyacente.The accessor's delete method removes the property from the cache, and also deletes it from the underlying storage.

Importante

Para la primera llamada a un método para obtener el descriptor de acceso, debe proporcionar un método de generador para crear el objeto si aún no existe en el estado.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. Si no se especifica ningún método de generador, obtendrá una excepción.If no factory method is given, you will get an exception. Encontrará más información sobre cómo usar un método de generador en el artículo de procedimientos de estado.Details on how to use a factory method can be found in the state how-to article.

Para conservar los cambios que realice en la propiedad de estado que obtiene del descriptor de acceso, la propiedad de la caché de estado debe actualizarse.To persist any changes you make to the state property you get from the accessor, the property in the state cache must be updated. Puede hacerlo mediante una llamada al método para establecer los descriptores de acceso, que establece el valor de la propiedad en la caché y está disponible si necesita leerlo o actualizarlo más tarde en ese turno.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. Para que esos datos permanezcan realmente en el almacenamiento subyacente (y por lo tanto estén disponibles después del turno actual), debe entonces guardar su estado.To actually persist that data to the underlying storage (and thus make it available after the current turn), you must then save your state.

Funcionamiento de los métodos de descriptor de acceso de propiedades de estadoHow the state property accessor methods work

Los métodos de descriptor de acceso son la manera principal para el bot interactúe con el estado.The accessor methods are the primary way for your bot to interact with state. La forma como trabajan y cómo interactúan las capas subyacentes son las siguientes:How each work, and how the underlying layers interact, are as follows:

  • Método para obtener el descriptor de acceso:The accessor's get method:
    • El descriptor de acceso solicita la propiedad desde la caché de estado.Accessor requests property from the state cache.
    • Si la propiedad está en la caché, la devuelve.If the property is in the cache, return it. De lo contrario, obténgalo del objeto de administración de estados.Otherwise, get it from the state management object. (Si todavía no está en el estado, utilice patrón de diseño Factory Method proporcionado en la llamada para obtener los descriptores de acceso).(If it is not yet in state, use the factory method provided in the accessors get call.)
  • Método para establecer el descriptor de acceso:The accessor's set method:
    • Actualice la caché de estado con el nuevo valor de propiedad.Update the state cache with the new property value.
  • Método para guardar cambios del objeto de administración de estados:The state management object's save changes method:
    • Compruebe los cambios de la propiedad en la caché de estado.Check the changes to the property in the state cache.
    • Escriba esa propiedad en el almacenamiento.Write that property to storage.

Estado en los diálogosState in dialogs

La biblioteca de diálogos usa un accessor de propiedad de estado de diálogo, definido en el estado de conversación del bot, para conservar el lugar de un diálogo en la conversación.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. La propiedad de estado del diálogo también permite que cada diálogo almacene información transitoria entre turnos.The dialog state property also allows each dialog to store transient information in between turns.

Los diálogos adaptables tienen una estructura de ámbito de memoria más elaborado, lo que facilita el acceso a los resultados de la configuración y el reconocimiento, entre otras cosas.Adaptive dialogs have a more elaborate memory scope structure, which makes it easier to access configuration and recognition results, among other things. El administrador de diálogos usa los objetos de administración de estado de usuario y conversación para proporcionar estos ámbitos de memoria.The dialog manager uses the user and conversation state management objects to provide these memory scopes.

Para obtener información sobre la biblioteca de diálogos, vea el artículo biblioteca de diálogos.For information about the dialogs library, see the dialogs library article.

Almacenamiento del estadoSaving state

Cuando llama al método para establecer el descriptor de acceso para registrar el estado actualizado, esa propiedad de estado todavía no se ha guardado en el almacenamiento persistente y, en su lugar, solo se guarda en la caché de estado del bot.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. Para guardar cualquier cambio en la caché de estado en el estado persistente, debe llamar al método para guardar cambios del objeto de administración de estados, que está disponible en la implementación de la clase de estado de bot mencionada anteriormente (como el estado de usuario o el estado de conversación).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).

La llamada al método para guardar cambios para un objeto de administración de estados (es decir, los cubos mencionados anteriormente) guarda todas las propiedades en la caché de estado que ha configurado hasta ese momento para ese cubo, pero no para ninguno de los otros cubos que pueda tener en el estado de bot.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.

Sugerencia

El estado del bot implementa un comportamiento del tipo "la última escritura prevalece", por el cual la última escritura sobrescribirá al estado escrito anteriormente.Bot state implements a "last write wins" behavior, where the last write will stamp over the previously written state. Esto puede funcionar para muchas aplicaciones, pero tiene otras implicaciones, especialmente en escenarios de escalado horizontal en los que puede haber un cierto nivel de simultaneidad o latencia en juego.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.

Si tiene algún middleware personalizado que pueda actualizar el estado después de que su controlador de turno se complete, considere controlar el estado en el middleware.If you have some custom middleware that might update state after your turn handler completes, consider handling state in middleware.

Recursos adicionalesAdditional resources