Managing state (Gerir o estado)
APLICA-SE A: SDK v4
O estado num bot segue os mesmos paradigmas que as aplicações Web modernas e o SDK do Bot Framework oferece algumas abstrações para facilitar a gestão do estado.
Tal como acontece com as aplicações Web, um bot é inerentemente sem estado; uma instância diferente do bot pode lidar com qualquer alteração à conversa. Para alguns bots, esta simplicidade é preferida - o bot pode operar sem informações adicionais, ou as informações necessárias são garantidas dentro da mensagem de entrada. Para outros, o estado (como o local onde a conversa foi deixada ou os dados previamente recebidos sobre o utilizador) é necessário para que o bot tenha uma conversa útil.
Por que preciso de estado?
Manter o estado permite que o seu bot tenha conversas mais significativas lembrando certas coisas sobre um utilizador ou conversa. Por exemplo, se já falou com um utilizador anteriormente, pode guardar informações anteriores sobre eles, para que não tenha de pedir novamente. O Estado também mantém os dados por mais tempo do que a curva atual, de modo que o seu bot mantém a informação ao longo de uma conversa multi-volta.
No que diz respeito aos bots, existem algumas camadas para usar o estado: a camada de armazenamento, a gestão do estado (contida no estado bot no diagrama abaixo) e os acessórios de propriedade do Estado. Este diagrama ilustra partes da sequência de interação entre estas camadas, com as setas sólidas representando uma chamada de método, e as setas tracejadas que representam a resposta (com ou sem valor de retorno).
O fluxo deste diagrama é explicado nas seguintes secções com detalhes de cada uma destas camadas.
Camada de armazenamento
A partir do backend, onde a informação do estado é realmente armazenada, é a camada de armazenamento. Isto pode ser considerado como o seu armazenamento físico, como em memória, Azure ou um servidor de terceiros.
O Bot Framework SDK inclui algumas implementações para a camada de armazenamento:
- O armazenamento de memória implementa o armazenamento na memória para fins de teste. O armazenamento de dados em memória destina-se apenas a testes locais, uma vez que este armazenamento é volátil e temporário. Os dados são limpos cada vez que o bot é reiniciado.
- Armazenamento de Blobs do Azure liga-se a uma base de dados de objetos Armazenamento de Blobs do Azure.
- O armazenamento dividido Azure Cosmos DB liga-se a uma base de dados noSQL do Cosmos.
Importante
A classe de armazenamento cosmos DB foi depreciada. Os contentores originalmente criados com CosmosDbStorage não tinham conjunto de chaves de partição, e receberam a chave de partição padrão de "/_partitionKey".
Os recipientes criados com armazenamento DeSS cosmos podem ser usados com armazenamento de divisórias Cosmos DB. Leia a Partição em Azure Cosmos DB para mais informações.
Note também que, ao contrário do armazenamento de Coss DB legado, o armazenamento dividido em Cosmos DB não cria automaticamente uma base de dados dentro da sua conta Cosmos DB. Precisa de criar uma nova base de dados manualmente, mas ignore manualmente a criação de um recipiente, uma vez que o CosmosDbPartitionedStorage irá criar o recipiente para si.
Para obter instruções sobre como ligar-se a outras opções de armazenamento, consulte a escrita diretamente para o armazenamento.
Gestão de estados
A gerência do Estado automatiza a leitura e a escrita do estado do seu bot para a camada de armazenamento subjacente. O Estado é armazenado como propriedades do estado, que são efetivamente pares de valor-chave que o seu bot pode ler e escrever através do objeto de gestão do estado sem se preocupar com a implementação específica subjacente. Essas propriedades do Estado definem como essa informação é armazenada. Por exemplo, quando recupera uma propriedade que definiu como uma classe ou objeto específico, sabe como esses dados serão estruturados.
Estas propriedades do Estado são agrupadas em "baldes" com âmbito, que são apenas coleções para ajudar a organizar essas propriedades. O SDK inclui três destes "baldes":
- Estado do utilizador
- Estado de conversação
- Estado de conversa privada
Todos estes baldes são subclasses da classe estatal bot , que pode ser derivada para definir outros tipos de baldes com diferentes âmbitos.
Estes baldes predefinidos são traçados para uma certa visibilidade, dependendo do balde:
- O estado do utilizador está disponível em qualquer turno que o bot esteja a conversar com esse utilizador naquele canal, independentemente da conversação
- O estado de conversação está disponível em qualquer turno numa conversa específica, independentemente do utilizador, como em conversas de grupo
- O estado de conversação privada é traçado tanto para a conversa específica como para aquele utilizador específico
Dica
Tanto o estado de utilizador como o estado de conversação são examinados por canal. A mesma pessoa que usa diferentes canais para aceder ao seu bot aparece como diferentes utilizadores, um para cada canal e cada um com um estado de utilizador distinto.
As teclas utilizadas para cada um destes baldes predefinidos são específicas do utilizador e da conversação, ou ambas. Ao definir o valor da sua propriedade do Estado, a chave é definida internamente, com informações contidas no contexto de turno para garantir que cada utilizador ou conversação seja colocada no balde e na propriedade corretas. Especificamente, as teclas são definidas da seguinte forma:
- O estado do utilizador cria uma chave utilizando o ID do canal e a partir de ID. Por exemplo, {Activity.ChannelId}/users/{Activity.From.Id}#YourPropertyName
- O estado de conversação cria uma chave usando o ID do canal e o ID de conversação. Por exemplo, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}#YourPropertyName
- O estado de conversação privada cria uma chave usando o ID do canal, a partir de ID e o ID de conversação. Por exemplo, {Activity.ChannelId}/conversations/{Activity.Conversation.Id}/users/{Activity.From.Id}#YourPropertyName
Quando usar cada tipo de estado
O estado de conversação é bom para acompanhar o contexto da conversa, tais como:
- Se o bot fez uma pergunta ao utilizador, e que pergunta que foi
- Qual é o tópico atual da conversa, ou o que o último foi
O estado do utilizador é bom para rastrear informações sobre o utilizador, tais como:
- Informações não críticas do utilizador, tais como nome e preferências, uma definição de alarme ou uma preferência de alerta
- Informação sobre a última conversa que tiveram com o bot
- Por exemplo, um bot de suporte ao produto pode rastrear quais os produtos que o utilizador pediu.
O estado de conversação privada é bom para canais que suportam conversas de grupo, mas onde você quer rastrear tanto o utilizador como a conversação informações específicas. Por exemplo, se tivesse um bot de clicker de sala de aula:
- O bot poderia agregar e mostrar respostas dos alunos para uma determinada pergunta.
- O bot poderia agregar o desempenho de cada aluno e retransmiti-lo em privado no final da sessão.
Para obter detalhes sobre a utilização destes baldes predefinidos, consulte o artigo de como fazer.
Ligação a várias bases de dados
Se o seu bot precisar de se ligar a várias bases de dados, crie uma camada de armazenamento para cada base de dados. Pode optar por utilizar várias bases de dados se o seu bot recolher informações que têm diferentes necessidades de segurança, concordância ou localização de dados.
Para cada camada de armazenamento, crie os objetos de gestão do estado necessários para suportar as suas propriedades do estado.
Acessórios imobiliários do Estado
Os acessórios de propriedade do Estado são usados para realmente ler ou escrever uma das suas propriedades do estado, e fornecer obter, definir e eliminar métodos para aceder às suas propriedades do estado a partir de uma volta. Para criar um acessório, você deve fornecer o nome da propriedade, que geralmente ocorre quando você está inicializando o seu bot. Então, podes usar esse acessório para obter e manipular essa propriedade do estado do teu bot.
Os acessórios permitem que o SDK obtenha o estado do armazenamento subjacente e atualize a cache estatal do bot para si. A cache do estado é uma cache local mantida pelo seu bot que armazena o objeto do estado para si, permitindo ler e escrever operações sem aceder ao armazenamento subjacente. Se já não está na cache, chamar o método de obter do acessório recupera estado e também coloca-o na cache. Uma vez recuperada, a propriedade do estado pode ser manipulada como uma variável local.
O método de eliminação do acessório remove a propriedade da cache, e também a elimina do armazenamento subjacente.
Importante
Para a primeira chamada para o método get de um acessório, você deve fornecer um método de fábrica para criar o objeto se ele ainda não existe no seu estado. Se não for dado nenhum método de fábrica, terá uma exceção. Detalhes sobre como usar um método de fábrica podem ser encontrados no artigo do estado como-a-fazer.
Para persistir quaisquer alterações que faça à propriedade do Estado que obtém do acessório, a propriedade na cache do estado deve ser atualizada. Pode fazê-lo através de uma chamada o método de conjunto de acessórios, que define o valor da sua propriedade na cache, e está disponível se isso precisar de ser lido ou atualizado mais tarde nessa volta. Para realmente persistir esses dados para o armazenamento subjacente (e assim disponibilizá-lo após a viragem atual), você deve então salvar o seu estado.
Como funcionam os métodos de acessórios de propriedade do Estado
Os métodos acessórios são a principal forma de o seu bot interagir com o estado. Como cada trabalho, e como as camadas subjacentes interagem, são as seguintes:
- O método do acessório obtém :
- Acessório solicita propriedade da cache do estado.
- Se a propriedade estiver na cache, devolva-a. Caso contrário, obtenha-o do objeto de gestão do estado. (Se ainda não estiver no estado, utilize o método de fábrica fornecido nos acessórios receber chamadas.)
- O método definido do acessório:
- Atualizar a cache do estado com o novo valor da propriedade.
- O método de poupança do objeto de gestão do estado:
- Verifique as alterações à propriedade na cache do estado.
- Escreva essa propriedade para armazenamento.
Estado em diálogos
A biblioteca de diálogos usa um acessório de propriedade do estado de diálogo, definido no estado de conversação do bot, para manter o lugar de um diálogo na conversação. A propriedade do estado de diálogo também permite que cada diálogo armazene informações transitórias entre turnos.
Os diálogos adaptativos têm uma estrutura de âmbito de memória mais elaborada, o que facilita o acesso à configuração e aos resultados de reconhecimento, entre outras coisas. O gestor de diálogo utiliza os objetos de gestão do estado de utilizador e de conversação para fornecer estes âmbitos de memória.
Para obter informações sobre a biblioteca de diálogos, consulte o artigo da biblioteca de diálogos .
- Consulte os diálogos de componentes e cascatas para obter informações específicas para este tipo de diálogos.
- Consulte a introdução a diálogos adaptativos e a gestão do estado em artigos de diálogo adaptativo para obter informações específicas aos diálogos adaptativos.
Estado de poupança
Quando você liga para o método definido do acessório para registar o estado atualizado, essa propriedade do estado ainda não foi guardada para o seu armazenamento persistido, e em vez disso é apenas guardado para a cache do seu bot estado. Para guardar quaisquer alterações na cache do estado para o seu estado de persistência, deve ligar para o método de poupança do objeto de gestão do estado, que está disponível na implementação da classe estatal bot acima mencionada (como estado de utilizador ou estado de conversação).
Chamar o método de poupança de alterações para um objeto de gestão do estado (como os baldes acima mencionados) guarda todas as propriedades na cache do estado que você estabeleceu até esse ponto para esse balde, mas não para qualquer outro balde que você pode ter no estado do seu bot.
Dica
O estado de bot implementa um comportamento de "última escrita ganha", onde a última escrita irá carimbar sobre o estado previamente escrito. Isto pode funcionar para muitas aplicações, mas tem implicações, particularmente em cenários de escala, onde pode haver algum nível de concordância ou latência em jogo.
Se tiver algum middleware personalizado que possa atualizar o estado após o seu maníssia turn handler, considere o estado de manuseamento no middleware.