Há pouco tempo, em São Petersburgo, foi realizada a segunda conferência de
Conversas , dedicada à IA de conversação, na qual tive a sorte de falar como palestrante. O tópico foi desenvolver uma habilidade B2B de protótipo para uma grande empresa. O relatório descreveu como eles conseguiram "fazer amizade" com os serviços da Web relativamente lentos e a infraestrutura fechada da empresa. Isso será discutido sob o corte.
Se de repente você não souber quais são as habilidades de Alice, olhe embaixo do spoiler: ele descreve brevemente o que é o quê.
Para os não iniciadosO que é quem é Alice, acho que muitas pessoas sabem. Mas por precaução - este é um assistente de voz da Yandex. Além do fato de que ela pode fazer muitas coisas "prontas para uso", os desenvolvedores têm à sua disposição uma plataforma para expandir sua funcionalidade - Yandex.Dialogues (são as habilidades de Alice).
Do ponto de vista do usuário, uma habilidade é o modo especial de Alice, invocado por certas frases de ativação. Nesse modo, Alice transfere réplicas de usuários para um serviço da web de terceiros e responde com uma mensagem enviada em resposta.
Do ponto de vista técnico, uma habilidade é o mesmo serviço da web de terceiros que deve aceitar
solicitações que contêm réplicas de usuários. Suas
respostas podem conter texto, links, imagens, sons etc.
Idéia
Como tudo começou? Em 13 de março de 2018,
eles anunciaram o teste beta da plataforma Yandex.Dialogs (habilidades de Alice). Naquela época, muitos já estavam interessados no assistente virtual, o que significa que era uma ótima oportunidade de trabalhar com um público bastante grande. A ideia de um bot de bate-papo está girando na minha cabeça há muito tempo, então decidi que seria interessante desenvolver alguma habilidade no seu tempo livre com base nele. E se ele também pode trazer benefícios no trabalho - geralmente será excelente.
Nossa empresa fornece uma gama completa de serviços no campo do turismo de negócios, o que significa que você pode criar uma habilidade que ajude o usuário a fazer uma viagem de negócios.
Então, eu estava na equipe para o desenvolvimento de um aplicativo móvel, com o qual você pode encontrar opções de voo e hotéis para viagens de negócios e organizar os adequados. Um dos principais indicadores, para os quais lutamos para aumentar, foi o número de downloads. Surgiu a ideia de que, se a habilidade levar os usuários ao aplicativo, isso nos ajudará a aumentar esses indicadores. Isso foi necessário para verificar o uso deste projeto.
Para que uma habilidade seja útil a qualquer pessoa, ela deve resolver uma tarefa específica do usuário. Nesse caso, procure opções para uma viagem de negócios. Ou seja, a habilidade deve coletar informações sobre onde ir e mostrar os resultados em um aplicativo móvel. Assim, o usuário receberá as opções desejadas usando uma interação de voz interessante e continuará trabalhando em nosso aplicativo, o que significa que os desenvolvedores receberão o aumento desejado no desempenho.
Acontece que a habilidade deve funcionar assim: cumprimentar o usuário; encontre-o pelo nome; faça perguntas esclarecedoras e, assim, obtenha os parâmetros de viagem necessários: cidades (de onde e onde) e datas. A seguir, mostre os parâmetros reconhecidos. Se tudo estiver correto, inicie a pesquisa e forneça um link para o aplicativo.
Recursos e limitações
Para concluir sua tarefa, a habilidade precisa interagir com nossas APIs internas e seu serviço da Web precisa ser publicado em algum lugar. Por um lado, poderia ser colocado no trabalho, mas, como já mencionado, o desenvolvimento foi realizado em tempo livre; portanto, não queria depender de nenhum recurso da empresa especialmente alocado. Portanto, você tinha que aproveitar o que está disponível por padrão.
Por exemplo, um servidor de teste. Os desenvolvedores têm direitos suficientes para implantar um aplicativo Web nele, mas ele estará disponível apenas na rede interna da empresa, porque o servidor não se destaca. Ao mesmo tempo, ele tem acesso à Internet, o que significa que isso pode ser usado.
O serviço da web de habilidades deve estar acessível a partir do exterior (para que Alice tenha para onde enviar solicitações), portanto, ele deve ser colocado em uma hospedagem externa.
Para que a habilidade cumpra sua tarefa, você precisa de um serviço da web da empresa que possa procurar perfis e cidades e que seja acessível a partir do exterior. A API do aplicativo móvel é adequada para isso, embora tenha suas próprias nuances. Eles consistem no fato de que você pode se conectar à API em nome de apenas um usuário específico, o que significa que o intervalo de perfis disponíveis para pesquisa será limitado. E a coisa mais desagradável - os resultados de uma pesquisa lançada por meio da API chegarão apenas a esse usuário. No entanto, possui a funcionalidade necessária, o que significa que você pode trabalhar com ele.
Portanto, a habilidade em hospedagem externa irá interagir com a API. É claro que é bastante rápido, mas às vezes, de acordo com os resultados do teste, a resposta não tem tempo para chegar nos 1500 ms necessários (esse é o requisito da plataforma Yandex.Dialogs). E, para continuar enviando os resultados ao usuário certo, você deve executar um serviço de pesquisa em seu nome, disponível apenas na rede interna. Infelizmente, a API não ajudará nisso, o que significa que você precisa transferir de alguma forma a solicitação da habilidade diretamente para a infraestrutura interna.
Resolveremos esses problemas assim que estiverem disponíveis.
Etapas Problemas e Soluções
Para começar, para implementar geralmente o cenário descrito, a habilidade precisa armazenar o estado em algum lugar: estágio, nome de usuário, cidade e data. Como não há muita informação, você não deve implantar um banco de dados inteiro para isso, principalmente porque há muito trabalho com ele. Você pode armazenar o estado no cache.
A escolha recaiu sobre
Redis . Ele se mostrou bem nos testes de resposta, e também o usamos no trabalho, o que significa que, se bem-sucedido, esse projeto pode ser facilmente transferido para a empresa (e o spoiler - nós o mudamos). Como chave, você pode usar o identificador de usuário na habilidade (indicada na solicitação) e armazenar os dados de status no formato JSON no valor Uma cópia gratuita do Redis pode ser implantada no
Heroku e, há algum tempo, ela é suportada no
Yandex.Cloud .
Agora, analisaremos os estágios da habilidade com mais detalhes. Desde o início, o usuário vê a frase de boas-vindas habitual. Em seguida, ele deve nomear seu nome, de acordo com o qual a habilidade procurará um perfil.
Se existir, seu nome deve ser gravado no estado e, como o cache é usado, as demais informações necessárias sobre o perfil podem ser colocadas nele. Agora, quando o cliente retornar à habilidade, ele verá uma saudação pessoal. Se a mesma pessoa efetuar login de outro dispositivo e nomear seu nome, seu perfil também será encontrado no cache, o que significa que evitaremos pesquisar novamente pela API, o que economiza tempo ao processar a solicitação.
Em seguida, os parâmetros de viagem são recebidos. Como usuário de habilidades de voz, desejo nomear cidades e datas como, por exemplo, "Peter" e "em uma semana". A habilidade deve ser capaz de reconhecer essas frases para transferir o nome completo da cidade na API e realizar uma pesquisa no dia desejado. Agora, o serviço da web da habilidade recebe imediatamente essas informações diretamente na solicitação:
Mas esse recurso
apareceu por volta de outubro de 2018 e a habilidade foi desenvolvida um pouco antes, então o
Dialogflow foi escolhido para entender a linguagem natural. Ele possui um excelente sistema de marcação e, de tempos em tempos, você pode treiná-lo, indicando o que o usuário quis dizer em uma determinada frase.
Assim, o cliente nomeia a cidade e a data da sua maneira, a habilidade passa suas palavras para o Dialogflow e envia o nome da cidade reconhecida para a API, de onde recebe o identificador necessário. A corrente é longa e, portanto, é provável que não atenda aos 1500 ms necessários.
A solução óbvia é fazer cache. E como chave, você pode especificar exatamente o que o usuário disse e, no valor, armazenar o identificador da cidade em nosso sistema. Depois, no cache, pode haver várias entradas para uma cidade, por exemplo, para as palavras "Peter" e "St. Petersburg". Mas isso não é crítico se o valor não indicar muita informação. De qualquer forma, essa abordagem permitirá preencher o cache com cidades populares solicitadas por outros usuários ou "aquecê-lo" com antecedência. Isso permitirá que você use o Dialogflow e a API com menos frequência no futuro, o que economizará tempo novamente.
O passo mais interessante é iniciar a pesquisa. Existem todos os parâmetros necessários, mas para que os resultados cheguem à pessoa certa, você deve, de alguma forma, "puxar" o serviço de pesquisa interno. Além disso, a pesquisa em si leva bastante tempo e as operações de longo prazo são melhor executadas não no mesmo serviço da Web, mas em um aplicativo separado.
É hora de usar o servidor disponível da empresa. Nele, você pode implantar um aplicativo que, de alguma forma, "retira" informações de fora e executa tarefas de longo prazo, incluindo o início de uma pesquisa.
Esse aplicativo pode muito bem ser um serviço em segundo plano.
Pelo nome, fica claro que esse é um aplicativo sem uma interface do usuário, que deve começar seu trabalho junto com o servidor e executar as ações planejadas ou ações em um comando específico (mensagem). Geralmente organizamos esse serviço na estrutura
Topshelf e ele pode receber comandos, por exemplo, de uma fila de mensagens com base no protocolo
AMQP .
Em resumo, a fila funciona mais ou menos assim: existe um intermediário no qual os remetentes adicionam mensagens de um determinado tipo. E há leitores que se conectam ao corretor e obtêm as informações necessárias.
Uma descrição mais detalhada pode ser encontrada, por exemplo,
neste artigo .
Uma boa solução em nuvem foi encontrada na Internet, fornecendo uma fila de mensagens como um serviço -
CloudAMQP . Ele tem uma tarifa gratuita, mas funciona de forma estável. Outro argumento para sua escolha é que esse serviço funciona com base no
RabbitMQ , que também usamos muito no trabalho.
Então, vamos dar uma olhada no trabalho da habilidade como um todo: o serviço da web de habilidades interage com a API do aplicativo para dispositivos móveis e o Dialogflow. Os resultados das chamadas para eles são armazenados em cache no Redis e o estado é armazenado lá. Após confirmar os parâmetros da viagem, a habilidade envia uma mensagem ao corretor com todas as informações necessárias. O serviço em segundo plano no servidor de teste se conecta a ele e, quando uma mensagem é exibida, inicia a pesquisa e os resultados são enviados para o aplicativo móvel.
Quando o cliente faz o download e o instala, ele os encontra em seus pedidos:
Isso completa o trabalho da habilidade.
Sumário
O que aconteceu depois? Essa habilidade foi demonstrada por vários clientes para feedback, e aqui está o que descobrimos: os próprios usuários relutam em mudar para um aplicativo móvel, não importa o quão legal seja. É mais fácil para alguns deles ligar para o nosso agente pelo telefone e pedir que ele procure o que ele precisa.
Como mostra a prática, nesse caso em particular, os usuários estão mais interessados em interagir com um assistente de voz. Nesse caso, ele substitui o agente, permitindo economizar um pouco de tempo e, ao mesmo tempo, motiva os clientes a baixar o aplicativo para continuar trabalhando com as opções nele.
Acontece que, graças à habilidade, é possível economizar determinados recursos e aumentar alguns indicadores-chave, ou seja, a assunção do benefício da habilidade para nossa empresa foi confirmada.
Eu gostaria de enfatizar algumas conclusões. Óbvio: para acompanhar 1500 ms, evite fazer solicitações desnecessárias de serviços da web, cache. Você pode usar chaves de cache diferentes para as mesmas informações. Isso se justifica se pelo menos uma pessoa entrar no cache gerado por outro usuário. E o mais importante: é melhor executar operações demoradas em um serviço em segundo plano separado: além de fornecer descentralização da habilidade, ele terá menos problemas com o multithreading e, se necessário, pode ser "implantado" dentro da rede fechada da empresa e "captar" mensagens externas.
Em vez de um epílogo
Chatbots e habilidades geralmente são escritos em JavaScript e Python (a julgar pelo número de repositórios no GitHub para "chatbot"). Isso também se deve à fácil publicação no servidor. Este projeto foi escrito em C # no núcleo .net. No caso da estrutura clássica .net, há algumas dificuldades com a publicação (funciona principalmente no Windows etc.), mas muita coisa mudou com o advento do núcleo .net. Para cada serviço ou estrutura mencionado acima, existem bibliotecas que oferecem suporte completo a essa tecnologia. Graças a isso, a habilidade pode ser executada em servidores Linux e, mais ainda, em qualquer hospedagem que suporte o Docker. Se de repente você estiver em uma pesquisa criativa, recomendo prestar atenção a essa estrutura, ela se tornará uma boa alternativa para o desenvolvimento de bots de bate-papo.
PSUPD 01/01/2019: a partir de agora, o tempo limite para as habilidades é de
3 segundos .