Come debuggare Hermes Agent: log, trace, buchi
Guida pratica al debug di Hermes Agent: dove stanno i log, quale aprire per primo, come leggere una trace tree e dove l'observability zoppica ancora.
Il tuo agente ha fatto una cosa strana. Dove guardi?
Hermes Agent ha due modalità di fallimento, dolorose ciascuna a modo suo. La prima è rumorosa: un'eccezione con stack trace o un crash all'avvio. La seconda è silenziosa: l'agente produce una risposta coerente ma sbagliata, chiama lo strumento sbagliato o si spegne dopo il risultato di un tool. Quello rumoroso finisce in errors.log. Quello silenzioso è il debug difficile e vive nell'audit log della sessione precisa che è deragliata.
Questa è una mappa pratica di dove stanno i log, quale file corrisponde a quale sintomo e dei piccoli strumenti attorno che trasformano 800 righe di JSONL in qualcosa che riesci davvero a leggere. Nomina anche i buchi che restano aperti, così sai cosa Hermes oggi non ti dirà.
Dove vivono i log
Tutto ciò che Hermes scrive atterra nella tua directory Hermes, di default ~/.hermes/logs/ (e in <profile>/logs/ per profili non predefiniti). Contano quattro file:
| File | Livello | Contenuto |
|---|---|---|
agent.log |
INFO+ | Attività principale di agente, strumenti e sessioni. Punto d'ingresso di default. |
errors.log |
WARNING+ | Solo warning ed errori. Triage rapido per "qualcosa si è rotto". |
gateway.log |
INFO+ | Solo eventi del gateway, ciclo di vita di sessione per utente su Telegram/Discord/Slack. |
gui.log |
INFO+ | Dashboard, websocket ed eventi del TUI-gateway. |
Tutti e quattro sono scritti dal RotatingFileHandler di Python. Quando un file raggiunge il limite di dimensione, ruota a agent.log.1, agent.log.2, e così via fino al backup_count configurato. Il file attivo è sempre quello senza suffisso. Questo conta quando insegui un bug di ieri, perché "ieri" potrebbe essere già ruotato. Prendi anche i file numerati, non solo quello corrente.
Il punto d'ingresso di tutto è hermes_logging.setup_logging(). Il gateway lo chiama con mode="gateway" all'avvio e collega solo handler di file, mai un handler di console. Perciò hermes gateway start è silenzioso per design. Se il tuo gateway sembra morto, non lo è. Fai un tail su gateway.log.
Quale log aprire per primo
Il sintomo sceglie il file, non il contrario. Un albero decisionale rapido:
- L'agente è crashato all'avvio, o una request restituisce 500. Apri
errors.logconhermes logs errors --since 30m -f. Gli stack trace atterrano qui per primi. - L'agente ha risposto, ma la risposta è sbagliata. Salta
errors.log. Le tool call che hanno prodotto quella risposta stanno nel transcript JSONL di quella sessione (vedi la sezione successiva su trace-tree). - Un utente Telegram o Discord dice "è diventato muto". Apri
gateway.loge filtra sulla sua sessione.hermes logs gateway --session abc123restringe. - Il dashboard non si aggiorna.
gui.log. Le disconnessioni websocket e gli errori di sync del TUI-gateway compaiono qui prima che altrove. - Non sai cosa stia succedendo, punto.
hermes logs -fsuagent.logcon un secondo pannello suerrors.log. La stragrande maggioranza delle risposte a "cosa sta facendo il mio agente" è a untail -fdi distanza.
La CLI hermes logs è la tua alleata. Alcune flag si guadagnano lo stipendio in una sessione di debug live:
hermes logs # ultime 50 righe di agent.log
hermes logs -f # segue agent.log in tempo reale
hermes logs gateway -n 100 # ultime 100 righe di gateway.log
hermes logs --level WARNING --since 1h # ultima ora, warning ed errori
hermes logs --session abc123 # restringe a un id di sessione
hermes logs errors --since 30m -f # segue gli errori da 30 min
hermes logs list # inventario dei file e dei loro pesi
Leggere una sessione come un albero, non come un muro di JSONL
Quando una sessione finisce, la sua traiettoria completa viene scritta come JSON per riga nel file di transcript. È l'artefatto più utile per debuggare la classe di bug "coerente ma sbagliato", perché ogni chiamata al modello, ogni tool call e ogni risultato vengono catturati in ordine con i loro argomenti. Ed è, in forma grezza, illeggibile. 800 righe di audit log per una sessione mediamente complessa è la norma.
Lo strumento community trace-tree (vedi il post di Mukunda Katta su dev.to) legge quel JSONL e stampa un albero nel terminale. Una sessione diventa la radice, ogni tool call è un figlio, le chiamate negate compaiono come figli con l'errore allegato. La apri, leggi l'albero, la chiudi. Nessun login, nessun upload, nessun vendor lock-in. Puntalo a un file di sessione:
trace-tree ~/.hermes/logs/sessions/2026-07-21T09-42-11.jsonl
Per diagnosi più profonde puoi anche pipare lo stesso JSONL in jq e filtrare per nome tool, latenza o stato di errore. I transcript sono stabili tra versioni in un modo in cui agent.log non lo è, quindi costruisci le tue query ad hoc contro il transcript, non contro un grep sul log leggibile.
Per l'indagine collegata "l'agente è muto, sarà bloccato?" sui canali di messaggistica, la nostra guida di troubleshooting Telegram percorre prima i sintomi lato consegna (bot token, webhook, permessi di gruppo), che spesso si rivelano la causa reale prima ancora di aver bisogno della trace tree.
Alzare il livello di log senza far uscire segreti
Il verbose mode è a una flag di distanza. hermes chat --verbose (o -v) imposta verbose_logging=True su AIAgent, che chiama setup_verbose_logging() e aggiunge uno StreamHandler di console a livello DEBUG sopra agli handler di file. Vedi tutto ciò che vede l'agente, live.
Il dettaglio critico è che ogni record di log, a qualsiasi livello, passa attraverso il RedactingFormatter di agent/redact.py prima di essere scritto. Il formatter riconosce forme note di credenziali (sk-, sk-or-, sk-ant-, pattern OAuth comuni e segreti in stile variabile d'ambiente) e sostituisce il valore inline. In pratica significa che puoi alzare il livello di log in produzione, o incollare un agent.log redatto in un bug report, senza far trapelare la tua chiave OpenRouter.
C'è una trappola che vale la pena nominare. Se scrivi un tuo logger o un tuo formatter e salti la pipeline, la redaction non si applica. Il crash all'avvio del gateway NameError: name 'RedactingFormatter' is not defined segnalato come issue #8090 è la stessa classe di errore al contrario. Considera il formatter come critico, non aggirarlo, e se scrivi logging personalizzato, avvolgilo attraverso hermes_logging.setup_logging(), non attorno.
I buchi di observability ancora aperti
Hermes è onesto su ciò che ancora non fa. Due feature request aperte descrivono il tetto attuale:
- Span strutturati con timestamp di inizio e fine. Oggi la maggior parte delle righe di log porta un singolo timestamp e alcuni output di tool includono un
duration_secondsad hoc. Non c'è uno schema stabile perstart_ts,end_ts,duration_mseparent_idsu tutta la traiettoria. È l'issue #6741, e blocca le dashboard pulite di latenza per tool che vorrai quando una sessione rallenta. - Attach live a una sessione di gateway in corso. Nella release corrente, una volta che una sessione di gateway è in esecuzione non puoi osservarla in tempo reale dall'esterno.
agent.logrecupera quando la sessione termina, ma non c'è un hook "guarda la sessione di questo utente mentre accade". È l'issue #18127, ed è il buco più grande per chi fa girare Hermes come servizio condiviso.
Due workaround coprono parte del buco nel frattempo. Il primo è tracing in stile OpenTelemetry verso un backend come SigNoz, che ti fa tradurre l'attività di Hermes in span a valle anche senza emissione nativa. Il secondo è Langfuse (issue #1501), che alcuni team cablano per turno come layer di strumentazione manuale. Nessuno è ufficialmente first-class ancora, ma entrambi girano in produzione da qualche parte oggi.
Quando preferisci non possedere proprio il layer dei log
Tutto quanto sopra assume che l'agente lo esegui tu. Se è proprio la parte che preferiresti delegare, Hermify gestisce un Hermes Agent per te su Telegram, con lo stesso logging e audit trail disponibili sul container sottostante. Tieni la memoria persistente, i transcript di sessione e la possibilità di far salire un problema specifico da noi, senza dover tenere hermes logs -f aperto sul tuo VPS. Se sei indeciso tra self-hosted e un setup gestito per motivi che includono il carico operativo dell'observability, la nostra analisi su Hermes gestito rispetto al self-hosted copre i compromessi per intero.
Inizia con Hermify e salta del tutto il lavoro di rotazione dei log e di observability. Oppure tieni i log in locale e usa questa guida la prossima volta che il tuo agente diventa muto. Entrambe le strade sono valide, e lo stesso audit trail è disponibile su entrambe.
Sources
- Chapter 9: Observability and Debugging (Claude Code vs. Hermes Agent) - Ken Huang
- Put a Microscope on Hermes: Full Visibility into Agent Execution - Alibaba Cloud
- I had 800 lines of Hermes agent audit log. trace-tree turned it into a tree I could read.
- hermes-agent/hermes_logging.py source
- Issue #18127: Observability for in-flight gateway sessions
- Issue #6741: Structured session tracing with start/end timestamps
- Hermes Monitoring and Observability with OpenTelemetry - SigNoz
Avvia il tuo Hermes Agent
Porta la tua chiave API, collega Telegram e ottieni un agente IA che migliora da solo, online in 60 secondi.
Inizia ora