“No, intendevo questo …”
Quante volte negli utilizzi di tutti i giorni con le intelligenze artificiali ci siamo ritrovati a scrivere questo.
Se ci riflettiamo un attimo, quante volte ci siamo trovati a utilizzare questa frase anche nella vita di tutti i giorni nel dialogo con gli esseri umani.
In questo articolo parlerò del “Reflection Pattern” nei sistemi AI.
Fortunatamente noi essere umani siamo tendenzialmente un pochino più bravi delle intelligenze artificiali nel capire un contesto per rispondere a domande.
I modelli probabilistici, per definizione, lo sono meno.
Se chiedete a un essere umano “dammi tre i film dal 1990 al 2000 che parlano di tecnologie e startup”, la risposta sicuramente non mancherebbe di affidabilità per quanto riguarda le tematiche del film e l’anno di uscita.
Le cose sono un pochino diverse se lo chiediamo alle AI, dove il problema delle allucinazioni è costante e all’ordine del giorno.
Ma le cose sono migliorate, lo abbiamo percepito tutti. Non sono solo migliorati i modelli, ma anche il design di questi sistemi.
Se utilizziamo ChatGPT, Gemini, Claude noteremo come ci sia una fase di “thinking”, o come probabilmente nei modelli
più avanzati, è lo stesso modello che chiede delle domande all’utente per chiarificare il contesto, un pò esattamente come si fa nell’interazione con un essere umani.
Reflection Pattern: cosa è?
Il Reflection pattern è un design pattern che permette a un sistema “agentico” di riflettere sui propri stessi comportamenti al fine di essere più efficace.
Ma in cosa consiste e come si fa?
Spoiler: non è così complicato come la parola potrebbe farlo sembrare.
Andiamo a spiegare questo concetto con un caso pratico semplicissimo: un movie finder.
Movie finder Reflection Pattern
Per prima cosa definiamo un attore, ossia un LLM istruito ad hoc per agire come Cinephile
# ROLE: The Cinephile (Movie Suggester)
1. A good film recommendation surfaces what the user would never find on their own.
...
...
# I. HOW YOU RESPOND
- If the user gives you a genre, decade, or mood — dig into the real underground, not the acclaimed underground unless specifically asked
- For each give: title, year, one-line reason to why you picked this movie based on user request
# OUTPUT FORMAT (strict JSON)
{
"movies": [
{
"title": "string",
"year": number,
"reason": "string — why this matches the vibe"
}
]
}Code language: PHP (php)
(prompt semplificato ai fini di scrittura di questo articolo)
Molto semplice con la sola accortezza di tornare un dato strutturato.
Normalmente se creiamo eseguiamo una call a un LLM istruito in questo modo, la risposta sarà tendenzialmente sufficiente in alcuni casi, mentre per altri casi più complessi molto probabilmente andremo incontro ad allucinazioni:
- date errate
- film non esistenti
- film non trovati
- film non corretti
- …
Ed è proprio qui che possiamo intervenire nel sistema introducendo un secondo attore che in questo esempio chiameremo Clerk, un addetto al videonoleggio.
Proprio colui che una volta incontravamo al Blockbuster negli anni 90, che mi manca a tal punto che ho provato a riprodurlo
Il Clerk, in questo esempio agirà da “fact checker”. Non ha particolari gusti, è freddo, ed è impostato per giudicare e criticare severamente le scelte del Cinephile.
# ROLE: The Clerk (Movie Fact-Checker)
You are a pedantic, data-driven movie database clerk. You have no taste — only facts.
# RESPONSIBILITIES
For each suggested movie, call tavily_search with max_results=3 using a query that targets
BOTH the film's existence AND its relevance to the user's specific criteria.
...
# OUTPUT FORMAT (strict JSON)
{
"critiques": [
"MovieTitle (year): [EXISTS ✓/✗] [YEAR ✓/✗] [CRITERIA FIT ✓/✗/UNVERIFIED] — explanation"
],
"isSatisfied": boolean,
"summary": "string — one sentence naming every film and its verdict"
}Code language: PHP (php)
(prompt semplificato ai fini di scrittura di questo articolo)
Andremo dunque a modificare il prompt del Cinephile, istruendo quest’ultimo che può ricevere delle critiche, ed in tal caso modificare il risultato prodotto precedentemente per produrre un risultato più efficace applicando le critiche del Clerk in questo modo:
# I. PREVIOUS CRITICS
If there are previous critics to fix check them and reuse accepted movies on the output.Code language: PHP (php)
Se mettiamo il Cinephile e il Clerk insieme in un “loop” otterremo diverse interazioni.
Quante?
Fin tanto che il Clerk non è soddisfatto, oppure raggiungo un maxRetry impostato per non entrare in loop infiniti ma soprattutto per non spendere una valanga di token e, dunque, di soldi.
Normalmente ci possiamo accontentare di 3 iterazioni, ma questo chiaramente dipende dal contesto e dal dominio del problema.
Il sistema, oltre al loop tra Cinephile e Clerk, ha anche un primo nodo “Refiner“, volto a capire la richiesta dell’utente trasformandola in un input strutturato in un json del tipo:
{
"primary_genre": "science fiction",
"secondary_genres": ["musical vibe"],
"start_year": 1970,
"end_year": 1979,
"is_classic": false,
"original_text": "I want some weird 70s space movies that feel like David Bowie's music",
"query_info": "weird space science fiction 1970s Bowie vibe"
}Code language: JSON / JSON with Comments (json)
Questo permette semplicemente di avere un input strutturato al primo step del Cinephile.
Un ultimo nodo chiamato Curator si occuperà invece di prendere il risultato finale a fine loop ed filtrare eventualmente
le ultime critiche del Clerk e produrre un risultato all’utente finale.
Di seguito riportato il grafico del loop di questo esempio.
MovieReflection in action
Allo scopo di vedere questo processo, ho implementato in Golang un Movie Finder, e mostrerò a seguire le interazioni del sistema.
Il codice può essere trovato qui, e tengo a specificare che è solo a scopo di dimostrazione, non certamente un workflow production ready.
Prepariamo una query abbastanza complicata da indurre in errore il Cinephile e vedere il processo di correzione in atto.
Query: “Voglio 3 film dove la crittografia è centrale alla trama, non come MacGuffin ma come meccanismo che il protagonista capisce davvero”
Run 1 — REFINER
↑ 284 ↓ 96 $0.0013 1.767s
{
"start_year": null,
"end_year": null,
"primary_genre": "all",
"secondary_genres": [],
"query_info": "movies about cryptography as central plot device protagonist solves"
}Code language: JSON / JSON with Comments (json)
Run 2 — Cinephile
| Titolo | Anno | Note |
|---|---|---|
| Enigma | 2001 | Protagonista codebreaker WWII, crittografia al centro della trama |
| Cry The Beloved Country | 1997 | Subplot con un crittografo che decifra un codice ad alto rischio |
| Rosencrantz and Guildenstern Are Undead | 2009 | Indie con vampiri e codici cifrati come motore narrativo |
Run 3 — Clerk ✗ RETRY
| Film | EXISTS | YEAR | CRITERIA FIT | Note |
|---|---|---|---|---|
| Enigma (2001) | ✓ | ✓ | ✓ | Matematico codebreaker a Bletchley Park — confermato |
| Cry The Beloved Country (1997) | ✓ | ✓ | ✗ | Nessuna crittografia — film su un pastore zulu a Johannesburg |
| Rosencrantz and Guildenstern Are Undead (2009) | ✓ | ✓ | ✗ | Commedia vampiresca su Amleto — nessun codice cifrato |
✗ Solo Enigma (2001) soddisfa i criteri. Due film da sostituire.
Run 4 — Cinephile
↑ 318 ↓ 162 $0.0019 4.504s
Critiche ricevute dal Clerk:
- Enigma (2001) fits all criteria, but Cry The Beloved Country (1997) and Rosencrantz and Guildenstern Are Undead (2009) do not have verified cryptography-centered plots.
| Titolo | Anno | Note |
|---|---|---|
| Enigma | 2001 | Codebreaker WWII, crittografia cuore del thriller |
| The Imitation Game | 2014 | Alan Turing e la decifrazione Enigma — processo reale, non MacGuffin |
| Pi | 1998 | Matematico ossessionato da pattern numerici e codici |
↻ Correzione applicata — sostituiti i due film bocciati dal Clerk
Run 5 — Clerk ✓ SATISFIED
↑ 2898 ↓ 397 $0.0090 7.846s
| Film | EXISTS | YEAR | CRITERIA FIT | Note |
|---|---|---|---|---|
| Enigma (2001) | ✓ | ✓ | ✓ | Confermato: processo di codebreaking dettagliato |
| The Imitation Game (2014) | ✓ | ✓ | ✓ | Confermato: Turing e macchina Enigma, crittografia centrale |
| Pi (1998) | ✓ | ✓ | ✓ | Accettato: pattern numerici assimilati a crittografia |
✓ Tutti e tre i film soddisfano i criteri.
⚠ Falso positivo silenzioso — Pi è un film su numerologia e ossessione matematica, non crittografia in senso stretto. Questo ci fa capire che nonostante il fatto che il Clerk abbia fatto una verifica, il sistema rimane sempre stocastico e non deterministico.
Run 6 — OUTPUT FINALE
| Titolo | Anno | Motivazione |
|---|---|---|
| Enigma | 2001 | La crittografia è il fulcro: protagonista esperto decifra codici nazisti mostrando il processo reale |
| The Imitation Game | 2014 | Vera storia di Turing, focus sul funzionamento della decifrazione Enigma |
| Pi | 1998 | Protagonista ossessionato da schemi nascosti nei numeri — crittografia centrale nella trama |
Analisi
Il ciclo si chiude in 6 run con una convergenza netta. Tre dinamiche degne di nota:
Run 2 — allucinazione su film reali. Il Cinephile non inventa titoli inesistenti, ma fabbrica trame false per film reali: Cry The Beloved Country è un dramma sudafricano senza alcun elemento crittografico; Rosencrantz and Guildenstern Are Undead è una commedia di vampiri su Amleto. Il Clerk smonta entrambe citando le fonti.
Run 3 — il Clerk lavora correttamente. Il formato EXISTS / YEAR / CRITERIA FIT permette di distinguere con precisione il tipo di fallimento: non “film sbagliato” in generale, ma quale check specifico ha fallito e perché.
Run 5 — falso positivo su Pi. Il Clerk approva Pi assimilando “ossessione per i pattern numerici” a crittografia. È un limite reale: la verifica automatica non distingue tra concetti adiacenti quando le fonti non usano esattamente le stesse parole della query.
Un revisore umano avrebbe probabilmente capito meglio questo dettagli
Conclusioni
In questo articolo ho presentato il Reflection Pattern, applicandolo ad un concetto molto semplice: un Movie Finder.
Il Reflection Pattern si basa sulla semplice idea che un sistema possa fare meglio se qualcuno lo corregge.
In fondo è quello che facciamo anche noi ogni giorno. Scriviamo una mail, la rileggiamo, cambiamo tre parole.
Consegniamo un progetto, riceviamo feedback, lo miglioriamo.
Scriviamo articoli come questo e li rileggiamo e correggiamo iterativamente.
Non perché la prima versione fosse sbagliata, ma perché un secondo sguardo quasi sempre aggiunge qualcosa.
In questo workflow succede circa la stessa cosa: il Cinephile sbaglia, il Clerk corregge, il ciclo riparte.
Alla fine il risultato è migliore non perché qualcuno sia diventato più bravo, ma perché il sistema è stato progettato per non fidarsi ciecamente di se stesso.
