Dezembro de 2016

Volume 31 - Número 13

Estrutura do Bot da Microsoft - Use a Estrutura do Bot para acesso a qualquer hora e em qualquer lugar aos Dados de Aplicativos

Por Srikantan Sankaran

Na última edição, apresentei a Estrutura de Bot da Microsoft e discuti como você pode tirar proveito dela para vencer um desafio que muitas organizações enfrentam hoje em dia, ou seja, fornecer aos clientes acesso interativo aos seus serviços, por meio de voz e texto (msdn.com/magazine/mt788623). No artigo, descrevi um cenário de negócios que envolvia a consolidação de informações de diferentes aplicativos de linha de negócios implementados em uma organização provedora de seguros, usando tecnologias como o Microsoft Flow e Aplicativo Lógico do Azure. O conteúdo, que consistia tanto em dados estruturados como não estruturados, foi indexado usando o Azure Search e, em seguida, disponibilizado para o consumo por aplicativos clientes.

A Figura 1, que também apareceu no artigo anterior, mostra a arquitetura da solução que implementa o cenário.

Arquitetura da Solução
Figura 1 - Arquitetura da Solução

Neste artigo, construirei e implementarei um aplicativo bot que pode consumir as informações reunidas por meio do Azure Search. O aplicativo bot será implementado como um aplicativo Web do Azure e publicado por meio do Serviço Conector da Estrutura Bot da Microsoft. Por meio do Serviço do Conector, o aplicativo Bot será acessado a partir do canal Skype, o que dará aos consumidores acesso ao status de suas solicitações de apólice de seguro e permitirá que eles baixem os documentos de política emitidos, agendem visitas de inspeção local e assim por diante. Os consumidores poderão se identificar para o bot usando a conta da Microsoft que foi registrada ao requerer uma apólice de seguro e poderão usar tanto o serviço de mensagens no cliente Skype quanto comandos de voz para interagir com o bot. O aplicativo bot se integra com o serviço LUIS, um dos vários serviços disponíveis nos Serviços Cognitivos do Azure, para interpretar conversas do consumidor com a finalidade de executar consultas no Azure Search.

As etapas necessárias para criar a solução são explicadas na seguinte sequência. Os trechos de códigos são retirados da solução do Visual Studio 2015, que pode ser baixada neste artigo. Veja o que você deve fazer se estiver acompanhando:

  • Crie e publique um modelo LUIS que captura as diferentes conversas que precisam ser suportadas no bot, usando a interface do usuário fornecida pelo serviço LUIS.
  • Use o modelo do Visual Studio 2015 para criar um novo aplicativo bot. Você pode tanto adicionar os blocos de código da solução fornecida neste artigo como seguir o resto do artigo, que se refere ao arquivo baixado da solução. O arquivo MessageController.cs é o ponto de entrada para o aplicativo bot, que é um tipo especial de aplicativo .NET MVC.
  • Insira a funcionalidade LUIS no bot, usando o diálogo LUIS disponível no SDK da Estrutura Bot. Isso é implementado no arquivo PolicyInfoDialog.cs na solução.
  • Usando o SDK do Azure Search, implemente o código que invoca as APIs do Azure Search e execute as solicitações de pesquisa interpretadas pelo serviço LUIS. Isso é implementado no arquivo SearchService.cs na solução.
  • Implemente um diálogo FormFlow para capturar a conta da Microsoft do usuário no canal do Skype, de um modo interativo, quando uma solicitação de usuário é feita pela primeira vez. Isso é implementado no arquivo SigninForm.cs na solução acompanhante.
  • Use o SDK do Azure Search para obter as informações de perfil de usuário com base na conta da Microsoft capturada quando o usuário acessa o bot pela primeira vez. Isso também é implementado no arquivo SearchService.cs
  • Use o Serviço de Estado do Bot para reter as informações de Perfil do Usuário. O endereço e as informações de contato do usuário do bot, que são armazenados no Serviço de Estado do Bot, são usados ao agendar uma visita de inspeção ao local. Isso também é implementado no arquivo PolicyInfoDialog.cs.
  • Teste o aplicativo bot executando-o localmente como um serviço em sua máquina de desenvolvimento e use o Emulador de Canal de Estrutura de Bot para avaliar a interação do usuário com o serviço.
  • Após testar o aplicativo bot localmente, implemente-o em um aplicativo Web no Azure diretamente do Visual Studio.
  • Registre o aplicativo bot com o Serviço Conector da Estrutura de Bot da Microsoft e configure-o na URL do aplicativo bot implementado no Azure.
  • Adicione o nome do aplicativo bot, ID do aplicativo e informações secretas obtidas durante o registro do bot na solução do Visual Studio e, em seguida, republique-o no Azure.
  • Permita o acesso ao aplicativo bot de canais como o Skype e Slack no Portal de desenvolvedor do bot.

