\n\n\n\n Nel Troubleshooting dei miei flussi di lavoro Agentic: Ecco come - AgntDev \n

Nel Troubleshooting dei miei flussi di lavoro Agentic: Ecco come

📖 12 min read2,266 wordsUpdated Apr 3, 2026

Ciao a tutti, Leo qui da agntdev.com. Spero che stiate tutti passando una settimana produttiva!

Oggi voglio esplorare qualcosa che mi occupa molto la mente ultimamente, specialmente mentre gioco con alcuni progetti personali che coinvolgono flussi di lavoro agentici più complessi e multi-passaggio. Parliamo molto di costruire agenti, degli stessi LLM e delle cose interessanti che possono fare. Ma che dire dell’aspetto meno glamour, ma assolutamente cruciale, di assicurarci che i nostri agenti funzionino realmente in modo affidabile ed efficiente nel tempo?

Specificamente, parlo di osservabilità degli agenti. Non si tratta solo di registrazione; si tratta di capire veramente cosa sta facendo il tuo agente, perché lo sta facendo e di rilevare i problemi prima che diventino incontrollabili. In un mondo in cui gli agenti interagiscono con API esterne, prendono decisioni sulla base di input dinamici e potenzialmente lavorano per periodi prolungati, navigare al buio è una ricetta per il disastro. L’ho imparato a mie spese, come spiegherò.

Il “Baco Misterioso” Che Mi Ha Insegnato Tutto

Qualche mese fa, stavo sviluppando un agente assistente personale. Chiamiamolo “Progetto Chronos.” Il suo compito era monitorare il mio calendario, i feed di notizie e specifici canali Slack, per poi suggerire proattivamente orari per le riunioni, riassumere aggiornamenti chiave o persino redigere risposte iniziali a domande comuni. Roba piuttosto standard in superficie.

Lo ho costruito, testato con un paio di scenari e sembrava funzionare bene. L’ho configurato per funzionare durante la notte, pensando che mi sarei svegliato con un riepilogo perfettamente curato. Invece, mi sono svegliato a… nulla. O meglio, a un riepilogo parziale che si è interrotto bruscamente, seguito da un messaggio di errore criptico nei log di sistema che diceva essenzialmente “qualcosa si è rotto.”

Il debug di questo è stato un incubo. Chronos doveva fare diverse cose: recuperare eventi dal calendario, interrogare un’API di notizie, colpire un’API Slack, elaborare i dati e poi generare un riepilogo. Quale passaggio ha fallito? Perché? Ha persino tentato tutti i passaggi? Era un limite di frequenza dell’API? Un prompt malformato? Un timeout? Non avevo idea.

La mia registrazione iniziale era basilare: “Inizio passo X,” “Fine passo Y,” e poi l’output finale o un errore. Questo non era sufficiente. Era come cercare di diagnosticare un problema motoristico sapendo solo che è partito e poi si è fermato, senza alcuna informazione sulla temperatura del motore, pressione del carburante o difetti elettrici.

Quell’esperienza ha sottolineato l’importanza: se sei serio nello sviluppo di agenti, hai bisogno di una solida osservabilità fin dal primo giorno. Non è un pensiero secondario; è un componente fondamentale.

Oltre Alla Registrazione Fondamentale: Cosa Significa “Osservabilità” Per Gli Agenti?

Per me, l’osservabilità degli agenti si divide in alcune aree chiave, ognuna delle quali offre una diversa prospettiva sul funzionamento del tuo agente:

1. Tracciamento Esecuzione Passo-Passo

Questo è il più critico. Devi sapere esattamente cosa sta facendo il tuo agente in ogni fase della sua esecuzione. Pensalo come un dettagliato percorso di briciole. Per il Progetto Chronos, avevo bisogno di vedere:

  • Quando ha iniziato a recuperare eventi dal calendario.
  • I parametri utilizzati per la chiamata all’API del calendario (es. intervallo di date).
  • La risposta grezza dall’API del calendario.
  • Come ha elaborato quella risposta.
  • Il prompt esatto inviato all’LLM per riassumere le informazioni del calendario.
  • La risposta dell’LLM.
  • Eventuali strumenti che ha chiamato, con i loro input e output.
  • Messaggi di errore, non solo “qualcosa è fallito,” ma un errore specifico con contesto (es. “L’API del calendario ha restituito 401 Non autorizzato per l’utente X”).

