Saltar al contenido

Patrones de arquitectura para agentes de IA autonomos

A
abemon
| | 12 min de lectura | Escrito por profesionales
Compartir

El agente monolitico es un callejon sin salida

Empezamos como todo el mundo. Un unico prompt, un modelo, una lista de herramientas, y a ver que pasa. El primer agente que pusimos en produccion procesaba emails de clientes de una empresa de logistica. Clasificaba, extraia datos y generaba un borrador de respuesta. Todo en una sola llamada.

Funciono tres semanas. Despues, un cliente envio un email con un PDF adjunto que contenia una imagen escaneada de un albaran. El agente intento parsear el PDF, fallo, reintento con una estrategia diferente, fallo otra vez, y entro en un bucle de razonamiento que consumio 47.000 tokens antes de que el circuit breaker lo cortara. Coste: 1.20 euros por un email. La media era 0.03.

Ese incidente nos forzo a repensar la arquitectura. Lo que sigue son los cuatro patrones que usamos ahora, con los tradeoffs reales de cada uno.

Patron 1: ReAct con limites estrictos

ReAct (Reasoning + Acting) es el patron mas simple que puede funcionar en produccion. El agente razona sobre la tarea, decide que herramienta usar, observa el resultado, y repite hasta completar la tarea o alcanzar un limite.

La clave esta en los limites. Sin ellos, ReAct es un cheque en blanco. Nuestras restricciones:

  • Maximo de pasos: 8 para tareas simples, 15 para complejas. Si el agente no resuelve en 15 pasos, escala.
  • Presupuesto de tokens: techo por ejecucion. Al 80% del limite, el agente recibe una instruccion de comprimir su razonamiento.
  • Timeout por herramienta: 30 segundos. Si una API externa no responde, el agente registra el fallo y decide si usa un fallback o escala.
  • Lista de herramientas cerrada: el agente solo puede usar las herramientas que le asignamos. No descubre herramientas dinamicamente.

El ciclo es: Observar -> Pensar -> Actuar -> Verificar resultado -> Repetir o finalizar.

Donde funciona bien: tareas con 2-5 pasos, con herramientas predecibles, donde el modelo puede razonar linealmente. Clasificacion de documentos con extraccion de campos. Consultas a APIs con interpretacion de resultados. Generacion de respuestas basadas en datos.

Donde falla: tareas que requieren coordinacion entre multiples fuentes de datos, o donde el espacio de decisiones es demasiado amplio para un solo agente.

Implementacion practica: usamos LangGraph con un grafo de un solo nodo que ejecuta el ciclo ReAct. El estado incluye el historial de acciones, tokens consumidos, y un contador de pasos. La condicion de salida es: tarea completada, limite alcanzado, o error no recuperable.

Patron 2: Supervisor con trabajadores especializados

Este es nuestro patron por defecto para tareas complejas. Un agente supervisor orquesta varios agentes trabajadores, cada uno especializado en una capacidad concreta.

La estructura:

Supervisor
├── Lector de documentos (extraccion, OCR)
├── Consultor de datos (APIs externas, bases de datos)
├── Generador de salida (respuestas, informes)
└── Validador (verifica calidad del resultado)

El supervisor no ejecuta herramientas directamente. Su trabajo es: recibir la tarea, descomponerla en subtareas, asignar cada subtarea al trabajador adecuado, recibir resultados, decidir si hacen falta mas pasos, y componer la salida final.

Cada trabajador es un agente ReAct acotado con su propio conjunto de herramientas y limites. El lector de documentos solo tiene acceso a herramientas de parseo y OCR. El consultor de datos solo a APIs y bases de datos. Esta separacion tiene tres beneficios:

Seguridad. Un trabajador comprometido o alucinante no puede ejecutar herramientas que no le corresponden. El lector de documentos no puede enviar emails.

Testabilidad. Puedes testear cada trabajador en aislamiento con inputs y outputs conocidos.

Coste. Cada trabajador puede usar un modelo diferente. El clasificador usa Haiku (barato, rapido). El generador de salida usa Sonnet (mejor calidad de texto). Solo el supervisor necesita un modelo con buena capacidad de razonamiento.

El tradeoff principal es latencia. Una tarea que un agente monolitico resolveria en 3 segundos puede tardar 8-12 segundos con supervisor + trabajadores porque hay multiples roundtrips al LLM. Para tareas de back-office, eso es irrelevante. Para interacciones en tiempo real con usuarios, puede ser un problema.

Implementacion: en LangGraph, el supervisor es un nodo que contiene un subgrafo por cada trabajador. El estado global del grafo contiene la tarea, las subtareas, los resultados parciales, y el resultado final. Las transiciones entre nodos estan condicionadas por las decisiones del supervisor.

Patron 3: Maquina de estados finitos con LLM

Este patron es para los procesos donde el flujo es conocido pero las decisiones dentro de cada paso requieren un LLM. Piensa en un workflow de aprobacion de facturas:

Recibir factura -> Extraer datos -> Validar contra pedido ->
  [OK] -> Registrar en ERP -> Notificar
  [Error] -> Solicitar correccion -> Esperar -> Volver a validar
  [Duda] -> Escalar a humano

El flujo es una maquina de estados. Cada transicion es determinista. Pero dentro de cada estado, el LLM decide. En “Extraer datos,” el agente parsea el documento. En “Validar contra pedido,” compara campos extraidos con datos del ERP. En “Solicitar correccion,” redacta un email al proveedor.

La ventaja sobre el patron supervisor: es mucho mas predecible. El flujo no puede salirse de los estados definidos. No hay posibilidad de que el agente decida “voy a hacer algo completamente diferente.” Los costes son predecibles porque cada estado tiene un presupuesto fijo de tokens.

