Más allá del cuadro de chat: Arquitectura de un agente de IA de WhatsApp en Google ADK
Cómo un asistente de WhatsApp para producción combina agentes especializados en Google ADK, RAG, herramientas deterministas, estado de sesión, transferencia a humanos y evaluación basada en trayectorias.
La mayoría de las demostraciones de IA consisten en un cuadro de texto conectado a un modelo: se ingresa una pregunta, sale una respuesta fluida y el público queda satisfecho. Un producto del que dependen clientes reales tiene una lista más extensa de requisitos. Debe recordar la conversación, trabajar con datos en tiempo real de la empresa, tomar acciones, superar fallos y transferir al cliente a un humano cuando la automatización no es suficiente.
Este artículo explica en detalle la arquitectura de un asistente de producción que funciona dentro de WhatsApp para un mercado de carga de vehículos eléctricos en Sri Lanka. Sirve a conductores de vehículos eléctricos, propietarios que podrían albergar cargadores y personas que simplemente desean aprender sobre la carga de vehículos eléctricos. Al final, dispondrá de un plano concreto de los componentes que rodean al modelo, además de un conjunto de reglas de diseño que puede reutilizar en su propio agente, independientemente del canal en el que opere.
Por qué el canal da forma al producto
El equipo eligió WhatsApp para que nadie tuviera que instalar otra aplicación solo para hacer una pregunta. Los usuarios objetivo ya están en WhatsApp: saben cómo enviar un mensaje, compartir una ubicación, guardar un contacto y responder a un mensaje específico en una conversación. Reunirse con ellos allí elimina por completo el problema de la adaptación al uso de la herramienta. En lugar de enseñar a las personas cómo usar un producto basado en IA, el asistente aparece dentro de una herramienta que ya comprenden.
Esa elección también impone restricciones que un chatbot web nunca enfrenta:
- Las respuestas deben ser breves, ya que las respuestas largas resultan pesadas en un teléfono.
- Los mensajes deben llegar a un ritmo natural y no como un bloque enorme de texto.
- Las solicitudes de ubicación deben utilizar la interfaz nativa de WhatsApp para compartir ubicaciones.
- Los datos de contacto deben presentarse como una tarjeta de contacto real, y no como texto pegado.
El objetivo es lograr una conversación que parezca nativa de WhatsApp, y no un chatbot de escritorio forzado dentro de una aplicación de mensajería. Tenga esto en cuenta para cualquier canal: las convenciones de interfaz de la plataforma forman parte de las especificaciones, no son meras decoraciones.
Ruta de solicitud desde el webhook hasta la respuesta
El backend está escrito en Python utilizando el Google Agent Development Kit (ADK) y FastAPI. ADK puede generar un servidor API listo para uso destinado a los agentes, con soporte integrado para ejecutarlos, gestionar sesiones y transmitir los resultados como eventos. Ese servidor API funciona con FastAPI y Uvicorn, lo que facilitó su ampliación con un webhook personalizado de WhatsApp y endpoints específicos para el negocio.
Un agente ADK se compone de cuatro elementos:
- Un modelo, como Gemini.
- Instrucciones que definen el rol y los límites del agente.
Seguir un único mensaje de principio a fin hace que el diseño sea concreto:
- Un usuario envía un mensaje de WhatsApp, y Meta lo entrega al webhook de FastAPI.
- El backend analiza el mensaje y lo refleja en Chatwoot para que el equipo de soporte pueda seguir la conversación.
- El backend busca la sesión correspondiente al usuario y pasa el mensaje a ADK.
- ADK ejecuta el coordinador, que dirige la solicitud: las preguntas técnicas al agente de EV, las preguntas sobre ingresos al agente de precios y las búsquedas de estaciones al agente de estaciones.
- El agente seleccionado busca en la base de conocimientos de Vertex AI o utiliza una herramienta, por ejemplo para consultar datos de estaciones, estimar ingresos, enviar una tarjeta de contacto o solicitar la ubicación del usuario.
Fíjese en cuán poco de este proceso corresponde al modelo en sí. El análisis, la búsqueda de sesiones, el enrutamiento, el formateo, la entrega y el reflejo son todas tareas habituales del backend.
Un coordinador, tres especialistas
El asistente está organizado como un coordinador que delega tareas a tres agentes especializados:
- Un agente de infraestructura para vehículos eléctricos encargado de los tipos de cargadores, su instalación y las regulaciones correspondientes.
- Un agente de precios y negocios que se ocupa de los aspectos económicos relacionados con el alojamiento.
- Un agente de búsqueda de estaciones para localizar puntos de carga.
La única tarea del coordinador es comprender la intención y transferir la conversación al especialista adecuado. Una pregunta sobre tipos de cargadores se dirige al área de infraestructura, una consulta de un propietario sobre ingresos potenciales va al departamento de precios, y una solicitud de estaciones cerca de Galle se envía a la función de búsqueda de estaciones. Estas transferencias son invisibles para el usuario, quien experimenta una sola conversación continua con un único asistente.
La alternativa era un único agente grande con una instrucción de sistema extensa y todas las herramientas asociadas. Eso funciona para un prototipo, pero a medida que se acumulaban herramientas y flujos de conversación, dividir las responsabilidades resultó beneficioso en tres aspectos: cada instrucción se mantenía breve, era fácil saber qué agente podía utilizar qué herramienta, y cada flujo podía probarse por separado. Separar a un coordinador de sus especialistas, uno de los patrones documentados de orquestación de agentes, también hacía que los cambios fueran más económicos, ya que se podía revisar el flujo de precios sin tocar la búsqueda de estaciones.
Existe un costo que merece ser mencionado. Cada decisión de enrutamiento representa otra llamada al modelo que puede fallar, por lo que una pregunta mal enrutada fracasa de una manera en la que un agente individual nunca lo haría. Esa es una de las razones por las cuales la estrategia de evaluación descrita más adelante verifica qué agente y herramienta se eligieron, no solo la redacción final. Para un análisis más profundo de cómo se integran el enrutamiento y los agentes especializados, consulte agentes especializados, un enrutador por palabras clave e interrupciones en LangGraph.
Basar las respuestas en una base de conocimientos controlada
Un asistente de empresa no debe inventar hechos, y la carga de vehículos eléctricos está llena de detalles que son fáciles de error: capacidades de los cargadores, tiempos de carga, requisitos de instalación, regulaciones, modelos de vehículos e información específica de la empresa. Muchos de estos cambian con el tiempo, y un modelo general tiene poca información sobre el mercado local.
La solución es la generación reforzada por recuperación de información. El conocimiento se almacena como un corpus en el RAG Engine de Vertex AI, y antes de responder a una pregunta técnica, el agente puede consultarlo en busca de los pasajes más relevantes. Existen dos rutas de recuperación separadas: una para la infraestructura general de vehículos eléctricos y otra para preguntas sobre modelos de vehículos y tiempos de carga. Dividir el corpus de esta manera mantiene los resultados enfocados, ya que una pregunta sobre cuánto tiempo tarda en cargarse un coche específico no compite con documentos regulatorios por los resultados principales.
La división del trabajo es la idea clave. El modelo sigue elaborando las respuestas, pero los datos provienen de fuentes que la empresa controla y puede actualizar sin necesidad de reentrenar nada.
Convierte la conversación en acción
El mayor avance fue ir más allá de responder preguntas. El asistente cuenta con herramientas que realizan tareas reales. Puede:
- Consultar el backend del mercado para saber cuántas estaciones de carga existen cerca de una ciudad determinada.
- Enviar una solicitud de ubicación a través de WhatsApp.
- Enviar la tarjeta de contacto de la empresa.
- Compartir la ubicación de la oficina como un marcador en el mapa.
- Estimar los ingresos potenciales para quienes consideren instalar una estación de carga.
- Marcar una conversación para que la atienda un humano cuando el usuario lo necesite.
Por qué el cálculo de ingresos se hace con Python puro
El flujo de ingresos muestra la regla de diseño más importante del sistema. El asistente primero recopila detalles sobre la propiedad del usuario y sus requisitos de cobro a través de una conversación. Luego calcula el consumo mensual de energía, los ingresos esperados, el costo de la electricidad, la ganancia mensual y la ganancia anual.
Ese cálculo se realiza con Python determinista, no es algo que el modelo de lenguaje determine por sí mismo. Los modelos son poco fiables en cálculos aritméticos, y las cifras financieras que se muestran a un cliente potencial deben ser reproducibles y auditables. El modelo gestiona el diálogo y extrae las entradas; el código genera los números. El resultado se envía a través de un template estructurado de WhatsApp, y la información del cliente potencial se registra en Google Sheets.
Utilice el modelo para tareas lingüísticas y toma de decisiones, y utilice software ordinario para todo lo que requiera precisión absoluta.
Esta regla se aplica ampliamente más allá de los precios: el manejo de fechas, la conversión de unidades, las verificaciones de elegibilidad y cualquier aspecto con relevancia legal o financiera deben estar en el código al que recurre el modelo, no en la salida del mismo.
El estado de sesión es parte de la lógica del producto
Una buena conversación depende de lo que ocurrió antes. El asistente mantiene una sesión separada para cada número de WhatsApp, y dicha sesión contiene el nombre del usuario, su número de teléfono, la opción del menú que seleccionó, los mensajes recientes, el estado de ubicación y el ID del último mensaje.
Al almacenar el ID del último mensaje, el sistema puede interpretar las respuestas a un mensaje específico del menú, algo que los usuarios de WhatsApp hacen constantemente. El estado de sesión también permite que los flujos de varias etapas continúen de manera natural. Por ejemplo, la transferencia de ubicación se realiza de esta forma:
- Preguntar si el usuario desea compartir su ubicación.
Sin ese estado, cada mensaje sería considerado como el inicio de una nueva conversación. La memoria en un agente no es un complemento opcional; define cómo se comporta el producto y merece la misma atención en su diseño que cualquier otra función.
Formateo para pantalla pequeña
Una lección sorprendente fue que una respuesta técnicamente correcta aún podía parecer incorrecta únicamente por su formato. Los modelos tienden a generar párrafos largos, listas en Markdown y varias ideas agrupadas en un mismo bloque. Eso se lee bien en una computadora de escritorio, pero mal en una burbuja de chat.
Una capa de formateo dedicada se encarga de esto. Ella:
- Convierte Markdown en la sintaxis de formateo propia de WhatsApp.
- Detecta listas ocultas dentro del texto continuo.
Los breves intervalos entre los fragmentos dan al lector tiempo para asimilar cada idea. El objetivo no es simular que es una persona quien escribe, sino controlar el ritmo. Los indicadores de escritura, enviados a través de la Meta API, muestran que se está preparando una respuesta.
El asistente también reacciona ante algunos mensajes con un emoji, y lo hace de forma selectiva. Un modelo ligero como Flash Lite decide si un mensaje merece una reacción, y si es así, la reacción se envía a través de la Meta API. Los mensajes emocionales, emocionantes, graciosos o significativos pueden recibir uno; los mensajes rutinarios como “ok”, “gracias” o instrucciones simples generalmente no. Utilizar un modelo pequeño y económico para esta decisión secundaria mantiene baja la latencia y el costo, mientras que los agentes principales se encargan del contenido principal. Detalles como estos son menores por separado, pero juntos determinan si el producto parece natural.
Mantener un camino hacia un humano
La automatización nunca debe convertirse en un muro entre los clientes y la empresa. Cada conversación recibida se sincroniza con Chatwoot, y también se añaden las respuestas del asistente, de modo que el equipo de soporte siempre ve exactamente lo que se dijo.
Cuando un usuario solicita hablar con una persona real o muestra signos de frustración, el asistente activa un proceso de ayuda humana que registra la solicitud, junto con la pregunta del usuario, para que el equipo pueda atenderla. Dado que toda la conversación ya está reflejada, la persona que toma el relevo no necesita pedir al cliente que se repita.
La automatización debe eliminar el trabajo repetitivo, no impedir el acceso a una persona.
Trabajo de fiabilidad fuera de la conversación
El sistema también envía campañas con plantillas de WhatsApp salientes, lo que plantea un problema sutil: una transmisión promocional nunca debe interrumpir a alguien que está en medio de una conversación de soporte. Antes de enviar, el sistema verifica cuándo interactuó por última vez cada destinatario con el asistente. Aquellos que estaban chateando hace poco tiempo quedan por ahora sin ser contactados: su mensaje se retrasa, se guarda en SQLite y se pone a disposición de un punto final de intentos múltiples que puede enviarlo más tarde.
Alrededor de esto se encuentran las funcionalidades poco llamativas que todo servicio necesita:
- Deduplicación de los mensajes recibidos, ya que los webhooks pueden entregar el mismo evento más de una vez.
- Monitoreo del estado del sistema.
- Gestión para la renovación de tokens de acceso.
- Controles CORS en los puntos finales HTTP.
- Despliegue basado en Docker.
- Rastreo de errores con Sentry.
Ninguno de estos elementos impresionaría a nadie en una demostración. Todos se vuelven esenciales en el momento en que la demostración se convierte en un servicio del cual dependen los clientes.
Prueba del comportamiento, no solo del texto
Los agentes son más difíciles de probar que las funciones ordinarias, ya que la misma entrada puede generar resultados ligeramente diferentes. Peor aún, los modos de fallo no son evidentes a partir del texto final. Una respuesta puede leerse bien aunque se haya utilizado la herramienta incorrecta, o bien se puede usar la herramienta correcta pero comunicar mal el resultado.
Por lo tanto, el conjunto de pruebas utiliza conversaciones simuladas que abarcan preguntas sobre infraestructura, flujos de precios y conversaciones entre especialistas. Las verificaciones examinan la trayectoria de las herramientas, es decir, qué agentes y herramientas se invocaron en qué orden, y no solo la redacción de la respuesta final.
Los cambios en los prompts se manejan de la misma manera. En lugar de editar el prompt del sistema a mano, el equipo experimentó con un bucle de optimización en el que se evaluaban instrucciones candidatas a través de un conjunto fijo de conversaciones, incluyendo la optimización de prompts basada en GEPA. Las instrucciones candidatas se someten a pruebas con preguntas de entrenamiento, y un evaluador independiente impulsado por Gemini califica cada respuesta en cuanto a precisión y personalidad. Esto convierte el trabajo con prompts en algo más similar a la ingeniería: en lugar de mantener un cambio porque se siente mejor, se puede comparar el comportamiento a través de un conjunto repetible de conversaciones. Existe una advertencia para cualquier configuración en la que el modelo actúe como evaluador: el evaluador tiene sus propios sesgos, por lo que vale la pena verificar sus calificaciones contra el juicio humano antes de confiar en ellas para decisiones importantes.
Puntos clave
- El modelo es un solo componente; la mayor parte del trabajo de ingeniería se centra en el enrutamiento, la recuperación de información, el estado del sistema, las herramientas, el formato, el manejo de fallos y la escalada de problemas.
- Divida un agente en crecimiento en un coordinador y especialistas enfocados una vez que las instrucciones y las listas de herramientas se vuelvan difíciles de gestionar, y pruebe el enrutamiento en sí.
- Sustente las respuestas factuales en una base de conocimientos que usted controle, y mantenga tareas precisas como los cálculos en código determinista.
- Trate el estado de la sesión y el formato específico del canal como parte fundamental de la lógica del producto.
- Siempre mantenga un camino visible y sencillo hacia un humano.
- Evalúe las trayectorias de las herramientas a lo largo de un conjunto fijo de conversaciones para que los cambios en las instrucciones se midan en lugar de adivinarse.
Al envolver una instrucción alrededor de una llamada a API se obtiene una demostración. Un agente fiable es un sistema completo en el que los modelos de lenguaje, los datos, las herramientas, el diseño del producto y la ingeniería tradicional de backend realizan cada uno aquello para lo que son más eficaces.