Un lote, muchos cerebros: delegate_task ya elige modelo o profile por tarea


Le entregas a Hermes un lote: ocho subtareas. Seis son búsquedas — leer un documento, hacer grep en un log, reformatear una tabla. Dos son las difíciles — desenredar un bug de concurrencia, rediseñar la frontera de un módulo. Y tienes un solo modelo para todas. Si eliges uno caro, las seis tareas triviales queman dinero; si eliges uno barato, las dos difíciles vuelven con tonterías plausibles. Esa elección forzada deja de ser obligatoria con el PR #142563, fusionado el 22 de octubre de 2026.

La regla antigua: un solo delegation.model para todos los hijos

El modelo hijo estaba fijado globalmente en config.yaml: delegation.model, delegation.provider, delegation.base_url. Con la estrategia por defecto, delegate_task no tiene ningún parámetro de modelo por tarea, así que cada subagente de un lote corre sobre la misma ruta. La documentación lo decía sin rodeos: para una subtarea sensible a la calidad, o dejas delegation.model sin definir en esa sesión, o le pasas el trabajo al tablero kanban, que sí admite una sobrescritura de modelo por tarea.

Así que todo el mundo hacía el mismo compromiso: fijar un modelo de gama media y aguantarse.

La regla nueva: delegation.backend decide cómo se enruta el trabajo

El cambio en una frase: la delegación pasó a ser una categoría de provider conectable, con la misma forma que TTS, la generación de imágenes y los backends de terminal. delegation.backend elige la estrategia. default significa exactamente lo que ya tenías: sin definir o en default, el esquema de delegate_task y cada definición de herramienta de hermes-cli quedan idénticos byte a byte a como estaban.

Las otras dos estrategias vienen del plugin oficial advanced-delegation:

  • model_map — listas opciones con nombre (fast, deep, …), cada una con una descripción de una línea más un provider y un modelo, y es el modelo quien elige una por tarea;
  • profile_routes — cada tarea corre como uno de tus profiles de Hermes, con el modelo, las credenciales, las skills y la persona de ese profile.
delegation:
  backend: model_map
  backends:
    model_map:
      options:
        - name: fast
          description: Cheap and quick; lookups, summaries, simple edits.
          provider: openrouter
          model: google/gemini-3-flash-preview
        - name: deep
          description: Slow and careful; hard debugging and design work.
          provider: anthropic
          model: claude-opus-5
          reasoning_effort: high
          service_tier: fast      # opcional; se rechaza al arrancar si esta ruta no tiene nivel fast
      default: fast                # opcional: opción para las tareas que no fijan ninguna
    profile_routes:                # se lee cuando backend: profile_routes
      profiles:
        - name: coder
          description: Writes and refactors code; runs tests.

Las descripciones no son decoración. El modelo solo ve los nombres y las descripciones que tú configuraste; nunca los campos crudos de provider, modelo o clave. Escribe «Cheap and quick; lookups, summaries» y le estás enseñando cuándo ahorrar; escribe «Slow and careful; hard debugging and design work» y le estás enseñando cuándo gastar.

Core conserva todo el ciclo de vida en cualquiera de los dos casos: spawn, aislamiento, roles leaf/orchestrator, profundidad, concurrencia, unidades en segundo plano, parada del fan-out, resultados, output_schema, progreso. Lo único que se movió fue la decisión de enrutamiento.

Ahora cada resultado enrutado lleva un recibo route

Una tarea que pasó por un backend informa dónde se ejecutó realmente: el backend, el nombre de la opción o del profile, y el provider, modelo, esfuerzo de razonamiento y nivel de velocidad que usó el hijo. Si un provider de fallback tomó el relevo, fallback_activated es true.

Eso importa más de lo que parece. Antes deducías el modelo del hijo a partir de «yo puse delegation.model». Ahora te lo reporta: cuando un lote se vuelve caro de repente, lees el recibo en vez de adivinar.

Los fallos se oyen, nunca un cambio silencioso

