Saltar al contenido

Un equipo editorial y una comunidad que crean con IA

← Vibe engineering

Vibe engineering · · 9 min de lectura

Arquitectura de sistemas con agentes de IA

Cómo dirigir agentes de IA a nivel de sistema: contratos de módulo, límites y lo que sigue en manos de la persona.

La mayoría de los equipos usa agentes de IA a nivel de archivo: “añade este endpoint”, “arregla este test”, “agrega validación”. Funciona mientras el cambio quepa en un solo archivo. El problema empieza más arriba, donde las decisiones afectan a los límites entre módulos, a los contratos entre ellos y a quién es responsable de qué. Dirigir un agente a nivel de sistema es una disciplina distinta de dirigirlo a nivel de archivo. Requiere que una persona (un senior, un tech lead, un arquitecto) mantenga el control sobre lo que un agente no va a inventar por sí solo: el modelo de datos, los límites y los requisitos no funcionales.

El módulo y su contrato como unidad de trabajo del agente

Un archivo es una mala unidad de trabajo para un agente porque no tiene semántica propia. La unidad correcta es un módulo con un contrato explícito: entrada, salida, errores e invariantes descritos con claridad. Cuando le dices a un agente “implementa el módulo de facturación según este contrato”, le das un espacio cerrado en el que puede ser creativo sin desparramarse por todo el sistema.

En la práctica, el contrato son los tipos en el borde del módulo (su interfaz pública), el esquema de los datos de entrada (por ejemplo, Zod), los casos de error definidos y una lista breve de invariantes: cosas que deben cumplirse sea cual sea la implementación. El agente recibe el contrato como entrada, no como algo que deba “completar” por su cuenta. Así, la decisión más importante, la forma del límite, pasa del modelo a la persona.

Hay otra ventaja que solo apreciarás a escala. Cuando un módulo tiene un contrato cerrado, puedes encargar su implementación a un agente y el módulo vecino a otro, en paralelo y sin colisiones. El límite del contrato es también el límite del paralelismo. Sin él, dos agentes que trabajan en la misma zona empiezan a sobrescribir las suposiciones del otro, y tú te pasas la tarde fusionando visiones contradictorias del mismo servicio. Un contrato no es burocracia: es el protocolo que permite a muchos agentes (y personas) trabajar codo con codo sin pisarse.

Por qué las interfaces claras importan más cuando el código lo escribe un agente

Una persona que escribe código lleva consigo un contexto que nadie ha dicho en voz alta: sabe que este servicio “en realidad” no debería llamar directamente a la base de datos, que aquella caché es temporal. El agente no tiene nada de ese contexto. Lee lo que está escrito en los tipos y las firmas, y lo trata como la verdad completa. Si una interfaz es difusa, el agente rellena el hueco con la suposición más simple que compile, no necesariamente con la que es correcta en el dominio.

De ahí la regla: cuanto más código escribe un agente, más nítidas deben ser tus interfaces. Firmas estrechas y explícitas, nada de parámetros “mágicos” como options: any, nada de efectos secundarios ocultos. Una buena interfaz es para un agente lo que una buena documentación es para una persona: dice qué está permitido y qué no. Un límite mal definido no frena a un agente; al contrario, el agente lo cruzará encantado en diez archivos a la vez antes de que te des cuenta.

Una consecuencia práctica: vale la pena hacer que los estados ilegales sean irrepresentables en el propio tipo. Si una función recibe status: string, tarde o temprano el agente le pasará un “peding” mal escrito y el código compilará. Si recibe una unión estrecha de literales, el compilador detecta el error antes de que llegue a la revisión. Cada una de estas decisiones de tipado es una barrera que el agente no puede saltarse: funciona siempre, sin depender de la vigilancia humana. Es una forma de control más barata que cazar el mismo bug a ojo en el décimo PR de la semana.

Lo que debe quedar en manos humanas

Hay tres áreas que no se delegan en un agente, no porque no pueda escribirlas, sino porque son decisiones, no generaciones.

  • El modelo de datos. La forma de las entidades, las relaciones, las claves, los límites de consistencia. Es la base sobre la que se apoya todo lo demás: el agente puede proponer un esquema, pero la aprobación y las consecuencias de la migración son tuyas.
  • Los límites entre módulos. Dónde termina una responsabilidad y empieza otra. Es la decisión sobre qué será barato de cambiar y qué será caro. El agente no ve la trayectoria de tu producto a un año vista.
  • Los requisitos no funcionales. Latencia, costo del LLM por petición, presupuesto de memoria, vía de rollback, modelo de seguridad. Por defecto, un agente optimiza para “funciona”, no para “funciona en 50 ms y cuesta poquísimo”. Esas restricciones tienes que expresarlas de forma explícita.

El denominador común: son cosas cuyo costo de error crece de forma exponencial con el tiempo. Un límite de módulo mal colocado en la primera semana es un refactor de un día. El mismo límite al cabo de seis meses supone reescribir una cuarta parte del sistema.

Cambios pequeños y revisables a nivel de arquitectura

