Osservabilità e governance dei workflow agentici: integrazione con MLflow
Razionale e architettura
I workflow agentici sono non deterministici, composti da più passaggi e mediati da strumenti: la stessa richiesta utente può seguire percorsi di esecuzione diversi in base all'output del modello, al contesto recuperato e alla disponibilità di strumenti esterni. Il logging applicativo tradizionale è insufficiente in questo contesto, perché registra che cosa ha fatto il servizio, ma non perché l'agente ha deciso di farlo.
Per questo motivo, ogni workflow agentico in ALIDA è collegato a MLflow, che funge da piattaforma unica per la memorizzazione delle tracce di esecuzione e la valutazione delle interazioni con l'agente. MLflow è stato scelto perché è open source, indipendente dal fornitore e il suo SDK di tracing è pienamente compatibile con OpenTelemetry, incluso il supporto nativo alle convenzioni semantiche GenAI. Questo riduce il lock-in: la stessa strumentazione può essere esportata verso un diverso backend di osservabilità senza riscrivere gli agenti.
L'integrazione comprende due agenti distinti, costruiti su stack tecnologici differenti:
- Agente A, basato su OpenCode;
- Agente B, basato su Agent Development Kit (ADK).
Entrambi scrivono sullo stesso server di tracking MLflow, in namespace di esperimento distinti.
L'integrazione segue un modello a due livelli.
Livello 1: raccolta delle tracce. Entrambi gli agenti inviano tracce al server di tracking MLflow. La strumentazione è applicata al livello del runtime dell'agente, anziché nella logica di business, affinché l'osservabilità non si propaghi nel codice applicativo e rimanga stabile tra le versioni degli agenti.
Livello 2: governance dell'accesso ai modelli. Per gli agenti per cui è possibile configurare il provider LLM, il traffico di inferenza viene inoltre instradato attraverso MLflow AI Gateway, che media l'accesso ai provider LLM sottostanti. L'agente basato su OpenCode invoca direttamente i propri provider di modelli ed è osservato solo tramite la raccolta delle tracce.
Tracing
Ogni invocazione dell'agente produce una traccia composta da span annidati, che riproducono l'intero albero di esecuzione del workflow: la richiesta in ingresso, le chiamate LLM, le invocazioni degli strumenti con i relativi risultati e la risposta finale.
Le tracce possono essere arricchite con un identificativo di sessione, che consente alla piattaforma di raggruppare tutte le interazioni appartenenti alla stessa conversazione o alla stessa esecuzione di un'attività. Questo è importante perché un singolo errore raramente si spiega osservando una sola traccia isolata; una sessione mostra invece come si è accumulato il contesto, dove l'agente è entrato in un ciclo e in quale passaggio il ragionamento si è discostato dal comportamento previsto.
Cosa viene acquisito
Per entrambi gli agenti, le tracce archiviate in MLflow permettono di ispezionare completamente:
- L'albero di esecuzione, con latenza per span, input, output e stato di errore;
- L'uso degli strumenti MCP: quali server e strumenti Model Context Protocol sono stati invocati, con quali argomenti e quali risultati hanno restituito. Questo rende più esplicito e verificabile il livello degli strumenti, normalmente la parte meno osservabile di un sistema agentico;
- Il consumo di token, suddiviso per span e aggregato per traccia e sessione, includendo input, output e, se applicabile, token in cache;
- Il modello sottostante, inclusi provider, identificativo del modello e parametri di campionamento, affinché le variazioni di comportamento possano essere correlate ai cambi di modello;
- Il contenuto di ragionamento, quando il provider lo espone, affinché la deliberazione intermedia del modello sia conservata insieme alla risposta finale anziché essere scartata.
Strumentazione dell'agente OpenCode
L'agente OpenCode è strumentato tramite l'integrazione MLflow di prima parte per OpenCode, distribuita come plugin OpenCode anziché come codice a livello applicativo. Nessuna logica di tracing viene scritta nell'agente: il plugin è dichiarato nella configurazione OpenCode e legge le proprie impostazioni dall'ambiente.
// opencode.json
{
"plugin": ["@mlflow/opencode"]
}# .env, caricato automaticamente da OpenCode all'avvio
MLFLOW_TRACKING_URI=<tracking-server-uri>
MLFLOW_EXPERIMENT_ID=<experiment-id>Una volta attivo il plugin, MLflow acquisisce automaticamente le tracce delle conversazioni OpenCode e le registra nell'esperimento configurato. Le tracce vengono emesse quando la sessione diventa inattiva, cioè alla fine di ogni turno conversazionale; il tracing non aggiunge quindi latenza al ciclo interattivo e non richiede un flush esplicito da parte dell'agente.
Ogni traccia registra:
- i prompt dell'utente e le risposte dell'assistente;
- l'uso degli strumenti nel turno, incluse operazioni sui file, comandi bash e modifiche al codice, e quindi anche gli strumenti esposti dai server MCP configurati;
- la tempistica e la durata del turno conversazionale;
- l'uso di token, suddiviso in input, output e totale, registrato nell'attributo
mlflow.chat.tokenUsagee mostrato nella pagina di dettaglio della traccia e nella dashboard di panoramica insieme al costo associato.
I metadati di sessione e utente sono collegati dal plugin senza configurazioni aggiuntive: ogni sessione OpenCode è contrassegnata con mlflow.trace.session e l'utente di sistema che avvia l'invocazione con mlflow.trace.user. Questi tag permettono di raggruppare e filtrare le tracce per sessione nell'interfaccia MLflow e tramite l'API di ricerca, e rendono l'agente OpenCode confrontabile con l'agente ADK nella stessa piattaforma.
L'accesso ai modelli rimane sotto il controllo diretto dell'agente: credenziali del provider e scelta del modello sono configurate in OpenCode, mentre MLflow osserva le chiamate risultanti senza mediarle. Ne derivano due conseguenze operative. Innanzitutto, l'uso di token viene registrato solo quando il provider sottostante lo comunica, perché il plugin non intercetta il percorso della richiesta. Inoltre, il tracing può essere disattivato semplicemente rimuovendo il plugin da opencode.json, senza modificare il comportamento dell'agente.
Strumentazione dell'agente ADK e AI Gateway
L'agente basato su ADK supporta il percorso di esportazione basato su OpenTelemetry offerto da MLflow, ma l'integrazione può andare oltre: le richieste di inferenza vengono inviate a un endpoint esposto da MLflow AI Gateway invece che all'endpoint nativo del provider. Il gateway offre un'interfaccia unificata verso più provider LLM dietro un unico endpoint sicuro e centralizza le API key dei provider, con logging di richieste e risposte.
L'agente invia le trace all'esperimento MLflow con il nome di FATHER_ID senza configurazione aggiuntiva; vedi Configurazione dell'ADK Agent.
Da questa scelta derivano tre vantaggi diretti.
Sostituzione dinamica del modello. Gli endpoint possono essere aggiunti, rimossi o riconfigurati dinamicamente senza riavviare il server o interrompere le applicazioni in esecuzione. In pratica, il modello usato dall'agente ADK può essere sostituito, oppure il traffico può essere ripartito tra modelli per test A/B, senza rideployare l'agente o modificarne il codice. Le catene di fallback automatico proteggono inoltre il workflow dalle indisponibilità dei provider.
Tracking senza sforzo di integrazione. Poiché ogni richiesta attraversa il gateway, utilizzo, consumo di token, latenza e costo vengono registrati centralmente, indipendentemente dal framework dell'agente. L'osservabilità non dipende quindi più dall'adozione o dalla corretta configurazione di un SDK da parte dell'agente: ogni client dell'endpoint è osservabile per costruzione. Questo riduce sensibilmente il costo di onboarding di nuovi agenti sulla piattaforma.
Guardrail. Il gateway consente di applicare policy sui contenuti a livello di endpoint tramite giudici basati su LLM, che possono bloccare o sanitizzare richieste e risposte. La policy viene così espressa una sola volta, al confine dell'infrastruttura, e applicata in modo uniforme a ogni consumer dell'endpoint, invece di essere reimplementata e potenzialmente resa divergente in ciascun agente. Sullo stesso livello possono essere configurati limiti di budget e avvisi di spesa.
Valutazione e monitoraggio
Oltre all'archiviazione delle tracce, MLflow viene usato per valutare la qualità delle interazioni degli agenti. Le tracce raccolte possono diventare il dataset di valutazione: le sessioni reali di produzione vengono valutate con metriche LLM-as-a-judge, tramite giudici predefiniti per dimensioni comuni, come allucinazione o rilevanza, oppure tramite scorer personalizzati che codificano criteri di dominio definiti per i casi d'uso ALIDA.
Questo chiude il ciclo tra osservabilità e miglioramento. Una modifica a un prompt, a uno strumento o a un modello non viene solo osservata in produzione, ma misurata rispetto a un insieme stabile di interazioni registrate, in modo da rilevare le regressioni prima che raggiungano gli utenti.