Hace unas semanas os contamos qué es Dialogflow CX, una nueva tecnología de Google para implementar asistentes conversacionales, y sus diferencias con Dialogflow ES. Ahora, toca meternos en materia y ver cómo aterrizar todos esos conceptos que os contamos con un ejemplo práctico.
Para ponernos un poco en contexto, Dialogflow CX supone un cambio de paradigma respecto a Dialogflow ES. En lugar de tener una conversación basada en intenciones (como hacíamos en ES) ahora el flujo conversacional se maneja mediante una máquina de estados.
En esta máquina los estados son representados mediante páginas. En estas páginas podemos definir formularios con parámetros, desde donde recogeremos la información introducida por el usuario. Siempre tendremos un estado activo, que será la página actual del usuario. Desde cada estado o página vamos a poder transicionar a otra mediante rutas. Una vez terminada la interacción del usuario, el asistente nos devolverá la respuesta mediante un fulfillment, que puede consistir en un texto estático, el seteo de algún parámetro o una respuesta dinámica procesada en un webhook. El webhook será la pieza de nuestra arquitectura donde podremos delegar lo referente a la lógica de negocio y la integración con otros servicios.
Para ejemplificar todo esto, crearemos un asistente virtual para una pizzería. Con esto vamos a poder realizar nuestro pedido directamente hablando con nuestro pizzero virtual.
Antes de nada deberíamos tener claro cuál es el flujo de conversación. En nuestro caso el diagrama sería:
Lo primero que tenemos que hacer es seleccionar un proyecto sobre el crear nuestro asistente virtual. En nuestro caso vamos a hacerlo sobre un proyecto ya existente:
Para la configuración inicial de nuestro asistente, solo necesitamos establecer nombre, localización, time zone e idioma:
Una vez creado el agente, ya tendremos acceso a la consola del mismo. Desde aquí es desde donde vamos a ir diseñando y definiendo nuestro flujo de conversación.
Por defecto el agente tiene creado la página Start, que es el inicio al flujo. Este es el punto de partida para comenzar nuestra conversación, con el saludo de nuestro asistente en Default Welcome Intent:
Para probarlo vamos a usar el Simulador que tenemos accesible arriba a la derecha. Desde este simulador podemos ir probando el flujo conversacional y ver el estado de los parámetros almacenados durante la conversación. Si escribimos ‘hola’ el asistente nos responde:
Este intent tiene por defecto la siguiente configuración:
Al introducir nosotros ‘hola’ en el simulador, y debido a las frases de entrenamiento introducidas en su configuración, la intención es detectada y responde en consecuencia con las opciones definidas en el fulfillment de la ruta:
Para que el saludo sea un poco más corporativo, vamos a modificarlo añadiendo un nuevo texto de salida haciendo click en Add dialogue option y añadiendo el nuevo texto:
Quedando de la siguiente manera:
Ahora el asistente nos debería devolver un texto de entre los 3 de arriba y el nuevo texto añadido abajo:
Vamos a empezar a definir el flujo conversacional para dar de alta un pedido en el sistema. Para ello vamos a crear un nuevo flujo llamado 'Pedido'. Pero primero: ¿qué es un flujo?
Los agentes en Dialogflow pueden manejar varios temas de conversación y el concepto flujo hace referencia a cada uno de estos temas. Si nuestro agente creciese y fuese capaz de, por ejemplo, obtener información de los clientes podríamos hacerlo en otro flujo y mediante rutas enlazarlos.
Para el caso que nos ocupa, desde este flujo 'Pedido' vamos a extraer qué es lo que el usuario quiere comprar.
Una vez creado el nuevo flujo vamos a enlazarlo con el flujo inicial, añadiendo en la ruta la transición a nuestro nuevo flujo. Al seleccionar la página Start del Default Start Flow veremos su configuración. En el apartado Transition podemos enlazarlos con el nuevo flujo:
Al hacer esto el diagrama debería ya quedar enlazado con el nuevo flujo:
Para crear la carta de nuestra pizzería vamos a usar entidades. Dialogflow nos proporciona entidades de sistema (como pueden ser date, email o phone-number), pero en este caso vamos a crear las nuestras propias.
Entidad pizza:
También tendremos disponible bebidas:
Junto a los valores de las entidades, en Dialogflow podemos establecer sinónimos para cada uno de ellos para hacer más fácil su detección. En este caso hemos añadido algunos para poder recoger correctamente la información.
Estas dos entidades las vamos asignar a una nueva, producto, que podrá ser o pizza o bebida:
Para hacer el pedido normalmente construimos frases del estilo: 'Quiero una pizza barbacoa y dos cervezas' o 'Me gustaría pedir dos pizzas y dos aguas'.
Para recoger esta información y mantenerla agrupada vamos a crear otra entidad compuesta, pedido. Esta entidad estará formada por una entidad de sistema de tipo number llamada cantidad y por otra de tipo producto a la que llamaremos producto, que como hemos visto podrá ser pizza o bebida.
Una vez tenemos preparadas las entidades ya podemos definir nuestra primera página 'Obtener pedido' que contendrá el parámetro de tipo pedido que esperamos rellenar.
En el Entry fulfillment vamos a especificar qué texto queremos que el asistente nos devuelva cuando entramos en esta página.
Para almacenar la información introducida vamos a crear un Parameter de tipo pedido para almacenar qué queremos pedir.
Va a ser lista, ya que igual queremos pedir varias cosas y es un campo obligatorio para poder continuar (no tiene mucho sentido acabar un pedido sin nada que pedir).
Con solo esto, el asistente ya es capaz de rellenar el parámetro con la información introducida por el usuario. Si quisiéramos refinar la obtención de los parámetros o hacer un entrenamiento más exhaustivo, podríamos usar un Intent para rellenarlo. Un Intent representa la intención del usuario en realizar una acción y podemos entrenarlas con frases. De estas frases podemos extraer la información para luego pasarlo al parámetro de la página. La primera frase de entrenamiento que vamos a introducir es:
De la frase 'quiero una pizza barbacoa' es capaz de detectar la correspondencia con una entidad de tipo pedido.
Si en lugar de pizza, lo que pedimos es una bebida:
Al añadir ‘birra’ como sinónimo de ‘cerveza’ también es capaz de identificarla.
Pero ¿qué pasa si en una misma frase añadimos más de un producto? Por ejemplo, 'quiero una pizza barbacoa y dos cervezas':
Detecta dos pedidos (‘una pizza barbacoa’ y ‘dos cervezas’), pero en este caso no detecta que va a ser una lista. Si queremos recoger ambos pedidos debemos establecer el parámetro pedido como lista clickando en el check is list.
En cualquier caso, de momento vamos a hacerlo sin el intent, ya que para el ejemplo en cuestión es suficiente.
Ahora ya podemos enlazar esta nueva página con la página inicial. En este caso desde la página Start del flujo vamos a crear una transición a nuestra nueva página siempre, es decir, su condición de transición será true.
Con esta configuración ya podemos hacer una primera prueba con nuestro simulador.
Si revisamos los parámetros detectados vemos que efectivamente fue capaz de extraer correctamente el pedido:
Estos parámetros son accesibles durante toda la conversación en el ámbito session.
Pero ¿qué pasa si pedimos una pizza que no tenemos en carta?
No es capaz de identificar el pedido, ya que no disponemos de ese producto en nuestras entidades y es incapaz de hacer el match con el parámetro esperado. Para esto Dialogflow nos proporciona los manejadores de estados que serán disparados cuando estos eventos sucedan en nuestra conversación. En este caso, añadimos uno del tipo “no-match-default” que es disparado cuando la entrada del usuario no coincide con ningún intent de la página ni cumple con ningún parámetro de formulario.
Si volvemos a lanzar la misma prueba veríamos que ahora nos devuelve un mensaje:
Con el pedido del usuario apuntado, lo trasladamos a los sistemas del restaurante. Crearemos una ruta a una nueva página 'Realizar pedido':
En esta página es donde vamos a registrar el pedido en el sistema. Para ello vamos a usar un webhook, pieza de nuestra arquitectura encargada de contener la lógica de negocio y la integración con otros sistemas (si hubiera). Aquí también podríamos hacer la validación de algunos de los campos si lo quisiéramos. A los webhook se les puede invocar desde un entry fulfillment, desde un parámetro, desde una ruta o desde un evento, y se puede generar una respuesta que será devuelta directamente al cliente. En nuestro caso, lo invocamos desde el entry fulfillment de la propia página.
Para implementar nuestro webhook, lo hacemos con nodejs y express. Dialogflow va a invocar mediante post a la url que le indiquemos añadiendo en el body el tag que es lo que identificará la acción a realizar. En este caso “registrar-pedido” será el tag:
La llamada al servicio para registrar el pedido (sendOrder) nos devolverá un booleano: true, en caso de que todo fuera correctamente; o false, en caso contrario. Esta respuesta la guardaremos en un parámetro ‘pedido_registrado’ para poder manejar mediante rutas lo que podemos hacer a la vuelta. En nuestro caso, mostramos un mensaje diferente y vamos a terminar el flujo.
Si la orden se envió correctamente:
En caso de que la orden no se procesara correctamente:
Una vez terminado el flujo de conversación en la consola del asistente queda:
Dialogflow CX nos permite diseñar e implementar de una manera sencilla y rápida un flujo de diálogo, apenas escribiendo unas pocas líneas de código. Este primer ejemplo es una pequeña toma de contacto para dar algunas pinceladas de las opciones que esta tecnología nos permite hacer, pero es en los casos complejos en los que podremos comprobar todo el potencial de esta herramienta.
Tell us what you think.