Hexagonal y agentes IA hablan el mismo idioma
Diseñamos agentes IA aplicando el patrón hexagonal porque mapea con precisión sobre cómo razonan los agentes y sobre cómo se conectan al mundo real. El núcleo del agente — el razonamiento, las reglas de dominio, los criterios de decisión — vive aislado en el centro. Las integraciones con LLMs, sistemas internos y herramientas externas viven en el borde, como adapters intercambiables.
El resultado es un agente testeable en aislamiento, portable entre modelos y proveedores, y con un coste de mantenimiento que crece de forma lineal con la complejidad del dominio, no multiplicativa con el número de integraciones. Esta es la arquitectura que aplicamos en proyectos serios de IA y cómo se construye paso a paso.
El patrón en cinco minutos
La hexagonal divide el sistema en tres capas:
- Dominio. La lógica de negocio pura: entidades, reglas, decisiones. Sin dependencias hacia fuera.
- Puertos. Interfaces que el dominio define para hablar con el mundo. "Necesito buscar un cliente" es un puerto; cómo se busca no.
- Adapters. Implementaciones concretas de los puertos: el adapter que llama a HubSpot, el adapter que consulta el ERP, el adapter que escribe en PostgreSQL. Intercambiables sin tocar el dominio.
La regla clave: el dominio depende solo de puertos. Los adapters dependen del dominio. Nunca al revés.
Mapping al agente IA
Un agente IA encaja en este patrón con sorprendente naturalidad. Tres componentes del agente, tres capas:
Dominio del agente. Contiene el razonamiento, las políticas de decisión, las reglas de negocio que el agente aplica. Una clase OrderQualificationAgent no conoce GPT, ni HubSpot, ni Postgres. Conoce el dominio: qué hace un lead cualificado, cuándo escalar, qué umbral disparar HITL. El dominio puede testarse con stubs sin necesidad de llamar a un LLM real.
Puertos. Las abstracciones que el dominio del agente necesita para operar:
LLMPort— "dame una decisión sobre este contexto". No sabe si detrás hay Claude, GPT, Gemini o un modelo propio.ToolPort— "ejecuta esta acción en un sistema externo". No sabe si la acción se ejecuta vía REST, MCP, llamada directa a un cliente Java, o cola asíncrona.MemoryPort— "recupera lo que el agente recuerda sobre esta entidad". No sabe si la memoria vive en un vector store, en una key-value, en archivos de markdown del repo.ObservabilityPort— "deja constancia de esta decisión". No sabe si va a un dashboard de Grafana, a un fichero, o a un sistema de auditoría externo.
Adapters. Implementaciones concretas que el dominio nunca ve:
AnthropicLLMAdapter,OpenAILLMAdapter— implementanLLMPortcontra el proveedor concreto.HubSpotMCPToolAdapter,SAPClientToolAdapter,InternalAPIToolAdapter— implementanToolPortcontra cada sistema integrado.PgVectorMemoryAdapter,FileSystemMemoryAdapter— implementanMemoryPort.OpenTelemetryObservabilityAdapter— registra cada decisión con trazas estándar.
El dominio recibe los puertos por inyección de dependencias. El día que cambias el proveedor del LLM, sustituyes el adapter. El dominio no se entera.
Cómo se ve un agente bien estructurado
Un esqueleto mínimo en código (Quarkus, Java moderno; el patrón aplica idéntico en Python, TypeScript o Go):
// Domain
public final class OrderQualificationAgent {
private final LLMPort llm;
private final ToolPort tools;
private final MemoryPort memory;
private final ObservabilityPort obs;
public QualificationDecision qualify(Lead lead) {
var context = memory.recall(lead.customerId());
var decision = llm.decide(buildPrompt(lead, context));
if (decision.requiresAction()) {
tools.execute(decision.action());
}
obs.record(lead, decision);
return decision;
}
}
// Ports (interfaces)
public interface LLMPort { Decision decide(Prompt p); }
public interface ToolPort { Result execute(Action a); }
// Adapters
public final class AnthropicLLMAdapter implements LLMPort { /* ... */ }
public final class HubSpotMCPToolAdapter implements ToolPort { /* ... */ }Ningún import del dominio apunta a una librería externa. Los import apuntan a interfaces (puertos) del propio dominio. Esa restricción es el corazón del patrón.
Beneficios concretos en un agente IA
Cuatro beneficios que la arquitectura entrega de serie:
Testabilidad real del razonamiento. El dominio se testa con stubs deterministas. FakeLLMPort devuelve decisiones controladas; FakeToolPort registra qué acciones se pidieron sin ejecutarlas; FakeMemoryPort retorna contextos sintéticos. Los tests del dominio corren en milisegundos, sin coste de inferencia, y validan exactamente la lógica de negocio del agente — no la del modelo.
Cambio de modelo como ejercicio gestionado. Pasar de Claude a GPT o de un modelo de frontera a uno open weights se hace cambiando el adapter del LLMPort. El dominio sigue igual. La eval del nuevo adapter contra el dataset existente decide si la migración pasa.
Aislamiento de fallos por integración. Si HubSpot está caído, el HubSpotMCPToolAdapter falla; el dominio lo recibe como Result.failed() y decide qué hacer — reintentar, escalar a humano, devolver respuesta degradada. La política de fallback vive en el dominio, no diseminada en cada adapter.
Observabilidad transversal. El ObservabilityPort se invoca desde el dominio en cada decisión clave. La trazabilidad no se "añade" al final del proyecto — emerge naturalmente de la arquitectura.
Anti-patrones que la hexagonal previene
Tres errores frecuentes en proyectos de agentes que esta arquitectura corta de raíz:
El "agente Frankenstein" — código donde llamadas a la API de OpenAI conviven en el mismo método con consultas SQL, integraciones HTTP y lógica de negocio. Sin separación de capas, cualquier cambio en el modelo o en la base de datos toca múltiples sitios.
El "agente fotocopia" — el equipo intenta soportar dos proveedores de LLM clonando todo el código del agente con condicionales. La hexagonal sustituye eso por dos adapters intercambiables.
El "agente intestable" — código que requiere llamar al LLM real para verificar cualquier rama del comportamiento. Esto produce tests lentos, caros y no deterministas. Con la hexagonal, los tests del dominio son tan rápidos como cualquier otro test unitario.
Un caso real: agente comercial sobre Salesforce y SAP
Un cliente nuestro tiene un agente de cualificación de leads que opera sobre dos sistemas distintos: Salesforce como CRM y SAP como ERP de respaldo. Histórico: el cliente migró de modelo dos veces durante el primer año del proyecto (Claude 3.x a Claude 4.x, después prueba con un open weights en infraestructura propia para casos con datos sensibles).
Diseño en hexagonal:
- Dominio:
LeadQualificationAgentcon la política comercial (ICP, umbrales, escalado, criterios de fit). Testado con 280 escenarios sintéticos. - Puertos:
LLMPort,CRMToolPort,ERPToolPort,MemoryPort,ObservabilityPort. - Adapters:
AnthropicLLMAdapter,OpenWeightsLLMAdapter(sustitutos transparentes),SalesforceMCPAdapter,SAPGRPCAdapter.
Resultado de las dos migraciones de modelo: ninguna tocó el dominio. Cada migración fue un pull request con un adapter nuevo, una pasada del dataset de evals, y aprobación si las métricas se mantenían. Tiempo medio de migración: cinco días, incluyendo revisión humana. Tiempo equivalente en un agente sin hexagonal: rehacer prácticamente medio sistema.
Cómo lo construimos en producción
En proyectos serios de agentes IA, la hexagonal no es una decoración técnica — es la decisión que protege el coste a tres años. Antes de elegir modelo, antes de escribir un prompt, definimos puertos: qué necesita el dominio del agente saber del mundo y qué puede dejar abstracto.
El repositorio del agente vive en el cliente, con CI/CD, tests sobre el dominio y un dataset de evals que se ejecuta contra cada adapter de LLMPort antes de promover. La arquitectura es ejecutable desde el primer commit.
Detrás de cada uno de estos sistemas hay un equipo de desarrolladores que cree que la ingeniería seria de IA empieza por separar lo que cambia rápido — modelos, proveedores, integraciones — de lo que tiene que aguantar años: la lógica de negocio del agente. Arquitectura hexagonal por defecto, simplificación cuando aporta.
Si tu agente IA mezcla lógica de negocio con llamadas al LLM y a sistemas externos en el mismo nivel, y cada cambio de modelo se siente como rehacer el sistema, podemos auditar la arquitectura actual y entregarte el refactor a hexagonal con el plan por fases.


