La maggior parte degli agenti IA gira un turno alla volta. Tu scrivi, loro rispondono, loro aspettano. Il loop lo fai tu. L'agente non è altro che una chiamata di funzione.
Hermes Agent ha questa modalità — è quella di default. Ma ne porta dentro anche un'altra, chiamata /goal, dove il loop lo fa l'agente. Tu metti un obiettivo più i criteri di successo, e l'agente propone, esegue, valuta, riprova, e continua finché un judge LLM a parte non accetta che i criteri sono stati soddisfatti. v0.14.0 (16 maggio 2026) ha aggiunto /subgoal perché tu possa impilare criteri ulteriori su un loop già in corsa senza riavviarlo (#25449).
Questo post scompone quello che succede davvero, quando è lo strumento giusto e quali sono i modi di rottura che lo rendono quello sbagliato.
La modalità di default (per fare contrasto)
Ogni sessione di chat in Hermes è un turno per messaggio utente. L'agente legge il tuo messaggio, chiama tool se serve, e restituisce una risposta. Se il task non è finito, devi punzecchiarlo: "vai avanti", "riprova", "e per X?". Il loop esterno lo fai tu.
Va benissimo per il lavoro esplorativo — "spiegami questo codice", "buttami giù una nota", "trovami un bug". Vuoi che l'agente si fermi dopo ogni passo così tu puoi cambiargli direzione.
Non va per task in cui la condizione di successo è concreta e il percorso per arrivarci è iterativo. "Refattorizza questo modulo finché pytest non passa" è un task da trenta turni se sei tu a guidare ogni turno. Con /goal è un singolo comando.
Cosa fa davvero /goal
/goal Make all tests in tests/api/ pass. Don't change the test assertions. Done when pytest exits 0.
Quando mandi quella riga, succedono tre cose:
- 1.Il testo dell'obiettivo diventa il prompt target del worker. A ogni turno successivo, il modello worker riceve un system message che include l'obiettivo e il miglior tentativo attuale.
- 2.Dopo ogni turno del worker parte una chiamata LLM "judge" separata. Il judge vede l'obiettivo, lo stato corrente e il completamento proposto. Restituisce o "done" (loop esce) o "vai avanti, manca questa cosa".
- 3.Il loop continua finché il judge non dice done — o finché non lo fermi con
/stop, o finché non sbatte contro il limite di iterazioni configurato.
Il judge è il pezzo chiave. Non è la stessa chiamata LLM del worker, e non vede la catena di pensieri — solo l'obiettivo e lo stato corrente. È quella separazione che fa funzionare /goal: un modello worker che si è già convinto che la sua risposta è giusta è un cattivo giudice. Una chiamata LLM fresca senza contesto è molto meglio.
Questo pattern, all'interno del codebase di Hermes, si chiama "Ralph loop", dal pseudocodice canonico while not done: do(work); ralph = judge(work). L'estensione /subgoal di v0.14.0 fa sì che l'utente possa iniettare nuovi criteri del judge dentro un loop in corsa.
/subgoal — aggiungere criteri in volo
Hai avviato un /goal per refattorizzare un modulo. Tre loop dentro ti rendi conto che vorresti anche che il refactor tenesse la complessità ciclomatica sotto 10 per funzione. Non vuoi fermare il loop e ripartire.
/subgoal Each function must have cyclomatic complexity <= 10.
Al prossimo passaggio del judge, quel nuovo vincolo entra nei calcoli. Se il miglior tentativo attuale lo manca, il loop continua. Se lo passa, il loop esce.
È quel tipo di feature che, dentro una bullet di release notes, sembra piccola — "criteri aggiunti dall'utente accodati a un /goal attivo" — e poi diventa una trave portante per chiunque usi il loop davvero. Gli obiettivi veri si raffinano mentre guardi l'agente lavorare. Senza /subgoal, l'unico modo per raffinare era /stop + ridefinire + /goal di nuovo, perdendo lo stato in corsa.
Esempi pratici
Refattorizzare finché i test non passano
/goal Refactor src/api/users.py so the User class follows the new naming convention in src/conventions.md. Don't break any existing tests. Done when:
1. pytest exits 0
2. The User class matches the convention rules in conventions.md
Il worker prova vari refactor, il judge controlla le due condizioni. Quando entrambe sono al verde, il loop esce.
Iterare su una UI
/goal Make the button on /pricing more prominent. Done when:
1. The button is the largest interactive element above the fold on desktop
2. It uses the primary brand color (#FF5A50)
3. Existing Lighthouse accessibility score doesn't drop
Il worker modifica il CSS, il judge fa uno screenshot tramite il tool browser e controlla. Si fanno parecchie iterazioni senza che tu debba stare lì a fare da balia.
Stanare un bug
/goal Find the cause of the intermittent test failure in tests/auth/test_session.py::test_logout_clears_cookie. Done when you produce a minimal failing repro and a one-paragraph explanation.
Il judge qui sta controllando che entrambe le parti del deliverable ci siano — riproduzione minimale e spiegazione — non solo che una delle due sia atterrata. /subgoal ti lascia aggiungere un vincolo del tipo "la spiegazione deve far riferimento al ciclo di request/response interessato" se la prima bozza è troppo vaga.
Quando non usarlo
/goal è lo strumento sbagliato per task dove:
- •La condizione di successo è sfocata. "Rendilo più elegante" — il judge non riesce a valutarlo in modo coerente, quindi il loop oscilla o timbra il cartellino. Qui si va in turno-per-turno.
- •Vuoi vedere il lavoro mentre succede. Ogni iterazione gira fino a completamento prima che il judge spari, quindi non hai la stessa visibilità per turno. Se ti serve revisione a metà strada, vai di turno-per-turno o
/handoff. - •Il costo ti interessa più della velocità. Ogni iterazione di loop è una chiamata worker più una chiamata judge. Per un obiettivo da 10 iterazioni, paghi 20 chiamate LLM. Vale la spesa per il lavoro di refactoring ; è uno spreco per "come chiamo questa variabile?".
- •Non hai riflettuto sui criteri di successo. Criteri spazzatura → loop spazzatura.
/goalpremia la precisione, e l'agente sfrutterà qualsiasi ambiguità.
Come /goal si sposa con /handoff
v0.14.0 ha sganciato anche /handoff, che trasferisce una sessione viva tra modelli senza perdere contesto (#23395). I due si combinano: puoi passare un goal in corsa da un modello veloce a uno di reasoning profondo quando il goal sbatte contro qualcosa che il veloce non risolve. Il judge continua a valutare gli stessi criteri ; è solo il worker che è migliorato.
Stessa cosa con /sessions (#20805) — puoi interrompere un goal, andare a sbirciare in un'altra sessione, e riprendere il goal più tardi. Lo stato del loop è in checkpoint.
Dove sta dentro lo stack dell'agente
Tre forme diverse di lavoro autonomo, in ordine crescente di quanto guidi l'agente:
- 1.Turno-per-turno — tu guidi, l'agente risponde. Conversazionale.
- 2.
/goal— tu metti i criteri, l'agente cicla finché non li soddisfa. Autonomia delimitata. - 3.Schedulazione cron — l'agente gira senza presidio su un orario, con consegna alle piattaforme di messaggistica. Autonomia senza confini nel tempo.
/goal è quello in mezzo. È la stoffa giusta per una categoria di task che prima richiedeva o babysitting pesante o uno script su misura. Il /subgoal di v0.14.0 rende il loop governabile in corsa, ed è quello che lo fa passare da curiosità a strumento di tutti i giorni.