La guía completa para crear Acciones del Asistente de Google

¿Cómo le enseñamos al Asistente de Google a enseñarte Español?

Uri Shaked
13 min readMay 31, 2019

Si actualmente estás construyendo o pensando cómo desarrollar una Acción del Asistente de Google, ¡Este post es para ti!

Mi amigo Daniel Gwerzman y yo lanzamos recientemente “Spanish Lesson” (La lección de Español), un asistente que te ayudará a aprender español enseñándote un número de palabras nuevas cada día, y leyendo frases sencillas en español para que las traduzcas al inglés.

Nos lo pasamos muy bien construyendo la app, así que pensamos que te mostraríamos como lo hicimos, incluyendo algunos fragmentos de código interesantes. Nuestra meta es ayudarte a ahorrar algo de tiempo cuando desarrolles tus propias Acciones, ¡Y mostrarte cuán divertido puede ser crear una!

The Spanish Lesson Logo :)

¿Cómo empezó todo?

Algunos meses atrás, mi compañera de vida Ariella obtuvo un nuevo dispositivo Google Home. Estaba muy emocionada y se puso a probar un montón de cosas. En algún momento, la escuché decirle a su altavoz: “Hey Google, enséñame español”, a lo que le respondió: “Lo siento, no se cómo ayudarte con eso aún

Casualmente, algunos días antes, leí un artículo de Daniel Gwerzman donde explicaba por qué ahora era un buen momento para construir acciones en Google. El tenía algunos puntos muy buenos- la gente es perezosa y prefieren hablar antes que escribir, y dado que aún son los primeros días de la plataforma, existen muchas oportunidades para tener un gran impacto en el espacio tecnológico.

Así que cuando el asistente respondió a Ariella que no podía enseñarle español “aún”. Aquello me impactó: ¿Por qué no hacer yo que sucediera?

Al día siguiente, llamé a Daniel y le pregunté si estaba listo para embarcarse en una nueva aventura. Daniel estaba muy emocionado con la idea, y empezamos a colaborar. Nos sentamos juntos y diseñamos una persona, que fue la base para la creación de los textos y posibles flujos de diálogo. Aprendimos mucho a lo largo del proceso, y probablemente publicaremos otro artículo desde el punto de vista del producto/UX en unas cuantas semanas.

Sin embargo, el objetivo de este post es la parte técnica de crear una acción para el Asistente; los desafío que encontramos, las herramientas que escogimos, básicamente compartir contigo la arquitectura de una solución completa para desarrollar una Acción compleja y real para el Asistente de Google.

Vamos a cubrir las decisiones técnicas que tomamos, y mostrar nuestra experiencia con los resultados de nuestras elecciones.

¿Plantillas, Dialogflow o Actions SDK?

Hoy día existen tres enfoques para crear acciones para el Asistente: plantillas preparadas, Dialogflow y Actions SDK

Las plantillas prefabricadas son ideales para casos como la creación de un juego de Trivia o Flash Cards. Cuando utilizas una plantilla, no necesitas escribir ni una sola línea de código, solo completar algunas hojas de cálculo en Google Sheets y la acción se creará en función de la información que completes. Esto puede ser muy útil para los profesores, quienes pueden crear fácilmente juegos para sus estudiantes.

Sin embargo, en nuestro caso, necesitábamos más poder: queríamos poder hacer un seguimiento del progreso del usuario y como podrás comprobar en breve, mezclar realmente español e inglés es una misma aplicación es todo un reto. Así que tuvimos que elegir entre Dialogflow y Actions SDK.

Dialogflow te brinda una interfaz de usuario agradable para crear flujos de conversación (en algunos casos, incluso puedes librarte de escribir código), y también nos permitiría hacer un prototipo de forma rápida.

Con el Actions SDK tienes acceso directo al input del usuario, y por eso tienes que analizar el texto en tu servidor y generar la respuesta correspondiente.

Las capacidades integradas de Dialogflow nos resultaron muy útiles. Por ejemplo, si un usuario no sabía cómo traducir la oración que se le dio, podría decir: ”no sé” para obtener la respuesta y pasar a la siguiente.

Poco después de que publicáramos la aplicación, nos dimos cuenta de que los usuarios tenían muchas maneras de decir que no lo sabían: “No tengo ni idea”, “lo olvidé”.

“I don’t know” — Dialogflow en Acción

Añadir estas alternativas a la app fue fácil. Ya que Dialogflow nos permite agregar nuevas variaciones rápidamente a medida que avanzamos. Esto significa que podemos mejorar de forma sencilla nuestra app a medida que aprendemos de lo que los usuarios realmente le dicen. Ya que es tan sencillo iterar rápidamente ¡Lo hacemos todo el tiempo!