Questo livello di dettaglio è inestimabile per ricreare problemi e comprendere i punti decisionali. I miei log iniziali dicevano semplicemente “Recupero dati dal calendario…” e poi “Riassumendo dati dal calendario…” senza nulla in mezzo. Non è utile quando il recupero dei dati stesso è fallito silenziosamente.

2. Tracciamento Prompt e Risposta

L’LLM è il cervello del tuo agente. Se non sai quali prompt sta ricevendo e quali risposte sta dando, stai navigando al buio. Questo include:

  • Il prompt completo inviato all’LLM (sistema, utente e qualsiasi descrizione di chiamata a funzione).
  • La temperatura, top_p e altri parametri di generazione.
  • La risposta grezza dall’LLM, inclusi eventuali richiami a strumenti che ha deciso di fare.
  • Utilizzo dei token (input, output, totale) per la tracciabilità dei costi e analisi delle prestazioni.

Questo è cruciale per l’ingegneria dei prompt. Se un agente fornisce risposte senza senso, vedere il prompt esatto ricevuto ti aiuta a capire se il contesto dell’input era errato o se il prompt stesso era male strutturato.

3. Monitoraggio Chiamate agli Strumenti

Gli agenti interagiscono spesso con strumenti o API esterne. Ogni interazione è un potenziale punto di fallimento o comportamento imprevisto. Devi registrare:

  • Quale strumento è stato chiamato.
  • Gli argomenti esatti passati allo strumento.
  • L’output grezzo dallo strumento.
  • Eventuali errori restituiti dallo strumento o durante la sua esecuzione.

Per Chronos, se ha provato a chiamare l’API di Slack per postare un riepilogo, avevo bisogno di sapere il canale mirato, il contenuto del messaggio e se l’API ha restituito un errore 403 Vietato, per esempio. La mia configurazione precedente diceva semplicemente “Tentato di postare su Slack.”

4. Snapshot dello Stato

Molti agenti mantengono uno stato interno – un blocco note, una memoria, un elenco di fatti raccolti. Catturare periodicamente questo stato può essere incredibilmente utile per il debug. Se un agente si blocca in un ciclo o prende una cattiva decisione, vedere i suoi “pensieri” interni in vari momenti può rivelare dove la sua comprensione è andata off-track.

Questo riguarda meno la registrazione di ogni singolo cambiamento di variabile e più la cattura di stati decisionali chiave. Per Chronos, questo potrebbe essere “Comprensione attuale del programma dell’utente,” o “Punti chiave dai feed di notizie finora.”

Approcci Pratici: Costruire L’Osservabilità

Ok, quindi come implementiamo effettivamente questo senza affogare nei log? Ecco alcune strategie pratiche e frammenti di codice.

Strategia 1: Registrazione Strutturata con Contesto

Dimentica le istruzioni `print()`. Usa una libreria di registrazione adeguata (come il modulo `logging` di Python). Fondamentale, arricchisci i tuoi messaggi di log con dati strutturati (JSON, dizionari) piuttosto che solo stringhe semplici. Questo rende i log analizzabili, ricercabili e molto più utili.

Ecco un esempio semplificato in Python:


import logging
import json
import uuid
from datetime import datetime

# Configurazione di base del logger (in un'app reale, lo configureresti in modo più solido)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(levelname)s: %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

def log_agent_step(agent_id: str, step_name: str, status: str, details: dict = None):
 log_data = {
 "timestamp": datetime.now().isoformat(),
 "agent_id": agent_id,
 "step_name": step_name,
 "status": status, # ad esempio, "started", "completed", "failed"
 "details": details if details is not None else {}
 }
 logger.info(json.dumps(log_data))

