Agent Teams: Mi Pipeline de 9 Agentes Especializados

No uso un agente de IA para programar. Uso nueve. Y cada uno tiene un rol, unas reglas, y un momento exacto en el que interviene.

Hace un mes publiqué mi primera experiencia con Agent Teams, donde monté un equipo de 7 agentes para una prueba de concepto. El resultado fue tan bueno que desde entonces no he parado de iterar. Hoy el pipeline tiene 9 pasos, dos pases de Devil’s Advocate, testing real contra Docker, y un flujo donde cada agente sabe exactamente qué archivos son suyos y cuáles no.

Este artículo es el complemento natural de mi artículo sobre Specification-Driven Development. SDD define QUÉ construir. Agent Teams define CÓMO ejecutarlo. Sin especificaciones claras, los agentes son solo ruido caro. Con ellas, son un equipo de desarrollo que trabaja en minutos lo que antes costaba horas.

Si todavía no conoces Claude Code, empieza por mi guía completa con 15 consejos de uso diario antes de seguir.

Por qué un solo agente no escala

Cuando le pides a un solo agente que diseñe la arquitectura, implemente el dominio, monte la infraestructura, escriba los tests, documente los endpoints y revise su propio código, pasan tres cosas:

El contexto se agota. Un agente que lleva 50.000 tokens arrastrando decisiones de arquitectura, código de dominio y configuración de migraciones empieza a olvidar cosas. Los últimos pasos se hacen con menos contexto que los primeros, y la calidad baja.

Las decisiones se contradicen. Un agente que implementa y revisa su propio trabajo no cuestiona sus decisiones. Si eligió mal una estructura al principio, va a construir todo encima de esa decisión sin cuestionarla. No hay segunda opinión.

No hay revisión real. Un code review hecho por el mismo agente que escribió el código no es un code review. Es validación de sus propias decisiones. No hay perspectiva externa.

La analogía con un equipo humano es directa: no pones al mismo desarrollador a diseñar la arquitectura, implementar todo el código, escribir los tests, documentar y aprobar su propio PR. Separas roles porque la especialización produce mejor resultado que el generalismo.

Agent Teams aplica ese principio: especialización + pipeline + quality gates. Cada agente tiene un rol acotado, un conjunto de herramientas limitado, y un momento exacto en el que interviene. El resultado es un pipeline donde cada paso valida o cuestiona el anterior.

El pipeline de 9 pasos

Después de varias iteraciones, este es el pipeline que uso para implementar features completas:

#AgenteRolProduce
1ArchitectAnaliza specs, propone estructura DDDDiseño técnico con Bounded Contexts, Aggregates, relaciones
2Devil’s AdvocateCuestiona las decisiones del arquitectoFeedback con alternativas, riesgos identificados
3Domain DevImplementa Domain + ApplicationEntidades, VOs, repositorios, servicios, commands, queries
4Devil’s Advocate (pase 2)Revisa el código de dominioFeedback sobre invariantes, naming, edge cases
5Infra DevInfraestructura completaORM, migrations, controllers, permissions, translations
6Unit TesterTests unitarios con mutation testing100% coverage, mutation score >80%
7Endpoint TesterTests HTTP reales contra Dockertest-results.md con curls, responses, validaciones
8DocumenterDocumentación verificadaDocs de endpoints + colección Bruno importable
9Code ReviewerGate final de calidadAPPROVED o feedback específico con agente responsable

El orden es obligatorio. El Architect va primero porque sin diseño no hay implementación. El Domain Dev va antes que el Infra Dev porque la infraestructura sirve al dominio, no al revés. El Code Reviewer va último porque necesita ver todo el trabajo completo para evaluarlo.

Los pasos 6 y 7 se ejecutan en paralelo. El Unit Tester trabaja con los archivos de dominio y aplicación, mientras el Endpoint Tester levanta Docker y hace HTTP real. No se pisan porque operan sobre capas distintas.

Arquitecto + Devil’s Advocate

El Architect recibe la especificación técnica y propone la estructura DDD completa: Bounded Context (nuevo o existente), Aggregates, entidades, Value Objects, relaciones entre ellos, tipo de migraciones necesarias, y cómo encaja todo con el sistema existente.

No escribe código. Solo diseña. Esto es clave: un agente que diseña e implementa a la vez tiende a tomar atajos para simplificar la implementación, sacrificando el diseño.

Una vez el Architect entrega su propuesta, entra el Devil’s Advocate. Su trabajo es cuestionar cada decisión:

  • “¿Por qué un nuevo Bounded Context en vez de extender el existente?”
  • “Este Aggregate tiene demasiadas responsabilidades. ¿No deberían ser dos?”
  • “Esta relación one-to-many va a generar problemas de rendimiento con datasets grandes.”
  • “El naming de este Value Object no refleja lo que representa en el dominio.”