El back-end y la Integración Continua

Como desarrollador web, JavaScript es mi pan y mantequilla, así que al elegir una tecnología para el backend, usé Node.js una decisión que también fue respaldada por el hecho de que existe un SDK de Node oficial para desarrollar acciones en Google usando Dialogflow. (el paquete actions-on-google). Daniel ya tenía experiencia previa con él, y lo recomendó de todo corazón.

Para complementar la experiencia de desarrollo, también configuré TypeScript, que es ahora mi solución para cualquier proyecto más grande que unas pocas líneas de código. Convenientemente, el SDK de acciones viene con sus definiciones de tipos completas, por lo que obtuve autocompletamiento y comprobación de tipos. Finalmente, configuré tests unitarios con Jest, un framework de tests de Facebook. Lo usé junto con Wallaby.js, una solución que ejecuta continuamente los tests y te muestra los resultados de la ejecución y la cobertura del código a medida que lo escribes. Estoy agradecido a Wallaby.js por crearlo.

Excerpt from our answer verification logic — the green bullets on the left is how Wallaby indicates our coverage

Además de probar la lógica de la app, también usamos Test Unitarios para verificar la consistencia de nuestro curriculum de palabras en español; por ejemplo, aquí hay un extracto de un test que verifica que cada palabra en la base de datos tiene al menos 3 oraciones en las que aparece:

Tener una base de tests sólida es un factor clave en la integración continua, la cual empleamos en nuestra Acción. Usamos CircleCI y lo configuramos para que cada vez que presione un cambio en la rama master, se ejecute el conjunto de tests, se compruebe el código con tslint y, si todo va bien, la nueva versión se desplegará de inmediato y se pondrá en producción.

Usamos Docker para crear un contenedor con nuestra aplicación transpilada, que luego enviamos al Google Container Registry, y luego desplegamos en una pequeña máquina que configuramos para eso (y también para Metabase, ver más abajo). Otras alternativas que manejamos para desplegar el código eran Firebase Functions, Google App Engine, Google Cloud Run o Google Kubernetes Engines, pero decidimos simplemente ejecutar Docker en nuestro servidor.

Aquí esta nuestro Dockerfile, que utiliza la funcionalidad de compilación de múltiples etapas introducidas en Docker 17. Primero, construimos un contenedor donde ejecutamos nuestros tests y transpilamos el código fuente con JavaScript. Una vez que esto se ha completado con éxito, pasamos a la segunda etapa en la que construimos el contenedor real de producción, basado en la imagen más liviana de Node-Alpine:

Finalmente, usamos un servicio llamado Sentry para rastrear errores. Sentry recopila información sobre cualquier excepción que ocurre en nuestro entorno de producción y nos envía un correo electrónico con información. También puedes ver en la línea 32 de Dockerfile que definimos una variable de entorno con la etiqueta de la compilación actual, que luego es utilizada por Sentry para rastrear si un problema aún ocurre después de que implementemos una nueva versión. Rellenamos la variable ${BUILD} con nuestro número de compilación de CircleCI, pasando como un argumento
--build-arg al comando docker al generar la imagen.

Example for an error we had, tracked by sentry down to the exact source code line

En general, nuestra configuración actual incluye tanto los tests como Sentry como redes de seguridad, en las que confiamos, para que podamos hacer grandes cambios y desplegar elementos en producción sin tests manuales exhaustivos y temiendo que rompamos la aplicación. Me encanta trabajar de esta forma.

Analítica

Si hay algo que la vida me enseñó como empresario, es que cada vez que inicias un nuevo proyecto, cada usuario que tienes es una enorme oportunidad de aprender algo nuevo sobre tu producto.

Mientras realizaba los prototipos, me senté junto a Ariella y la observé usando la app, y obtuvimos comentarios muy valiosos con solo hacer esto. Así es como, por ejemplo, decidimos agregar el escenario de “No sé” mencionado anteriormente.

Teniendo esto en cuenta, teníamos claro que queríamos rastrear todas las interacciones del usuario con nuestra app, y también queríamos tener una forma fácil de consultar estas interacciones, analizarlas y visualizarlas para ayudarnos a ver los patrones. Queríamos recopilar Analytics desde el día 0 y buscamos una solución simple que no requiriera demasiada codificación y que pudiera crecer junto con la aplicación. Fuimos con BigQuery, una solución de almacenamiento de datos de Google, que puede escalar fácilmente a cantidades masivas de datos y es compatible con el lenguaje de consulta SQL con el que estamos familiarizados.

