Un agente de IA en tu app que nunca afirma algo que no hizo
Un agente de IA dentro de tu app, hecho para escalar con tus usuarios, que agenda, crea y cambia cosas a través de tu propia API, y cada respuesta se verifica en código contra lo que de verdad pasó.
Un agente de IA dentro de tu app que hace cosas reales por tus usuarios, hecho para escalar con tu base de usuarios: no guarda estado y cada conversación corre en su propia sesión aislada, sobre un runtime gestionado. Nuestra versión de referencia es el coach de una app de fitness, probado contra una suite automática de conversaciones reales: el usuario pide en palabras simples y el agente encuentra rutas, agenda sesiones, agrega amigos y organiza salidas en grupo con unas pocas decenas de herramientas sobre la API de la app. Sus respuestas pueden abrir una pantalla de la app, y recuerda lo importante de cada usuario entre conversaciones.
El problema que resuelve
Los modelos de lenguaje conversan bien, pero no siempre cumplen lo que dicen. Si les pides agendar algo, a veces responden “listo” cuando la llamada falló o nunca ocurrió, citan un registro que no existe o completan un dato que el usuario nunca dio. En un chatbot que solo responde preguntas, eso es una respuesta equivocada. En uno que cambia datos, es una promesa rota: una sesión que nunca se agendó, una solicitud de amistad que nunca salió y un caso de soporte cuando el usuario se da cuenta.
Lo usual es sumar reglas al prompt o poner un segundo modelo a calificar al primero. Las dos cosas siguen siendo apuestas. Los equipos muestran un demo convincente y se estancan, porque nadie puede decir con qué frecuencia el agente miente sobre lo que hizo.
Qué obtienes
Acciones, no solo respuestas: el agente agenda, crea, edita y cancela a través de tu API, con los mismos permisos y validaciones de tus pantallas.
Respuestas que coinciden con lo que pasó: si un cambio falló o no se hizo, el usuario lo sabe y puede reintentarlo.
Nada inventado: registros, lugares y fechas salen de tus datos o de las palabras del usuario; si falta algo, el agente pregunta.
Memoria que se mantiene: cada conversación conserva su contexto, y lo duradero, como una lesión o un horario preferido, acompaña al usuario a chats nuevos.
Respuestas que hacen algo: la respuesta puede abrir una tarjeta o una pantalla de tu app, no solo mostrar texto.
Una red de seguridad que crece: cada error que encontramos se vuelve una verificación y una conversación de prueba que sigue pasando.
Cómo lo entregamos
Empezamos con un Sprint de IA y Datos: elegimos lo que tus usuarios más quieren hacer conversando, describimos esas operaciones de tu API en especificaciones, las conectamos como herramientas y escribimos las verificaciones de lo que nunca puede salir mal, junto con conversaciones de prueba contra tu API real y una cuenta de pruebas. Luego, con Integración de Sistemas sumamos más de tu API como herramientas, y con un Retainer de Ingeniería las verificaciones y pruebas siguen creciendo con los casos que traen los usuarios reales. Necesitamos tu API, su documentación y alguien que sepa qué errores dolerían más.
¿Es para ti?
Encaja si tu app ya tiene una API, tus usuarios repiten tareas de varios pasos y un “listo” falso te costaría confianza o tiempo de soporte. No es para ti si solo necesitas respuestas sobre tu documentación: un asistente de búsqueda y respuesta es más simple y barato. Tampoco es el camino más rápido si necesitas muchos idiomas desde el primer día, porque las verificaciones leen las respuestas del agente y se escriben por idioma.
Técnico
01Un usuario le pide al coach agendar una salida
02El agente encuentra la ruta y la agenda
03El código compara la respuesta con lo que hicieron
04Una afirmación sin respaldo vuelve para corregirse
05El usuario recibe la respuesta y una tarjeta
06Lo duradero, como una lesión, pasa a otros chats
Objetivos de diseño
El agente nunca le dice a un usuario que algo se hizo si un resultado de herramienta no lo respalda.
Registros, lugares y fechas salen de resultados de herramientas o de las palabras del usuario, nunca de una suposición del modelo.
Lo que el modelo no debe decidir (dónde está el usuario, qué día es, qué herramientas puede usar) lo fija el código.
El agente no guarda estado: cualquier contenedor puede responder cualquier mensaje.
Cada error encontrado se vuelve una regla, una prueba unitaria o una conversación de prueba que sigue pasando.
Arquitectura
Personas y entradas
UsuariosPiden en palabras simples
App móvilIngreso, ubicación, tarjetas
Backend
API de chatAutenticación, reloj, contexto
MemoriaHistorial y datos duraderos
Agente
Grafo del agenteModelo, herramientas, verificación, reintento
Modelo de lenguajeGestionado, llamado en cada paso
Herramientas y datos
Gateway de herramientasGestionado, desde especificaciones de API
API de la appCatálogo y datos por usuario
Datos de la appRutas, planes, amigos
Cuatro piezas, y solo una habla con el modelo. La API de chat verifica el ingreso del usuario, carga el historial de la conversación y sus datos duraderos, agrega la ubicación y la hora actual con su propio reloj, e invoca al agente. La app nunca tiene una llave del modelo.
El agente corre en un runtime gestionado de contenedores que aísla cada sesión. Es un servicio pequeño en Python con un chequeo de salud y un endpoint de invocación, así que corre igual en un portátil y en la nube.
El gateway de herramientas convierte la API de la app en herramientas. Cada grupo de operaciones se describe en una especificación de API, y el gateway las expone por el Model Context Protocol, firma las llamadas del agente e inyecta la credencial de cada grupo desde su propia bóveda. Las herramientas de catálogo, de solo lectura, no llevan identidad de usuario; las del usuario son un grupo aparte con una llave aparte.
La memoria vive en la tabla clave-valor del backend, junto a los datos de la app: un ítem por turno de conversación y uno por dato duradero.
Cómo resolvemos lo difícil
El grafo: modelo, herramientas, verificación, reintento
Verificar la respuestaReglas en código, sin otro modelo
Corregir y reintentarObligado a actuar si hace falta
Un éxito falso nunca sale. Si un cambio falló o nunca se hizo, el código reemplaza la respuesta por una honesta, escriba lo que escriba el modelo.
Cada mensaje es un pequeño grafo de estados. El modelo llama herramientas, que corren y le devuelven el resultado, o da su respuesta. La respuesta misma es una llamada a una herramienta con esquema (el texto, una acción opcional de la app y unas sugerencias de continuación), así que no hay nada que extraer de texto libre, y los campos son planos porque los esquemas planos son los que toda combinación de modelo y gateway llena de forma confiable. Luego la respuesta pasa por un nodo de verificación. Si falla, el grafo agrega una corrección que el usuario nunca ve y la devuelve al modelo. Los turnos de herramientas y los reintentos tienen tope, así que un turno confundido termina en vez de dar vueltas.
Verificaciones deterministas alrededor de un modelo que no lo es
Las verificaciones son código simple que compara la respuesta con lo que las herramientas de verdad hicieron en el turno. Una herramienta de escritura cuya última llamada falló debe reportarse como falla. Una respuesta que afirma una acción terminada (“agendé”, “borré”) sin ninguna escritura exitosa detrás no pasa. Tampoco una petición de agendar que termina sin agendar y sin una pregunta por la fecha que falta. Todo registro al que la respuesta lleve a la app debe venir de un resultado de este turno. Cuando arreglarlo exige hacer algo y no solo reescribir, el reintento quita la opción de responder y obliga a llamar una herramienta, así que el modelo no puede volver a disculparse en prosa. Al terminar el grafo, las mismas reglas corren otra vez como respaldo: si el modelo ignoró todas las correcciones, el código sobrescribe la respuesta. Las negativas que nuestras propias protecciones devuelven a propósito, como “pregúntale primero al usuario”, quedan exentas, así que se vuelven preguntas y no disculpas.
Herramientas desde especificaciones, con argumentos que el modelo no pone
El agente carga las herramientas del gateway en cada mensaje y envuelve cada una. La ubicación del usuario se quita del esquema que ve el modelo y el código la agrega, así que nunca pregunta la ciudad ni adivina coordenadas. Las respuestas se recortan a lo que el modelo necesita, porque las tarjetas de la app muestran el detalle, pero los errores pasan intactos para que las verificaciones los vean. Las herramientas que crean rutas tienen una protección: cada palabra distintiva de cada punto debe aparecer en lo que el usuario escribió en la conversación; si no, la herramienta se niega y el agente propone el punto. Las herramientas del usuario ni se ofrecen si nadie ha iniciado sesión. Una prueba de contrato en CI revisa que cada especificación siga coincidiendo con una ruta real del backend.
Memoria sin estado en el agente
El agente no recuerda nada entre llamadas. El backend envía los turnos anteriores de la conversación en cada mensaje y guarda el turno nuevo al final, lo que también alimenta la pantalla de historial de la app. Los datos duraderos son otro almacén: el agente guarda uno con una herramienta dedicada cuando el usuario menciona una lesión, una rutina o una meta, y el backend envía esos datos con cada mensaje, en cualquier conversación. La fecha actual va escrita con su día de la semana y no como una marca de tiempo, porque los modelos fallan al calcular el día de la semana, y las sesiones se agendan en hora local.
Decisiones
Pregunta
Opciones
Elegimos
Por qué
El ciclo del agente
Ciclo escrito a mano; agente de un framework; grafo explícito
Grafo explícito con un nodo de verificación
Cada camino, tope y reintento se ve y se puede probar
Cómo vuelve la respuesta
Texto libre con etiquetas; una herramienta final con esquema
Herramienta final con campos planos
Nada que extraer; los esquemas planos se llenan bien
Cómo se verifica
Un segundo modelo como juez; reglas en código
Reglas en código, más un respaldo
El mismo veredicto siempre, gratis, con pruebas unitarias
Cómo se construyen las herramientas
Funciones a mano; desde especificaciones detrás de un gateway
Especificaciones detrás de un gateway gestionado
Una sola fuente de verdad, credenciales fuera del agente
Dónde vive la memoria
En el proceso del agente; almacén del backend enviado en cada llamada
Almacén del backend, agente sin estado
El runtime puede reciclar cualquier contenedor; el historial se necesita igual
Cómo se recuperan los datos duraderos
Embeddings y ranking; la lista completa
La lista completa en cada llamada
Un usuario tiene pocos; el ranking se puede sumar sin cambiar el almacenamiento
Protecciones
Seguridad. Los usuarios inician sesión con un servicio de identidad gestionado y el backend verifica cada token. El agente llega a las herramientas solo por un gateway que revisa solicitudes firmadas, y la credencial de cada grupo se queda en la bóveda del gateway, nunca en el prompt ni en la app.
Mínimo privilegio. Sin sesión, las herramientas del usuario no aparecen. Las de catálogo no llevan identidad. El runtime del agente solo puede llamar a su propio gateway, y los límites por usuario en búsquedas e invitaciones impiden usar al agente para enumerar usuarios o llenarlos de spam.
Costo. Tope de turnos de herramientas y de reintentos por mensaje, un modelo pequeño y rápido, verificaciones en código y no como llamadas extra al modelo, y resultados recortados antes de volver al modelo.
Confiabilidad. Verificaciones con reglas, un respaldo en código, pruebas unitarias para cada regla y una suite de conversaciones guionadas contra el modelo, el gateway y la API reales, que reinicia a su usuario de prueba antes de cada escenario.
Datos personales. El modelo ve resultados recortados: nombres, no fotos de perfil ni chats privados. Los datos duraderos son solo lo que el usuario dijo con claridad, y la ubicación siempre viene del dispositivo, nunca del modelo.
Modos de falla
Qué falla
Qué pasa
Una herramienta de escritura falla
La respuesta dice que falló y ofrece reintentar, nunca “listo”
El modelo afirma una acción que no hizo
Vuelve obligado a actuar; si aun así no lo hace, el código reemplaza la respuesta
El modelo elige un lugar que el usuario no nombró
La herramienta se niega; el agente propone el lugar y pregunta
El modelo cita un registro que no consultó
Vuelve; solo valen registros de los resultados de este turno
El modelo no deja de llamar herramientas
Los turnos tienen tope y debe responder
El agente se cae a mitad de un turno
El usuario recibe un “intenta de nuevo” breve; nada a medias se da por hecho
Compromisos, y cuándo no usar esto
Las verificaciones son reglas de palabras clave sobre la respuesta en un idioma: atrapan las fallas que ya vimos, no todas las posibles, y un idioma nuevo implica escribirlas otra vez. Por eso cada error nuevo se vuelve una regla y una conversación de prueba. Las herramientas del usuario reciben su id como un argumento que el agente toma de su contexto, porque la credencial compartida del gateway demuestra “soy el agente” pero no “para qué usuario”; el backend solo lo acepta junto con la llave del agente, pero para datos sensibles el siguiente paso es un token de corta duración limitado a un usuario (planeado). Las respuestas llegan completas y no palabra por palabra, un reintento cuesta otra llamada al modelo y se abre una sesión nueva con el gateway en cada mensaje. Si tu asistente solo responde preguntas y nunca cambia datos, esta capa es más de lo que necesitas.
Qué mediríamos
Porcentaje de turnos que pasan las verificaciones al primer intento.
Reintentos y reemplazos del respaldo, por regla.
Tasa de éxito de las conversaciones de prueba en corridas repetidas.
Tasa de error por herramienta.
Latencia de respuesta (p95) y turnos de herramientas por mensaje.
Costo del modelo por conversación.
¿Quieres algo así en tu stack?
Cuéntanos tu contexto y te diremos qué haría falta.
Una plataforma de consentimiento para decenas de millones de clientes: un centro de preferencias, una lista de supresión en la que tus envíos pueden confiar y un backoffice para operar ambos, migrados desde una base de datos heredada sin perder una sola desuscripción.
Un despachador de campañas masivas, en producción en tu propia cuenta de nube: envía campañas de correo a millones de destinatarios a un ritmo seguro y constante, y registra cada entrega, apertura y rebote por destinatario.