Il prompt perfetto non esiste, il contesto strutturato sì
La maggior parte dei team che mette un sistema AI in produzione passa settimane a rifinire il prompt di sistema. Versione dopo versione, aggiungono istruzioni, esempi, edge case. E poi, la prima volta che un utente reale fa una richiesta leggermente fuori dal pattern previsto, il modello produce output inconsistenti.
Il problema di solito non è il prompt. È il contesto che il sistema gli ha dato da lavorare.
Il prompt è una funzione. Il contesto sono gli argomenti. Un team che passa il 90% del tempo sulla funzione e il 10% sulla qualità degli argomenti sta ottimizzando la parte sbagliata del sistema.
Cosa significa "context engineering"
Context engineering è il lavoro di decidere, per ogni chiamata al modello:
- Quali informazioni includere
- In quale formato rappresentarle
- In che ordine presentarle
- Quali informazioni escludere deliberatamente
- Come gestire la loro compressione quando il contesto cresce
Il prompt è la parte visibile. Il contesto è quello che determina se il prompt funziona davvero.
I quattro strati di contesto che ogni sistema ha
Quando progetti un chatbot, un agent o un workflow AI, hai sempre quattro strati di contesto — anche quando non te ne rendi conto:
Strato 1 — Istruzioni di sistema: chi è l'assistant, cosa deve e non deve fare, quale tono usa. È lo strato più stabile. Cambia raramente.
Strato 2 — Contesto di dominio: informazioni sulla tua azienda, sui tuoi prodotti, sulle tue policy. È stabile nel tempo ma specifico per la tua implementazione.
Strato 3 — Contesto di sessione: chi è l'utente, da dove arriva, che cosa ha fatto nei turni precedenti. Cambia a ogni conversazione.
Strato 4 — Contesto della query corrente: la richiesta specifica che il modello deve risolvere ora, con tutti i dati recuperati dinamicamente per rispondere.
Sistemi che funzionano male spesso hanno uno di questi strati troppo grande, troppo piccolo, o mescolato con gli altri in modo confuso.
La regola della separazione tra strati
Un pattern che vale quasi sempre: ogni strato dovrebbe essere modificabile indipendentemente dagli altri.
Se cambi il tono dell'assistant, dovresti poter toccare solo lo strato 1. Se aggiorni una policy aziendale, dovresti toccare solo lo strato 2. Se l'utente ha cambiato piano nel CRM, dovrebbe propagarsi allo strato 3 senza riscrivere il prompt.
Quando vedi un prompt di sistema che include istruzioni generali, pezzi di knowledge base, variabili utente hard-coded e la domanda dell'utente tutta mescolata — sai che il sistema farà fatica a evolvere. Ogni cambiamento piccolo richiederà un test su tutto.
Il pattern "compact, then expand"
Nei sistemi con contesto lungo, una trappola comune è dare al modello tutto quello che si ha, nella speranza che trovi quello che serve. È quasi sempre un errore.
Un pattern migliore è compact, then expand:
- Prima chiamata: il modello riceve una versione compatta del contesto (titoli, riassunti, metadati) e decide cosa serve davvero.
- Seconda chiamata: il sistema recupera solo i pezzi richiesti in forma estesa e li passa al modello per la risposta finale.
Questo pattern ha tre vantaggi misurabili:
- Costo: due chiamate mirate spesso costano meno di una chiamata gigante.
- Accuratezza: il modello non si distrae su informazioni irrilevanti.
- Debugging: se qualcosa va storto, sai esattamente in quale step.
Il problema del contesto stantio
Un errore strutturale che si paga nel tempo: caricare nel contesto informazioni che sembravano rilevanti all'inizio della sessione ma non lo sono più.
Se un utente ha iniziato la conversazione chiedendo una cosa e ora ne sta chiedendo un'altra, il contesto accumulato dai turni precedenti può contaminare le risposte nuove. Il modello cercherà di collegare la richiesta corrente al thread precedente anche quando non ha senso farlo.
Due strategie pratiche:
Context reset espliciti: al cambio di topic, comprimere il contesto precedente in un riassunto e ricominciare con un contesto pulito.
Context scoping: marcare ogni pezzo di contesto con un TTL (turni di vita utile). Dopo N turni, viene automaticamente rimosso o compresso.
Il contesto non è un file di testo, è un'API
Il cambio mentale più utile è smettere di pensare al contesto come a una stringa da concatenare e iniziare a trattarlo come a una struttura dati.
context = {
"system": system_instructions,
"domain": load_domain_context(tenant_id),
"session": {
"user": user_profile,
"history_summary": summarize_history(messages, max_tokens=500),
"recent_turns": messages[-4:]
},
"query": {
"text": user_query,
"retrieved_docs": rag_results,
"entities": extracted_entities
}
}
Quando il contesto è strutturato, puoi fare cose che con una stringa monolitica sono impossibili:
- Loggare quale strato ha causato un errore
- A/B testare una modifica solo sullo strato
domain - Riutilizzare gli stessi oggetti
sessiontra sistemi diversi - Validare che ogni strato rispetti i limiti di token prima di inviarlo
Quando il contesto è il collo di bottiglia, smetti di ottimizzare il prompt
La domanda da porsi prima di riscrivere l'ennesima versione di un prompt di sistema è: il modello ha le informazioni giuste, nel formato giusto, al momento giusto?
Se la risposta è no, nessun miglioramento del prompt risolverà il problema. Se la risposta è sì, il prompt probabilmente va bene così com'è.
Il prompt engineering è il lavoro dell'ultimo miglio. Il context engineering è il lavoro che rende l'ultimo miglio possibile.