Con los agentes, la tentación es encargar un único cambio enorme (“reescribe la capa de persistencia con un ORM nuevo”) y recibir cien archivos que revisar. Es un antipatrón. Una persona no revisará cien archivos a conciencia; revisará los cinco primeros y confiará en el resto. Y el bug está precisamente en el resto.

Divide los cambios de arquitectura en una secuencia de pasos pequeños y reversibles, cada uno de los cuales deje el sistema funcionando. Primero introduce la nueva interfaz junto a la antigua. Luego cambia un módulo. Después el siguiente. Cada paso es su propio PR, su propio build en verde, su propio punto de rollback. Un agente ejecuta estos pasos de maravilla, siempre que la secuencia la hayas trazado tú y no él. El plan de migración es una decisión de arquitectura; ejecutar un solo paso es trabajo que puedes delegar.

Documentación que consume un agente

En un mundo de agentes, la documentación deja de ser “para los recién llegados”. Se convierte en una entrada para el modelo, el contexto sobre el que el agente construye sus decisiones. Eso cambia su forma.

  • ADR (Architecture Decision Records). Registros breves de una decisión: qué se decidió, en qué contexto, cuáles eran las alternativas y las consecuencias. Un agente que lee un ADR entiende por qué el límite está aquí y no allí, y no lo “arreglará” en contra de la intención original.
  • Especificaciones de módulo. El contrato, las invariantes, los casos límite y un “fuera de alcance” explícito. Es el documento que le das al agente antes de la implementación, no después.
  • Un mapa de límites. Una página: qué módulos hay, quién habla con quién, qué no se debe llamar directamente. Es la brújula que mantiene al agente a raya a nivel de sistema.

La documentación que el agente no lee está muerta. La que le pasas en el contexto se convierte en un mecanismo de dirección activo, más barato y más rápido que cazar errores en la revisión.

Modos de fallo: un agente toca la arquitectura sin supervisión

Cuando dejas que un agente tome decisiones de arquitectura por su cuenta, los fallos siguen un patrón repetible. Vale la pena conocerlos, porque cada uno es predecible.

  • Erosión de límites. El agente llama a un módulo interno desde el otro extremo del sistema “por comodidad”, porque es el camino más corto. Tras veinte atajos así, los módulos están enredados y el contrato es pura ficción.
  • Deriva del modelo de datos. Cada cambio añade un campo “por si acaso”. Las entidades se hinchan, la semántica se difumina y nadie sabe qué campo es la fuente de verdad.
  • Duplicación invisible. El agente no encuentra la abstracción existente, así que escribe una tercera versión de la misma lógica. Localmente parece correcto; globalmente tienes tres implementaciones que divergen.
  • Regresión no funcional silenciosa. El código funciona y los tests pasan, pero la latencia se duplicó o el costo del LLM por petición se disparó. Nadie se da cuenta, porque nadie lo mide con una barrera automática.

La causa común de los cuatro: el agente optimiza a nivel local y a corto plazo, porque eso es todo lo que ve en el contexto. La arquitectura es optimización global y a largo plazo, y esa es exactamente la parte que no se delega.

Lo crucial es que estos modos de fallo no hacen ruido. Ninguno rompe el build ni enciende una luz roja en el CI, porque localmente todo es correcto. Solo afloran como una fricción creciente: cada cambio cuesta un poco más, cada onboarding tarda un poco más, cada incidente es más difícil de diagnosticar. Es deuda de arquitectura y, a diferencia de la deuda en un solo archivo, casi nunca la paga el agente: la paga el equipo, a mano, durante meses. Por eso la supervisión de la arquitectura no es algo que se añade “más adelante”; es la condición para que la velocidad que te da un agente se sostenga.

Cómo organizarlo en la práctica

  1. Una persona define el modelo de datos y los límites entre módulos, y los deja por escrito en ADR y en un mapa de límites.
  2. Cada módulo recibe un contrato (tipos, esquema, invariantes, fuera de alcance).
  3. El agente implementa dentro de un solo módulo, con el contrato como entrada.
  4. Los cambios de arquitectura se entregan como una secuencia de PR pequeños y reversibles.
  5. Los requisitos no funcionales tienen sus propias barreras de control (latencia, costo, bundle), no solo tests.
  6. La revisión entre módulos la hace una persona; el agente puede revisar dentro de un módulo.

TL;DR

Dirigir un agente a nivel de sistema no es lo mismo que hacerlo a nivel de archivo. La unidad de trabajo es un módulo con un contrato explícito, no un archivo. Cuanto más código escribe un agente, más nítidas deben ser tus interfaces, porque el agente solo lee lo que está escrito. La persona se queda con el modelo de datos, los límites entre módulos y los requisitos no funcionales: son decisiones, no generaciones. Divide los cambios de arquitectura en pasos pequeños y reversibles, y trata la documentación (ADR, especificaciones, el mapa de límites) como una entrada para el modelo, no como un archivo muerto. Sin supervisión, un agente erosiona los límites, hincha el modelo de datos, duplica lógica y rompe en silencio los requisitos no funcionales, porque optimiza a nivel local, mientras que la arquitectura es global.

Arquitectura de sistemas con agentes de IA | vibecoding.inc