La forma en que usamos BigQuery es mediante el informe directo de cualquier interacción del usuario utilizando una función llamada “Insertar transmisión”, que le permite insertar nuevas filas una por una, siempre que ocurran. A continuación, puedes ver el fragmento de código que informa de las interacciones de los usuarios:

Básicamente, llamas a la función con la instancia DialogflowConversation y la respuesta que envia al usuario (sin corresponder), y está todo listo. Así es como definimos nuestro esquema de tabla BigQuery:

Inicialmente, solo rastreamos la entrada y la respuesta, pero cuando comenzamos a ver a los usuarios interactuar con la app, vimos muchos casos en los que parecía que la aplicación no entendía al usuario correctamente, por lo que queríamos entender cómo interactúan los usuarios con la app y de qué parte del mundo eran.

Aquí es donde empezamos a recoger partes locale, inputType y surfaceCapabilities. Los dos últimos no fueron muy sencillos, ya que requerían un procesamiento previo antes de que pudiéramos almacenarlos en la base de datos:

Aprendimos que la gran mayoría de los usuarios interactúan con nuestra aplicación usando la voz:

Al observar las capacidades de la superficie, también pudimos ver que muchos de los usuarios interactuaron con nosotros utilizando un dispositivo con capacidad de salida de audio y audio de respuesta media, que creemos que es Google Home (en contraste con un dispositivo con capacidad de salida de pantalla, como un Smartphone):

En general, la configuración de BigQuery fue una cuestión de aproximadamente una hora de codificación y prueba, y luego generar un archivo de cuenta de servicio con las credenciales e incluirlo en nuestro código, Con suerte, esta es una parte que no tendremos que volver a visitar pronto, ya que toda la base de datos está totalmente administrada para nosotros. Como puedes ver, ya estamos produciendo algunas ideas muy útiles que nos ayudan a dar forma y mejorar nuestro producto.

Quizás te preguntes de dónde provienen los gráficos anteriores. BigQuery no viene con visualizaciones de datos integradas, y aunque puede exportar los resultados de la consulta a Excel, esto no es muy conveniente. Utilizamos un producto gratuito llamado Metabase, que se conecta a BigQuery y te permite consultar y visualizar fácilmente los datos. Por ejemplo, así es como configuro la consulta para el primer gráfico:

También puedes optar por escribir tus consultas utilizando SQL, en caso de que necesites una agregación más sofisticada, o para unir datos de varias tablas. Finalmente, Metabase te permite crear un panel de control agradable que puedes configurar para mostrar las métricas que te interesan:

Bueno, según el gráfico anterior, probablemente puedas adivinar en qué momento lanzamos la app 😊

Actualización: a partir de mayo de 2019, Google lanzó su propia herramienta de visualización de datos, Data Studio Explorer. Todavía está en la versión beta, pero puede ser una alternativa viable a Metabase, y no requiere ninguna configuración.

Google también proporciona información sobre tu aplicación en una sección dedicada al Análisis de Acciones en la consola de Google, donde puedes obtener información sobre el estado de tu app, la latencia, el descubrimiento y más.

La moraleja es que configurar una solución para tus analíticas es muy sencillo, y hay mucho que aprender de tus datos, por lo que definitivamente es algo que quieres hacer antes de lanzar tu app.

Hablando español

Esta parte es algo específica para nuestro caso, así que la haré corta. Queríamos que la app hablara en español además de en inglés. Google Assistant te permite personalizar las respuestas usando un lenguaje llamado SSML, que puede especificar parámetros de voz como la velocidad, el tono y también dar sugerencias sobre cómo leer partes específicas del texto, como agregar un énfasis

Desafortunadamente, la implementación de SSML de Google actualmente no admite el cambio entre idiomas. Sin embargo, si que permite insertar archivos de audio externos, por lo que teóricamente podríamos generar el habla en español usando un método diferente.

Lo gracioso es que encontramos la solución en un lugar bastante inesperado: la cloud de Amazon. Esta cuenta con un servicio de TTS en la nube, llamado Amazon Polly, con un generoso nivel gratuito: 5 millones de caracteres al mes. También admite SSML, lo que significa que podemos pedirle que hable más lento cuando el usuario le pide que repita la oración.

La moraleja de la historia es que, a veces, puedes obtener mejores resultados si combinas servicios de múltiples proveedores de la nube para satisfacer tus necesidades específicas.

Una base de datos para datos de usuario

El primer prototipo de la aplicación simplemente dio a los usuarios una oración aleatoria en español para traducirla al inglés. Mientras observaba a Ariella, nuestra probadora beta número 1 que lo usaba, me di cuenta de que este no era el enfoque correcto, ya que había muchas palabras con las que aún no está familiarizada; hacer que la acción escupiera una oración al azar sin tener en cuenta su vocabulario actual no tenía mucho sentido.

