Nel momento in cui un'applicazione inizia a chiamare tools, l'output del modello smette di essere testo da leggere e diventa un'istruzione da eseguire, e ogni garanzia costruita finora da questa serie riguardava i token. Un framework può rendere quel loop facile da scrivere e, nello stesso gesto, nascondere il throttling, aggirare il routing del gateway e trasformare una richiesta misurata in undici che nessuno aveva pianificato. La Parte 7 ha dato il retrieval alle applicazioni. Questa parte riguarda ciò che ci sta sopra, e in particolare quali compiti il framework non dovrebbe fare perché la piattaforma li fa già.

Punta il framework al gateway, e fermati lì

La meccanica è banale, ed è proprio per questo che la disciplina deve essere esplicita. Un orchestration framework parla il formato OpenAI Chat Completions, il gateway espone esattamente quello, quindi l'integrazione è una base URL e una credenziale:

from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    base_url="https://apim-genai-prod.azure-api.net/llm/v1",
    api_key=gateway_token,        # Entra ID token, not a model key
    model="chat-default",         # gateway alias, never a deployment name
    max_retries=0,                # the gateway owns retry and failover
    timeout=60,
)

max_retries=0 è la riga che conta, ed è la prima che la gente cancella. I framework arrivano con retry lato client, exponential backoff e spesso provider fallback, tutte scelte ragionevoli per un'applicazione che parla direttamente con un model provider e tutte attivamente dannose davanti a un gateway che fa già routing, load balancing e circuit breaking.

Considera cosa fa il retry lato client al circuit breaker della Parte 3. Il breaker scatta e restituisce 503 proprio perché i caller smettano di martellare un backend in difficoltà. Un framework configurato per ritentare il 503 cinque volte con backoff converte quel segnale in cinque volte il carico, che arriva esattamente quando il backend è meno in grado di reggerlo. Lo stesso vale per il 429: un token limit esiste per dare forma alla domanda, e un client che lo ritenta fino a passare non viene sagomato affatto. I retry appartengono a un solo posto, e quel posto esiste già.

Il contrappunto onesto: un singolo retry su un fallimento a livello di connessione, nel client, va bene. La regola riguarda il ritentare le risposte del gateway stesso, non l'instabilità della rete.

Cosa dovrebbe ancora fare il framework

Tolti dalla sua job description provider abstraction, routing, retry e failover, a un framework restano le parti davvero tediose da scrivere a mano e prive di implicazioni di piattaforma: il templating dei prompt con input tipizzati, la generazione degli schema dei tool dalle firme delle funzioni, il parsing dell'output in tipi strutturati e la contabilità dell'agent loop che trasforma una tool call in un messaggio di follow-up. È una quantità reale di lavoro e un motivo ragionevole per prendersi la dipendenza.

Ciò che non deve diventare è il posto in cui vive la scelta del modello. L'alias nel codice qui sopra è un alias del gateway, risolto dal model catalog della Parte 2. Il model registry interno di un framework, le sue catene di fallback, la sua lista di provider, tutto questo è un secondo catalogo che sarà in disaccordo con il primo il giorno in cui un modello viene ritirato.

I tools sono la seconda superficie, e possono condividere la prima porta

I tools di un agent meritano lo stesso trattamento dei suoi modelli: un punto di ingresso governato, accesso per tenant, un audit trail. API Management può esporre una REST API che già gestisce come remote MCP server, pubblicando operazioni selezionate come tools che i client MCP chiamano, disponibile sui tier Developer, Basic, Standard e Premium comprese le varianti v2. Associare quell'MCP server a un product significa che l'accesso ai tools è gestito attraverso gli stessi products e subscriptions dell'accesso ai modelli, che è esattamente il punto: una identità, una storia di quota, un posto dove revocare.

Due limitazioni decidono fin dove si arriva oggi. API Management supporta i tools degli MCP server, ma non le resources né i prompts MCP, per i server esposti da REST API gestite. E le capacità MCP server non sono supportate nei workspaces, il che conta esattamente per i team isolati che la Parte 5 aveva indirizzato ai workspaces. Un team che ha bisogno sia di un workspace gateway sia della pubblicazione di MCP tool deve sceglierne uno, ed è meglio scoprirlo mentre si disegna l'architettura.

Content safety sul percorso del prompt

Un agent loop allarga la superficie di input: documenti recuperati, output dei tool e testo dell'utente finiscono tutti in un prompt. La policy llm-content-safety instrada il contenuto verso Azure AI Content Safety prima che il modello lo veda.

