In produzione la domanda cambia. Non è più «quanto è buona la risposta media» ma «cosa è successo dentro questa singola richiesta, quanto ci ha messo e quanto è costata». Sono tre superfici distinte: le tracce, che raccontano il percorso di una chiamata; le metriche di piattaforma, che danno latenza, volumi e token; e la valutazione continua, che riporta i giudizi di qualità sul traffico reale invece che su un dataset. Un MLOps engineer le collega tutte e tre alla stessa risorsa Application Insights e sa quali permessi servono per leggerle.
Tracing: la superficie di debug della produzione
Il punto di partenza è collegare una risorsa Application Insights al progetto Microsoft Foundry. Fatto questo, il tracing server-side si attiva senza toccare il codice per gli agenti ospitati in Foundry e nel portale hai le tracce degli ultimi 90 giorni, navigabili span per span. Il tracing client-side è il secondo passo e serve per vedere anche la logica applicativa attorno alla chiamata: si installano i pacchetti OpenTelemetry con l’exporter Azure Monitor e si esporta verso Azure Monitor, verso la console o verso qualunque backend OTLP.
import os
os.environ["AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING"] = "true"
from azure.ai.projects.telemetry import AIProjectInstrumentor
from azure.monitor.opentelemetry import configure_azure_monitor
configure_azure_monitor(
connection_string=project.telemetry.get_application_insights_connection_string()
)
AIProjectInstrumentor().instrument()
Due variabili d’ambiente vanno sapute a memoria. AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING va impostata prima di chiamare instrument(), altrimenti l’instrumentazione non parte e resta solo un warning. OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT è disattivata per impostazione predefinita e governa la registrazione dei contenuti — prompt, output, argomenti dei tool; il decoratore @trace_function sulle tue funzioni, invece, traccia sempre parametri e valori di ritorno a prescindere da quella variabile.
Il contenuto sensibile ha un percorso dedicato. Attributi come gen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructions e gen_ai.tool.call.arguments si instradano nella tabella AppGenAIContent di Log Analytics registrando il feature flag protectGenAISensitiveData; poi si marca quella tabella come protetta e si concede la lettura al solo ruolo Privileged Monitoring Data Reader. Chi ha soltanto Log Analytics Reader continua a vedere la traccia ma non il contenuto. Dal 30 settembre 2026 questo diventa il comportamento predefinito per i dati ingeriti: i valori restano solo in AppGenAIContent e le query personalizzate che li leggevano da AppDependencies, AppTraces o AppEvents vanno aggiornate.
Il monitoraggio continuo in Foundry
L’Agent Monitoring Dashboard, nella scheda Monitor dell’agente, legge la telemetria dalla stessa risorsa Application Insights e mostra consumo di token, latenza, tasso di successo delle run ed esiti delle valutazioni. La documentazione offre due riferimenti di lettura: una latenza sopra i 10 secondi suggerisce throttling del modello, chiamate a tool complesse o problemi di rete, e un tasso di successo sotto il 95% merita un’indagine sulle run fallite.
Ciò che l’obiettivo chiama monitoraggio continuo sono le valutazioni ricorrenti, di due tipi da non confondere. La scheduled evaluation gira su un orario fisso, definita con uno Schedule e un trigger di ricorrenza. La continuous evaluation campiona il traffico vivo mentre accade: si crea una EvaluationRule con azione continua, evento RESPONSE_COMPLETED e un filtro sull’agente.
continuous_eval_rule = project_client.evaluation_rules.create_or_update(
id="my-continuous-eval-rule",
evaluation_rule=EvaluationRule(
display_name="Sicurezza sul traffico live",
action=ContinuousEvaluationRuleAction(eval_id=eval_object.id, max_hourly_runs=100),
event_type=EvaluationRuleEventType.RESPONSE_COMPLETED,
filter=EvaluationRuleFilter(agent_name=agent.name),
enabled=True,
),
)
Tre dettagli operativi. Il limite max_hourly_runs ha default 100 e, quando viene raggiunto, le run in eccesso vengono saltate: è la spiegazione più comune di risultati che sembrano sparire. L’identità gestita del progetto deve avere il ruolo Foundry User (nome precedente: Azure AI User), altrimenti la regola non funziona. E sul traffico live si sceglie fra campionamento casuale e intelligent sampling, che deduplica, scarta le sessioni rotte e seleziona le tracce più dissimili fra loro per massimizzare la copertura invece di prendere le prime N. Anche gli evaluator personalizzati si agganciano alla valutazione continua.
Latenza, throughput e costo a token
Le metriche di piattaforma vivono in Azure Monitor e hanno una trappola dichiarata: la metrica legacy Latency della categoria Cognitive Services non è pensata per questi carichi e produce risultati fuorvianti. Quelle corrette sono Time to Response (AzureOpenAITimeToResponse) per la reattività percepita, Time to Last Byte (AzureOpenAITTLTInMS) per il tempo totale, Time Between Tokens (AzureOpenAINormalizedTBTInMS) per la velocità di generazione e Normalized Time to First Byte (AzureOpenAINormalizedTTFTInMS). Il throughput si legge con Tokens per Second e con il volume di richieste (AzureOpenAIRequests), scomponibile per StatusCode per separare errori client e server.
Sul costo i nomi esatti contano: Processed Prompt Tokens (ProcessedPromptTokens) è l’input, Generated Completion Tokens (GeneratedTokens) è l’output, Processed Inference Tokens (TokenTransaction) è la somma. Si filtrano per ModelDeploymentName, ModelName e ModelVersion, ed è così che la spesa si attribuisce a un deployment invece che alla sottoscrizione intera. Per la capacità riservata c’è Provisioned-managed Utilization V2: raggiunto il 100% le chiamate vengono limitate con errore 429. La regola da interiorizzare è accoppiare sempre una metrica di latenza a una di token: se salgono insieme e in proporzione è comportamento atteso, se la latenza sale da sola c’è un problema.
Esiste poi un costo che si dimentica, quello della telemetria stessa. Il campionamento OpenTelemetry è la leva principale, con una percentuale fissa oppure un limite di tracce al secondo. Le metriche non vengono campionate, quindi sono la base giusta per gli alert; dei log conviene esportare gli errori. Il campionamento in ingestione è sconsigliato perché rompe le tracce, e il daily cap è un freno di emergenza, non un sostituto del campionamento. Per verificare che il campionamento sia attivo si interroga Log Analytics:
union requests, dependencies, pageViews, browserTimings, exceptions, traces
| where timestamp > ago(1d)
| summarize RetainedPercentage = 100/avg(itemCount) by bin(timestamp, 1h), itemType
Da ricordare per l esame
- Il tracing server-side si abilita collegando Application Insights al progetto, senza codice; il portale mostra 90 giorni di tracce.
AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACINGva impostata prima diinstrument();OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENTè disattivata di default e governa i contenuti.- Il contenuto sensibile va nella tabella
AppGenAIContentmarcata protetta: per leggerla serve Privileged Monitoring Data Reader, non basta Log Analytics Reader. - Scheduled evaluation = orario fisso; continuous evaluation = campionamento del traffico live via
EvaluationRule, conmax_hourly_runsa 100 di default e ruolo Foundry User sull’identità gestita del progetto. - Latenza: Time to Response, Time to Last Byte, Time Between Tokens — mai la metrica legacy
Latency. Token:ProcessedPromptTokens,GeneratedTokens,TokenTransaction, scomposti perModelDeploymentName.