¿Tu subagente va por mal camino? Ahora puedes corregirlo a mitad de ejecución


Un lunes por la tarde, haces que Hermes lance tres subagentes para paralelizar un refactor: uno para el frontend, otro para el backend y un tercero para los tests. Media hora después, echas un vistazo al progreso y te das cuenta de que el del backend va disparado en la dirección equivocada — sigue escribiendo contra la API antigua mientras la nueva cambió todas las firmas. Antes, tu única opción era matar el lote entero, reexplicar los requisitos y empezar de cero; y si tenías mala suerte, los dos subagentes que iban bien también salían alcanzados por la explosión. Eso se acabó. Desde el 13 de agosto, delegate_task incorpora un plano de control en tiempo real — puedes hacer list de los subagentes en ejecución, steer al que se desvió o stop al que ya no tiene salvación, todo sin interrumpir al resto del equipo.

La consola del director: tres acciones de control

Primero, una premisa rápida: un subagente es un «clon» separado que Hermes despacha para trabajar de forma independiente, con su propio contexto de conversación aislado y su propia sesión de terminal. Antes, delegate_task tenía exactamente un verbo — spawn: lanzas una tarea y esperas el resumen. El PR #85232 añade tres acciones de control directamente en la misma herramienta, sin introducir ninguna herramienta nueva. El modelo sigue llamando a delegate_task; solo que ahora recibe tres parámetros nuevos: action, subagent_id y message.

Acción Parámetros Efecto
action='list' ninguno Muestra los subagentes aún en ejecución lanzados por esta conversación
action='steer' subagent_id + message Encola una corrección de rumbo en un subagente en ejecución sin detenerlo
action='stop' subagent_id Interrumpe un subagente antes de tiempo; su resultado parcial vuelve igualmente con normalidad
omitido o action='spawn' goal/tasks etc. El modo spawn original — comportamiento sin cambios

Las tres acciones de control se ejecutan de forma síncrona — nunca entran en la cola de despacho en segundo plano y devuelven el resultado al instante, así que obtienes una respuesta inmediata de «esto es lo que está corriendo» directamente en la conversación.

Cómo usarlo: un ejercicio completo de descubrir → corregir → detener

Digamos que acabas de despachar tres subagentes y quieres ver cómo van:

{
  "tool": "delegate_task",
  "action": "list"
}

Cada entrada de la lista devuelta incluye subagent_id, parent_id, depth, goal, model, started_at y accepting_steer — el campo goal te permite identificar de un vistazo cuál es el que «sigue escribiendo contra la API antigua».

Una vez localizado el rezagado, inyecta una corrección:

{
  "tool": "delegate_task",
  "action": "steer",
  "subagent_id": "sa-7f3k9",
  "message": "Heads up: the backend API signature changed. Use the new /v2/users endpoint — the field is userId, not id."
}

steer funciona encolando el texto en la entrada pendiente del subagente objetivo, que se entrega en el siguiente tool boundary del hijo — no arranca al subagente de lo que esté haciendo; la corrección aterriza en un punto seguro. Y si el subagente termina antes de llegar a consumir el steer, la instrucción no se desvanece en el aire: aparece como un campo missed_steer en la entrada de finalización de ese subagente, para que sepas que la corrección de rumbo nunca llegó a aplicarse.

Si ese subagente ya no tiene salvación, termínalo:

{
  "tool": "delegate_task",
  "action": "stop",
  "subagent_id": "sa-7f3k9"
}

stop viaja en la maquinaria de interrupción: el subagente se detiene en su siguiente límite de iteración, y el resultado parcial que haya producido vuelve como un mensaje de finalización normal — sin trabajo desperdiciado ni estados colgados. Puedes tomar esa salida parcial y despachar un subagente nuevo para que termine el resto.

Límites y seguridad: solo puedes controlar tu propio árbol

El plano de control viene con unos cuantos límites diseñados a propósito — conócelos y no te llevarás sorpresas:

  • Cadena de propiedad: una conversación solo puede controlar los subagentes que ella misma lanzó. Hermes lo garantiza mediante una cadena weakref _delegate_parent_ref con comprobaciones de identidad — no puedes hacer steer de los hijos de otra conversación desde la tuya. Es la misma garantía que impide que varias sesiones de Hermes se pisen unas a otras.
  • Las acciones de control no consumen el presupuesto de spawn: hay un tope por turno de cuántos subagentes puedes lanzar, pero list/steer/stop están exentos — a propósito. Justo cuando se alcanza el tope es cuando más importa «detener urgentemente al que se ha desbocado», así que stop sigue disponible.
  • Los subagentes no pueden lanzar subagentes por defecto: un hijo con role='leaf' nunca recibe la herramienta delegate_task; solo un role='orchestrator' explícito conserva el conjunto de herramientas de despacho (acotado por delegation.max_spawn_depth). El control siempre reside en el lado de la conversación de nivel superior.
  • Momento de entrega del steer: steer es «inyección en cola», no «interrupción instantánea». Si el subagente está atascado dentro de una llamada de herramienta muy larga, la corrección solo aterriza en el siguiente tool boundary — suficiente para la mayoría de los casos, pero para situaciones de «hay que pararlo ya» la herramienta adecuada es stop.

Cuándo merece la pena la orquestación en vivo

El valor real está en mover tu «inspección humana» de después del hecho a mitad de vuelo:

  • Corrección de rumbo temprana en tareas largas: al reescribir decenas de miles de líneas, descubrir una dirección equivocada pasados 10 minutos sale caro. Un list + steer a mitad de camino puede ahorrarte horas.
  • Gestión quirúrgica en lotes paralelos: de tres subagentes, solo uno se desvió — haz steer o stop solo a ese mientras los otros dos siguen corriendo, en lugar de reiniciar el lote entero.
  • Complementa los flujos de kanban/review: si gestionas tareas de subagentes en un tablero (consulta nuestra guía del ciclo de vida de review en kanban), el plano de control llena el hueco de «cómo intervengo a mitad de tarea» que el tablero por sí solo no podía cubrir.

Ya hemos hablado de delegate_task antes — el merge-reconciler, un árbitro neutral de fusión de código mostró el patrón «despachar y esperar resultados». Esta superficie de control evoluciona delegate_task de «dispara y olvida» a «dirigir en plena marcha». Los subagentes son el núcleo de los flujos multi-agente de Hermes desde la v0.20.0 (consulta las notas de la versión v0.20.0 Herald), y por fin tienen un volante en vivo.

Una frase para recordar: list te deja ver, steer te deja hablar y stop te deja frenar — las tres sin interrumpir a los subagentes que van bien. La próxima vez que un subagente se desvíe, no tendrás que volcar la mesa y empezar de nuevo.