<llm-content-safety backend-id="content-safety-backend" shield-prompt="true">
  <categories output-type="EightSeverityLevels">
    <category name="Hate" threshold="4" />
    <category name="Violence" threshold="4" />
  </categories>
</llm-content-safety>

Tre attributi vanno letti con attenzione invece che copiati. Il threshold funziona come una tolleranza, non come un limite: con threshold="4" il filtro permette le severità da 0 a 3 e blocca da 4 a 7, quindi alzare il numero alza la tolleranza e blocca di meno. È la stessa inversione dello score threshold della cache nella Parte 6, e sorprende le persone nello stesso modo.

shield-prompt="true" attiva il controllo per gli attacchi avversariali degli utenti, e il default è false. Per un agent che concatena documenti recuperati nel proprio contesto, quel default è quello sbagliato: la prompt injection che arriva attraverso un documento è la minaccia realistica, non un utente che digita un attacco in una chat box.

enforce-on-completions, anch'esso false di default, estende il controllo alle risposte del modello quando la policy sta in inbound. E window-size, che di default è il limite di 10.000 caratteri di Content Safety, è configurabile solo per le risposte; per le richieste viene sempre usata la window di default. Un contesto recuperato molto lungo viene quindi valutato dallo stesso windowing che non controlli, il che è un argomento per tenere limitati i risultati del retrieval, non per fidarsi che il filtro scali con loro.

Cosa fa un loop a ogni numero della Parte 5

Una singola domanda dell'utente che attiva quattro tool call non è una richiesta, sono cinque invocazioni del modello, ognuna delle quali reinvia il transcript che cresce. Tre conseguenze per la piattaforma:

  • La quota per minuto smette di riguardare il volume utenti. Diventa il volume utenti moltiplicato per la profondità media del loop, e la profondità del loop è una proprietà del prompt dell'applicazione, che cambia senza una review di piattaforma.
  • Un loop fuori controllo è indistinguibile dal carico. Il gateway vede richieste ben formate dentro la quota. L'applicazione deve limitare da sola le proprie iterazioni, e la piattaforma dovrebbe pubblicarlo come requisito invece di darlo per scontato.
  • Il chargeback ha bisogno di un correlation ID per interazione utente, non per richiesta, altrimenti i numeri per team sono veri e inutili. Quell'ID appartiene al log record, che è dove la Parte 5 ha messo i dati ad alta cardinalità esattamente per questa ragione.

Un tetto di token per richiesta al gateway è un backstop utile e non un sostituto. Limita il danno di una singola chiamata enorme; non fa nulla contro un loop che ne fa duecento piccole.

Modalità di fallimento da tenere d'occhio

  • Retry del framework che vanifica il circuit breaker. Il default è attivo. Spegnilo deliberatamente e documenta il perché, o il meccanismo di protezione della piattaforma diventa un amplificatore di carico.
  • Un secondo model catalog dentro il framework. Sarà in disaccordo con quello del gateway il giorno del ritiro, e l'applicazione risulterà ancorata a un deployment name che nessuno sapeva avesse.
  • Threshold del content safety letto come un limite. Più alto è più permissivo. Un team che elimina i falsi positivi a colpi di tuning può disattivare il filtro nella pratica credendo di averlo stretto.
  • shield-prompt lasciato al suo default. Spento. Su un agent che ingerisce documenti recuperati, è il percorso di injection lasciato aperto.
  • Loop senza limite. Nessuna policy del gateway esprime "fermati dopo sei iterazioni". Solo l'applicazione può farlo, quindi è un contratto, non un controllo.
  • MCP più workspaces. Non supportati insieme oggi. Scoprirlo dopo aver promesso entrambi a un team è un rollback di architettura.

Cosa eredita la Parte 9

Applicazioni con orchestrazione, tools pubblicati attraverso lo stesso gateway e content safety nel percorso della richiesta. Tutto configurato in policy XML, mapping degli alias e definizioni di product che oggi raggiungono la produzione come qualsiasi altra modifica, che è la parte non ancora esaminata. Prossima tappa: Azure DevOps, e cosa significa mettere il cambio di versione di un modello dietro una evaluation invece che dietro un commento di review.

Leggi questo dopo

Per il lato infrastruttura e piattaforma di come far girare tutto questo su scala, gli appunti tecnici sono su ercan.cloud, e l'hub è su ercanermis.com.

Riferimenti