La desventaja: es rigido. Si llega un caso que no encaja en los estados definidos, no hay forma de manejarlo sin modificar el flujo. Cada caso nuevo requiere actualizar el codigo, no solo ajustar un prompt.

Cuando lo usamos: para procesos de negocio regulados o con SLA estrictos. Procesamiento de facturas, flujos de aprobacion, onboarding de clientes. Cualquier proceso donde la predecibilidad es mas importante que la flexibilidad.

Implementacion: LangGraph es ideal para esto. Cada estado es un nodo. Las transiciones son aristas condicionales. El estado del grafo contiene los datos del proceso y el resultado de cada paso. Podemos serializar el estado completo, lo que permite pausar y reanudar procesos (por ejemplo, cuando se espera aprobacion humana).

Patron 4: Event-driven con agentes reactivos

El patron para sistemas que necesitan responder a eventos en tiempo real sin un orquestador central.

La arquitectura:

Cola de eventos (Kafka / Redis Streams)
├── Agente de clasificacion (escucha: email.received)
├── Agente de procesamiento (escucha: document.classified)
├── Agente de notificacion (escucha: task.completed, task.failed)
└── Agente de monitorizacion (escucha: *.*)

Cada agente se suscribe a tipos de eventos especificos. Cuando llega un evento, lo procesa y puede emitir nuevos eventos que activan otros agentes. No hay un controlador central; el flujo emerge de la composicion de eventos.

Este patron es el mas escalable. Puedes anadir o quitar agentes sin tocar los existentes. Si necesitas un nuevo tipo de procesamiento, despliegas un agente nuevo que escuche los eventos relevantes. Si un agente falla, los eventos quedan en la cola y se reintentan.

El riesgo principal lo mencionamos en nuestro whitepaper sobre agentes de IA: las tormentas de eventos. Un evento que genera otro evento que genera otro puede crear cascadas que consumen recursos sin control. La solucion tiene tres capas:

  1. Deduplicacion. Cada evento tiene un ID unico. Si un agente ya proceso ese ID, lo ignora.
  2. Rate limiting. Cada agente tiene un maximo de ejecuciones por minuto. Si lo alcanza, los eventos quedan en la cola hasta que haya capacidad.
  3. Dead letter queue. Eventos que fallan tres veces van a una cola muerta para revision manual.

Cuando lo usamos: para sistemas que ya tienen una arquitectura de microservicios basada en eventos. Si tu backend ya usa Kafka o RabbitMQ, anadir agentes como consumers es natural. Si tu arquitectura es monolitica, este patron introduce complejidad que probablemente no necesitas.

Componentes transversales

Independientemente del patron, hay tres componentes que implementamos en todos los proyectos.

Structured outputs con validacion

Nunca dejamos que un agente devuelva texto libre cuando necesitamos datos estructurados. Cada herramienta define un schema Pydantic o Zod para su salida. Si la salida del LLM no conforma al schema, se rechaza y se reintenta con una instruccion explicita del error.

En la practica, Claude y GPT-4o cumplen con el schema correcto el 95-98% de las veces en la primera llamada. Pero ese 2-5% restante es suficiente para generar decenas de errores al dia en volumen alto. La validacion es obligatoria, no opcional.

Observabilidad integrada

Cada agente emite trazas OpenTelemetry con spans personalizados para cada tipo de accion. Las trazas incluyen: tokens de entrada y salida, latencia de cada llamada, resultado de cada herramienta, y decision del agente en cada paso.

Usamos LangSmith para visualizacion y debugging, pero las trazas van tambien a nuestro stack de observabilidad general (Grafana + Loki) para correlacionar con metricas de infraestructura.

Circuit breakers y fallbacks

Cada herramienta que un agente puede llamar tiene un circuit breaker. Si falla 3 veces consecutivas, se desactiva durante 5 minutos. El agente recibe una notificacion de que la herramienta no esta disponible y puede decidir usar un fallback o escalar.

A nivel de agente, si la tasa de error supera el 20% en una ventana de 5 minutos, todo el agente se desactiva y las tareas se enrutan a la cola de procesamiento manual. Esto previene degradaciones silenciosas donde el agente sigue funcionando pero produciendo resultados de baja calidad.

Como elegir el patron correcto

La decision depende de tres variables:

VariableReActSupervisorMaquina de estadosEvent-driven
Complejidad de la tareaBaja-mediaAltaMedia-altaVariable
Predecibilidad del flujoBajaMediaAltaBaja
Requisitos de latenciaBajosMediosBajosMedios
Facilidad de testingMediaAltaMuy altaMedia
Coste de infraestructuraBajoMedioBajoAlto

La regla practica: empieza con ReAct. Si se queda corto, pasa a supervisor. Si el flujo es conocido y regulado, usa maquina de estados. Si ya tienes una arquitectura de eventos, usa event-driven.

No mezcles patrones sin necesidad. Hemos visto equipos que implementan un supervisor que dentro tiene maquinas de estado que emiten eventos que activan otros supervisores. El resultado es inmantenible. Elige un patron principal y usalo consistentemente.

Para profundizar en estos patrones aplicados a casos de uso reales, puedes consultar nuestro servicio de IA y Machine Learning. Si estas evaluando que patron se adapta a tu caso, nuestro equipo de consultoria ofrece assessments tecnicos de 2 semanas.

Tambien recomendamos revisar nuestra serie sobre ingenieria de datos para entender como preparar los datos que alimentaran a tus agentes.

Sobre el autor

A

abemon engineering

Equipo de ingenieria

Equipo multidisciplinar de ingenieria, datos e IA con sede en Canarias. Construimos, desplegamos y operamos soluciones de software a medida para empresas de cualquier escala.