Diseñar sistemas agenticos que no colapsen en producción
Por qué muchos sistemas agenticos fallan en producción y cómo diseñar agentes fiables con máquinas de estados, contratos claros de herramientas, reintentos e observabilidad profunda.

De demos impresionantes a agentes frágiles en producción
Los sistemas agenticos son aplicaciones en las que un LLM no solo responde a un prompt, sino que decide qué hacer después: qué herramientas invocar, qué datos recuperar, qué pasos ejecutar y cuándo ha terminado. Combinan un modelo, un conjunto de herramientas (APIs, bases de datos, servicios), un bucle de planificación/ejecución y la infraestructura que lo conecta todo.
En una demo, esto parece mágico: un agente diseña un plan, invoca unas cuantas herramientas y devuelve un resultado perfecto. La ruta feliz es corta, la latencia baja y nada falla al mismo tiempo.
Por qué las demos funcionan y la producción se rompe
Bajo cargas reales, el mismo agente se ve forzado de maneras que la demo nunca vio:
- Las APIs hacen timeouts, devuelven datos parciales o cambian contratos.
- Múltiples solicitudes compiten por recursos compartidos y corrompen estado.
- Conversaciones de larga duración inflan la memoria y exceden los límites de contexto.
- Errores sutiles del modelo se acoplan a través de muchas llamadas a herramientas.
El resultado: comportamiento intermitente difícil de reproducir, corrupción silenciosa de datos y flujos de usuario que ocasionalmente se quedan colgados o girando indefinidamente.
El impacto real en el negocio
Los agentes intermitentes no solo afectan la “satisfacción”. Ellos:
- Disparan incidentes y alertas de on-call.
- Producen respuestas erróneas que se filtran a sistemas posteriores.
- Erosionan la confianza del usuario: la gente deja de confiar en la función.
- Inflan la factura en la nube mediante reintentos y bucles fuera de control.
En qué se centra esta guía
Este artículo trata sobre patrones de ingeniería, no sobre “mejores prompts”. Veremos máquinas de estados, contratos explícitos de herramientas, estrategias de reintento y manejo de fallos, control de memoria y concurrencia, y patrones de observabilidad que hacen a los sistemas agenticos predecibles bajo carga, no solo impresionantes en el escenario.
Por qué la mayoría de las arquitecturas de agentes se rompen a escala
La mayoría de los sistemas de agentes parecen bien en una demo de ruta feliz. Fallan cuando llegan tráfico, herramientas y casos límite al mismo tiempo.
Comportamientos frágiles: bucles, bloqueos, trabajo parcial, errores silenciosos
La orquestación ingenua asume que el modelo “hará lo correcto” en una o dos llamadas. Bajo uso real, aparecen patrones recurrentes:
- Bucles: el agente sigue replanteando o llamando la misma herramienta porque nunca reconoce la finalización o el fallo.
- Bloqueos: el agente espera una herramienta o subtarea sin timeout, dejando sesiones de usuario colgando.
- Trabajo parcial: el agente completa la mitad del flujo (por ejemplo, redacta un correo pero no lo envía, genera un plan pero no ejecuta los pasos).
- Errores silenciosos: las herramientas fallan o los esquemas no coinciden, pero el agente devuelve con confianza una respuesta verosímil con datos faltantes o erróneos.
Sin estados explícitos y condiciones de finalización, estos comportamientos son inevitables.
No determinismo oculto e inestabilidad de las herramientas
El muestreo del LLM, la variabilidad de latencia y el timing de las herramientas crean no determinismo oculto. La misma entrada puede recorrer ramas distintas, invocar herramientas diferentes o interpretar resultados de herramientas de distinto modo.
A escala, los problemas de las herramientas dominan:
- Timeouts y flakiness de APIs y bases de datos aguas arriba
- Deriva de esquemas entre contratos de herramientas y lo que los servicios realmente devuelven
- Formatos de error inconsistentes que el agente nunca aprendió a manejar
Cada uno de estos se convierte en bucles espurios, reintentos o respuestas finales incorrectas.
La concurrencia amplifica casos límite y desajustes con el producto
Lo que raramente falla a 10 RPS fallará constantemente a 1.000 RPS. La concurrencia revela:
- Condiciones de carrera sobre estado o caches compartidos
- Límites de tasa agotados causando fallos en cascada de las herramientas
- Manadas de reintentos (thundering herds) desencadenadas por un solo fallo de dependencia
Los equipos de producto a menudo esperan flujos deterministas, SLAs claros y auditabilidad. Los agentes, dejados sin restricciones, ofrecen comportamiento probabilístico y de mejor esfuerzo con garantías débiles.
Cuando las arquitecturas ignoran este desajuste —tratando a los agentes como servicios tradicionales en vez de planificadores estocásticos— los sistemas se comportan de forma impredecible justo cuando la fiabilidad importa más.
Principios de diseño para sistemas agenticos aptos para producción
Los agentes listos para producción tienen menos que ver con “prompts inteligentes” y más con diseño de sistemas disciplinado. Una forma útil de pensar en ellos es como pequeñas máquinas predecibles que ocasionalmente llaman a un LLM, no como masas misteriosas de LLM que de vez en cuando tocan tus sistemas.
¿Qué hace a un agente apto para producción?
Cuatro propiedades importan más:
- Seguridad: el agente debe respetar restricciones sobre acceso a datos, efectos secundarios y promesas al usuario. Eso implica permisos explícitos, salvaguardas en las herramientas y manejo cuidadoso de salidas no confiables.
- Predictibilidad: con las mismas entradas y estado, el agente debe comportarse dentro de una banda estrecha y esperada. Debes poder explicar lo que puede y no puede hacer.
- Depurabilidad: cuando algo falla, puedes rastrear el camino: qué estado, qué decisión, qué llamada a herramienta, qué llamada al modelo. Nada de bucles ocultos ni “pensamientos” opacos sin estructura.
- Tolerancia al cambio: puedes actualizar modelos, herramientas o estrategias sin reescribir todo el sistema.
No obtienes estas propiedades solo con prompts. Se obtienen mediante estructura.
Prefiere flujos explícitos sobre bucles libres
El patrón por defecto con el que muchos equipos empiezan es: "mientras no esté hecho, llama al modelo, que el modelo piense, quizá llama a una herramienta, repetir". Esto es fácil de prototipar y difícil de operar.
Un patrón más seguro es representar el agente como un flujo explícito:
- Define un conjunto finito de estados (por ejemplo,
COLLECTING_INPUT,PLANNING,EXECUTING_STEP,WAITING_ON_HUMAN,DONE). - Define qué transiciones están permitidas entre estados.
- Usa el LLM principalmente para decisiones locales: elegir el siguiente estado, seleccionar una herramienta o completar parámetros.
Esto convierte al agente en una máquina de estados donde cada paso es inspeccionable, testeable y reproducible. Los bucles libres parecen flexibles, pero los flujos explícitos son los que hacen que los incidentes sean depurables y el comportamiento auditable.
Divide el “agente dios” en habilidades modulares
Los agentes monolíticos que “lo hacen todo” son atractivos, pero crean acoplamientos fuertes entre responsabilidades no relacionadas: planificación, recuperación, lógica de negocio, orquestación de UI y más.
En su lugar, compón agentes pequeños y bien acotados o skills:
- Un planificador que descompone tareas.
- Un ejecutor que corre pasos concretos.
- Un especialista para cada dominio (facturación, soporte, analítica, etc.).
Cada skill puede tener su propia máquina de estados, herramientas y reglas de seguridad. La lógica de composición se convierte entonces en un flujo de alto nivel, no en un prompt cada vez más grande dentro de un único agente.
Esta modularidad mantiene cada agente lo bastante simple como para razonar sobre él y te permite evolucionar una capacidad sin desestabilizar el resto.
Separa política, estado y herramientas
Un modelo mental útil es dividir un agente en tres capas:
-
Política de decisión (prompts + modelo)
Encapsula cómo el agente elige las siguientes acciones, interpretado bajo restricciones estrictas. Debes poder cambiar el modelo, ajustar la temperatura o refinar prompts sin tocar el cableado del sistema. -
Máquina de estados / motor de workflow
Posee dónde estás en el proceso, qué transiciones son posibles y cómo persistir el progreso. La política sugiere un movimiento; la máquina de estados lo valida y lo aplica. -
Capa de herramientas
Implementa qué puede ocurrir en el mundo: APIs, bases de datos, colas, servicios externos. Las herramientas exponen contratos estrechos y tipados y hacen cumplir autorización, límites de tasa y validación de entrada.
Al forzar esta separación, evitas la trampa de esconder lógica de negocio en prompts o descripciones de herramientas. El LLM se convierte en un componente de decisión dentro de una carcasa determinista clara, no en la carcasa misma.
Diseña para pequeñez y claridad
Los sistemas agenticos más fiables no son las demos más impresionantes: son aquellos cuyo comportamiento puedes explicar en una pizarra.
Concretamente:
- Mantén cada agente enfocado en un trabajo y una métrica de éxito principal.
- Codifica los flujos y transiciones de estado explícitamente en lugar de en prosa.
- Deja que los LLMs elijan entre opciones bien definidas, no que inventen procedimientos completos desde cero.
Esta preferencia por agentes pequeños, componibles y bien estructurados es lo que permite que los sistemas crezcan en alcance sin colapsar bajo su propia complejidad.
Modelar flujos de agente como máquinas de estados explícitas
La mayoría de las implementaciones de agentes empiezan como un bucle de "pensar, actuar, observar" alrededor de una llamada al LLM. Eso está bien para demos, pero rápidamente se vuelve opaco y frágil. Un enfoque mejor es tratar al agente como una máquina de estados explícita: un conjunto finito de estados, con transiciones bien definidas disparadas por eventos.
Representar flujos de agente como estados y transiciones
En lugar de permitir que el modelo decida implícitamente qué hacer a continuación, define un pequeño diagrama de estados:
- PLAN – interpretar la solicitud del usuario, descomponer en pasos, elegir herramientas.
- CALL_TOOL – ejecutar una sola llamada a herramienta (o lote) con entradas validadas.
- VERIFY – comprobar las salidas de herramientas contra invariantes simples o verificaciones adicionales del modelo.
- RECOVER – manejar errores: reintentar, caer a alternativas o escalar.
- DONE – devolver una respuesta final y cerrar el flujo.
- FAILED – error terminal con razón y contexto claros.
Las transiciones entre estos estados son disparadas por eventos tipados como UserRequestReceived, ToolCallSucceeded, ToolValidationFailed, TimeoutExceeded o HumanOverride. Cada evento, junto con el estado actual, determina el siguiente estado y acciones.
Esto hace que los reintentos y timeouts sean directos: adjuntas políticas a estados individuales (por ejemplo, CALL_TOOL puede reintentar 3 veces con backoff exponencial, PLAN podría no reintentar) en vez de esparcir la lógica de reintentos por todo el código.
Externalizar el estado para resiliencia y escala
Persiste el estado actual y el contexto mínimo en un almacén externo (base de datos, cola o motor de workflows). El agente se convierte entonces en una función pura:
next_state, actions = transition(current_state, event, context)
Esto permite:
- Resiliencia – si un worker muere a mitad de ejecución, otro puede reanudar desde el último estado persistido.
- Escalado horizontal – workers sin estado consumen eventos, actualizan estado y emiten los siguientes eventos.
- Reproducciones y compensaciones – puedes reconstruir una ejecución, reactivarla desde cualquier estado o ejecutar acciones compensatorias cuando un flujo debe retroceder.
Beneficios para razonamiento y auditorías
Con una máquina de estados, cada paso del comportamiento del agente es explícito: en qué estado estaba, qué evento ocurrió, qué transición se disparó y qué efectos secundarios se produjeron. Esa claridad acelera la depuración, simplifica las investigaciones de incidentes y crea una traza natural para auditorías de cumplimiento. Puedes probar, a partir de logs e historial de estado, que ciertas acciones arriesgadas solo se toman desde estados específicos y bajo condiciones definidas.
Diseñar contratos de herramientas fiables para agentes
Los agentes se comportan de forma mucho más predecible cuando las herramientas se parecen menos a “APIs escondidas en prosa” y más a interfaces bien diseñadas con garantías explícitas.
Define el contrato, no solo el prompt
Cada herramienta debería tener un contrato que cubra:
- Esquema de entrada: campos requeridos, tipos, enums, restricciones, valores por defecto.
- Esquema de salida: payload de éxito, campos anulables y qué significa “sin resultado”.
- Modelo de errores: errores tipados (por ejemplo,
InvalidInput,NotFound,RateLimited,TransientFailure) con semánticas claras. - SLAs: expectativas de latencia, objetivos de disponibilidad y límites de tasa.
Expón este contrato al modelo como documentación estructurada, no como un muro de texto. El planificador del agente debe saber qué errores son reintentables, cuáles requieren intervención humana y cuáles deben detener el flujo.
JSON estricto, validación estricta
Trata la E/S de las herramientas como cualquier otra API de producción:
- Usa schemas JSON estrictos (por ejemplo, OpenAPI, JSON Schema) para entradas y salidas.
- Valida antes de la llamada (para atrapar errores del modelo) y después (para detectar regresiones de la herramienta).
- Repara automáticamente problemas menores (por ejemplo, coerción de tipos) pero regístralos para ajustes posteriores.
Esto te permite simplificar los prompts: en lugar de instrucciones verbosas, confía en orientación dirigida por esquemas. Las restricciones claras reducen argumentos alucinados y secuencias de herramientas sin sentido.
Versionado y compatibilidad
Las herramientas evolucionan; los agentes no deberían romperse cada vez que lo hacen.
- Versiona los contratos de las herramientas (
v1,v1.1,v2) y fija los agentes a una versión. - Depreca campos gradualmente; conserva campos antiguos legibles durante un tiempo.
- Añade campos de forma compatible hacia atrás; evita cambiar semánticas de manera silenciosa.
La lógica de planificación puede entonces mezclar agentes y herramientas en distintos niveles de madurez con seguridad.
Manejo de fallos y modos degradados
Diseña contratos con fallos parciales en mente:
- Permite resultados parciales con detalles de error por ítem.
- Define una respuesta degradada (por ejemplo, datos en caché, aproximados o desactualizados) en lugar de un fallo duro.
- Marca qué campos son “mejor esfuerzo” frente a cuáles son “obligatorios”.
El agente puede entonces adaptarse: continuar el flujo con funcionalidad reducida, pedir confirmación al usuario o cambiar a una herramienta de respaldo.
Límites de seguridad y autorización
Los contratos de herramientas son un lugar natural para codificar límites de seguridad:
- Delimita lo que la herramienta puede leer o modificar.
- Requiere parámetros explícitos para acciones sensibles (p. ej.,
confirm: true). - Distingue operaciones con alcance de usuario de las de sistema.
Combina esto con verificaciones server-side; nunca confíes únicamente en que el modelo “se comporte”.
Por qué los buenos contratos simplifican a los agentes
Cuando las herramientas tienen contratos claros, validados y versionados, los prompts pueden ser más cortos, la orquestación más sencilla y la depuración mucho más fácil. Mueves complejidad de instrucciones en lenguaje natural frágiles a esquemas y políticas deterministas, reduciendo llamadas a herramientas alucinadas y efectos secundarios inesperados.
Reintentos, idempotencia y patrones de manejo de fallos
Los sistemas agenticos fiables asumen que todo fallará eventualmente: modelos, herramientas, redes e incluso tu propia capa de coordinación. La meta no es evitar el fallo, sino hacerlo barato y seguro.
Idempotencia: la base para reintentos seguros
Idempotencia significa: repetir la misma solicitud tiene el mismo efecto visible externamente que hacerla una vez. Esto es crítico para agentes LLM, que frecuentemente reemiten llamadas a herramientas tras fallos parciales o respuestas ambiguas.
Haz que las herramientas sean idempotentes por diseño:
- IDs de petición: cada llamada incluye un
request_idestable. La herramienta almacena esto y devuelve el mismo resultado si ve el ID otra vez. - Upserts en lugar de inserts: usa semánticas “crear-o-actualizar” indexadas por una clave de negocio natural o sintética, no por un ID autoincremental.
- Checksums y versionado: adjunta hashes de contenido o números de versión para que la herramienta detecte duplicados, escrituras obsoletas o conflictos.
Estrategias de reintento que no disparen los costes
Usa reintentos estructurados para fallos transitorios (timeouts, límites de tasa, 5xx): backoff exponencial, jitter para evitar manadas y un máximo de intentos estricto. Registra cada intento con IDs de correlación para poder trazar el comportamiento del agente.
Para fallos permanentes (4xx, errores de validación, violaciones de reglas de negocio), no reintentes. Muestra un error estructurado a la política del agente para que pueda revisar el plan, pedir al usuario o elegir otra herramienta.
Cortacircuitos (circuit breakers) y alternativas
Implementa circuit breakers tanto en la capa del agente como en la de la herramienta: tras fallos repetidos, bloquea temporalmente llamadas a esa herramienta y falla rápido. Acompaña esto con alternativas bien definidas: modos degradados, datos en caché o herramientas alternativas.
Evita reintentos ciegos desde el bucle del agente. Sin herramientas idempotentes y clases de fallo claras, solo multiplicarás efectos secundarios, latencia y coste.
Gestionar memoria, estado y consistencia de datos para agentes
Los agentes fiables empiezan por pensar claramente en qué es estado y dónde vive.
Estado a corto plazo vs memoria a largo plazo
Trata a un agente como tratarías a un servicio que maneja una petición:
- Estado a corto plazo: todo lo necesario para completar la tarea actual o subtarea. Incluye el objetivo activo, paso actual, salidas de herramientas, decisiones parciales y variables de control (reintentos restantes, rama elegida, etc.). Debe estar acotado y desechable al finalizar el workflow.
- Memoria a largo plazo: información que debe sobrevivir entre ejecuciones y sesiones: perfiles de usuario, preferencias, decisiones previas, historial de proyectos y atajos aprendidos.
Mezclarlos lleva a confusión y errores. Por ejemplo, poner resultados efímeros de herramientas en “memoria” hace que los agentes reutilicen contexto obsoleto en conversaciones futuras.
Dónde almacenar estado
Tienes tres opciones principales:
- En contexto (solo prompt) – Simple, baja latencia, pero limitado y no durable. Mejor para estado a corto plazo dentro de una sola ejecución.
- Almacén externo – Base de datos, caché o store vectorial. Úsalo para memoria a largo plazo y cualquier estado que deba sobrevivir reinicios o coordinarse entre workers.
- Híbrido – Mantén el estado autoritativo externamente; carga solo lo necesario en el contexto para el siguiente paso.
Una buena regla: el LLM es una función sin estado sobre un objeto de estado explícito. Persiste ese objeto fuera del modelo y regenera prompts a partir de él.
Evitar el antipatrón “logs como memoria”
Un patrón de fallo común es usar logs de conversación, trazas o prompts crudos como memoria de facto.
Problemas:
- La recuperación se vuelve ad-hoc y frágil.
- Los hechos importantes quedan enterrados en texto largo.
- Varias ejecuciones pueden contradecirse sin una regla clara de “última escritura gana”.
En su lugar, define esquemas de memoria estructurados: user_profile, project, task_history, etc. Deriva logs del estado, no al revés.
Consistencia con datos y herramientas compartidas
Cuando múltiples herramientas o agentes actualizan las mismas entidades (por ejemplo, un registro CRM o el estado de una tarea), necesitas controles básicos de consistencia:
- Usa fuentes únicas de verdad para entidades clave (por ejemplo, order, ticket, documento).
- Prefiere contratos de herramienta idempotentes: las herramientas deben manejar reintentos usando IDs estables y semántica de “upsert”.
- Aplica concurrencia optimista (números de versión, timestamps) cuando agentes puedan competir por actualizar el mismo registro.
Para operaciones de alto valor, registra un log de decisiones separado del log conversacional: qué cambió, por qué y basado en qué entradas.
Instantáneas y ejecuciones reanudables
Para sobrevivir crashes, despliegues y límites de tasa, los workflows deben ser reanudables:
- Después de cada paso significativo, persiste una instantánea de estado: paso actual, entradas, resultados de herramientas y acciones pendientes.
- Haz que cada transición en tu máquina de estados sea reproducible desde la instantánea.
- Ante un fallo o reinicio, recarga la última instantánea y continúa en vez de reiniciar desde cero.
Esto también habilita la depuración por viaje en el tiempo: puedes inspeccionar y reproducir el estado exacto que llevó a una decisión errónea.
Privacidad, retención y minimalismo en la memoria
La memoria es una responsabilidad tanto como un activo. Para agentes en producción:
- Modela explícitamente qué nunca debe almacenarse (por ejemplo, secretos, documentos crudos, PII sensible). Usa redacción o hashing cuando proceda.
- Define políticas de retención por tipo de memoria (nivel de sesión, 30 días, retención legal, etc.).
- Da a los usuarios controles para ver y borrar su memoria a largo plazo.
- Evita almacenar prompts completos o entradas de herramientas cuando un resumen estructurado más pequeño sea suficiente.
Trata la memoria como una superficie de producto: diseñada, versionada y gobernada —no como un volcado de texto que crece sin control.
Concurrencia, límites de tasa y backpressure en sistemas de agentes
Los agentes se ven secuenciales en un diagrama, pero se comportan como sistemas distribuidos bajo carga real. En cuanto tienes muchos usuarios concurrentes, herramientas y jobs en background, te encuentras con condiciones de carrera, trabajo duplicado y problemas de orden.
Riesgos de concurrencia en flujos de agentes
Modos comunes de falla:
- Condiciones de carrera: dos ejecuciones del agente actualizan el mismo ticket, carrito o documento concurrentemente, sobrescribiéndose.
- Trabajo duplicado: reintentos o workers mal configurados procesan la misma tarea dos veces (por ejemplo, cobrar dos veces un pago).
- Efectos fuera de orden: llamadas a herramientas terminan en un orden inesperado, de modo que un resultado antiguo sobrescribe un estado más nuevo.
Mitígalos con contratos idempotentes de herramientas, estado de workflow explícito y bloqueo optimista/pesimista en la capa de datos.
Colas vs flujos síncronos
Los flujos síncronos request–response son simples pero frágiles: cada dependencia debe estar arriba, dentro de límites de tasa y ser rápida. Cuando los agentes disparan muchas herramientas o subtareas en paralelo, mueve pasos de larga ejecución o con efectos secundarios detrás de una cola.
La orquestación basada en colas te permite:
- Controlar la concurrencia con pools de workers
- Centralizar reintentos y deduplicación
- Aislar herramientas lentas o frágiles de la latencia visible al usuario
Límites de tasa y backpressure
Los agentes suelen chocar con tres clases de límites:
- Modelos: tokens por minuto, requests por minuto, tamaño de contexto
- Herramientas: servicios internos con QPS o restricciones de CPU
- APIs externas: cuotas de terceros y límites rígidos
Necesitas una capa de limitación de tasa explícita con throttles por usuario, por tenant y globales. Usa token buckets o leaky buckets para aplicar políticas, y expón tipos de error claros (por ejemplo, RATE_LIMIT_SOFT, RATE_LIMIT_HARD) para que los agentes retrocedan con gracia.
El backpressure es cómo el sistema se protege bajo estrés. Estrategias incluyen:
- Sacrificar primero tráfico no crítico
- Degradar características (contextos más pequeños, menos llamadas a herramientas)
- Pausar colas de baja prioridad manteniendo flujos críticos en movimiento
Monitoriza señales de saturación: profundidad de colas, utilización de workers, tasas de error y percentiles de latencia. Colas que crecen junto con latencias o errores 429/503 son la señal temprana de que los agentes están sobrepasando su entorno.
Observabilidad: trazas, métricas y logs para el comportamiento de agentes
No puedes hacer fiable a un agente si no puedes responder dos preguntas rápido: ¿qué hizo? y ¿por qué lo hizo? La observabilidad para sistemas agenticos consiste en hacer esas respuestas baratas y precisas.
Qué necesitas ver
Diseña la observabilidad para que una sola tarea tenga una traza que atraviese:
- Cada paso del agente y transición de estado
- Cada llamada a herramienta y su respuesta
- Cada invocación del modelo y variante de prompt
Dentro de esa traza, adjunta logs estructurados para decisiones clave (elección de enrutamiento, revisión de planes, disparos de guardrails) y métricas de volumen y salud.
Una traza útil suele incluir:
- Metadatos de la tarea: tenant, usuario, canal, prioridad
- Estado del agente: nombre del estado actual, siguiente estado, contador de reintentos
- E/S de herramientas: entradas, salidas, latencia, errores, estado del circuit-breaker
- Llamadas al modelo: ID de plantilla de prompt, nombre del modelo, conteo de tokens, latencia
Logging y redacción
Loggea prompts, entradas y salidas de herramientas en forma estructurada, pero pásalos primero por una capa de redacción:
- Enmascara PII y secretos
- Trunca payloads sobredimensionados con hashes para correlación
- Marca campos con niveles de sensibilidad para controlar retención y acceso
Mantén contenido crudo detrás de feature flags en entornos inferiores; producción debe por defecto mostrar vistas redactadas.
Métricas que realmente importan
Como mínimo, controla:
- Tasa de éxito/fracaso de tareas por agente y caso de uso
- Conteo medio y P95 de pasos por tarea
- Latencia: end-to-end y por herramienta/modelo
- Coste por tarea (tokens, gasto en herramientas) y por resultado exitoso
Cuando ocurren incidentes, buenas trazas y métricas te permiten pasar de “el agente está inestable” a afirmar con precisión: “P95 de tareas fallando en ToolSelection tras 2 reintentos debido a un nuevo esquema en billing_service”, reduciendo el diagnóstico de horas a minutos y dándote palancas concretas para ajustar el comportamiento.
Estrategias de prueba y evaluación para sistemas agenticos
Probar agentes significa probar tanto las herramientas que llaman como los flujos que lo cosen todo. Trátalo como pruebas de sistemas distribuidos, no solo como ajuste de prompts.
Tests unitarios: contratos de herramientas, no prompts
Empieza con tests unitarios en el borde de la herramienta:
- Valida esquemas: campos requeridos, enums, rangos e invariantes.
- Comprueba idempotencia y semántica de errores (qué errores, qué códigos, qué reintentabilidad).
- Asegura que las herramientas manejan entradas malformadas con gracia y devuelven fallos estructurados.
Estos tests nunca dependen del LLM. Llama a la herramienta directamente con entradas sintéticas y afirma la salida o el contrato de error exacto.
Tests de integración: flujos y comportamiento multi‑paso
Los tests de integración ejercitan el workflow del agente end-to-end: LLM + herramientas + orquestación.
Modela esto como tests basados en escenarios:
- Rutas felices para viajes de usuario clave (reserva, reembolso, escalado, etc.).
- Casos límite: datos faltantes, fallos parciales de herramientas, timeouts, límites de tasa.
- Interacciones entre herramientas: cuando la salida de A alimenta a B.
Estos tests verifican transiciones de estado y llamadas a herramientas, no cada token del LLM. Comprueba: qué herramientas fueron llamadas, con qué argumentos, en qué orden y qué estado/resultado final alcanzó el agente.
Fixtures deterministas para LLM y herramientas
Para mantener tests repetibles, fija tanto respuestas del LLM como salidas de herramientas:
- Graba respuestas del LLM una vez (por prompt + modelo + configuración) y almacénalas como fixtures JSON.
- Mockea sistemas externos detrás de las herramientas para que los tests no toquen servicios en vivo.
- Usa seeds explícitos y configuraciones de temperatura fija en tests.
Un patrón típico:
with mocked_llm(fixtures_dir="fixtures/llm"), mocked_tools():
result = run_agent_scenario(input_case)
assert result.state == "COMPLETED"
Suites de regresión para prompts y esquemas
Cada cambio de prompt o esquema debe activar una ejecución de regresión no negociable:
- Conserva un corpus curado de entradas más estados esperados, trazas de herramientas o clasificaciones.
- Bloquéalos como archivos golden; los diffs resaltan cambios de comportamiento.
- Aprueba o revierte explícitamente cualquier deriva en flujos críticos.
La evolución de esquemas (añadir campos, endurecer tipos) tiene sus propios casos de regresión para detectar agentes o herramientas que aún asumen el contrato antiguo.
Evaluación offline antes del despliegue
Nunca lances un nuevo modelo, política o estrategia de enrutamiento directo a tráfico de producción.
En su lugar:
- Reejecuta tu corpus de regresión offline contra la nueva configuración.
- Ejecuta pruebas de replay sobre muestras históricas de interacciones.
- Calcula métricas automáticas (éxito de tareas, tasa de errores de herramientas, latencia, coste) y, donde haga falta, valoraciones humanas sobre una muestra.
Solo tras pasar las puertas offline debería una nueva variante alcanzar producción, idealmente tras un rollout gradual y controlado por feature flags.
Gestión de datos de prueba y anonimización
Los logs de agentes suelen contener datos sensibles. Las pruebas deben respetar eso.
- Construye datasets de prueba a partir de entradas anonimizadas o sintéticas.
- Elimina o hashea identificadores, PII en texto libre y secretos antes de almacenar logs o fixtures.
- Segmenta el acceso: ingenieros pueden ver trazas de comportamiento, pero no secretos crudos de usuarios.
Codifica estas reglas como parte de tu pipeline CI para que ningún artefacto de prueba pueda generarse o almacenarse sin checks de anonimización.
Operar, monitorizar y evolucionar agentes en producción
Operar agentes en producción se parece más a ejecutar un sistema distribuido que a desplegar un modelo estático. Necesitas controles de despliegue, objetivos de fiabilidad claros y gestión disciplinada del cambio.
Estrategias de despliegue seguro
Introduce nuevos agentes o comportamientos gradualmente:
- Modo sombra: ejecuta el agente junto a un sistema existente, registra sus decisiones pero no afectes a usuarios. Compara resultados offline.
- Canarios: expón una pequeña porción del tráfico (p. ej., 1–5%) a la nueva versión. Observa tasas de error, latencia y calidad antes de aumentar la carga.
- A/B tests: para flujos de cara al usuario, compara nuevo vs viejo en KPIs de negocio, no solo métricas del modelo.
Apóyalo todo con feature flags y políticas configurables: reglas de enrutamiento, herramientas habilitadas, temperatura, ajustes de seguridad. Los cambios deben ser desplegables por configuración, no por código, y reversible al instante.
SLOs y flujos de incidentes
Define SLOs que reflejen tanto la salud del sistema como el valor para el usuario:
- Fiabilidad: tasa de éxito de tareas, llamadas a herramientas y workflows end-to-end.
- Latencia: p50/p95 para rutas críticas.
- Calidad: puntuaciones de auto-evaluación, distribuciones de valoraciones humanas o métricas de éxito por tarea.
Conecta esto a alertas y opera incidentes como cualquier servicio de producción: propiedad clara, runbooks para triage y pasos de mitigación estándar (revertir flag, drenar tráfico, modo seguro).
Mejora continua y control de cambios
Usa logs, trazas y transcripciones para refinar prompts, herramientas y políticas. Trata cada cambio como un artefacto versionado con revisión, aprobación y capacidad de rollback.
Evita cambios silenciosos en prompts o herramientas. Sin control de cambios no podrás correlacionar regresiones con ediciones específicas, y la respuesta a incidentes se convierte en conjeturas en vez de ingeniería reproducible.
Una arquitectura de referencia para sistemas agenticos fiables
Un sistema agentico listo para producción se beneficia de una separación clara de responsabilidades. El objetivo es mantener al agente inteligente en decisiones, pero tonto en infraestructura.
Componentes centrales
1. Gateway / edge API
Punto único de entrada para clientes (apps, servicios, UIs). Maneja:
- Autenticación y autorización (usuario, servicio, tenant)
- Límites de tasa y cuotas
- Formado de peticiones (esquemas, límites de tamaño, validación básica)
2. Orquestador
El orquestador es el “tronco”, no el cerebro. Coordina:
- Planner: traduce la intención del usuario a un workflow o máquina de estados
- State orchestrator: ejecuta ese workflow, rastrea estado, maneja reintentos y timeouts
- Policy engine: aplica seguridad, cumplimiento, herramientas permitidas, reglas de PII y presupuestos de coste
Los LLMs viven detrás del orquestador, usados por el planner y por herramientas específicas que necesitan comprensión de lenguaje.
3. Capa de herramientas y almacenamiento
La lógica de negocio permanece en microservicios, colas y sistemas de datos existentes. Las herramientas son wrappers delgados alrededor de:
- Servicios internos HTTP/gRPC
- Bases de datos, stores vectoriales, caches
- APIs externas
El orquestador invoca herramientas vía contratos estrictos, mientras los sistemas de almacenamiento siguen siendo la fuente de verdad.
Integración, controles y telemetría
Aplica auth y cuotas en el gateway; aplica seguridad, acceso a datos y políticas en el orquestador. Todas las llamadas (LLM y herramientas) emiten telemetría estructurada a un pipeline que alimenta:
- Trazas para comportamiento paso a paso
- Métricas para SLOs y límites de tasa
- Logs de auditoría para seguridad y cumplimiento
- Contabilidad de costes por usuario, proyecto y herramienta
Una arquitectura más simple (gateway → orquestador único → herramientas) es más fácil de operar; añadir planners separados, engines de política y gateways de modelos incrementa flexibilidad a costa de más coordinación, latencia y complejidad operacional.
Ponerlo todo junto y siguientes pasos para tu equipo
Ahora tienes los ingredientes básicos para agentes que se comporten de forma predecible bajo carga real: máquinas de estados explícitas, contratos de herramientas claros, reintentos disciplinados y observabilidad profunda. El paso final es convertir esas ideas en una práctica repetible para tu equipo.
Los patrones centrales, en una sola imagen
Piensa en cada agente como un workflow con estado:
- Una máquina de estados define pasos legales (plan → recoger → actuar → resumir, etc.) y sus transiciones.
- Contratos de herramientas definen lo que cada acción puede hacer, con esquemas estrictos, timeouts y superficies de error.
- Reintentos e idempotencia protegen cada interacción externa para que las re‑ejecuciones sean seguras y los efectos no se apliquen doble.
- Observabilidad (trazas, métricas, logs) hace que cada decisión y llamada a herramienta sea explicable y depurable.
Cuando estas piezas se alinean, obtienes sistemas que se degradan con gracia en lugar de colapsar ante casos límite.
Lista de verificación ligera para llevar un agente a producción
Antes de enviar un agente prototipo a usuarios reales, confirma:
- Workflow: estados y transiciones son explícitos; no hay bucles ocultos ni cadenas de herramientas sin límite.
- Contratos: cada herramienta tiene entradas/salidas tipadas, modos de fallo claros y timeouts.
- Seguridad: guardrails en entradas, salidas y acciones (límites de tasa, listas blancas, cuotas).
- Reintentos: políticas definidas por herramienta; llaves de idempotencia para todas las llamadas con efectos.
- Estado: memoria y estado persistente están acotados, versionados y recuperables.
- Observabilidad: puedes responder “¿qué pasó?” para cualquier sesión de usuario en una sola traza.
- Testing: cuentas con tests basados en escenarios y suites de regresión para prompts, herramientas y políticas.
Si falta alguno, aún estás en modo prototipo.
Cómo pueden dividir la propiedad los equipos
Una estructura sostenible suele separar:
- Equipos de producto: poseen el comportamiento del agente, prompts, herramientas específicas de su dominio y datasets de evaluación.
- Equipos de plataforma/infra: poseen el framework de la máquina de estados, SDKs comunes para herramientas, logging y tracing, enforcement de políticas e infraestructura de evaluación compartida.
Esto permite a los equipos de producto moverse rápido mientras los equipos de plataforma garantizan fiabilidad, seguridad y control de costes.
Extensiones futuras y iteración segura
Una vez que tengas cimientos estables, puedes explorar:
- Políticas basadas en aprendizaje: usar trazas registradas para mejorar enrutamiento, selección de herramientas y estrategias de fallback.
- Aprendizaje por refuerzo: optimizar para resultados a largo plazo como completitud de tareas o ingresos, no solo respuestas puntuales.
- Workflows autoajustables: ajustar automáticamente temperaturas, herramientas o sub‑flujos según el rendimiento observado.
El progreso aquí debe ser incremental: introduce nuevos componentes de aprendizaje tras feature flags, con evaluación offline y salvaguardas fuertes.
El tema a lo largo de todo esto es el mismo: diseña para el fallo, prefiere claridad sobre la ingeniosidad e itera donde puedas observar y revertir con seguridad. Con esas restricciones en su lugar, los sistemas agenticos dejan de ser prototipos temibles y se convierten en infraestructura de la que tu organización puede depender.
Preguntas frecuentes
¿Qué es un sistema agentico y en qué se diferencia de una app normal con LLM?
Un sistema agentico es una aplicación donde un LLM no se limita a responder un único prompt, sino que decide qué hacer a continuación: qué herramientas invocar, qué datos recuperar, qué paso de un flujo ejecutar y cuándo debe detenerse.
A diferencia de una simple finalización de chat, un sistema agentico combina:
- Una política de decisión (LLM + prompts)
- Un flujo de trabajo o máquina de estados que rastrea el progreso
- Un conjunto de herramientas (APIs, bases de datos, servicios)
- Infraestructura para reintentos, persistencia de estado, registro y observabilidad
En producción, el LLM se convierte en un componente de decisión dentro de una envoltura determinista más amplia, no en todo el sistema.
¿Por qué los agentes que funcionan bien en demos a menudo fallan en producción?
Los demos suelen ejecutarse en una ruta feliz: un usuario, comportamiento ideal de las herramientas, sin timeouts, sin deriva de esquemas y conversaciones cortas. En producción, los agentes se enfrentan a:
- Herramientas inestables: timeouts, errores 5xx y formatos de respuesta cambiantes
- Concurrencia: muchos usuarios compitiendo por recursos compartidos y límites de tasa
- Sesiones de larga duración: contexto hinchado, confusión de memoria y deriva de estado
- Errores del modelo que se multiplican: pequeños fallos que se acumulan a través de muchas llamadas a herramientas
Sin flujos explícitos, contratos y manejo de fallos, estos factores generan bucles, bloqueos, trabajo parcial y errores silenciosos que no aparecen en entornos de demo.
¿Cómo hago que un agente sea predecible y fácil de depurar?
Haz que el LLM opere dentro de una estructura clara en lugar de un bucle libre:
- Modela el agente como una máquina de estados con un conjunto finito de estados y transiciones permitidas.
- Usa el LLM solo para decisiones locales (por ejemplo, qué herramienta invocar a continuación, cómo rellenar parámetros), no para inventar flujos arbitrarios.
- Persiste el estado externamente para que cada transición sea reproducible y auditable.
- Mantén los agentes pequeños y focalizados: un único trabajo principal y una métrica de éxito clara.
Esto te permite explicar, probar y depurar el comportamiento paso a paso en lugar de perseguir bucles opacos de “pensamiento del agente”.
¿Qué significa modelar un agente como una máquina de estados?
Modela el agente como un flujo de trabajo con estados nombrados y eventos tipados en lugar de while not done: call LLM.
Los estados típicos pueden incluir:
PLAN– interpretar la solicitud y producir un plan paso a pasoCALL_TOOL– invocar una herramienta específica o lotes de herramientasVERIFY– comprobar salidas contra reglas simples o verificaciones secundarias con modelosRECOVER– manejar errores mediante reintentos, alternativas o escaladoDONE/FAILED– resultados terminales
Los eventos (por ejemplo, ToolCallSucceeded, TimeoutExceeded) junto con el estado actual determinan el siguiente estado. Esto hace que los reintentos, timeouts y el manejo de errores sean explícitos en vez de estar escondidos en prompts o código “pegamento”.
¿Cómo debo diseñar los contratos de las herramientas para mis agentes?
Diseña las herramientas como APIs de producción, no como descripciones en prosa. Cada herramienta debería tener:
- Esquema de entrada: campos requeridos, tipos, restricciones y valores por defecto
- Esquema de salida: estructura clara para éxito, resultados parciales y qué significa “sin resultado”
- Errores tipados: por ejemplo,
InvalidInput,NotFound,RateLimited,TransientFailure - Expectativas operativas: objetivos de latencia y límites de tasa
Valida las entradas antes de llamar a la herramienta y las salidas después. Versiona los contratos de las herramientas y fija a los agentes a una versión para que los cambios de esquema no rompan los flujos silenciosamente.
¿Cómo manejo fallos, reintentos e idempotencia en los flujos de agentes?
Asume que cualquier llamada externa fallará alguna vez y diseña en torno a eso.
Patrones clave:
- Idempotencia: las herramientas con efectos deben aceptar un
request_idestable o una clave de negocio y devolver el mismo resultado si se llaman de nuevo. - Reintentos dirigidos: reintenta solo fallos transitorios (timeouts, 5xx, límites de tasa) con backoff exponencial y un máximo estricto de intentos.
- Cortafuegos (circuit breakers): deja de llamar temporalmente a una herramienta que falla de forma repetida y cambia a modo degradado o a una alternativa.
- Superficies de fallo estructuradas: devuelve tipos de error explícitos para que el agente decida si reintentar, replanear o pedir intervención del usuario.
Esto mantiene la fiabilidad alta sin crear bucles descontrolados, efectos secundarios duplicados o costos desmesurados.
¿Cuál es la forma correcta de gestionar la memoria y el estado para los agentes?
Separa el estado de corto plazo de la memoria de largo plazo y mantén el LLM sin estado.
- Usa el estado de corto plazo para todo lo necesario para completar el flujo actual: objetivo activo, pasos, salidas de herramientas y contadores de reintento.
- Almacena la memoria de largo plazo (por ejemplo, perfil de usuario, historial de proyectos) en un almacén externo con esquemas estructurados, no en transcripciones sin procesar.
- Trata al LLM como una función pura sobre un objeto de estado explícito: carga el estado relevante, construye el prompt, llama al modelo y persiste el estado actualizado.
Evita usar registros crudos o todo el historial de conversación como “memoria”; en lugar de eso, deriva registros compactos y estructurados con reglas claras de retención y privacidad.
¿Cómo debo tratar la concurrencia, límites de tasa y backpressure en sistemas de agentes?
Piensa en tu sistema de agentes como un sistema distribuido bajo carga, incluso si cada flujo parece secuencial.
Para mantener la fiabilidad:
- Coloca pasos de larga duración o con efectos secundarios detrás de colas para controlar la concurrencia con pools de workers.
- Aplica límites de tasa para modelos y herramientas con cuotas por usuario, por inquilino y globales.
- Usa presión regresiva (backpressure): descarta tráfico no crítico, degrada funcionalidades o pausa colas de baja prioridad cuando la saturación aumenta.
- Combina contratos idempotentes con bloqueo optimista/pesimista en la capa de datos para evitar trabajo duplicado y condiciones de carrera.
Monitorea la profundidad de colas, percentiles de latencia y tasas de 429/503 para detectar sobrecarga antes de que se convierta en un incidente.
¿Qué observabilidad necesito para ejecutar agentes con seguridad en producción?
Necesitas poder responder “¿qué hizo el agente?” y “¿por qué lo hizo?” para cualquier tarea.
Requisitos prácticos:
- Trazas: una traza de extremo a extremo por tarea que cubra transiciones de estado, llamadas a herramientas e invocaciones de modelo.
- Logs estructurados: captura decisiones clave (selección de herramienta, revisiones del plan, activaciones de guardrails) con IDs de correlación.
- Métricas: tasa de éxito de tareas, tasa de fallo por estado, latencia (global y por herramienta/modelo) y coste por resultado exitoso.
- Redacción: enmascara PII y secretos en prompts, entradas y salidas de herramientas antes de loguear; controla la retención según sensibilidad.
Con esto, la investigación de incidentes pasa de “el agente parece inestable” a localizar el estado, la herramienta y el cambio exacto que causó la regresión.
¿Cómo deberían los equipos desplegar y operar sistemas agenticos con seguridad a lo largo del tiempo?
Trata a los agentes como servicios en evolución y gánalos con el mismo rigor que otros sistemas de producción.
Prácticas recomendadas:
- Usa shadow mode, canarios y feature flags para desplegar nuevas versiones de agentes o modelos de forma gradual.
- Define SLOs para fiabilidad, latencia y calidad, y enlázalos con alertas y runbooks.
- Mantén suites de regresión y replay offline para cualquier cambio en prompts, herramientas o políticas.
- Divide la responsabilidad: los equipos de producto poseen el comportamiento y las herramientas de dominio; los equipos de plataforma poseen el marco de la máquina de estados, SDKs comunes, observabilidad y aplicación de políticas.
Esto permite mejorar agentes continuamente mientras mantienes los fallos contenidos, diagnosticables y reversibles.