Aquí es donde el PR pone casi todo su esfuerzo:

  • Si el backend seleccionado falta (plugin no instalado o deshabilitado) o informa que no puede ejecutarse, delegate_task devuelve un error de herramienta que nombra el backend y la solución (instalar o habilitar el plugin, /delegation default, o hermes config set delegation.backend default). No arranca ningún subagente, y los hijos nunca corren en silencio por la ruta por defecto.
  • Dentro de un lote, una tarea que su backend no puede enrutar — una opción desconocida, un parámetro que el backend elegido no acepta, un profile que no existe, un service_tier que la ruta no ofrece, un reasoning_effort desconocido, credenciales ausentes — se rechaza sola. Su entrada de resultado tiene status: "error", el motivo y route.refused: true; las hermanas siguen corriendo.
  • La llamada solo se convierte en error de herramienta cuando se rechazaron todas las tareas.
  • Una ruta de modelo sin sus propios fallback_providers hereda delegation.fallback_providers; fallback_providers: [] en la ruta desactiva el fallback para ella. Una ruta de profile usa la cadena de fallback propia de ese profile.

Un límite que conviene conocer: mientras model_map o profile_routes está activo, delegation.model y delegation.provider quedan inactivos: mandan las rutas. No configures opciones y luego te preguntes por qué el fijado antiguo dejó de importar.

Cambiar, y volver a cambiar

Ambas estrategias, el comando de barra /delegation y hermes delegation config (crear, editar y borrar rutas de modelo, elegir profiles) vienen en el plugin oficial:

hermes plugins search advanced-delegation
hermes plugins install advanced-delegation
hermes plugins enable advanced-delegation

Luego cambiar no requiere editar archivos:

/delegation model_map               # solo esta sesión
/delegation profile_routes --global # escribe delegation.backend en config.yaml
/delegation default                 # vuelve a la estrategia por defecto

Hay un matiz que la documentación señala explícitamente: cambiar de backend dentro de la sesión cambia el enrutamiento, no el esquema de la herramienta. Los parámetros por tarea (option, profile) forman parte del prompt en caché y siguen a config.yaml, así que cambian en la sesión siguiente. Hasta entonces el modelo puede seguir enviando el parámetro del backend anterior: un option: fast después de pasar a profile_routes. Esa tarea se rechaza por su cuenta, con la solución en el mensaje: /delegation <backend> --global y luego /new (porque /new arranca con el backend guardado), o /delegation <saved backend> para volver. Nunca se ejecuta por la ruta por defecto del nuevo backend solo para seguir adelante.

Sin el plugin, hermes config set delegation.backend default restaura el comportamiento anterior.

Qué estrategia encaja

  • model_map — un solo juego de credenciales, dinero repartido por dificultad. Las tareas ligeras van a un modelo barato, las difíciles a uno fuerte. Encaja en lotes cuyas subtareas varían muchísimo en dificultad: arreglar diez issues en una sola pasada, lanzar veinte hilos de investigación.
  • profile_routes — el hijo cambia de identidad. Cada profile lleva su propio modelo, pool de credenciales, SOUL.md y política de terminal, lo que encaja con «estos subagentes deberían correr con permisos distintos», por ejemplo mantener el trabajo de código dentro de una política de terminal restringida.

Un aviso viene directo de la documentación y merece citarse: incluir un profile en delegation.backends.profile_routes permite que los subagentes de este profile usen las credenciales, el pool de credenciales, el SOUL.md y la política de terminal de ese profile. Incluye solo los profiles cuyas claves y cuyo acceso a terminal te parezca bien que este agente use.

Estado del lanzamiento

El PR #142563 se fusionó en main el 22 de octubre de 2026. El siguiente, #142564, mueve la propia estrategia por defecto a un plugin incluido, y #143126 añade los ajustes de delegación en el escritorio (selector de modo, editor de rutas de modelo, rutas de profile). El lanzamiento más reciente es v0.22.4, del 21 de octubre, así que hoy todo esto está solo en main y llega al canal estable con la próxima versión. Si te pasas ahora, ojo con el canal: las versiones de parche todavía no lo traen.

Si aún no has usado el control en vivo de subagentes (list/steer/stop), empieza por la guía de orquestación de subagentes. Para la sección completa de delegation, la referencia de hermes config es más rápida que leer el código. La otra mitad del enrutamiento por modelo está en la guía de model_overrides, y la instalación de plugins se cubre en la guía del catálogo de plugins.