Parâmetros de request/response da conversa do Conversation

Franklin Lindemberg Guimarães
8 min readApr 9, 2017

Este é o terceiro post sobre o serviço Watson Conversation. Nele irei explicar em detalhes os parâmetros do endpoint /message, pelo qual conseguimos enviar e receber as respostas do Conversation, e também algumas boas práticas para enviar/receber dados do Conversation.

Endpoint /message

O endpoint responsável pela troca de mensagens no Conversation é o:

POST /v1/workspaces/{workspace_id}/message

Ele deve ser chamado a partir do método HTTP POST e também devem ser passados as credencias do serviço (username e password) para que seja feita a autenticação (pode ser Basic Authentication ou ser utilizado token).

Parâmetros de request

Ao realizar uma chamada no endpoint /message, deve-se passar:

workspace_id

O parâmetro workspace_id é uma string, obrigatório, e deve ser passado no PATH e representa o workspace no qual a conversa será realizada.

version

O parâmetro version é uma string, obrigatório, deve ser passado na QUERY da chamada, e define a data da versão da API que será utilizada e deve ser enviado na query da chamada. A versão mais recente é a de 2017–02–03, e a anterior a ela é a de 2016–09–20. A principal diferença entre estas duas versões é que a mais recente retorna as confianças das intenções com score absoluto (cada intenção tem a sua confiança real), enquanto a anterior retornava esse score normalizado (a soma das confianças de todas as intenções é igual a 1). Essa mudança pode ter impacto na forma de utilizar as confianças. Entrarei em mais detalhes sobre isso em um post futuro.

input

O parâmetro input é um objeto JSON, opcional, e deve ser enviado no body da chamada. Ele contém uma propriedade chamada text, que é uma string, representando o texto que você quer enviar para o Conversation. No entanto, este objeto tem muitas outras utilidades, se usado da forma correta.

Um exemplo é quando desejamos enviar alguma informação para o Conversation que corresponde à apenas aquela chamada. Faz muito mais sentido enviá-la dentro do input ao invés de enviá-la dentro do context (lembrem-se que o context vai e volta, e no caso você continuaria enviando/recebendo esta informação nas chamadas seguintes caso ela não fosse removida).

Um exemplo real de uso? Talvez você queira enviar o saldo da conta do usuário para o Conversation para que ele determine de alguma forma a mensagem que deve ser retornada. Neste caso, não faz sentido manter o saldo dele no context (já que o saldo pode mudar a qualquer hora), mas apenas enviá-lo uma única vez (ou quando for necessário) para o Conversation.

"input": {
"text": "",
"saldo": "1000"
}

Obs: o input deve ser sempre um objeto novo a cada envio. Não deve-se enviar o mesmo input recebido no retorno do Conversation, pois neste caso os mesmos atributos estariam sempre sendo enviados e a lógica explicada acima não funcionaria.

alternate_intents

O parâmetro alternate_intents é um booleano, opcional, e deve ser enviado no body da chamada. Ele diz para o conversation se devem ser retornadas todas as intenções reconhecidas (no máximo 10 em ordem decrescente de confiança) ou apenas a intenção de maior confiança. Por padrão este parâmetro é false. Portanto, caso queira ter todas as intenções retornadas deve-se enviar true.

"alternate_intents": true

Em um post futuro eu mostrarei como podemos utilizar as várias confianças retornadas para engajar o usuário, por exemplo oferecendo uma segunda intenção para ele caso a primeira não o tenha agradado.

context

Como explicado no post anterior, o parâmetro context é um objeto JSON, opcional, e deve ser enviado no body da chamada. Ele representa o estado da conversa. Sem ele o conversation não saberia dizer se é uma conversa nova ou de qual nó ele deve continuar. Caso ele não seja enviado, o Conversation irá sempre interpretar como uma conversa nova, e poderá retornar sempre a mesma resposta, dependendo de como esteja configurado.

Ele possui no mínimo duas propriedades: o conversation_id (que é o id único da conversa) e o system (que é um objeto JSON que contém as informações necessárias para que o Conversation saiba como prosseguir com o fluxo da conversa). Estas propriedades não devem ser alteradas.

Porém, assim como o input, o context pode ser utilizado para guardar qualquer tipo de informação. Ele pode ser alterado tanto antes de ser enviado para o Conversation de modo a conter alguma informação relevante para o fluxo de diálogo.

Exemplo: Digamos que você já possua alguns dados do usuário (nome e sobrenome) mesmo antes dele iniciar a conversa com o Conversation (ele está logado por exemplo). Digamos que o nó inicial do conversation deseja dar as boas vindas iniciando a frase com “Olá nome + sobrenome, em que posso ajudá-lo?”. No meu caso ficaria “Olá Franklin Guimarães, em que posso ajudá-lo?”. Para conseguir isso pode-se passar o nome e sobrenome dentro do contexto e acessá-los no diálogo dentro do Conversation.

"context": {
"nome": "Franklin",
"sobrenome": "Guimarães"
"conversation_id": "66a91bd9-48f5-4d3d-8179-46b586814f1f",
"system": {
"dialog_stack": [
{
"dialog_node": "root"
}
],
"dialog_turn_counter": 1,
"dialog_request_counter": 1,
"_node_output_map": {
"Start And Initialize Context": [
0,
0
]
},
"branch_exited": true,
"branch_exited_reason": "completed"
}
}

entities

O parâmetro entities é um array, opcional, e deve ser enviado no body da chamada.

"entities": [
{
"entity": "appliance",
"location": [
12,
18
],
"value": "lights"
}
]

Você pode reenviar as entidades retornadas (ou um subset delas) de uma resposta anterior do Conversation para continuar usando-as no fluxo, ao invés de detectar as entidades a partir do input do usuário.

