/loop: los wakeups recurrentes de Hermes dentro de la sesión — timer-driven, ni judge-driven ni cron


El script de despliegue terminó, pero no puedes alejarte: ¿el CI se pondrá en rojo? ¿Se acumulará la cola? ¿Cuándo estará el servicio realmente en línea? Así que refrescas la página cada cinco minutos como un centinela obediente.

El nuevo comando /loop de Hermes existe para quitarte ese turno de centinela: re-ejecuta un prompt con una cadencia recurrente dentro de tu sesión, despertándose en cada tick para trabajar contra el estado actual. Es la versión de Hermes del /loop de Claude Code (el alias /proactive también funciona), recién integrado en main. Este post lo explica como corresponde: qué lo separa fundamentalmente de /goal y de cron, y cómo usarlo de verdad.

Tres comandos, tres motores

Comando Motor Ciclo de vida Uso típico
/goal Judge-driven — después de cada turno un modelo juez comprueba “¿ya está hecho?”, y Hermes sigue trabajando si no lo está Sesión única, a lo largo de los turnos “Arregla todos los errores de lint en src/ y verifica que la comprobación pasa”
/loop Timer-driven — despierta con una cadencia, hace el trabajo, hasta que algo diga para Sesión única, a lo largo de los turnos y de los resumes “Comprueba el despliegue cada 5 minutos y avísame cuando esté en vivo”
cron Schedule-driven — horario fijo, sin sesión implicada Fuera de todas las sesiones, sin supervisión “Publica un digest diario en el canal a las 9 de la mañana”

/goal significa “sigue trabajando hasta lograr el objetivo”, /loop significa “sigue comprobando hasta que algo diga para”, cron significa “ejecutar según un horario, sin relación con la conversación”. Tres herramientas que no se solapan.

Dos modos de cadencia: pones tú el reloj, o se marca su propio ritmo

Intervalo fijo — tu reloj

/loop 5m check the deploy status and tell me if it's live yet

Cada 5 minutos (mientras la sesión esté inactiva) Hermes inyecta un turno real del agente contra el estado actual: el último resultado del CI, la profundidad más reciente de la cola, el archivo tal y como está ahora.

Self-paced — se vuelve más listo cuanto más espera

Omite el intervalo y Hermes se marca su propio ritmo:

/loop keep an eye on the migration and summarize progress

El mecanismo es ingenioso: arranca en el suelo de 60s y, mientras las respuestas del agente dejen de cambiar, hace backoff exponencial (2m → 4m → 8m … hasta el techo de 15 minutos). En cuanto una respuesta difiere, la cadencia vuelve de golpe al suelo. La detección de cambios es una comparación de digest local, insensible a las marcas de tiempo — cero coste adicional de LLM. Cuanto más calmadas estén las cosas, menos te molesta; en cuanto hay progreso, se acerca.

Regla práctica: intervalo fijo cuando un reloj externo marca el ritmo del trabajo; self-paced cuando es el trabajo el que marca el ritmo.

Condiciones de parada: cinco salidas

Condición Cómo
El agente decide que ha terminado Respuestas de wakeup que terminan con LOOP_COMPLETE en su propia línea
Un límite de ejecuciones --times N (p. ej. --times 30)
Una condición basada en evidencias --until <condición> — juzgada por el mismo juez auxiliar que impulsa /goal (fail-open: un juez roto nunca atasca el loop)
/loop stop (o /loop pause para mantenerlo activo)
El presupuesto de seguridad loops.max_ticks (por defecto 100; 0 = ilimitado), para que una sesión sin supervisión no queme tokens eternamente
/loop 2m poll CI --times 30
/loop 5m watch the queue --until "queue depth reaches zero"

Control y composición

  • /loop status muestra la cadencia, los ticks disparados y el tiempo hasta el siguiente wakeup; /loop pause / resume / stop cubren todo el ciclo de vida (Ctrl+C durante un wakeup pausa el loop, recuperable con /loop resume).
  • Haz un loop de un comando de barra igual de fácil: /loop 10m /recap.
  • Trabajando con /goal: un goal activo y no aparcado es dueño del límite de inactividad — los ticks del loop se difieren hasta que el goal termina, se pausa o se aparca (un wait barrier). Un goal aparcado más un heartbeat de loop se compone de forma natural. La entrada real del usuario siempre se antepone a ambos — en cuanto escribes, los dos se apartan.

Por qué no se cae: la arquitectura

Esta es la parte que merece la pena entender de verdad — /loop no es un bucle while true:

  1. Inyección de turnos user-role ordinarios: cada wakeup es un mensaje normal con rol de usuario. Sin mutación del system prompt, sin intercambio de toolset, el prompt cache se mantiene intacto — hacer loops no destruye tu caché ni malgasta tokens.
  2. Estado persistido: el estado del loop vive en SessionDB.state_meta bajo loop:<session_id>, así /resume recupera el loop y migra a través de la compresión de contexto (el mismo mecanismo que /goal, con el peligro conocido corregido de forma preventiva).
  3. Todas las superficies: CLI, TUI, dashboard, app de escritorio y todas las plataformas de mensajería del gateway — un loop_wakeup_watcher supervisado escanea los loops persistidos e inyecta los wakeups pendientes en chats inactivos incluso mientras estás fuera. Eso es algo que Claude Code no puede hacer (su loop muere con la sesión de CLI).
  4. El apartado de Slack: Slack tiene un límite de 50 comandos de barra, así que Hermes movió /version a /hermes version para liberar un hueco nativo para /loop.

Comparado con el /loop de Claude Code

Claude Code Hermes
Superficies Solo sesión de CLI CLI, TUI, dashboard, escritorio, todas las plataformas de mensajería
Persistencia Muere con la sesión Sobrevive a /resume y a la compresión de contexto
Ritmo self-paced Decidido por el modelo Backoff de digest local (gratis, determinista)
Condiciones de parada Incrustadas en el prompt LOOP_COMPLETE + --times + --until juzgado + presupuesto de seguridad
Interacción con /goal Funciones separadas Precedencia explícita: un goal activo es dueño del límite de inactividad

¿Cuál quiero?

  • Vigilar estado externo (despliegue, CI, cola, tasas de error) → /loop (fijo o self-paced)
  • Un objetivo bien hecho (arreglar todos los lints, dejar el CI en verde) → /goal (ver Heartbeats, Refinement & Goal Gates)
  • Trabajos programados sin supervisión (digests diarios, ejecuciones nocturnas) → cron (guía completa: The Hermes Cron Automation Guide)

Estado del lanzamiento y cómo obtenerlo

/loop se integró en main el 14 de agosto de 2026 (PR #72333, con 77 tests nuevos + 367 tests de regresión + 22 tests de escritorio, todos en verde). Todavía no está en ningún lanzamiento oficial (el último sigue siendo v0.20.1). Para probarlo:

  • Espera al próximo lanzamiento y ejecuta hermes update;
  • O instálalo desde main ahora: hermes update --branch main (vuelve a cambiar cuando salga el lanzamiento).

Claves de configuración opcionales: loops.min_interval_seconds, loops.max_ticks, loops.self_paced_floor_seconds, loops.self_paced_ceiling_seconds.

Resumen

/loop te quita la “vigilancia” de las manos y del refresco manual: intervalos fijos para relojes externos, cadencia self-paced que se vuelve más lista cuanto más espera (backoff cuando hay estabilidad, se acerca cuando las cosas cambian — a coste cero de LLM), persistencia y cobertura de todas las plataformas que superan al original de Claude Code, y cooperación explícita con /goal. En el próximo despliegue, pásale el turno de centinela.