class MyAgent:
 def __init__(self, agent_id: str = None):
 self.agent_id = agent_id if agent_id else str(uuid.uuid4())
 self.memory = [] # Memoria interna semplice

 def _fetch_calendar_events(self, user_id: str, date_range: str):
 log_agent_step(self.agent_id, "fetch_calendar_events", "started", 
 {"user_id": user_id, "date_range": date_range})
 try:
 # Simula una chiamata API
 if "error" in date_range:
 raise ValueError("Errore API calendario simulato")
 
 events = [
 {"title": "Sincronizzazione di Team", "time": "10:00 AM"},
 {"title": "Incontro con il Cliente", "time": "02:00 PM"}
 ]
 log_agent_step(self.agent_id, "fetch_calendar_events", "completed", 
 {"num_events": len(events), "data_preview": events[0]})
 self.memory.append(f"Eventi del calendario: {events}")
 return events
 except Exception as e:
 log_agent_step(self.agent_id, "fetch_calendar_events", "failed", 
 {"error": str(e), "traceback": "..."}) # Nella vita reale, cattura il traceback
 raise

 def _summarize_with_llm(self, prompt_text: str):
 log_agent_step(self.agent_id, "summarize_with_llm", "started", 
 {"prompt_length": len(prompt_text), "prompt_preview": prompt_text[:100]})
 try:
 # Simula una chiamata LLM
 if "fail_llm" in prompt_text:
 raise RuntimeError("Errore API LLM simulato")
 
 response = f"Riepilogo LLM di: {prompt_text[:50]}..."
 token_usage = {"input": len(prompt_text) // 4, "output": len(response) // 4}
 log_agent_step(self.agent_id, "summarize_with_llm", "completed", 
 {"response_length": len(response), "token_usage": token_usage, 
 "llm_response_preview": response[:100]})
 self.memory.append(f"Riepilogo prodotto dal LLM: {response}")
 return response
 except Exception as e:
 log_agent_step(self.agent_id, "summarize_with_llm", "failed", 
 {"error": str(e), "traceback": "..."})
 raise

 def run_daily_briefing(self, user_id: str):
 log_agent_step(self.agent_id, "run_daily_briefing", "started", {"user_id": user_id})
 try:
 calendar_data = self._fetch_calendar_events(user_id, "today")
 news_summary = self._summarize_with_llm("Riepiloga le notizie principali di oggi...")
 
 final_briefing_prompt = (
 f"Crea un briefing giornaliero basato su:\n"
 f"Calendario: {json.dumps(calendar_data)}\n"
 f"Notizie: {news_summary}"
 )
 final_briefing = self._summarize_with_llm(final_briefing_prompt)
 
 log_agent_step(self.agent_id, "run_daily_briefing", "completed", 
 {"final_briefing_length": len(final_briefing)})
 return final_briefing
 except Exception as e:
 log_agent_step(self.agent_id, "run_daily_briefing", "failed", 
 {"error": str(e), "current_memory": self.memory}) # Cattura la memoria in caso di errore
 raise

# Esempio di utilizzo
if __name__ == "__main__":
 agent = MyAgent()
 print(f"\n--- Esecuzione dell'agente {agent.agent_id} (Caso di Successo) ---")
 try:
 briefing = agent.run_daily_briefing("leo_g")
 print(f"Briefing: {briefing[:100]}...")
 except Exception as e:
 print(f"L'esecuzione dell'agente è fallita: {e}")

 agent_fail = MyAgent()
 print(f"\n--- Esecuzione dell'agente {agent_fail.agent_id} (Caso di Errore Calendario) ---")
 try:
 # Simula un errore del calendario passando "error" in date_range
 agent_fail._fetch_calendar_events("leo_g", "error_today") 
 except Exception as e:
 print(f"L'esecuzione dell'agente è fallita come previsto: {e}")

 agent_llm_fail = MyAgent()
 print(f"\n--- Esecuzione dell'agente {agent_llm_fail.agent_id} (Caso di Errore LLM) ---")
 try:
 # Simula un errore LLM
 agent_llm_fail._summarize_with_llm("fail_llm_please")
 except Exception as e:
 print(f"L'esecuzione dell'agente è fallita come previsto: {e}")

Nota come `log_agent_step` cattura l’ID dell’agente, il nome del passaggio, lo stato e un dizionario di dettagli pertinenti. Questo rende facile filtrare i log per ID agente, tracciare una singola esecuzione o cercare tutti i passaggi “falliti”.

Strategia 2: Osservabilità Centralizzata con una Libreria/Servizio Dedicato

Per agenti più complessi o ambienti di produzione, crescerai rapidamente oltre la semplice registrazione su file. È qui che brillano gli strumenti specializzati. Librerie come `LangSmith` di LangChain (o simili per altri framework) forniscono tracciamento integrato, visualizzazione e debug per le applicazioni LLM.

Anche se non stai usando LangChain, il concetto è trasferibile. Puoi costruire il tuo wrapper attorno all’esecuzione dell’agente che invia eventi strutturati a un servizio di logging (Datadog, Splunk, ELK stack, o anche un semplice bucket S3 con processamento Lambda). La chiave è standardizzare lo schema degli eventi.

Il mio migliorato Project Chronos ora utilizza una classe custom `TraceManager` che avvolge operazioni critiche. Questo manager invia eventi strutturati a un database locale per lo sviluppo e a un servizio di logging cloud in produzione. Questo mi permette di vedere una “traccia” completa di ogni esecuzione dell’agente, con passaggi annidati e tutti i dati associati (prompt, risposte, input/output degli strumenti, errori).

Strategia 3: Intercettazione delle Chiamate LLM e degli Strumenti

Molti SDK LLM ti permettono di impostare callback o intercettori per chiamate API. Usali! Invece di registrare manualmente prima e dopo ogni prompt LLM, puoi avere un singolo intercettore che registra automaticamente:

  • L’esatto endpoint API colpito.
  • Intestazioni e corpo della richiesta (specialmente il prompt).
  • Intestazioni e corpo della risposta (la completazione).
  • Latenza.
  • Eventuali eccezioni.

Analogamente, avvolgi le tue chiamate agli strumenti. Se hai uno strumento `search_web`, il wrapper dovrebbe registrare la query di ricerca, il motore di ricerca utilizzato e i migliori N risultati restituiti, insieme a eventuali errori.

Note Azionabili per il Tuo Prossimo Progetto di Agenti

  1. Progetta per l’Osservabilità Prima: Non trattarlo come un pensiero secondario. Pensa a cosa avresti bisogno per fare debug prima ancora di scrivere il tuo primo passo dell’agente.
  2. Abbraccia la Registrazione Strutturata: Abbandona `print()` e `console.log()` per il codice di produzione. Usa una libreria di logging adeguata e restituisci dati strutturati (JSON) per ogni evento significativo.
  3. Traccia Tutto ciò che è Importante: Registra l’inizio e la fine di ogni passaggio principale, tutti i prompt e le risposte LLM (inclusi parametri e conteggio dei token), e ogni chiamata agli strumenti con i suoi input e output.
  4. Cattura lo Stato in Caso di Errore: Quando un agente fallisce, registra il suo stato interno o la memoria in quel momento. Questo fornisce un contesto cruciale per capire perché è fallito.
  5. Usa ID Specifici per Agenti: Assegna un ID unico a ciascun esecuzione dell’agente (ad esempio, un UUID). Questo ti consente di filtrare e tracciare facilmente un singolo percorso di esecuzione attraverso i tuoi log.
  6. Visualizza le tue Tracce: Se possibile, utilizza o costruisci uno strumento che possa visualizzare questi log strutturati come una sequenza di eventi. Vedere il flusso rende il debug infinitamente più semplice rispetto a setacciare testo grezzo. LangSmith lo fa magnificamente, ma anche uno script personalizzato può rendere una semplice linea temporale HTML.
  7. Monitora i Costi: L’uso di token LLM è un costo diretto. Registralo. Questo ti aiuta a capire dove vanno i tuoi soldi e a ottimizzare i tuoi prompt.

Costruire agenti è entusiasmante, ma costruire agenti affidabili è dove risiede il vero lavoro (e il vero valore). E l’affidabilità inizia con la conoscenza di ciò che avviene dietro le quinte. La mia dolorosa esperienza con Project Chronos mi ha insegnato bene quella lezione. Non aspettare il tuo personale “bug misterioso” per convincerti. Inizia a registrare in modo intelligente oggi.

Quali sono le tue strategie di osservabilità preferite per gli agenti? Contattami nei commenti o sui social media. Sono sempre interessato a sentire come altri affrontano queste sfide!

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: Agent Frameworks | Architecture | Dev Tools | Performance | Tutorials
Scroll to Top