Saltar al contenido principal
Volver al blogCopiar Markdown
·11 min de lectura
·claude codesubagentsskillsagentsios

Subagentes o skills en Claude Code: el fallo del simulador

Anthropic y un paper de octubre cuestionan cuándo compensan los subagentes. Mi caso: agentes en paralelo con un simulador de iOS compartido. Cuándo usarlos. →

Óscar Gallego

Ingeniero de software · Málaga

Varios puestos de trabajo separados que comparten un único dispositivo en el centro
En este artículo

Respuesta corta: no voy a dejar de usar subagentes, pero sí a repartirlos de otra forma. Anthropic recomienda dividir el trabajo por contexto y no por especialidad, y un paper de octubre encuentra que lo que más rompe a los subagentes en paralelo es lo que comparten. A mí me pasó con algo tan tonto como un simulador de iOS. Ahora uso subagentes para leer, buscar y verificar, y para escribir en paralelo solo cuando cada uno tiene sus propios recursos.

Hace nueve días publiqué cómo reparto entre subagentes las stories de Rydger, mi app de iOS y Android para el mantenimiento de la moto o el coche. Opus coordina, Sonnet implementa, cada story va en su worktree. Desde entonces tengo dos quejas, las dos de impresión y sin medir: se van muchos tokens, y muchas veces todo parece una caja negra, con el trabajo repartido en contextos que no veo.

Esta semana han llegado dos lecturas que parecen ir en contra de ese flujo. Un post de Anthropic del 22 de octubre propone meter los subagentes dentro del agente principal como skills y tools. Y un paper, todavía sin revisión por pares y con una sola ejecución por tarea, compara Codex, Claude Code y Kimi Code con y sin subagentes en paralelo: en una muestra de 100 tareas de SWE-bench Verified, Claude Code baja del 83% al 59% cuando puede lanzarlos.

Y luego está mi fallo: las pruebas de UI de Rydger fallaban sin motivo cuando varios agentes las ejecutaban a la vez.

Los tests rojos sin motivo venían de un iPhone virtual compartido

El simulador es el iPhone virtual de Xcode donde se ejecutan las pruebas de UI. Todos los worktrees usaban el mismo. Dos ejecuciones de xcodebuild sobre el mismo simulador le corrompen el estado de CoreData, y fallan tests que no tienen ningún problema.

Además, con el simulador apagado, xcodebuild lo encendía y lo apagaba en cada ejecución. Unos 28 segundos cada vez.

El arreglo es darle a cada worktree su propio simulador, creado la primera vez y siempre encendido. El script de Rydger hace más cosas, pero la idea cabe en esto:

# Un simulador por worktree: se crea la primera vez y se queda encendido
name="Agent $(basename "$(git rev-parse --show-toplevel)")"
udid=$(xcrun simctl list devices available | grep -E "^ +$name \(" | grep -oE '[0-9A-F-]{36}' | head -1)
[ -n "$udid" ] || udid=$(xcrun simctl create "$name" "iPhone 17 Pro")
xcrun simctl bootstatus "$udid" -b >/dev/null
xcodebuild test -scheme MiApp -destination "id=$udid"

Para las pruebas de UI hay otro script que compila una vez y reparte las clases entre cuatro simuladores del worktree, empezando por la más larga. La opción de paralelismo de Xcode se quedaba en 615 segundos: crea y arranca simuladores nuevos en cada ejecución y metía las dos clases de capturas en el mismo. La clase de capturas, que era la mitad del tiempo, ahora son dos que se ejecutan a la vez.

Desde que cada worktree tiene su simulador no me han vuelto a salir fallos falsos: las 35 pruebas de UI pasaron cinco veces seguidas, aunque no tengo apuntado cuántas veces fallaban antes. La tabla mide otra cosa, la velocidad, que viene sobre todo de no encender el simulador en cada ejecución y de repartir las clases:

EjecuciónAntesDespués
Pruebas de UI (35 tests)1062 s324–370 s
Pruebas unitarias completas47–52 s19–26 s
Una sola suite unitaria33 s8 s

Sin quitar ningún test. El después de las pruebas de UI cambia según la ejecución, de ahí el rango.

Lo que me molesta no es el tiempo. Es que un test rojo dejó de significar «el código está mal», y un agente que ve un test rojo intenta arreglar el código. Los worktrees separan los ficheros; no separan nada más.

Anthropic mantiene los subagentes y pide dividir por contexto

El resumen que circula es «un solo agente con skills gana a un orquestador con subagentes». El post es más matizado, y conviene leerlo entero antes de borrar nada.

Habla de agentes construidos en Claude Platform para empresas grandes, de cara al cliente, donde cada equipo monta su subagente y un equipo central pone un orquestador encima. Sus ejemplos son agentes de cara al cliente, no de código. En sus comparativas, un agente con skills ganó a menudo en calidad, muchas veces con menos coste y latencia. A menudo, no siempre.

Mantiene los subagentes para tres casos: cuando el contexto del agente principal empeora y se nota en los resultados, cuando hay tareas en paralelo con un contexto que se puede tirar al terminar, y cuando un solo agente no sabe elegir herramienta o tiene instrucciones contradictorias. Dice además que son buenos para verificar, para trabajar en paralelo y para separar permisos.

La regla que me llevo: si divides, divide por contexto. Dale a cada subagente un trabajo que necesite poco del resto y que devuelva un resultado compacto. Cuando se divide por tipo de problema, lo describen como un teléfono escacharrado donde cada traspaso pierde fidelidad. Y cuando cada equipo tiene su subagente, la arquitectura acaba siendo una copia del organigrama: la ley de Conway aplicada a agentes.

Por contexto, mi reparto por stories pasa: una story es un trozo de trabajo con su resultado visible, no «el agente de iOS» y «el agente de Android». Por recursos compartidos no pasó, y esa regla no lo habría detectado.