Você pode baixar a solução do Visual Studio 2015 para o aplicativo bot e uma exportação de arquivo do modelo LUIS usado neste aplicativo no repositório do GitHub em bit.ly/2cOfANh.

Criação e Treinamento do Modelo LUIS para Diferentes Cenários de Casos de Uso

A Figura 2 mostra como mapeei o modo como um usuário poderia potencialmente convergir (por meio de uma declaração LUIS) com o bot e como isso deve ser interpretado como uma tentativa ou ação LUIS específica a ser executada por meio do Azure Search, além de como extrair palavras chave (entidades LUIS) da declaração LUIS a serem usadas como parâmetros de consulta ao realizar a pesquisa.

Figura 2 - Mapeando Declarações e Tentativas

Declarações ou Conversa Tentativas ou Ações Mapeadas Qualificadores ou Parâmetros
Algo que LUIS não pode interpretar (ou não está treinado para fazê-lo). Nenhum (Padrão) Não se aplica
Obter (ou exibir) todas as minhas solicitações de política. GetPolicyRequests Implícito para usuário do bot com sessão iniciada
Tenho um registro de solicitação de política, ou minha solicitação de política foi aprovada? GetPendingPolicyRequests Implícito para solicitações de política onde o status não é aprovado
Obtenha os detalhes da solicitação de política número VehPolicy001. GetPolicyRequestDetails ID da Solicitação de Política – VehPolicy001
Obtenha o status da minha solicitação de apólice de seguro de vida. GetPolicyRequestStatusByType Tipo de Solicitação de Apólice – Vida
Obtenha o documento de política número Policy0101 emitido este ano. GetPolicyDocument Nome do Arquivo – Policy0101 e lastmoddate – ano atual
Agende uma visita de inspeção do local amanhã. ScheduleSiteVisit Data de Inspeção – Amanhã

O serviço LUIS fornece um aplicativo Web em luis.ai no qual um modelo de aplicativo LUIS pode ser criado visualmente para o problema com o qual se está lidando. A Figura 3 exibe o modelo LUIS configurado para este cenário.

O Modelo LUIS para o Meu Cenário
Figura 3 - O Modelo LUIS para o Meu Cenário

 As tentativas, entidades e declarações identificadas na etapa anterior podem ser criadas no aplicativo LUIS. Use o menu Tentativas para adicionar as tentativas e o menu Entidades para criar as entidades. Observe que há dois tipos especiais de entidades:

  • Entidades hierárquicas: Neste caso, a “Apólice de Seguros” é criada como uma entidade hierárquica, o pai, com os vários tipos, Vida, Veículo, Casa e assim por diante, criados como filhos.
  • Entidades pré-criadas: Usei uma entidade pré-criada, fornecida pelo LUIS, chamada Datetime. Os parâmetros de entrada, tais como o ano em que um documento de política foi gerado ou a data do agendamento de uma visita de inspeção do local, serão mapeados pelo mecanismo LUIS para esses tipos de entidades pré-criados.

A entidade com o nome “Palavra Chave” será usada para realizar uma pesquisa de texto completo no índice de documentos de política no Azure Search.

Agora, selecione a guia Novas declarações e crie declarações para cada uma das conversas identificadas anteriormente e etiquete-as.