El Architect responde, ajusta o defiende. Máximo dos iteraciones. Si después de dos rounds no hay acuerdo, se escala al lead (yo) para tomar la decisión. Esto evita bucles infinitos de debate entre agentes.

Un ejemplo real (anonimizado): el Architect propuso crear un nuevo Bounded Context para gestión de documentos adjuntos. El Devil’s Advocate cuestionó: “Los documentos siempre están asociados a una entidad del contexto principal. No tienen ciclo de vida independiente. ¿No es un Aggregate dentro del contexto existente?” Tenía razón. Se ajustó el diseño y nos ahorramos una capa de complejidad innecesaria.

Ese tipo de cuestionamiento es exactamente lo que un agente solo no hace. No se cuestiona a sí mismo.

Domain Dev + Infra Dev: separación por capas

La separación más importante del pipeline es entre Domain Dev e Infra Dev. No es cosmética: es estructural.

Domain Dev solo toca Domain y Application. Cero dependencias de framework. Entidades, Value Objects, interfaces de repositorio, excepciones de dominio, servicios de aplicación, commands, queries, handlers. Si algo necesita un use Doctrine\... o un use Symfony\..., no es su responsabilidad.

Entre el Domain Dev y el Infra Dev hay un segundo pase de Devil’s Advocate. Este pase revisa específicamente el código de dominio: ¿los invariantes se protegen en el constructor? ¿Los Value Objects son inmutables? ¿Los nombres reflejan el lenguaje ubicuo del dominio? ¿Hay algún acoplamiento accidental con infraestructura?

Solo después de que el dominio esté validado entra el Infra Dev. Mappings ORM, repositorios Doctrine que implementan las interfaces de dominio, controllers, FormTypes, migraciones de base de datos, configuración de permisos, traducciones a los idiomas del proyecto. Todo lo que conecta el dominio con el mundo exterior.

Esta separación tiene un efecto secundario valioso: como cada agente tiene su propio contexto, el Domain Dev trabaja con una ventana de contexto limpia, enfocada solo en reglas de negocio. No arrastra el ruido de configuraciones de Doctrine o mappings de Symfony. El resultado es código de dominio más puro.

Testing real: el Endpoint Tester

Este es el agente que más valor aporta al pipeline y el que más me costó afinar.

El Endpoint Tester no usa mocks. Hace HTTP real contra Docker. La API está en http://localhost:10000, levantada con Docker Compose, con base de datos real, con datos de test reales.

El flujo del Endpoint Tester:

  1. Descubre los usuarios de test disponibles consultando la tabla auths en MySQL
  2. Genera tokens JWT válidos para cada perfil de permisos que necesita probar
  3. Ejecuta requests HTTP reales con curl contra cada endpoint implementado
  4. Valida: happy path, validaciones de input, permisos (403 para usuarios sin acceso), edge cases, respuestas de error

El output es un test-results.md estructurado así:

### POST /api/v1/resources

**Status**: ✅ OK

**Auth**: Bearer token (user: admin@test.com)

**Curl**:

curl -X POST http://localhost:10000/api/v1/resources
-H “Authorization: Bearer eyJhbGciOiJ…”
-H “Content-Type: application/json”
-d ’{“name”: “Test Resource”, “type”: “standard”}’


**Response** (201):
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Test Resource",
  "type": "standard",
  "created_at": "2026-03-09T10:30:00+00:00"
}

Validaciones:

  • ✅ 201 Created con datos correctos
  • ✅ 422 si falta campo obligatorio “name”
  • ✅ 422 si “type” no es un valor válido del enum
  • ✅ 403 si el usuario no tiene permiso RESOURCE_CREATE
  • ✅ 409 si ya existe un recurso con el mismo name

Cada curl es copiable y ejecutable. Cada response es real, no inventada. Esto es lo que alimenta al Documenter.

## Documenter: solo lo verificado

El Documenter tiene una regla estricta: solo documenta endpoints que el Endpoint Tester verificó con éxito. Si un endpoint no pasó el testing, no se documenta. Punto.

Esto parece obvio pero tiene una implicación importante: la documentación refleja realidad, no intención. No documenta lo que el endpoint *debería* hacer según la spec, sino lo que *hace* según las pruebas reales.

El Documenter genera dos outputs:

**Documentación markdown** de cada endpoint con request, response, códigos de error, y notas de uso. Directamente derivada de los datos del `test-results.md`.

**Colección Bruno** con archivos `.bru` importables directamente en el cliente Bruno. Cada endpoint tiene su archivo con headers, body de ejemplo, y variables de entorno configuradas. El equipo de frontend puede importar la colección y empezar a probar inmediatamente, sin tener que montar nada a mano.

