Cuarenta pasos y ningún error
Un agente que lleva 40 pasos rara vez se cae con una excepción. Se va volviendo torpe.
La traza lo cuenta bien. Los primeros diez pasos son limpios. En el 25 repite una búsqueda que ya hizo. En el 38 cita un fichero que leyó al principio y que entendió al revés. Nadie lanzó un error. El modelo simplemente dejó de distinguir qué importaba.
La reacción habitual es subir la ventana de contexto. No arregla nada, porque el problema no es cuánto cabe.
Lo que compite dentro del contexto
Cada llamada a herramienta deja residuos. El JSON completo de una respuesta de API. Las 200 líneas de un fichero del que interesaban tres. El stack trace de un intento que salió mal. Todo eso se queda en el historial y compite por la atención con la instrucción original.
Conviene separar dos efectos, porque se arreglan distinto:
Dilución. La señal útil es un porcentaje cada vez menor del prompt. El modelo atiende a todo, y “todo” es cada vez más ruido. Esto se parece a lo que pasa con un chunk mal recortado: no falta información, sobra.
Contaminación. Un paso fallido no desaparece, se convierte en contexto. Si el agente probó una ruta equivocada en el paso 12, esa ruta sigue ahí en el paso 30 con el mismo aspecto de evidencia que el resto. El modelo no tiene forma fácil de saber que aquello ya se descartó.
La compactación ayuda con la primera y poco con la segunda. Resumir un historial contaminado produce un resumen contaminado, más corto.
Orquestador y trabajadores
El patrón es viejo y aquí encaja bien. Un orquestador mantiene el objetivo, el plan y el estado. Cada subagente recibe una tarea acotada, un contexto limpio y devuelve un resultado estructurado. El trabajo sucio ocurre dentro de un contexto que se tira al terminar.
La consecuencia importa más que el diagrama: lo que vuelve al hilo principal no es la traza, es la conclusión. El orquestador nunca ve los 40.000 tokens que el subagente leyó para llegar a ella.
Y de ahí la tesis incómoda: los subagentes no están principalmente para paralelizar. Paralelizar es un efecto secundario agradable. Están para que el coste de contexto de una tarea no lo pague el resto de la sesión.
El contrato importa más que el prompt
Si el subagente devuelve prosa libre, has cambiado ruido por ruido más corto. El valor aparece cuando el resultado tiene forma.
from pydantic import BaseModel, Field
class ResultadoSubagente(BaseModel):
"""Lo único que cruza de vuelta al orquestador."""
hallazgo: str = Field(max_length=600) # La conclusión, no el camino.
evidencia: list[str] = Field(max_length=5) # Rutas o IDs, no el contenido.
confianza: float # 0–1, declarada por el modelo.
incompleto: bool # Se quedó sin pasos o sin datos.
async def delegar(tarea: str, herramientas: list, max_pasos: int = 12):
# Contexto nuevo: ni el historial del orquestador ni el de otro subagente.
hilo = [{"role": "user", "content": tarea}]
for paso in range(max_pasos):
respuesta = await modelo.invocar(
mensajes=hilo,
herramientas=herramientas, # Subconjunto mínimo, no el catálogo.
formato_salida=ResultadoSubagente,
)
if respuesta.final:
return respuesta.parsed
hilo += await ejecutar_herramientas(respuesta)
# Sin resultado no se devuelve None: se devuelve el fallo, y con etiqueta.
return ResultadoSubagente(
hallazgo="Límite de pasos alcanzado sin conclusión.",
evidencia=[], confianza=0.0, incompleto=True,
)
Tres decisiones ahí dentro que se pagan caras si se saltan.
evidencia guarda referencias, no contenido. Si devuelves los fragmentos
enteros, el subagente se convierte en un tubo y el contexto vuelve a crecer. El
orquestador ya decidirá si necesita abrir alguno.
max_pasos no es una salvaguarda de coste, es parte de la semántica. Un
subagente sin límite bloquea al orquestador de forma indefinida y, lo que es
peor, lo hace sin avisar.
incompleto existe porque un fallo silencioso se paga más tarde y más caro. Un
subagente que devuelve una conclusión pobre con confianza alta empuja
al orquestador a decisiones malas, y la traza no enseña dónde empezó el
desvío.
Cuándo repartir y cuándo no
| Señal | Un solo hilo | Subagentes |
|---|---|---|
| Contexto que consume la tarea | Cabe con holgura | Decenas de miles de tokens de los que sobreviven cuatro líneas |
| Relación entre pasos | Cada paso depende del anterior | Ramas explorables por separado |
| Escrituras | Modifica estado compartido | Solo lectura, o particiones que no se tocan |
| Necesidad de la traza | El resultado se justifica con el camino | Basta con la conclusión y sus referencias |
| Coste aceptable | Presupuesto ajustado | Se admite multiplicar tokens a cambio de acierto |
La fila de las escrituras es la que más veces se ignora. Dos subagentes que escriben en el mismo sitio sin saber el uno del otro producen conflictos que ninguno de los dos puede detectar, porque cada uno cree que su contexto es el mundo entero. Si hay efectos secundarios, que los ejecute el orquestador con lo que le devuelven.
Lo que se rompe en producción
El coste se multiplica. Cada subagente arranca con su propio prompt de sistema y su propio catálogo de herramientas. Cinco subagentes no cuestan como cinco pasos, cuestan como cinco sesiones cortas. Si la tarea cabía en un hilo, has pagado de más para nada.
El resumen pierde justo lo que hacía falta. El subagente decide qué es relevante sin conocer la pregunta completa del orquestador. Se mitiga estrechando la tarea: “¿cumple este módulo la política de reintentos?” se resume bien; “mira el módulo y cuéntame” no.
Depurar se complica. Un fallo puede estar en la tarea que se delegó, en la ejecución del subagente o en cómo el orquestador leyó el resultado. Sin la traza de cada hilo guardada por separado y con su identificador, la investigación es a ciegas.
Por dónde empezar
No adoptes el patrón porque salga bien en los diagramas. Adóptalo si tienes el síntoma.
Coge diez trazas de tu agente que hayan terminado mal y mide dos cosas: cuántos tokens había en el contexto en el momento del primer paso claramente erróneo, y qué fracción de esos tokens venía de una sola llamada a herramienta. Si el patrón es “la traza estaba llena de una lectura gigante que ya no hacía falta”, los subagentes te van a mover la aguja. Si el agente se equivocó en el paso 3 con el contexto casi vacío, el problema es el prompt o las herramientas, y repartir solo te dará tres sitios donde equivocarte.
Cuando decidas probarlo, empieza por la tarea más recortada que tengas: lectura pura, resultado corto, sin efectos secundarios. Búsqueda en el código, comprobación de una condición, exploración de una hipótesis. Delega esa, mide acierto y coste frente al hilo único y solo entonces amplía.
Y quédate con la regla general, que sirve para más cosas que para agentes: cuando un modelo rinde por debajo de su ficha técnica, la primera sospecha no es el modelo. Suele ser todo lo que le hemos ido metiendo delante sin quitarlo después.