Para cada declaração, identifique ou etiquete a tentativa e as entidades associadas. Por exemplo, na Figura 3, mapeei a declaração “obtenha o status da minha solicitação de apólice de seguro de vida” para a tentativa “GetPolicyRequestStatusByType” e mapeei o texto “Seguro de Vida” para a entidade hierárquica “Insurance:life.”

Repita essa etapa para adicionar outras variações, tais como quando o tipo de apólice é: Veículo, Casa ou Geral. Além disso, considere variações onde a mesma solicitação pode ser feita de uma maneira diferente. Contudo, não é necessário que você capture cada permutação e combinação de maneiras com as quais a mesma mensagem pode ser transmitida. Por exemplo, ao adicionar uma nova declaração com a frase “mostre o status...”, conforme exibido na Figura 4, o LUIS poderia interpretar isso corretamente como uma variante da frase anterior, ou seja, “obtenha o status...”. O LUIS deu as sugestões corretas sobre a intenção e as entidades associadas, mesmo que a pergunta tenha sido feita de uma maneira diferente.

Identificando Declarações LUIS e Lidando com Variações
Figura 4 - Identificando Declarações LUIS e Lidando com Variações

Após cada declaração ter sido capturada, o aplicativo LUIS fornece a opção para Treinar o Modelo. Isso resulta na geração de modelos otimizados pelo mecanismo de IA no LUIS, que podem em seguida ser usados por aplicativos clientes. Essa etapa deve ser repetida sempre que novas declarações são identificadas ou alterações são feitas em declarações existentes.

A publicação do modelo LUIS permite que aplicativos do lado do cliente o invoquem, usando uma API REST. O diálogo de publicação no aplicativo também permite que você teste o modelo para se certificar de que ele funciona conforme o esperado. A Figura 5 mostra como testar rapidamente o modelo LUIS passando uma frase de conversa e visualizando a saída no navegador. (Para sua comodidade, a Figura 5 mostra as capturas de tela para três invocações diferentes de declarações e os resultados correspondentes lado a lado.)

Testando o Modelo LUIS
Figura 5 - Testando o Modelo LUIS

Observe que a intenção recomendada pelo LUIS tem um valor máximo de probabilidade atribuído, e aparece em primeiro lugar na lista. As entidades que foram extraídas da frase também são retornadas na resposta. Se houver várias entidades identificadas na declaração, elas também serão retornadas. Você pode ver como o modelo LUIS interpreta termos como “este ano” na frase da declaração, mapeia-os para uma entidade “Datetime” pré-criada e retorna o valor “2016”, que o aplicativo cliente pode usar diretamente.

Criando o Aplicativo Bot

Agora que o modelo LUIS está pronto, ele pode ser usado em um aplicativo bot. Baixe o Modelo do Visual Studio 2015 em aka.ms/bf-bc-vstemplate para criar o aplicativo. (Visite bit.ly/2dYrwyW para conhecer as noções básicas sobre como construir um aplicativo bot e como usar um emulador de bot para construir e testar o bot localmente.)

O projeto criado com o uso desse modelo é uma variante de um projeto MVC. O ponto de entrada para o projeto é MessageController.cs, que processa mensagens de entrada de canais como Skype ou Slack e envia as respostas de volta.

O Diálogo LUIS para a Estrutura Bot é usado para passar, implicitamente, mensagens do bot para o modelo LUIS. Para cada uma das intenções implementadas no modelo LUIS, um método correspondente é implementado, que pode ser chamado diretamente quando o aplicativo bot estiver em execução. Isso elimina a necessidade de que um código personalizado chame as APIs REST LUIS para interpretar a conversa e para identificar a tentativa e as entidades.

A ID do aplicativo LUIS e os valores secretos são usados para decorar os atributos em nível de classe, especialmente LuisModel. O atributo LuisIntent é usado no método que fornece a implementação quando a tentativa é encontrada na solicitação do usuário. Isso é tudo o que é necessário para que a integração LUIS funcione no bot. A Figura 6 mostra como isso é implementado no código.