La combinación de testing real + documentación verificada elimina uno de los problemas más comunes en equipos: documentación desactualizada. Si la documentación se genera desde las pruebas, siempre refleja el estado actual del código.

## Code Reviewer: el gate final

El Code Reviewer es el último agente del pipeline y el más exigente. Revisa todo el código producido contra tres referencias:

1. **La especificación técnica**: ¿se implementó lo que se pidió? ¿Falta algo? ¿Se añadió algo que no estaba en la spec?
2. **El diseño del Architect**: ¿la implementación respeta las decisiones de diseño? ¿Se desvió en algo?
3. **Las reglas del proyecto**: PHPStan, convenciones de naming, estructura de directorios, patrones obligatorios.

El Code Reviewer puede hacer dos cosas:

**APPROVED**: todo cumple. La feature está lista para merge.

**Feedback específico**: identifica el problema, explica por qué es un problema, y asigna la corrección al agente responsable. "El Domain Dev dejó un acoplamiento con Doctrine en el servicio X. Debe corregirlo." No feedback genérico, sino accionable y con responsable.

Si el Code Reviewer envía trabajo de vuelta, se re-ejecuta solo el agente afectado. No se repite todo el pipeline. El Domain Dev corrige su código de dominio, el Infra Dev ajusta su migración, o lo que sea. Después, el Code Reviewer vuelve a revisar solo los cambios.

Usar Opus aquí no es capricho. El Code Reviewer necesita criterio, no velocidad. Necesita entender la intención del diseño, detectar violaciones sutiles de principios, y evaluar si la implementación es coherente con el sistema existente. Sonnet es un buen implementador pero Opus es mejor revisor.

## Cómo se comunican los agentes

Los agentes no trabajan en silos. Se comunican entre ellos de dos formas:

**SendMessage** para comunicación directa entre agentes. Es un mensaje privado, no un broadcast. El Architect envía su diseño al Domain Dev. El Devil's Advocate envía su feedback al Architect. El Code Reviewer envía correcciones al agente específico que debe arreglar algo. Cada mensaje va dirigido a un destinatario concreto.

**TaskCreate / TaskUpdate** para tracking del progreso. Cada agente crea tareas cuando empieza su trabajo y las actualiza cuando termina. El lead (el agente orquestador) ve el estado de todas las tareas y sabe cuándo un agente terminó para lanzar el siguiente.

El lead orquesta el flujo: asigna trabajo, espera a que termine, lanza el siguiente paso o los pasos paralelos. Si un agente se bloquea (tarda demasiado, entra en loop, o falla), el lead interviene: puede hacer shutdown del agente y reasignar el trabajo.

La comunicación es asíncrona. El Architect no espera activamente al Devil's Advocate. Envía su diseño, y el Devil's Advocate lo procesa cuando le toca. Esto permite que el pipeline fluya sin bloqueos innecesarios.

## Worktrees: cada agente en su sandbox

Cada feature se desarrolla en un worktree aislado. Esto no es opcional: es parte fundamental de cómo funciona el pipeline.

