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 developer nei 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 titolo e sintesi”.
  • 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 temperature vicino a 0 (eventualmente con seed), non aumentare la creatività.
  • Vuoi ridurre la casualità → regola o temperature o top_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.