Figura 6 - Implementando a Integração LUIS

[LuisModel("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", 
  "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")]
[Serializable]
  public class PolicyInfoDialogs : LuisDialog<object>
  {
    [LuisIntent("")]
    public async Task None(IDialogContext context, LuisResult result)
    {
      // Called when the incoming utterance is not recognized (default bin)
    }
    [LuisIntent("GetPolicyRequests")]
    public async Task GetPolicyRequests(IDialogContext context, LuisResult result)
    {
      //
    }
        ----------------------
      }

Neste ponto, a implementação de cada um dos métodos pode ser simples. Posso simplesmente retornar uma mensagem identificando qual implementação de LuisIntent foi invocada.

Em MessageController.cs, adicione o trecho de código a seguir para capturar a mensagem recebida do usuário bot e encaminhe-a para o LuisDialog:

if (activity.Type == ActivityTypes.Message)
  {
    await Conversation.SendAsync(activity, () => new PolicyInfoDialog());
  }

Execute o aplicativo bot e inicie o Emulador de Canal de Estrutura Bot, que pode ser baixado em aka.ms/bf-bc-emulator. Digite as declaração para as quais você treinou o Modelo LUIS anteriormente e certifique-se de que a mensagem de resposta indica que o método correto mapeado para a tentativa LUIS foi invocado.

Integração de Pesquisa

Agora, adicionarei a SDK do Azure Search para .NET à solução do Visual Studio usando o Gerenciador de Pacote NuGet. O arquivo SearchService.cs na solução usa esse SDK e encapsula toda a integração com o Serviço do Azure Search. Ele implementa métodos que executam consultas no Azure Search, retorna o UserProfile do cliente e obtém PolicyRequests e PolicyDocuments.

Comandos de busca para os diferentes cenários são construídos com a sintaxe de consulta Lucene, que é implementada no arquivo PolicyInfoDialog.cs. Estes são alguns exemplos: 

Obter todas as solicitações de política para o usuário bot na conversa:

command += "CustomerId:(" + msftid + ")";
Retrieve all policy requests for the bot user that haven’t yet been approved:
command += "CustomerId:(" + msftid + ") -PolicyStatus:(Approved)";
Query policy requests for the bot user based on the policy request Id:
public async Task GetPolicyRequestDetails(IDialogContext context, LuisResult result)
  {
    ----------------------
      string  command += "CustomerId:(" + msftid + ") AND PolicyRequestId:(" +
        result.Entities[0].Entity + ")";
    ----------------------
  }

O trecho anterior mostra como a entidade PolicyRequestId (os parâmetros de entrada para executar as consultas de pesquisa) é passada pelo mecanismo LUIS por meio de LuisResult (resultado).

A Figura 7 mostra como implementar pesquisas baseadas em propriedades e pesquisas de texto completo para documentos.

Pode ser útil consultar meu artigo anterior para saber mais sobre os nome e valores de propriedade no código da Figura 7. Além disso, você pode baixar o esquema de todas as tabelas usadas no banco de dados que acompanha este artigo por meio dos links fornecidos nas seções seguintes. 

Figura 7 - Implementando Pesquisas baseadas em propriedades e Pesquisas de texto completo para documentos

foreach (EntityRecommendation curEntity in request.Entities)
  {
    switch (curEntity.Type)
      {
        case "PolicyNumber": // Look for documents with this filename
          {
            command += " filename:(" + request.Entities[0].Entity + ") ";
            break;
          }
        case "keyword": // Search within documents for this keyword expression
          {
            command += " " + request.Entities[0].Entity + " ";
            break;
          }
        case "builtin.datetime.date":
        // Retrieve based on the year a document was generated
          {
            char[] delimiterChars = { '.', ':' };
        List<string> allvalues = curEntity.Resolution.Values.ToList<string>();
             string val = allvalues[0];
             string[] vals = val.Split(delimiterChars);
             command += " lastmoddate:(" + vals[0] + ") ";
             break;
          }
        default:
          {
            break;
          }
        }
    }

