/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) |
| Tú | /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 statusmuestra la cadencia, los ticks disparados y el tiempo hasta el siguiente wakeup;/loop pause/resume/stopcubren 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:
- 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.
- Estado persistido: el estado del loop vive en
SessionDB.state_metabajoloop:<session_id>, así/resumerecupera 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). - Todas las superficies: CLI, TUI, dashboard, app de escritorio y todas las plataformas de mensajería del gateway — un
loop_wakeup_watchersupervisado 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). - El apartado de Slack: Slack tiene un límite de 50 comandos de barra, así que Hermes movió
/versiona/hermes versionpara 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.