El fallo más común del paper es el estado compartido, y mi simulador encaja

El diseño es razonable: los subagentes no se forzaban. En el modo concurrente cada agente decidía si lanzarlos; en el secuencial se desactivaban las herramientas de delegación. 354 tareas, más de 2.000 ejecuciones y más de 20.000 dólares de API, con las configuraciones de julio de 2026. Claude Code iba con Opus 5 y, en el modo concurrente, con ultracode y Dynamic Workflow, que no es exactamente lanzar subagentes con la herramienta Agent. Los autores limitan sus conclusiones a esos agentes y esos benchmarks.

El 83% → 59% de Claude Code en SWE-bench Verified es el dato más llamativo, y su caída en el conjunto de los benchmarks es estadísticamente significativa. Con subagentes se gastan entre 1,4 y 3,3 veces los tokens del modo secuencial, y el tiempo medio sube en 14 de las 15 combinaciones de agente y benchmark.

La conclusión del paper es que los subagentes compensan más cuanto más larga es la tarea, y que conviene activarlos cuando hacen falta, no por defecto. En Claude Code, los cuatro benchmarks largos dan un resultado mixto: mejora en dos y baja en RepoZero del 42,7% al 26,7%. Mis stories se parecen más a una tarea acotada de SWE-bench que a construir un repositorio entero, así que me aplico la parte mala del titular.

Lo más útil es su clasificación de fallos. La categoría más grande, un 33%, es estado compartido y merge: agentes que leen o modifican ficheros o entornos compartidos sin coordinarse. La pérdida de contexto global es la más pequeña, un 9%. Un simulador que usan varios agentes a la vez encaja en esa definición. El paper no clasifica simuladores de iOS, así que la comparación es mía.

Cognition llegó a una conclusión parecida en su post de abril: lo que funciona son varios agentes aportando inteligencia mientras las escrituras siguen en un solo hilo.

La caja negra son dos resúmenes en cada delegación

Mi otra queja tiene explicación en la documentación de subagentes. Un subagente empieza con un contexto nuevo y aislado; no ve la conversación. El agente principal le escribe un mensaje de delegación que resume la tarea, y el subagente devuelve solo un resumen.

Lo que no entra en el primer resumen, el subagente no lo sabe. Lo que no entra en el segundo, el principal no lo ve. Si algo sale raro, la traza completa está en el contexto del subagente, no en el tuyo.

Hay una excepción que no conocía: los forks heredan la conversación del principal en vez de empezar de cero. Para un encargo que depende de lo que ya hemos hablado, un fork pierde menos que un subagente normal.

Y cada subagente cuenta para el límite de uso aunque su trabajo acabe en la papelera. No he medido cuántos tokens me cuestan, así que no voy a poner una cifra de ahorro.

Subagentes para leer y verificar; para escribir, solo si no comparten nada

Esto ya está hecho, fusionado en Rydger o ya activo en mis skills:

  • Un simulador por worktree y el script de pruebas de UI que he descrito arriba. El script que borra un worktree borra también sus simuladores.
  • Orden fijo de pruebas en la skill de testing: mientras itera, swift test y solo las suites tocadas; la suite unitaria completa una vez antes de cada commit; la de UI, una vez al fusionar.
  • Un traspaso menos en mi skill de equipo de agentes. Tenía un agente que investigaba con Haiku y le pasaba los datos a otro que implementaba con Sonnet, que los volvía a comprobar. Ahora investiga e implementa el mismo agente. Los revisores siguen en paralelo, pero solo uno ejecuta los tests; los demás leen.

Y así reparto a partir de ahora:

  • Subagentes para leer. «Busca dónde se usa esta función y devuélveme la lista» es el caso de manual: el subagente lee muchos ficheros y yo solo recibo la lista.
  • Subagentes para verificar. Un revisor con contexto limpio que no ha visto cómo se escribió el código.
  • Escrituras en paralelo solo si no comparten nada. Ficheros, ramas, ficheros generados, simuladores, puertos. Si comparten algo, primero lo separo o lo pongo en serie.
  • Los pasos del equipo, en skills. Lo que antes iba en el prompt de un subagente especialista va a una skill que el agente principal carga cuando la necesita.

Un proyecto y un simulador no bastan para dar la razón a nadie

Mi caso es un proyecto y un recurso compartido: yo paralelicé sin mirar qué compartían los agentes, y eso no prueba que un solo agente sea mejor.

Y quitar subagentes también rompe cosas. El ejemplo de Anthropic es un agente de soporte con un especialista de envíos: al fusionar un subagente con otro bajó la latencia, pero el agente empezó a contestar sin preguntarle la fecha de entrega a ese especialista. El fallo solo salió en una de las dos ejecuciones, y por eso piden repetir cada caso.

Empieza por la lista de lo que comparten tus agentes

Antes de quitar o añadir un subagente, apunta qué usan tus agentes a la vez cuando trabajan en paralelo: ficheros generados, simuladores, emuladores, puertos, bases de datos locales. Cada cosa de esa lista necesita una copia por agente o ir en serie. Es lo que hice yo, tarde.

Si después quieres quitar un subagente, Anthropic propone escribir antes unos diez casos de principio a fin con el resultado esperado, ejecutar cada uno más de una vez con el subagente y sin él, y quitarlos de uno en uno. Yo todavía no lo he hecho. Si sin el subagente sale igual o mejor, sobra.

Fuentes

Lectura relacionada: cómo reparto las stories entre subagentes y por qué falla tu agente sin harness.


P.D. ¿Qué compartían tus agentes en paralelo que no habías visto? Cuéntamelo en LinkedIn.

Comparte este artículo

Artículos relacionados