```bash
lm: git worktree add ../project-feature-invoicing feature/invoicing

El worktree tiene su propia copia del código, su propio Docker Compose (con puertos dinámicos para evitar conflictos), y su propia base de datos. Los agentes trabajan dentro de ese worktree sin afectar develop ni otras features en progreso.

Las ventajas:

  • Aislamiento total: si un agente rompe algo, solo afecta su worktree. develop sigue intacto.
  • Paralelismo real: puedo tener dos pipelines corriendo en dos features distintas a la vez, cada uno en su worktree.
  • Merge limpio: cuando el pipeline completo termina y el Code Reviewer aprueba, el merge a develop es un PR limpio con todos los commits del pipeline.

Sin worktrees, los agentes trabajarían directamente sobre la rama de desarrollo. Un error en el paso 3 podría dejar el código en un estado roto para los pasos 4-9. Con worktrees, cada pipeline es un sandbox descartable hasta que se aprueba.

Configuración práctica

Cada agente se define en un archivo markdown con frontmatter YAML que especifica su nombre, modelo, y herramientas disponibles:

---
name: API Endpoint Tester
model: sonnet
tools:
  - Read
  - Bash
  - Grep
  - Glob
---

Debajo del frontmatter van las instrucciones detalladas del agente: qué hace, qué no hace, qué archivos puede tocar, qué formato debe usar para su output, y cómo comunicarse con otros agentes.

La limitación de herramientas es intencional. El Architect no tiene Bash ni Edit porque no debe escribir código. El Domain Dev no tiene acceso a ejecutar migraciones. El Endpoint Tester tiene Bash porque necesita ejecutar curl y consultar MySQL. Cada agente solo tiene las herramientas que su rol necesita.

Qué modelo para cada rol

No todos los agentes necesitan el mismo modelo. Mi distribución:

ModeloAgentesRazón
OpusArchitect, Devil’s Advocate, Code ReviewerNecesitan criterio, razonamiento profundo, detección de problemas sutiles
SonnetDomain Dev, Infra Dev, Unit Tester, Endpoint Tester, DocumenterNecesitan velocidad de implementación y ejecución

Opus es significativamente más caro que Sonnet, pero para los roles de decisión y revisión, la diferencia en calidad lo justifica. Un Architect que no detecta un problema de diseño genera trabajo para todos los agentes posteriores. Un Code Reviewer que deja pasar una violación anula todo el value del pipeline.

Sonnet para implementación es excelente. Es rápido, sigue instrucciones bien, y produce código limpio cuando tiene reglas claras.

El comando implement

En mi setup, el comando /implement arranca preguntando: solo mode o team mode?

En solo mode, un agente generalista hace todo secuencialmente. Es más barato, más rápido para features simples, y suficiente el 80% de las veces.

En team mode, se lanza el pipeline completo de 9 pasos. Es para features que tocan múltiples capas, tienen complejidad de dominio real, o necesitan testing exhaustivo.

La decisión es pragmática. Si la feature es “añadir un campo a un endpoint existente”, solo mode. Si es “implementar un nuevo módulo de facturación con reglas de negocio complejas”, team mode.

Cuándo SÍ, cuándo NO

Después de un mes usando este pipeline, tengo claros los límites:

Usa Agent Teams cuando:

  • La feature toca múltiples capas (dominio, infraestructura, tests, docs)
  • Hay complejidad real de dominio que necesita validación
  • Quieres testing exhaustivo con endpoints reales
  • La feature es lo suficientemente grande como para justificar el coste en tokens

NO uses Agent Teams cuando:

  • Es un cambio simple: añadir un campo, corregir un typo, ajustar una validación
  • Todo depende de todo secuencialmente sin posibilidad de paralelismo
  • No tienes specs claras de lo que hay que implementar
  • No tienes reglas de proyecto afinadas

La regla práctica: si necesitarías más de 3 sesiones individuales de Claude Code para completar la feature (implementar, luego tests, luego docs, luego review…), Agent Teams probablemente merece la pena. Si se resuelve en una sesión, no.

Lo que he aprendido

Después de iterar el pipeline durante un mes, las lecciones más importantes:

Las specs son el 80% del resultado. Un pipeline de 9 agentes con una spec mediocre produce código mediocre. Un solo agente con una spec excelente produce buen código. Agent Teams amplifica la calidad de lo que le das, para bien o para mal.

El Devil’s Advocate es el agente más infravalorado. Los dos pases de cuestionamiento (uno en diseño, otro en dominio) detectan problemas que ningún otro agente encontraría. Es el agente que más dinero me ahorra en refactorizaciones posteriores.

La separación Domain Dev / Infra Dev no es negociable. Cada vez que intenté que un solo agente hiciera ambas capas, el código de dominio acababa contaminado con dependencias de framework. La separación forzada produce mejor arquitectura.

El Endpoint Tester contra Docker cambió todo. Pasar de mocks a HTTP real contra un entorno Docker eliminó una categoría entera de bugs: “funciona en los tests pero falla en producción”. Si el curl funciona contra Docker, funciona en producción.

El coste se amortiza. Sí, Agent Teams consume 7-10x más tokens que una sesión individual. Pero el código sale bien a la primera. No hay 3-4 sesiones de ida y vuelta corrigiendo cosas. No hay bugs que descubres en staging porque los tests no eran suficientes. El coste total (tokens + tiempo humano de revisión) es menor.

Conclusión

Los agent teams no son el futuro. Son el presente. Pero solo funcionan si les das estructura. Sin specs, sin pipeline, sin rules… son solo un agente caro haciendo vibe coding en paralelo.

La combinación que funciona es clara: SDD para definir qué construir + Agent Teams para ejecutarlo + reglas de proyecto afinadas durante meses. Quita cualquiera de los tres y el resultado se degrada.

Si llevas meses usando Claude Code y ya tienes tus reglas afinadas, Agent Teams es el siguiente paso natural. No porque sea más “cool” que una sesión individual, sino porque la especialización por roles produce mejor código que el generalismo. Igual que en un equipo humano.

Y si todavía no tienes reglas de proyecto, empieza por ahí. Ese es el cimiento sobre el que se construye todo lo demás.


P.D.: Si estás experimentando con Agent Teams o tienes un pipeline diferente, me encuentras en Twitter como @lmmartinb. Y si todavía no usas Claude Code, empieza por mi guía de consejos de uso diario.

💡

¿Te ha gustado este artículo?

Explora más artículos sobre desarrollo, buenas prácticas y herramientas.