Formatando a Resposta para o Usuário

Você pode formatar o estilo do texto na mensagem de resposta retornada pelo bot, adicionar hiperlinks ou conteúdo de mídia e assim por diante. Isso facilita o uso do aplicativo bot pelo usuário. Veja alguns exemplos:

Para formatar o estilo de fonte como negrito, apenas para os dados dinâmicos retornados do Azure Search, encapsule-o dentro de asteriscos duplos (**):

foreach (SearchResult<PolicyRequest> result in eachGroup)
  {
    searchResponse += (counter) + ". **" + result.Document.PolicyRequestId + "**" +
      " on the insured :**" + result.Document.InsuredIdentifier + "**
      for an amount of :**" +
    result.Document.Currency + " " + result.Document.AssessedValue + "**
      has status: **" +
    result.Document.PolicyStatus + "**\n\n";
    counter++;
  }

Para adicionar um hiperlink a um documento de política retornado pelo Azure Search, adicione o atributo de Link à URL do documento:

foreach (SearchResult<PolicyDocument> result in results)
 {
   searchResponse += counter + ". Link: [" + result.Document.filename + "](" +
     result.Document.fileurl + ") \n";
   counter++;
 }

Identificando o Usuário Bot

A Estrutura de Bot fornece a ID do canal do usuário e o nome de exibição do contexto da conversa, mas não fornece o nome de usuário usado para iniciar uma sessão no canal, tal como o Skype. Portanto, essas informações devem ser explicitamente obtidas quando um usuário começa a interagir com o bot. O diálogo FormFlow descrito anteriormente é usado para solicitar essas informações ao usuário. As informações de perfil de usuário são obtidas do Azure Search com base no nome da conta.

Para assegurar que o usuário que está interagindo com o bot é o proprietário do nome de conta da Microsoft compartilhado no FormDialog, você pode integrar um início de sessão interativo na página de entrada de conta da Microsoft e fornecer acesso ao bot somente depois da autenticação e validação. Isso está fora do escopo deste artigo. Em vez disso, você pode simplesmente solicitar o nome de conta ao usuário usando o diálogo SigninForm e considerar que o usuário é quem ele afirma que é:

public static IForm<SigninForm> BuildForm()
  {
    return new FormBuilder<SigninForm>()
      .Message("I would need some information before we get started.")
      .Field(nameof(MicrosoftAccount))
      .Build();
  }

Armazenando o Perfil de Usuário no Estado de Bot

Uma vez que o usuário esteja identificado durante o começo de uma conversa no bot, um objeto de perfil de usuário é obtido do Azure Search. Essas informações são armazenadas no estado do bot para serem usadas, por exemplo, quando o usuário solicita que uma visita de inspeção ao local seja agendada. O endereço e número de contato do usuário são verificados durante a confirmação da visita de inspeção.

A Estrutura de Bot fornece uma API para armazenar essas informações no contexto privateConversationData, por usuário e por conversa, conforme mostrado na Figura 8.

Figura 8 - Armazenando o Perfil de Usuário

private async Task SignUpComplete(IDialogContext context, IAwaitable<SigninForm> result)
  {
----------------------------------------------
----------------------------------------------
  UserProfile profile =
    await LoadBotUserState(profileIdentityForm.MicrosoftAccount);
  if (profile == null)
  {
  message = $"Sorry, I could not locate your profile in our system.
    Please retry with the right Microsoft Account";
  }
  else
  {
    context.PrivateConversationData.SetValue<bool>("ProfileComplete", true);
    context.PrivateConversationData.SetValue<string>(
      "FirstName", profile.FirstName);
    context.PrivateConversationData.SetValue<string>("LastName", profile.LastName);
    context.PrivateConversationData.SetValue<string>("Address", profile.Address);
    context.PrivateConversationData.SetValue<string>("Phone", profile.Phone);
    context.PrivateConversationData.SetValue<string>(
      "CustomerId", profile.CustomerId);
    message = $"Thanks {profile.LastName},{profile.FirstName}
      for identifying yourself! \n\n
      Let me know how I could assist you.";
  }
    await context.PostAsync(message);
  }
    context.Wait(MessageReceived);
  }

