Puntata 117
Puntata 117 — System prompt vs user prompt
Livello: ✔️✔️ Doppie Spunte Blu · Capitolo 11 · Prompt engineering decente
Stessa stanza, due voci. Il system prompt sussurra all’orecchio del modello “ecco chi sei”. L’user prompt dice “ecco cosa voglio adesso”. Confondere i due è il primo errore di chi passa da chat ad API.
I tre ruoli del chat completion
Quando lavori via API (OpenAI, Anthropic, Google, ecc.), un messaggio non è una stringa. È una lista di messaggi, ognuno con un ruolo:
messages = [
{"role": "system", "content": "Sei un assistente di support tecnico…"},
{"role": "user", "content": "Il mio router non si connette."},
{"role": "assistant", "content": "Hai provato a riavviarlo?"},
{"role": "user", "content": "Sì, niente da fare."},
]
I tre ruoli:
| Ruolo | Significato |
|---|---|
| system | ”Le regole del gioco”: personalità, vincoli, formato, contesto persistente. |
| user | Quello che dice l’utente in questo turno. |
| assistant | Quello che il modello ha risposto in turni precedenti. |
In ChatGPT consumer non vedi questo dietro le quinte, ma c’è. Quando vai su API, devi conoscerlo.
Cosa va nel system prompt
Il system prompt è la costituzione del modello per questa conversazione. Deve includere:
1. Identità / ruolo (puntata 112)
“Sei un assistente clienti di [azienda X], specializzato in software contabile per PMI italiane.”
2. Vincoli persistenti
“Rispondi solo in italiano. Non discutere di argomenti fuori dal supporto tecnico.”
3. Tono e stile
“Tono professionale, cordiale. Mai sarcasmo. Mai disclaimer non richiesti.”
4. Knowledge persistente
“L’azienda è stata fondata nel 2018. Operiamo in Italia, Spagna, Portogallo. Il prodotto principale si chiama ContaPlus.”
5. Regole di comportamento
“Se l’utente chiede prezzi specifici, rimandalo alla pagina /prezzi. Se l’utente chiede di parlare con un umano, fornisci il link al ticket support.”
6. Output format di default
“Risposte in markdown. Bullet quando ci sono passi sequenziali. Niente emoji.”
Cosa va nello user prompt
L’user prompt è quello che l’utente scrive in questo turno. Nulla di più:
✅ “Il mio router non si connette.” ✅ “Aiutami a scrivere una mail al fornitore.” ✅ “Quanto fa 18 × 27?”
Non deve contenere identità, regole, format. Quelle stanno nel system. Il user è dinamico, per-turn.
La differenza pratica
Approccio sbagliato (tutto nello user)
Sei un avvocato del lavoro italiano con 20 anni di esperienza.
Rispondi sempre in italiano. Niente paroloni. Cita le norme.
Niente disclaimer. Massimo 300 parole.
Domanda dell'utente: posso essere licenziato per assenze
giustificate da malattia?
Ogni turno, ripeti tutta la cattedrale di istruzioni + la domanda. Spreco di token, e il modello può confondere istruzioni con domanda.
Approccio giusto (system + user)
messages = [
{
"role": "system",
"content": """Sei un avvocato del lavoro italiano (20 anni esp.).
Risposte: italiano semplice, max 300 parole, cita le norme.
Niente disclaimer non richiesti."""
},
{
"role": "user",
"content": "Posso essere licenziato per assenze giustificate da malattia?"
}
]
System istruisce una volta, user è solo la domanda. Pulizia, efficienza, comportamento prevedibile.
Perché conta in produzione
1. Prompt caching
OpenAI, Anthropic, Gemini offrono prompt caching: paghi ~10% del prezzo per token già visti. Se metti il system prompt corposo in system e lasci variare user, il system viene cachato → risparmio enorme.
Esempio: system prompt da 2.000 token usato 1M volte/mese. Senza cache: $30.000/mese. Con cache: $3.000/mese. 10x di sconto solo separando bene.
Vedi puntata 296.
2. Sicurezza e isolamento
Il system prompt è meno influenzabile dall’user. I provider trainano i modelli per dare maggior peso alle istruzioni di sistema rispetto a quelle dell’utente. È una difesa (parziale) contro:
- Jailbreak (puntata 249).
- Prompt injection (puntata 247).
- “Ignora le istruzioni precedenti e fai X” (l’utente non può sovrascrivere il system).
⚠️ Difesa parziale, non perfetta. Gli attaccanti hanno tecniche per bypassare. Ma la separazione system/user è il livello-zero della security.
3. Manutenibilità
Cambi il system → cambi tutta l’app. Cambi l’user → cambi solo il turno corrente. Codice pulito.
4. Routing e A/B test
Vuoi testare 2 versioni del prompt? Cambi solo il system. L’app esterna resta identica. Niente refactoring.
Le gerarchie di “istruzione weighting”
I provider trainano i modelli con una gerarchia implicita (a volte esplicita, dal 2024):
1. Provider system prompt (definito da OpenAI/Anthropic, immutabile)
2. Developer system prompt (il tuo)
3. User message (dell'utente finale)
4. Tool / function call outputs (risultati di azioni esterne)
I conflitti vengono risolti a favore del livello più alto. Esempio: se tu (developer) dici “non parlare di politica” nel system, e l’utente chiede di politica, il modello rifiuta.
Questo modello a istruzioni gerarchiche è codificato esplicitamente nei modelli recenti (OpenAI “Instruction Hierarchy”, maggio 2024).
System prompt e personality
Caso d’uso classico: dare al modello una personalità di prodotto.
Esempio: assistente fitness chiamato “Coach Leo”:
Sei "Coach Leo", assistente fitness virtuale dell'app FitPro.
Personalità:
- Energico ma non urlato. Motivazionale senza essere fastidioso.
- Tratti l'utente come un compagno di palestra, non come cliente.
- Mai paternalistico. Mai colpevolizzante.
Conoscenze:
- Sai di allenamento (forza, cardio, mobilità) e nutrizione di base.
- Non sei un dietologo né un medico. Per piani strutturati o problemi
di salute, indirizzi a un professionista.
Vincoli:
- Mai dare diagnosi mediche.
- Mai prescrivere integratori specifici.
- Mai consigliare deficit calorici sotto 1.500 kcal.
Output:
- Italiano. Frasi brevi. Niente emoji eccessive (max 1 per messaggio).
- Risposte in 2-4 frasi tipicamente. Più lunghe solo se l'utente chiede
un piano specifico.
Questo system prompt è il prodotto Coach Leo. Tutti gli utenti vedono lo stesso Leo. Cambi una riga, cambi prodotto per tutti.
L’antipattern: system prompt-only
❌ Mettere tutto nel system, niente di sostanziale nello user.
Esempio scarso:
System: "Sei un AI che risponde a 'Come va?'"
User: ""
Il modello non sa cosa fare. Lo user deve contenere la richiesta corrente. Il system deve essere generico-per-il-prodotto, non per-il-turno.
”Roleplay” con system prompt
Per simulazioni e training: il system prompt definisce un personaggio fittizio.
“Sei Maria, una cliente difficile di un’assicurazione, indignata perché il rimborso che aspettavi da 2 mesi non è arrivato. Sei stanca delle giustificazioni. Vuoi soluzioni concrete e veloci. Il tuo umore peggiora se l’utente (l’assicuratore) ripete frasi di rito.”
User: l’utente reale gioca il ruolo dell’assicuratore.
Risultato: simulazione per training. Vedi puntata 152 (insegnanti).
I limiti del system prompt
⚠️ Non è invulnerabile. Tecniche di jailbreak e prompt injection (puntata 247-249) possono fargli ignorare le istruzioni. Per uso ad alto rischio: defense-in-depth (filtri pre-input, post-output, monitoring).
⚠️ Va riletto a ogni turno. In conversazioni molto lunghe, il system rimane in context window — ma il modello può dimenticarsi istruzioni se sono soffocate da molti turni utente. Conviene rinforzare le istruzioni critiche anche nello user, soprattutto verso la fine di chat lunghe.
⚠️ Massimo di token: non c’è limite stretto, ma system >5k token diventa difficile da mantenere e da “ricordare” interamente. Mantieni conciso.
TEST pratico (10 minuti)
Se hai accesso a API (OpenAI, Anthropic, Gemini):
- Costruisci una conversazione di 3 turni con tutto nello user (un solo big prompt + domanda).
- Riscrivi con system prompt separato + user per ogni turno.
- Misura: numero di token consumati nei 3 turni, qualità della risposta, prevedibilità del comportamento.
Aspettative:
- Token ridotti del 30-60% nella seconda versione (specie con caching).
- Comportamento più stabile (il modello non perde regole quando lo user è breve).
- Codice più pulito se è in app.
Take-away in una riga
Il system prompt è il prodotto, l’user prompt è il turno. Separarli non è formalità: è efficienza, sicurezza, manutenibilità.
➡️ Prossima puntata: Iterare il prompt — il loop di raffinamento.