El año pasado construí un agente que pretendía ser el ingeniero de software definitivo. Fue mi primer intento serio de arquitectura de subagentes IA — y la forma en la que fallé me enseñó por qué un solo agente nunca debería hacerlo todo.
Su System Prompt ocupaba casi 3.000 palabras. Le instruí para ser arquitecto de software, experto en seguridad, programador senior de TypeScript, tester meticuloso y redactor técnico. Además, le configuré 28 herramientas distintas: leer archivos, escribir código, ejecutar comandos bash, consultar 3 bases de datos y hacer peticiones HTTP.
Al principio parecía impresionante. En la primera tarea sencilla respondió bien.
Pero a la cuarta tarea compleja, el sistema colapsó por completo:
- Confundía las reglas de testing con las de documentación.
- Para cambiar una sola línea de CSS llamaba a herramientas de base de datos.
- Consumía 100.000 tokens en cada paso solo leyendo la lista gigante de herramientas disponibles.
Ese día entendí una verdad fundamental del desarrollo con IA: en lugar de construir un único agente que intente hacerlo todo, necesitas un equipo de subagentes con tareas concretas y contextos aislados.
Por qué los Mega-Prompts fallan en la práctica
No es una limitación de que el modelo "sea tonto"; es el resultado de cómo funcionan los Transformers:
1. Degradación por ruido de herramientas (Tool Noise)
Cuantas más herramientas (tools) le expones a un modelo en un único turno, mayor es la probabilidad de que elija la herramienta equivocada o invente parámetros incompatibles.
Con pocas herramientas bien definidas, la precisión de selección se mantiene alta. Cuando la lista crece a decenas de herramientas mezclando responsabilidades distintas (leer archivos, escribir código, consultar bases de datos, hacer peticiones HTTP), esa precisión cae de forma abrupta — es el mismo problema que un desarrollador tendría memorizando 30 comandos de CLI casi idénticos.
2. Dispersión de atención (Attention Drift)
Si tu prompt contiene 50 reglas diferentes ("no uses any", "usa el prefijo on en eventos", "escribe tests en Vitest", "documenta en JSDoc"), el mecanismo de atención del LLM diluye la importancia de cada una.
Cuando el contexto se llena de logs y código, las reglas del medio del prompt simplemente dejan de tener peso estadístico.
3. Contaminación de contexto
Si un agente pasa 20 minutos investigando archivos y leyendo logs de error, esos 80.000 tokens de "ruido exploratorio" se quedan atascados en la memoria para siempre.
Cuando luego le pides que escriba la solución final, su respuesta estará condicionada por todo ese texto basura previo.
La solución: Arquitectura de Subagentes en 3 capas
La solución no es hacer prompts más largos ni añadir más mayúsculas al texto. Es aplicar el principio de Responsabilidad Única que llevamos décadas usando en ingeniería de software.
En Dominicode organizamos el trabajo en tres tipos de subagentes especializados:
┌───────────────────────┐
│ AGENTE ORQUESTADOR │
│ (Planifica y delega) │
└──────────┬────────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ RESEARCHER │ │ IMPLEMENTER │ │ REVIEWER │
│ (Read-only) │ │(Write + TDD)│ │ (Auditoría) │
└─────────────┘ └─────────────┘ └─────────────┘
1. El Investigador (Researcher — Solo Lectura)
- Herramientas permitidas: Búsqueda en archivos, lectura de código, búsqueda web.
- Herramientas prohibidas: Edición de archivos, ejecución de comandos destructivos.
- Misión: Explora el codebase, localiza las funciones relevantes y devuelve un resumen limpio de 50 líneas con los hallazgos. Su memoria sucia de 60.000 tokens se descarta al terminar; solo el resumen pasa al siguiente agente.
2. El Implementador (Implementer — Escritura + TDD)
- Herramientas permitidas: Edición precisa de archivos, ejecución de tests.
- Misión: Recibe el resumen del Researcher y la especificación técnica. Su único objetivo es crear el test, escribir el código mínimo para pasarlo y verificar que compila. No pierde tiempo buscando archivos porque el Researcher ya le dio las rutas exactas.
3. El Revisor (Reviewer — Auditor de Calidad)
- Herramientas permitidas: Lectura de diffs de git, linter.
- Misión: Revisa los cambios antes de hacer commit. Evalúa si se respetan los estándares de tipado, si hay regresiones de rendimiento y si se cumplió la especificación original.
Cómo se comunican los subagentes sin saturar tokens: El patrón Artifact
El error habitual al montar sistemas multiagente es hacer que el Agente A le hable al Agente B en un chat conversacional interminable ("Hola Agente B, ¿cómo estás? He encontrado esto…"). Eso gasta tokens en cortesías inútiles.
El patrón más eficiente es la comunicación mediante artefactos en disco:
- El
Researcherescribe sus hallazgos en un archivo local:scratch/research_findings.md. - El
Orchestratorlee ese archivo y lanza alImplementerpasándole únicamente la ruta del archivo. - El
Implementerejecuta los cambios y escribe el resumen de modificaciones enscratch/changes_summary.md.
Cada subagente arranca con una ventana de contexto limpia, consumiendo solo los tokens necesarios para su tarea concreta.
Este flujo de trabajo desacoplado es el que explicamos a fondo en el curso Construye con IA: de la idea al producto con Claude Code, donde mostramos cómo estructurar entornos reales multiagente que no se degradan con el tiempo.
Ejemplo práctico: Definiendo un subagente en TypeScript
Si estás creando tus propios agentes con código propio, no necesitas frameworks gigantes. Puedes instanciar agentes especializados restringiendo las tools y el system prompt:
import { generateText, tool, stepCountIs } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { z } from "zod";
// Agente especializado solo en investigación.
// Modelo de ejemplo: sustituye por la versión vigente de Claude en tu build.
export async function spawnResearcherAgent(query: string, codebaseDir: string) {
const result = await generateText({
model: anthropic("claude-sonnet-5"),
system: `Eres un agente de investigación técnica de solo lectura.
Tu objetivo es explorar el código en "${codebaseDir}", localizar las funciones clave
y responder con un informe conciso. NUNCA propongas escribir código ni modificar archivos.`,
prompt: `Investiga: ${query}`,
tools: {
searchFiles: tool({
description: "Busca patrones en el repositorio",
inputSchema: z.object({ pattern: z.string() }),
execute: async ({ pattern }) => {
// Lógica de búsqueda grep/ripgrep
return { matches: ["src/auth/service.ts:45", "src/auth/jwt.ts:12"] };
},
}),
readFile: tool({
description: "Lee un archivo específico",
inputSchema: z.object({ path: z.string() }),
execute: async ({ path }) => Bun.file(path).text(),
}),
},
stopWhen: stepCountIs(8),
});
return result.text; // Salida limpia lista para pasar al Implementador
}
Al limitar el rol a lectura y 2 herramientas, la tasa de error baja notablemente y el coste por ejecución se reduce al mínimo.
Qué hacer hoy con tu proyecto
Si tienes un archivo de prompt de 5 páginas o un agente que intenta resolver todo el ciclo de vida de tu software:
- Separa la lectura de la escritura: Crea un agente explorador con herramientas de solo lectura y un agente constructor que solo toque archivos cuando ya sabe exactamente qué cambiar.
- Usa especificaciones previas: Antes de lanzar a los subagentes, asegúrate de tener una base firme con Spec-Driven Development (SDD) para que ningún agente tenga que improvisar requisitos sobre la marcha.
- Pasa datos, no conversaciones: Haz que tus subagentes se comuniquen a través de archivos estructurados en lugar de historiales de chat kilométricos.
En Dominicode Labs compartimos arquitecturas reales de subagentes que usamos a diario para automatizar la creación de cursos, la refactorización de código y el mantenimiento de proyectos en producción.
Deja de pedirle milagros a un mega-prompt. Diseña un sistema de subagentes donde cada uno haga una sola cosa, pero la haga con precisión quirúrgica.