Para cada solicitação, o aplicativo bot verifica o estado do bot para se assegurar de que a identidade do usuário que está emitindo a solicitação está verificada e que as informações de perfil de usuário estão disponíveis.

Usando o Emulador de Canal de Bot Localmente

O aplicativo bot exige que o namespace, a tecla de acesso e o nome de índice do Azure Search sejam usados para executar as solicitações do usuário. Esses parâmetros são armazenados no arquivo SearchParameters.cs e seus valores são configurados no arquivo web.config quando o aplicativo bot é executado. Agora você pode executar a solução do Visual Studio.

Inicie o Emulador de Canal de Bot e insira as conversas para as quais você treinou o modelo LUIS. Um cenário típico de interação com o usuário é mostrado na Figura 9. Uma vez que o aplicativo tenha sido executado com sucesso no ambiente local, ele pode ser publicado em um aplicativo Web do Azure.

Executando o Bot de um Emulador
Figura 9 - Executando o Bot de um Emulador

Implementando o Bot no Azure

Crie um aplicativo Web no Portal do Azure e, em seguida, nas configurações do Aplicativo, adicione as chaves e valores de appSetting do arquivo web.config na solução do Visual Studio.

Antes de publicar o aplicativo bot em um aplicativo Web do Azure, você deve registrar esse bot em dev.botframework.com/bots/new. Esse processo gera uma ID do Bot, uma ID de Aplicativo Microsoft e um Segredo. Adicione esses valores ao web.config do aplicativo bot no Visual Studio 2015 e republique este aplicativo no Azure.

Durante o processo de registro, para o parâmetro de redirecionamento de URL, use a URL compatível com SSL do aplicativo bot no Azure e adicione o sufixo “/api/messages.”

Habilitando o Bot nos Canais

No registro de Bot em dev.botframework.com/bots, você pode habilitar o bot em outros canais. A Figura 10 mostra o aplicativo bot habilitado nos canais Skype e Slack. A habilitação do aplicativo bot para o Slack exige algumas etapas adicionais. Um assistente será iniciado ao escolher adicionar o bot a esse canal, o que guiará você pelas etapas adequadas.

Registrando o Bot em Vários Canais
Figura 10 - Registrando o Bot em Vários Canais

A Figura 11 mostra o aplicativo bot quando é acessado do Skype.

Acessando o Bot do Skype
Figura 11 - Acessando o Bot do Skype

Conclusão

A Estrutura de Bot da Microsoft e outras tecnologias compatíveis como LUIS e Azure Search fornecem a base correta para criar aplicativos bot intuitivos que permitem que os clientes interajam com seus aplicativos de linha de negócios. O modo como cada um desses serviços se integra à arquitetura geral da solução assegura que os componentes individuais podem ser evoluídos ou melhorados independentemente de outros. Por exemplo, o modelo LUIS pode ser alterado para suportar mais declarações que os usuários poderiam usar para interagir com o bot, sem que haja mudanças no aplicativo bot principal ou no conteúdo do Azure Search. Uma vez implementado, um aplicativo bot pode, sem nenhuma modificação adicional de código, ser habilitado para acesso de vários canais, sendo que mais canais podem ser adicionados ao longo do tempo, para aumentar o alcance e o uso do aplicativo bot.


Srikantan Sankaran  é um evangelista técnico da equipe DX na Índia e vive em Bangalore. Trabalha com diversos ISVs na Índia e ajuda-os a arquitetar e implantar suas soluções no Microsoft Azure. Entre em contato com ele pelo e-mail sansri@microsoft.com.

Agradecemos aos seguintes especialistas técnicos da Microsoft pela revisão deste artigo: Sandeep Alur e Hemanth Kathuria
Sandeep Alur é o Evangelista Principal do DX Índia e vive em Bangalore.

Hemanth Kathuria é um Consultor Sênior na Equipe de Serviços da Índia