Osservabilita e governance dei workflow agentici: integrazione con MLflow
Razionale e architettura
I workflow agentici sono non deterministici, composti da piu passaggi e mediati da strumenti: la stessa richiesta utente puo seguire percorsi di esecuzione diversi in base all'output del modello, al contesto recuperato e alla disponibilita di strumenti esterni. Il logging applicativo tradizionale e insufficiente in questo contesto, perche registra che cosa ha fatto il servizio, ma non perche l'agente ha deciso di farlo.
Per questo motivo, ogni workflow agentico in ALIDA e collegato a MLflow, che funge da piattaforma unica per la memorizzazione delle tracce di esecuzione e la valutazione delle interazioni con l'agente. MLflow e stato scelto perche e open source, indipendente dal fornitore e il suo SDK di tracing e pienamente compatibile con OpenTelemetry, incluso il supporto nativo alle convenzioni semantiche GenAI. Questo riduce il lock-in: la stessa strumentazione puo essere esportata verso un diverso backend di osservabilita 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 e applicata al livello del runtime dell'agente, anziche nella logica di business, affinche l'osservabilita 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 e 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 e osservato solo tramite la raccolta delle tracce.
flowchart TD
OC["Agent (OpenCode)"]
ADK["Agent (ADK)"]
GW["MLflow AI Gateway"]
MLF["Server di tracking"]
OC -- "tracce" --> MLF
ADK -- "tracce (OTel)" --> MLF
ADK -- "inferenza" --> GW
GW --> MLF
GW -. "provider LLM" .-> P(["OpenAI / Anthropic / ..."])
classDef agent fill:#eef4ff,stroke:#4a6fa5,stroke-width:1px;
classDef infra fill:#f4f1e8,stroke:#8a7a4a,stroke-width:1px;
class OC,ADK agent;
class GW,MLF infra;
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'attivita. Questo e importante perche un singolo errore raramente si spiega osservando una sola traccia isolata; una sessione mostra invece come si e accumulato il contesto, dove l'agente e entrato in un ciclo e in quale passaggio il ragionamento si e 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 piu 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, affinche le variazioni di comportamento possano essere correlate ai cambi di modello;
- Il contenuto di ragionamento, quando il provider lo espone, affinche la deliberazione intermedia del modello sia conservata insieme alla risposta finale anziche essere scartata.
Strumentazione dell'agente OpenCode
L'agente OpenCode e strumentato tramite l'integrazione MLflow di prima parte per OpenCode, distribuita come plugin OpenCode anziche come codice a livello applicativo. Nessuna logica di tracing viene scritta nell'agente: il plugin e dichiarato nella configurazione OpenCode e legge le proprie impostazioni dall'ambiente.
opencode.json
# .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, cioe 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 e 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, perche il plugin non intercetta il percorso della richiesta. Inoltre, il tracing puo 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 puo 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 piu provider LLM dietro un unico endpoint sicuro e centralizza le API key dei provider, con logging di richieste e risposte.
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 puo essere sostituito, oppure il traffico puo 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 indisponibilita dei provider.
Tracking senza sforzo di integrazione. Poiche ogni richiesta attraversa il gateway, utilizzo, consumo di token, latenza e costo vengono registrati centralmente, indipendentemente dal framework dell'agente. L'osservabilita non dipende quindi piu dall'adozione o dalla corretta configurazione di un SDK da parte dell'agente: ogni client dell'endpoint e 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 cosi 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 qualita 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 osservabilita 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.