Chiarezza: la regola del collega
La documentazione propone un test semplice: fai leggere il prompt a un collega che non conosce il compito e chiedigli di eseguirlo. Se si confonde lui, si confonde anche Claude. Da qui tre abitudini concrete. Primo, sii esplicito su formato e vincoli dell’output desiderato, e se vuoi un comportamento sopra la media chiedilo, invece di sperare che il modello lo deduca da un prompt vago. Secondo, spiega il motivo di un’istruzione: la doc contrappone un secco divieto di usare i puntini di sospensione alla stessa regola motivata dal fatto che la risposta verrà letta da un motore di sintesi vocale che non sa pronunciarli — con la motivazione il modello generalizza ai casi che non hai previsto. Terzo, quando l’ordine o la completezza dei passi contano, dalli come elenco numerato.
Un caso particolare merita attenzione perché è controintuitivo: per il formato conviene dire cosa fare invece di cosa non fare. Al posto di vietare il markdown, chiedi prose paragraphs; e se il divieto resta ambiguo, usa un tag XML come indicatore di formato.
Esempi: quanti, e fatti come
Qui le due fonti ufficiali non dicono la stessa cosa, ed è utile saperlo. Il blog di prompt engineering consiglia di partire da un solo esempio e aggiungere il few-shot solo se l’output non è ancora quello che serve; la guida di riferimento sul prompting dice che per i risultati migliori se ne includano da tre a cinque. La sintesi operativa è: parti da uno, e sali verso i tre-cinque solo quando una eval fallisce, non per abitudine.
Contano più il come del quanto. Gli esempi devono rispecchiare il caso d’uso reale, coprire i casi limite ed essere abbastanza vari da non far cogliere a Claude uno schema che non intendevi, e vanno racchiusi in tag dedicati così che si distinguano dalle istruzioni:
<examples>
<example> ...caso tipico... </example>
<example> ...caso limite... </example>
</examples>
Il modo tipico di sbagliare è mettere cinque esempi quasi identici: il modello impara la coincidenza, non la regola.
System contro user: è una questione di priorità
Il ruolo va nel system prompt, e basta una frase per orientare tono e comportamento. Ma la differenza vera fra i due ruoli non è stilistica: un messaggio user è trattato come proveniente dall’utente finale, un messaggio system come proveniente da te che gestisci l’applicazione, e quando i due confliggono vince il system. Lì dentro mettici i fatti e i vincoli operativi che devono reggere anche se l’utente chiede altro.
Cambiare il system prompt a metà sessione ha però un costo: il prefisso della richiesta viene hashato nell’ordine tools, poi system, poi messages, quindi anche solo aggiungere una frase in fondo al campo system di primo livello cambia l’hash e fa mancare la cache per tutto quello che segue. I messaggi di sistema a metà conversazione risolvono questo: appendi un messaggio con ruolo system nel punto in cui l’istruzione diventa rilevante, il prefisso in cache resta identico e l’istruzione conserva il peso di sistema. Vale da lì in avanti, e i messaggi di sistema più recenti prevalgono sui precedenti e sul campo di primo livello. Attenzione ai vincoli di posizione: non può essere il primo elemento di messages, deve seguire immediatamente un turno user e non può stare fra un blocco tool_use e il suo tool_result, altrimenti la richiesta torna 400. Verifica anche il supporto del modello che stai usando.
Input non fidato: sanificare significa collocare
La sanificazione, prima che filtrare stringhe, è decidere dove finisce il contenuto di terze parti. Regola: pagine web, email, OCR e risultati di tool vanno consegnati dentro blocchi tool_result, mai nel system prompt né in un normale blocco di testo user — Claude è addestrato a guardare con scetticismo le istruzioni che arrivano da un tool result, e mettere quel testo in un messaggio di sistema gli regala autorità da operatore. Dichiara nel system prompt che il contenuto restituito dai tool è dato, non comando, e che non può cambiare gli obiettivi. Codifica il payload in JSON invece di concatenarlo: l’escaping toglie all’attaccante il trucco di chiudere una virgoletta per uscire nel contesto delle istruzioni. Per lo screening, un modello leggero più structured outputs ti danno un verdetto booleano su cui ramificare. Il simmetrico è meno noto: non mettere le tue istruzioni dentro un tool_result, perché rischiano di essere ignorate o segnalate come iniezione; mandale nel turno user successivo.
Sul contesto lungo, infine, la collocazione paga: dati e documenti voluminosi vanno in alto, sopra domanda, istruzioni ed esempi, con la richiesta in fondo.
Vincoli di output e iterazione
Il prefill — precompilare l’inizio del turno assistant per forzare un formato — non è più supportato sui modelli recenti: quelle richieste tornano 400. Se lo usavi per costringere il JSON, la sostituzione è structured outputs; se lo usavi per eliminare i preamboli, un’istruzione esplicita nel system prompt più eventuale pulizia in post-processing.
Il resto è metodo: la doc mette come prerequisito al prompt engineering avere criteri di successo definiti e un modo per testarli empiricamente. Senza eval non stai iterando, stai cambiando frasi.