Un modello di linguaggio in Azure OpenAI (esposto anche tramite Azure AI Foundry) non “ragiona” leggendo un blocco di testo indistinto: interpreta una conversazione strutturata. Progettare bene questa struttura, insieme ai parametri di generazione, è ciò che distingue una soluzione robusta da un prototipo fragile.
Anatomia di una chiamata chat completions
Una richiesta all’endpoint Chat Completions (o alla più recente Responses API) è una lista di messaggi, ognuno con un ruolo:
- system (o
developernei modelli recenti): definisce identità, comportamento, tono, formato di output e limiti. È il messaggio a maggiore autorità e va posto in cima. - user: l’input finale dell’utente o dell’applicazione.
- assistant: le risposte precedenti del modello; reinserirle mantiene il contesto conversazionale (il modello è stateless, quindi la history va rispedita a ogni turno).
Ogni turno consuma token di input (system + history + user) e produce token di output: entrambi si pagano, e la finestra di contesto è finita. Da qui la regola pratica: contesto conciso, history potata quando non serve.
System message efficace
Un buon system message è specifico e verificabile. Conviene dichiarare esplicitamente:
- Ruolo e ambito: “Sei un assistente che risponde solo su prodotti X”.
- Formato: es. “Rispondi in JSON con i campi
titoloesintesi”. - Guardrail comportamentali: cosa rifiutare, come gestire richieste fuori tema, cosa fare quando non conosce la risposta (“se l’informazione non è nel contesto fornito, dichiara di non saperlo”).
Tecniche di prompt engineering
- Few-shot: inserire 2-4 esempi input→output nel prompt per fissare formato e stile. Alza l’accuratezza su compiti strutturati, ma aumenta i token di input.
- Chain-of-thought: chiedere al modello di ragionare per passi (“spiega il ragionamento prima di concludere”) migliora i compiti logico-matematici, al costo di output più lungo.
- Grounding: fornire nel prompt i dati autorevoli (documenti, risultati di ricerca) e istruire il modello a rispondere solo su quelli. È il cuore del pattern RAG: riduce le allucinazioni ancorando la risposta a fonti verificabili, spesso combinato con Azure AI Search.
Parametri di completamento
- temperature (0-2): controlla la casualità. Valori bassi (≈0) → output deterministici e ripetibili, ideali per estrazione dati o classificazione; valori alti → più creatività e varianza.
- top_p (nucleus sampling, 0-1): limita il campionamento alla massa di probabilità cumulata. È un modo alternativo di regolare la casualità.
- max_tokens /
max_completion_tokens: tetto ai token di output. Protegge da risposte troncate impreviste e controlla il costo in uscita. - stop: una o più sequenze che interrompono la generazione (utile per fermare il modello a un delimitatore).
- frequency_penalty e presence_penalty (-2..2): la prima scoraggia la ripetizione della stessa parola in proporzione alla frequenza; la seconda spinge a introdurre argomenti nuovi. Utili contro output ridondanti.
Effetto su determinismo, verbosità e costi
Per output riproducibili (test, pipeline dati) si tiene temperature bassa e si può fissare un seed. La verbosità dipende da chain-of-thought e max_tokens. Il costo cresce con lunghezza del contesto (few-shot, grounding, history) e con la lunghezza dell’output: un system message enorme si paga a ogni chiamata.
Sicurezza: il system message non basta
Un guardrail scritto nel system message è istruzione, non controllo: un prompt malevolo può tentare di aggirarlo. La difesa reale è a più livelli con Azure AI Content Safety:
- Content filter: filtra input e output su categorie (hate, sexual, violence, self-harm) con severità configurabile.
- Prompt Shields: rileva jailbreak e indirect prompt injection (istruzioni nascoste nei documenti di grounding).
Il system message imposta il comportamento; i filtri e gli shield impongono la sicurezza.
Trappole tipiche d’esame
- Serve output riproducibile per una pipeline di estrazione dati → imposta
temperaturevicino a 0 (eventualmente conseed), non aumentare la creatività. - Vuoi ridurre la casualità → regola o
temperatureotop_p, non entrambi insieme: modificarli in coppia rende il comportamento imprevedibile. - Un system message vieta contenuti dannosi ma passano comunque richieste di jailbreak → aggiungi content filter e Prompt Shields, non irrobustire solo il testo del prompt.
- Il modello ignora la knowledge base e inventa risposte → applica grounding/RAG istruendo a rispondere solo dal contesto fornito, non alzare la temperature.
- I costi per chiamata sono alti → riduci token di input (potatura della history, meno esempi few-shot) e imposta
max_tokens; ricorda che input e output si pagano entrambi.