Obs: Não funciona caso o input também seja enviado na chamada. Portanto caso queira que as entidades enviadas na chamada sejam de fato utilizadas, não envie o parâmetro input.

intents

O parâmetro intents é um array, opcional, e deve ser enviado no body da chamada.

"intents": [
{
"intent": "turn_on",
"confidence": 1
}
]

Você pode reenviar as intenções retornadas (ou um subset delas) de uma resposta anterior do Conversation para continuar usando-as no fluxo, ao invés de obter novas intenções a partir do input do usuário.

Obs: Não funciona caso o input também seja enviado na chamada. Portanto caso queira que as intenções enviadas na chamada sejam de fato utilizadas, não envie o parâmetro input.

output

O parâmetro output é um objeto JSON, opcional, e deve ser enviado no body da chamada.

Deve-se ter cuidado ao retornar este parâmetro pois ele pode comprometer a boa prática apresentada neste post (de quando a informação for específica de um nó, ela deve ser retornada no output ao invés do context).

Ele deve ser retornado apenas quando deseja-se manter uma informação intermediária dentro da mesma branch do diálogo. Pense na branch como o caminho percorrido entre a raiz do diálogo até uma resposta final. Neste caminho podem haver diversas interações com o usuário, solicitando informações por exemplo. Neste caso o output serviria para guardar a informação apenas até chegar a resposta final.

Parâmetros de response

input

É sempre retornado e possui o mesmo valor do input enviado no request.

alternate_intents

É retornado apenas se for enviado no request. Neste caso retornará com o mesmo valor.

context

É sempre retornado. O parâmetro context pode ser alterado dentro do conversation para salvar informações relevantes para o diálogo. Para isto é utilizada a linguagem SpEL. Eu cobrirei estas alterações com mais detalhes em um post futuro, porém caso queiram dar uma olhada podem entrar neste site. A propriedade conversation_id será sempre a mesma (pois representa o id da conversa) enquanto a propriedade system será atualizada pelo Conversation para corresponder ao novo estado da conversa.

Exemplo: Digamos que durante o fluxo de diálogo você deseja perguntar a idade do usuário para usá-la posteriormente? Como fazer isso de modo que você não perca o valor? Simples! No próprio fluxo de diálogo você pode capturar este dado e salvá-lo no context. Como o context sempre vai e volta, você sempre terá esse dado a disposição, seja para ser utilizado em um outro nó do fluxo de diálogo ou no próprio backend da aplicação.

entities

Sempre quando um input é enviado para o Conversation, ele tentará reconhecer quais das entidades cadastradas ocorrem no input, retornando elas sempre que encontradas.

Este parâmetro será sempre retornado como um array onde cada posição contém um objeto de entidade. Cada objeto de entidade possui uma propriedade chamada entity (nome da entidade), location (posição início e fim do input do usuário onde a entidade foi encontrada) e value (a palavra enviada pelo usuário que disparou a entidade).

intents

Sempre quando um input é enviado para o Conversation, ele tentará classificar o input do usuário nas intenções cadastradas, retornando no máximo 10 intenções em ordem decrescente de confiança.

Este parâmetro será sempre retornado como um array onde cada posição contém um objeto de intenção. Cada objeto de intenção possui uma propriedade chamada intent (nome da intenção) e confidence (a confiança com que a intenção foi reconhecida).

output

Será sempre retornado como um objeto e que representa o retorno do fluxo de diálogo. Ele possui por padrão três propriedade: log_messages (array de string com mensagens de log. Útil para saber se há algum erro ou aviso no fluxo de diálogo), text (array de string com as mensagens retornadas pelo conversation, aquelas que serão mostradas ao usuário) e nodes_visited (array de string com os nome dos nós dos do diálogo visitados na chamada do Conversation. Útil para testar se o fluxo está correto). Porém, assim como o input, este objeto pode ser muito útil se utilizado corretamente.

Quando desejamos receber alguma informação do Conversation que corresponde à apenas aquela chamada, faz muito mais sentido recebê-la dentro do output ao invés de recebê-la dentro do context (lembrem-se que o context vai e volta, e no caso continuaria enviando/recebendo esta informação nas chamadas seguintes caso ela não fosse removida).

Vamos a um exemplo real! Imagine que, quando a conversa chegar em determinado nó do diálogo, ele deverá retornar um código que será interpretado pelo seu backend como consultar saldo da conta corrente. O backend então fará a consulta e enviará o saldo da conta corrente para o usuário. Perceba que este código só faz sentido ser retornado uma única vez (apenas neste nó), e que caso ele seja retornado no context poderá provocar um comportamento estranho na aplicação (ela pode ficar consultando o saldo em todo retorno do Conversation). Neste caso a solução é retornar este código dentro do objeto output, pois dessa forma ele é utilizado apenas uma vez.

"output": {
"log_messages": [],
"text": [
"O saldo da sua conta corrente é "
],
"nodes_visited": [
"consultar_saldo"
],
"codigo_operacao": "consultar_saldo_cc"
}

O que fazer em seguida

Para melhor compreender estes conceitos, sugiro praticar as chamadas ao Conversation utilizando o API Explorer (veja post anterior) e também ler as referências abaixo:

Referência da API do Conversation

Documentação do Conversation

É importante também entender as diferenças entre enviar dados no input/context e de receber dados no context/output. O mal uso destes conceitos pode impactar na experiência do usuário. Portanto se necessário leia novamente o post ou coloque sua dúvida nos comentários.

Posts relacionados

Introdução ao Serviço Watson Conversation

Testando o Conversation pelo API Explorer

Originally published at franklinlindemberg.wordpress.com on April 3, 2017.

--

--