Questa è la prima di una serie di note di progettazione sugli agenti a lungo orizzonte, nate da una lettura approfondita di BEACON (Università di Zhejiang, arXiv:2605.06078).
Perché un agente regga durante un’attività lunga, pensiamo che debbano funzionare bene due cose:
- Deve continuare a progredire verso l’obiettivo. Questo comprende la compattazione del contesto (che cosa si può dimenticare senza rischi), la progettazione dei traguardi (come sapere che un passaggio è davvero completato) e la prevenzione degli stalli (quando si blocca, qualcosa deve accorgersene).
- Deve saper riflettere e migliorare.
Questo articolo tratta la prevenzione degli stalli, perché è quella che ci è costata di più.
Il sintomo
Ce lo avevano segnalato gli utenti e lo avevamo visto anche internamente: alcune attività molto lunghe smettono di avanzare a un certo punto.
Guardando i log, l’agente è indaffarato: legge file, effettua ricerche, esegue comandi, non resta mai inattivo. Ma mezz’ora dopo non è avanzato nulla.
La nostra prima spiegazione era la perdita di contesto: la compattazione aveva eliminato l’informazione che una strada fosse già stata tentata, quindi l’agente la ripercorreva. Leggendo insieme codice e log, abbiamo scoperto che era solo metà della storia.
Avevamo già delle protezioni, su tre livelli
| Livello | Criterio | Soglie |
|---|---|---|
| Ripetizione esatta | Nome dello strumento + argomenti in forma canonica, identici byte per byte | LOOP_WARN=3 avviso / LOOP_HARD=5 arresto forzato |
| Quasi duplicato | Identico salvo i campi volatili di ID / marca temporale | NEAR_DUP_LOOP_WARN=6 / NEAR_DUP_LOOP_HARD=12 |
| Convergenza dei segnali di attività a vuoto | ≥2 compattazioni e ≥75% del budget del ciclo di chiamate agli strumenti consumato | SPIN_CONVERGENCE_MIN_COMPACTIONS=2SPIN_CONVERGENCE_TOOL_LOOP_RATIO=0.75 |
Il commento su quel terzo livello recita, testualmente: Segnale composito «potrebbe girare a vuoto dopo una perdita di contesto». Qualcuno aveva già previsto il problema. Quindi il problema non è mai stato l’assenza di protezioni, ma il fatto che quelle costruite non riuscissero a intercettarlo.
Il punto cieco: tutti e tre i rilevatori guardano gli input
La firma su cui si basa ogni livello è tool name + canonicalized args. Risponde a una sola domanda: stai facendo la stessa cosa due volte?
Ma un modello capace, quando si blocca, non ripete le chiamate. Fa questo:
leggere il file A → grep X → rileggere A con un intervallo di righe diverso
→ eseguire un comando leggermente diverso → leggere il file B → usare di nuovo grep …Ogni chiamata ha una firma diversa. Tutti e tre i livelli restano in silenzio. E per tutto quel periodo il numero di cambiamenti di stato verificabili è zero: nessun file effettivamente riscritto, nessun comando che produca un risultato nuovo, nessun evento irreversibile.
Rilevare i cicli ripetitivi non significa rilevare gli stalli. Nel primo caso si osservano gli input. Nel secondo bisogna osservare gli output.
Lo studio fornisce proprio questa definizione basata sugli output
La ricompensa all’interno del segmento in BEACON:
r_t = R_ms · γ^(t_k − t) if the segment ends in a milestone
= 0 otherwiseUn segmento che non termina con un traguardo guadagna esattamente zero, indipendentemente dal numero di azioni che contiene. Il conteggio delle azioni non entra mai nella formula. È la formalizzazione più limpida di essere indaffarati ≠ progredire che abbiamo visto.
Il livello della baseline è ancora più severo. La baseline è il rendimento medio del gruppo per passo, quindi un segmento che ha richiesto 8 passi, quando la media del gruppo era 5, vede il suo intero vantaggio spostato verso valori negativi, e la penalità cresce con lo sforamento. Girare a vuoto non è soltanto privo di ricompensa: viene penalizzato attivamente e in modo proporzionale.
La Figura 8 dello studio mostra una traiettoria fallita in cui le ultime due azioni ricevono un identico −2.20. Quella coda, il tratto dopo l’ultimo traguardo che non ne raggiunge mai un altro, è la forma matematica del girare a vuoto. Ed è comune: le traiettorie che completano almeno un sotto-obiettivo ma falliscono l’attività restano stabilmente al 39–47% dei campioni.
Un esperimento di ablazione esclude le attivazioni basate sul conteggio dei passi
| Suddivisione | Punteggio | Rispetto alla baseline (72.8) |
|---|---|---|
| Suddivisione casuale in 5 parti | 74.2 | +1.4 |
| Traguardi reali | 91.4 | +17.2 |
Suddividere in base a un numero arbitrario di passi serve a poco o nulla. Suddividere in base alla struttura reale serve molto.
Ora ripensiamo al criterio del nostro terzo livello: 75% del budget del ciclo di chiamate agli strumenti consumato. È una condizione di attivazione basata su un conteggio arbitrario dei passi. Chiede quanto hai consumato, non che cosa hai ottenuto. La forma corretta è:
✗ if steps > N → intervene
✓ if steps > N AND zero verified milestones → interveneLa seconda non scatterà a sproposito durante un’attività legittimamente lunga che sta avanzando, perché un’attività del genere raggiunge traguardi lungo il percorso. La prima sì.
C’è anche un ciclo di retroazione positiva
Mettiamo le costanti una accanto all’altra. La compattazione scatta all’82% della finestra di contesto. Il rilevatore di convergenza dei segnali di attività a vuoto richiede due compattazioni più il 75% del budget del ciclo prima di attivarsi.
girare a vuoto → il contesto si riempie → scatta la compattazione → il riepilogo perde lo stato duraturo
→ ricostruire ciò che è andato perso → continuare a girare a vuotoIl rilevatore deduce che l’agente sta girando a vuoto osservando che la compattazione si è verificata ripetutamente, ma la compattazione è proprio il passaggio che causa l’amnesia. Sta rilevando un sintomo a valle e deve aspettare che il ciclo si ripeta due volte.
Peggio ancora, il suo intervento consiste nello spingere il modello a riancorarsi al proprio stato persistente. Se è proprio lo stato persistente a essere stato eliminato dalla compattazione, non resta nulla a cui riancorarsi. È una correzione a livello di prompt per un problema a livello di stato.
Che cosa stiamo aggiungendo: il rilevamento degli stalli basato sugli output
Un quarto livello, costruito su due contatori. Entrambi sono ricavati meccanicamente dalle osservazioni degli strumenti che il sistema ospitante registra già; nessuno dei due richiede il giudizio del modello.
Passi dall’ultimo traguardo verificato. La metrica di avanzamento più semplice possibile, usata nel criterio composito descritto sopra anziché da sola.
Nuovi cambiamenti di stato deduplicati. Il più utile dei due:
- La lettura di un file il cui hash del contenuto coincide con quello di una lettura precedente non fornisce informazioni nuove: rileggere lo stesso file su un diverso intervallo di righe lascia invariato l’hash.
- Un comando il cui nome, codice di uscita e hash dell’output coincidono tutti con quelli di un’esecuzione precedente non fornisce informazioni nuove.
- Una scrittura in cui l’hash successivo è uguale a quello precedente significa che non è stato scritto nulla di fatto.
Questo contatore prende di mira esattamente il caso che il confronto delle firme non intercetta: ogni azione è diversa, il guadagno informativo è zero. Il criterio è meccanico e non richiede comprensione semantica.
Poi la pressione dovrebbe essere continua, anziché limitarsi a un singolo richiamo:
mostrare il contatore nel contesto perché il modello possa vederlo
→ imporre una revisione del piano (ammettere che questa strada è senza uscita)
→ chiedere all’utente
→ interrompere, conservando però i traguardi già raggiuntiQuest’ultimo gradino conta. Se l’esecuzione deve fermarsi, dovrebbe farlo conservando quanto ha ottenuto: proprio quel 39–47% di progressi parziali che lo studio ha misurato e che viene scartato.
Che cosa non ci dà lo studio
BEACON è un metodo di addestramento. Modella i gradienti affinché la politica addestrata sia meno incline a vagare, ma non ha alcun meccanismo proprio di rilevamento o intervento durante l’esecuzione. Fornisce una definizione di progresso, non un controllore. Soglie, livelli di escalation e condizioni di interruzione spettano a noi.
La sua baseline per passo richiede anche una lunghezza media dei segmenti del gruppo come riferimento. In produzione, una determinata attività dell’utente viene di solito eseguita esattamente una volta, quindi non esiste un gruppo. Il miglior sostituto disponibile sono le statistiche storiche su attività simili, che sono notevolmente più rumorose e non offrono alcuna delle garanzie di isolamento della varianza dello studio.
La prima mossa è misurare, non correggere
Prima di cambiare qualsiasi logica decisionale, vogliamo aggiungere strumenti di misurazione e rispondere a una domanda a cui oggi non sappiamo rispondere: degli stalli che si verificano in produzione, quanti sono dovuti all’amnesia e quanti all’assenza di gradiente?
- Perlopiù accompagnati da guadagno informativo pari a zero mentre tutte le firme delle chiamate sono diverse → tipo senza gradiente. I tre livelli esistenti non possono strutturalmente intercettarli, e la soluzione è il rilevamento basato sugli output.
- Perlopiù accompagnati dalla rilettura di contenuti già eliminati dalla compattazione → tipo amnesia. Va corretto ciò che la compattazione conserva.
Queste due conclusioni richiedono investimenti completamente diversi. Misurare prima costa meno che progettare prima, e la strumentazione è quasi gratuita perché le osservazioni esistono già.
Tutto quanto descritto sopra dipende da un concetto su cui questa nota si è basata senza definirlo: un traguardo verificato. La prossima nota parla proprio di questo. Perché dichiarare un passaggio completato non dimostra che lo sia, quali due metà esistono già nel prodotto senza essere mai state collegate e un criterio che lo studio non contempla: guardare all’irreversibilità, non all’importanza.