![]()
Fino a questo punto del corso hai costruito agenti che girano sul tuo laptop, all’interno di un notebook, guidati da az login e da alcune variabili d’ambiente. Questo è esattamente il modo giusto per imparare. Non è però il modo corretto per far girare un agente da cui migliaia di clienti dipendono alle 3 del mattino.
Questa lezione riguarda il divario tra “funziona sulla mia macchina” e “funziona, in modo affidabile e conveniente, in produzione.” Chiudiamo questo divario usando Microsoft Foundry e il Microsoft Foundry Agent Service, costruendo un vero agente di assistenza clienti con strumenti, recupero, memoria, valutazione e monitoraggio.
Questa lezione coprirà:
Dopo aver completato questa lezione, saprai come:
Questa lezione presuppone che tu abbia completato le lezioni precedenti e che tu sia a tuo agio con:
Avrai inoltre bisogno di:
az login).requirements.txt.Un agente prototipo e un agente di produzione condividono lo stesso ciclo di base — ragionare, chiamare strumenti, rispondere. Ciò che cambia è tutto ciò che circonda quel ciclo. Il modello è forse il 20% di un agente di produzione; l’altro 80% è lo scheletro operativo.
| Aspetto | Prototipo | Produzione |
|---|---|---|
| Hosting | Gira nel tuo notebook | Gira come un servizio ospitato, versionato e distribuito |
| Identità | Il tuo token di az login |
Identità gestita con RBAC con ambito definito |
| Stato | In memoria, perso al riavvio | Esternalizzato (thread store, servizio di memoria) |
| Errori | Vedi il traceback | Riprova, fallback, dead-letter, allarmi |
| Costo | “Sono pochi centesimi” | Tracciato per richiesta, instradato, memorizzato nella cache, budgettato |
| Qualità | Controlli visivamente l’output | Valutato automaticamente prima di ogni rilascio |
| Fiducia | Approvi ogni azione | Policy + persona nel ciclo per azioni rischiose |
Tieni a mente questa tabella. Ogni sezione qui sotto corrisponde a una di queste righe.
Ci sono tre modelli che userai, spesso combinati.
L’oggetto agente vive all’interno del processo della tua applicazione. Il tuo codice chiama direttamente il provider del modello; il ciclo di ragionamento gira nel tuo servizio. Questo è ciò che ogni lezione precedente ha fatto.
L’agente è registrato come risorsa in Microsoft Foundry. Foundry ospita il ciclo di ragionamento, memorizza i thread, applica la sicurezza dei contenuti e l’RBAC, e rende l’agente visibile nel portale Foundry. La tua app diventa un client leggero che crea thread e legge risposte.
Molti agenti (e strumenti) sono composti in un grafo con flusso di controllo esplicito — passaggi sequenziali, diramazioni, nodi di approvazione umana, e checkpoint duraturi che possono mettere in pausa e riprendere. Questa è la capacità Workflow del Microsoft Agent Framework applicata alla scala di distribuzione.
flowchart TB
subgraph P1[Ospitato dal cliente]
A1[Il processo della tua app] --> M1[Fornitore del modello]
end
subgraph P2[Agente ospitato]
A2[Cliente leggero] --> F2[Servizio agente Foundry]
F2 --> M2[Modello + Strumenti + Archivio Thread]
end
subgraph P3[Flusso di lavoro agente]
A3[Orchestratore] --> S1[Agente di valutazione]
S1 --> S2[Agente risolutore]
S2 --> H[Nodo di approvazione umana]
H --> S3[Agente d'azione]
end
Distribuire un agente non è un push una tantum. È un ciclo, e assomiglia molto a un ciclo di rilascio software perché è esattamente quello che è.
flowchart LR
Create[Crea / Autore] --> Version[Versione]
Version --> Evaluate[Valuta offline]
Evaluate -->|supera il controllo| Deploy[Distribuisci ospitato]
Evaluate -->|non supera il controllo| Create
Deploy --> Observe[Osserva online]
Observe --> Improve[Raccogli errori]
Improve --> Create
Deploy --> Retire[Ritira la versione vecchia]
L’idea chiave, ripresa da Lezione 10: la valutazione offline è un cancello, non un ripensamento. Una nuova versione dell’agente non viene distribuita se non supera le tue soglie di valutazione. L’osservabilità online poi alimenta i fallimenti reali nel tuo set di test offline. Questo è tutto il ciclo.
Scalare un agente è diverso dal scalare un’API web senza stato, perché ogni richiesta può innescare molte chiamate costose a modelli e strumenti. Quattro tecniche sostengono la maggior parte del carico.
Gestione delle richieste senza stato. Non conservare alcuno stato per utente nella memoria di processo. Conserva i thread delle conversazioni nel thread store di Foundry o in un servizio di memoria così ogni istanza può gestire ogni richiesta. Questo ti permette di scalare orizzontalmente — aggiungi istanze, senza sessioni sticky.
Instradamento del modello. Non ogni richiesta ha bisogno del tuo modello più potente (e più costoso). Instrada le richieste semplici — classificazione dell’intento, risposte fattuali brevi — a un modello piccolo e veloce, e riserva il modello grande per il vero ragionamento. Il Model Router di Foundry può farlo per te, oppure puoi implementare un classificatore leggero da solo. Costruirai la versione fai-da-te nel laboratorio.
Caching delle risposte. Molte richieste di supporto sono quasi duplicati (“come faccio a resettare la mia password?”). Memorizza in cache le risposte alle domande comuni e servile senza invocare il modello. Anche un modesto tasso di hit nella cache riduce significativamente costi e latenza.
Concorrenza e backpressure. I provider di modelli hanno limiti di velocità. Limita la concorrenza, usa ripetizioni con backoff esponenziale, e fallisci con grazia (una risposta in coda “stiamo lavorando” è meglio di un 500).
flowchart LR
Q[Richiesta utente] --> C{Cache attiva?}
C -->|sì| R[Restituisci risposta memorizzata]
C -->|no| Router{Complessità?}
Router -->|semplice| SLM[Modello piccolo]
Router -->|complesso| LLM[Modello grande]
SLM --> Out[Risposta]
LLM --> Out
Out --> Store[Cache + traccia]
Non puoi operare ciò che non puoi vedere. Come trattato nella Lezione 10, il Microsoft Agent Framework emette nativamente tracce OpenTelemetry — ogni chiamata modello, invocazione strumento, e passaggio di orchestrazione diventa una span. In produzione esporti queste span in Microsoft Foundry (o in qualsiasi backend compatibile OTel) così puoi:
from agent_framework.observability import get_tracer
tracer = get_tracer()
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("customer.tier", "enterprise")
span.set_attribute("routed.model", "gpt-5-nano")
# l'esecuzione dell'agente viene tracciata automaticamente all'interno di questo intervallo
Attributi come customer.tier e routed.model trasformano una parete di tracce in domande a cui si può rispondere (“i clienti enterprise vengono instradati troppo spesso al modello piccolo?”).
Il costo negli agenti di produzione è dominato dai token. Tre leve, in ordine di impatto:
I cancelli di valutazione e il controllo dei costi sono la stessa disciplina vista da due angoli: la valutazione ti dice il pavimento di qualità, l’instradamento e il caching ti mantengono il più vicino possibile al costo di quel pavimento.
Governance. Gli Hosted Agents ereditano l’RBAC, la sicurezza dei contenuti e la registrazione audit di Foundry. Assegna a ogni agente un’identità gestita con il minimo privilegio necessario — accesso in sola lettura alla knowledge base, accesso limitato all’API di ticketing, nulla di più.
Persona nel ciclo. Alcune azioni sono troppo importanti per essere automatizzate completamente — emettere un rimborso, eliminare un account, escalation a un team legale. Il Microsoft Agent Framework supporta strumenti con approvazione richiesta: l’agente propone l’azione, l’esecuzione si mette in pausa, una persona approva o rifiuta, e il workflow riprende. Hai visto il primitivo in Lezione 6; qui lo distribuisci.
MCP in produzione. MCP permette al tuo agente di consumare strumenti esterni tramite un’interfaccia standard. In produzione, tratta ogni server MCP come un confine non affidabile: fissa la versione del server, eseguilo con un’identità limitata, valida i suoi output, e mai esporre segreti a esso. Un server MCP è una dipendenza, e le dipendenze vengono aggiornate, controllate e rate-limited.
flowchart TB
subgraph Dev[Architettura di Sviluppo]
D1[Notebook] --> D2[Framework Agente]
D2 --> D3[Fornitore di Modelli]
D2 --> D4[Strumenti locali]
end
subgraph Deploy[Architettura di Distribuzione]
E1[Pipeline CI] --> E2[Porta di valutazione]
E2 -->|superamento| E3[Servizio Agente Foundry]
E3 --> E4[Agente ospitato versionato]
end
subgraph Run[Architettura di Runtime]
F1[App client] --> F2[Agente ospitato]
F2 --> F3[Router di Modelli]
F2 --> F4[Azure AI Search RAG]
F2 --> F5[Servizio di memoria]
F2 --> F6[Strumenti MCP]
F2 --> F7[OTel -> tracing Foundry]
F2 --> F8[Approvazione umana]
end
Quei tre diagrammi — sviluppo, distribuzione, runtime — sono lo stesso agente in tre fasi della sua vita. Il laboratorio che segue ti guida nella sua costruzione.
Apri code_samples/16-python-agent-framework.ipynb e seguilo dall’inizio alla fine. Assemblerai un agente di supporto clienti Contoso con ogni preoccupazione di produzione collegata:
Il notebook è organizzato in sezioni auto-contenute e eseguibili per ogni preoccupazione di produzione. Il cuore è il gestore di richieste routing-plus-caching:
async def handle_support_request(query: str, customer_id: str) -> str:
# 1. Servire dalla cache quando possibile.
cached = response_cache.get(normalize(query))
if cached:
return cached
# 2. Instradare in base alla complessità per controllare i costi.
model = "gpt-5-nano" if is_simple(query) else "gpt-5-mini"
# 3. Eseguire l'agente all'interno di uno span di traccia per l'osservabilità.
with tracer.start_as_current_span("support_request") as span:
span.set_attribute("routed.model", model)
span.set_attribute("customer.id", customer_id)
response = await support_agent.run(query, model=model)
# 4. Memorizzare nella cache e restituire.
response_cache.set(normalize(query), response.text)
return response.text
Il cancello di valutazione che protegge un rilascio è simile a questo:
async def evaluation_gate(agent, test_cases, threshold: float = 0.8) -> bool:
passed = 0
for case in test_cases:
result = await agent.run(case["input"])
if score_response(result.text, case["expected"]) >= 0.8:
passed += 1
pass_rate = passed / len(test_cases)
print(f"Evaluation pass rate: {pass_rate:.0%} (gate: {threshold:.0%})")
return pass_rate >= threshold # distribuisci solo se il cancello passa
Leggi ogni riga — il notebook mantiene i primitivi deliberatamente piccoli così nulla è nascosto dietro una chiamata framework.
Il cancello di valutazione sopra gira offline contro il tuo oggetto agente. Una volta che l’agente è distribuito come Hosted Agent, ti serve un controllo in più, ancora più economico: l’endpoint distribuito risponde davvero?
Distribuire “con successo” dimostra solo che il piano di controllo ha accettato la definizione — non dimostra che l’agente risponda. Una dipendenza mancante, un errato instradamento modello, o una connessione scaduta possono lasciare una distribuzione verde che non risponde nulla. Un test smoke lo intercetta in secondi, a ogni deploy, senza il costo di una valutazione completa.
Questo repository fornisce una pipeline pronta all’uso di test smoke basata sul GitHub Action AI Smoke Test:
tests/lesson-16-smoke-tests.json contiene prompt e asserzioni per l’agente di supporto Contoso (risposte grounded sulla policy, ricerca di un ordine, rimanere sul tema, continuità multi-turno). Cataloghi per agenti di altre lezioni vivono insieme; vedi tests/README.md..github/workflows/smoke-test.yml esegue il login con Azure OIDC e invia in POST ogni prompt all’endpoint Responses dell’agente, fallendo il lavoro al minimo errore di asserzione.- name: Smoke-test hosted agent
uses: JFolberth/ai-smoketest@v1
with:
project_endpoint: $
agent_name: ContosoSupportAgent
tests_file: tests/lesson-16-smoke-tests.json
Eseguilo dalla scheda Actions una volta che il tuo agente è distribuito, fornendo l’endpoint del progetto Foundry e il nome dell’agente. L’identità federata necessita del ruolo Azure AI User a livello di progetto Foundry. Pensa agli strati come a una piramide: i test smoke (raggiungibile e risponde?) vengono eseguiti ad ogni distribuzione, la valutazione offline (abbastanza buona per essere rilasciata?) viene eseguita prima della promozione e la valutazione online (come si comporta sul campo?) viene eseguita continuamente.
Metti alla prova la tua comprensione prima di passare all’assegnazione.
1. Approssimativamente, quanto di un agente in produzione è “il modello” e cos’è il resto?
2. Quando sceglieresti un Hosted Agent invece di un agente ospitato dal client?
3. Perché un agente scalabile deve essere senza stato nella memoria del proprio processo?
4. Quale problema risolve il model routing e quale relazione ha con la valutazione?
5. Cos’è un “evaluation gate” e dove si colloca nel ciclo di vita?
6. Perché un server MCP deve essere trattato come un confine non affidabile in produzione?
7. Quale singolo cambiamento ha solitamente il maggiore impatto sul costo di un agente in produzione e perché?
8. Quale ruolo giocano attributi di span come customer.tier e routed.model nell’osservabilità?
Prendi l’agente di supporto clienti dal laboratorio e rafforzalo per uno scenario specifico: un agente di supporto per la fatturazione abbonamenti per un’azienda SaaS.
Il tuo invio dovrebbe:
get_subscription_status, get_invoice, e issue_credit (i crediti superiori a $50 richiedono approvazione umana).Scrivi un breve paragrafo (in una cella markdown) spiegando quale regola di routing modello hai scelto e come la convalideresti con traffico reale. Non esiste una risposta corretta unica — sarai valutato sul fatto che le preoccupazioni di produzione siano collegate in modo coerente.
In questa lezione hai portato un agente dal prototipo alla produzione con Microsoft Foundry:
La prossima lezione compie il percorso opposto: invece di scalare gli agenti verso il cloud, li porterai giù su una singola macchina dello sviluppatore e li eseguirai interamente localmente.
Costruire Agenti per l’Uso del Computer (CUA)
Disclaimer: Questo documento è stato tradotto utilizzando il servizio di traduzione AI Co-op Translator. Sebbene ci impegniamo per garantire la precisione, si prega di notare che le traduzioni automatizzate possono contenere errori o imprecisioni. Il documento originale nella sua lingua nativa deve essere considerato la fonte autorevole. Per informazioni critiche, si raccomanda una traduzione professionale effettuata da un essere umano. Non siamo responsabili per eventuali malintesi o interpretazioni errate derivanti dall’uso di questa traduzione.