En ese momento, me di cuenta de que necesitábamos usar algún tipo de base de datos para almacenar el progreso de cada usuario individual.

Elegimos la nueva base de datos Cloud Firestore, ya que está completamente alojada y administrada, y es una base de datos de documentos sin esquema, lo que la hace perfecta para la creación rápida de prototipos. Todavía soy bastante nuevo en Firestore, pero realmente disfruto usando Firebase (en realidad, he sido usuario desde su versión beta publicada en 2013):

Using the FireStore console to check on our users progress

En algún momento, Daniel me preguntó por qué necesitábamos tanto BigQuery como Firestore. La respuesta está en la diferencia fundamental entre los dos: BigQuery es ideal para consultas complejas en una gran cantidad de datos. Obtendrás respuesta en segundos, sin importar el tamaño de los datos que tenga. En esto es también donde se encuentra su debilidad: incluso si se desea un solo registro, el motor aun tendrá que escanear toda la tabla y obtendrá la respuesta en cuestión de segundos. Mientras que esperar 5 segundos para obtener un resultado para una consulta compleja tiene sentido, hacer que nuestros usuarios esperen 5 segundos o más por cada interacción con la aplicación no es el tipo de experiencia que buscamos.

Además, BigQuery es bastante limitado cuando se trata de modificar datos existentes. Así que Firestore es ideal para operaciones rápidas de lectura/inserción/actualización, mientras que BigQuery se destaca en el almacenamiento y la consulta de datos agregados de los usuarios. Entonces, al igual que la forma en que terminamos usando múltiples servicios para hacer que nuestra app hable español, se trata de encontrar la herramienta adecuada para el trabajo.

El Front-end

Ahora puede que te estés preguntando: ¿Qué tiene que ver el Front-end con una Acción? Probablemente, en algún momento construiremos una página web para que nuestros usuarios puedan ver su propio progreso, pero por ahora, decidimos construir una pequeña herramienta para nosotros mismos poder explorar cómo nuestros usuarios interactúan con la aplicación. Es cierto que tenemos todos los datos en BigQuery, pero leer una conversación en una tabla de base de datos no es muy conveniente.

Decidí tomar esta oportunidad para aprender una nueva tecnología, Vue.js. Comencé desde fuse-box-vue-seed, que también incluye Vuetify, una biblioteca de componentes de Material Design para Vue, y fuse-box, un paquete de módulos súper rápido, que es una buena alternativa a Webpack.

Luego agregué el inicio de sesión único de Google utilizando Firebase Authentication, desplegué la aplicación en la web con Firebase Hosting y usé el firebase-admin SDK para verificar la identidad del usuario en nuestro servidor.

En general, estoy muy contento con Vue: la curva de aprendizaje fue suave, trabajar con Vuetify fue bastante fácil y logré construir rápidamente una herramienta que ahora utilizamos a diario y a la que podemos agregar nuevas funcionalidades.

Conclusión

Ya tenemos algo de kilometraje con nuestra aplicación, pero aún es el principio. Utilizando las tecnologías existentes y aprovechando los servicios en la nube, como Dialogflow, BigQuery, Firestore, Sentry, Amazon Polly, mientras usamos una configuración de Despliegue Continuo con Jest, Docker, Circle CI y Google Container Registry nos permiten comenzar a trabajar rápidamente y mantener el ritmo incluso una vez que la aplicación se mantuvo en vivo.

Han pasado dos semanas desde el lanzamiento de nuestra aplicación, y ya hemos servido a cientos de usuarios y hemos aprendido un montón sobre lo que podríamos mejorar. Algunas de las mejoras más pequeñas ya se han incorporado a la aplicación, y ahora estamos trabajando en una revisión de la estructura de la lección, para hacerla más efectiva. Probablemente verás otra publicación nuestra en las próximas semanas que cubran las cosas más desde la perspectiva del producto.

Nos da mucha satisfacción ver a los usuarios que regresan a nuestra aplicación diariamente para aprender nuevas palabras, ¡y Ariella también se ha divertido aprendiendo nuevas palabras en español!

¿Suena divertido? ¡Prueba nuestra acción!

¡Ah y no olvides probar nuestra acción! Puedes verla en Google Home, televisores con Android 6.0+, teléfonos con iOS 9.0+ o en tu Chromebook. Simplemente instala Google Assistant (si aún no la has hecho) y di:

Talk to Spanish Lesson

¡Diviértete!

--

--

Uri Shaked

Google Developer Expert for Web Technologies, Maker and Public Speaker