Immagine di copertina per la "AI Debug Challenge" con un ragno pixel art bianco appeso a un filo, su sfondo sfumato blu scuro e viola.

Abbiamo costruito un gioco sui bug dell'AI. La parte difficile non è stata l'AI

Integrare l'AI in un prodotto è relativamente facile. Decidere cosa dovrebbe poter fare, e progettare tenendo conto di ciò che non riesce a fare in modo affidabile, è il vero lavoro. In Nephila non partiamo chiedendoci quanto possiamo automatizzare. Ci chiediamo dove il modello genera valore, quali decisioni può prendere e quali devono restare in mano alle persone o a codice deterministico.

Un'applicazione agentica ha bisogno di confini netti: cosa sa l'AI, quanta autonomia le viene data, dove finisce la sua responsabilità. Il nostro principio è semplice: dare all'AI un compito preciso e mantenere il controllo su regole e risultati, partire dal prodotto e dall'esperienza per progettare l'architettura, non dal modello.

Perché l'abbiamo costruito (in breve)

Per PyCon Italia 2026 abbiamo costruito l'AI Debug Challenge: un piccolo gioco web che parte da una domanda scomoda: riesci a trovare i bug un'AI lascia dietro di sé?

Tre livelli, trenta snippet di Python generati da un'AI. Il livello uno nasconde un bug di correttezza evidente, di quelli che un junior dovrebbe riuscire a cogliere. Il livello due nasconde un difetto di manutenibilità o di gestione degli errori: un'accezione mal gestita, l'astrazione sbagliata. Il livello tre nasconde qualcosa di sistemico: un accoppiamento, un invariante mancante, un design che non regge la scalabilità. A ogni passo leggi il codice, scegli cosa non va, e un'AI ti restituisce un feedback breve e schietto.

L'abbiamo costruito per prendere una posizione concreta: l'AI è utile, ma non sostituisce il giudizio ingegneristico. Trenta occasioni per vedere la differenza tra codice che gira e codice fatto bene.

Questo è il perché, ed è la parte che tutti si aspettano. Quello che ci ha sorpreso è stato il come, e in particolare il ruolo dell'ingegneria. Perché c'è una cosa di cui nessuno ti avverte quando sviluppi con l'AI: l'AI è la parte facile.

Abbiamo chiesto all'AI di sbagliare di proposito. Quella è stata la parte facile

Far produrre a un modello uno snippet buggato è banale. Ottenere bug plausibili ha richiesto progettazione. Plausibile significa abbastanza sottile da ingannare un junior, ma sbagliato nei modi specifici in cui tende a sbagliare il codice generato da un'AI. Tutto ciò che sta attorno al modello, la parte che decide se l'insieme regge davanti a una platea, è stato invece ingegneria pura.

Lo si vede già nella prima decisione che abbiamo preso. Le trenta domande sono pre-scritte e vengono selezionate all'inizio di ogni sessione, mai generate al volo. In parte per garantire una latenza prevedibile, ma soprattutto per un motivo che è il tema di tutto il progetto: nel momento in cui lasci che il testo di uno sconosciuto raggiunga un modello, hai aperto una superficie d'attacco. Un gioco sui limiti dell'AI ci ha messi faccia a faccia proprio con quei limiti.

La parte interessante di questo progetto, allora, non è il contenuto generato dall'AI. È il sistema costruito attorno: una mappa di decisioni su cosa al modello è permesso fare, e cosa, deliberatamente, no.

Gli agenti e i loro confini

Ogni risposta che invii attraversa la stessa breve catena: un reviewer che filtra il tuo input, un evaluator che lo valuta, e un arbitro, fatto di solo codice, senza alcun modello al suo interno, che ha l'ultima parola. Ogni agente del sistema vive dentro un confine scelto di proposito. Il secondo articolo di questa serie ripercorrerà l'intera catena, richiesta per richiesta.


Welcome e summary: libertà, dentro un recinto

L'AI parla con voce propria in due punti (un terzo verrà trattato nel prossimo articolo): il messaggio di benvenuto che apre la challenge e il riepilogo che la chiude, ricapitolando come sei andato nei tre livelli, quanti turni hai bruciato e quante volte hai provato a barare. Entrambi parlano con un tono caldo, rivolto a chi sta dall'altra parte dello schermo. In ogni altro punto della challenge, dove conta la correttezza, quella libertà sparisce.

Il comportamento in apertura e in chiusura è governato dall'esterno. Entrambi i prompt vivono in un prompt registry (Phoenix), con un fallback locale nel caso il registry non sia raggiungibile. Questo ci dà tre vantaggi. Possiamo regolare come parlano questi agenti senza rilasciare codice. Se il registry è giù, hanno comunque qualcosa da dire invece di andare in crash. E, meno ovvio ma altrettanto prezioso, i prompt smettono di essere artefatti di ingegneria chiusi nel repository: il team di comunicazione può aprirli, rivederne il testo e provare come suonano, tutto senza toccare la codebase o aspettare un deploy. L'intera voce rivolta all'utente, dal primo saluto al riepilogo finale, resta nelle mani di chi possiede la voce del brand.


Valutazione: il giudizio non è mai lasciato all'istinto

Questo è il cuore, ed è dove la maggior parte delle persone si aspetterebbe un unico modello intelligente. Non è così.

Quando invii una risposta, non va a un solo modello che "fiuta" se hai ragione. Passa per una pipeline di due modelli e un referee deterministico, ognuno con un compito che gli altri non possono svolgere.

Il reviewer va per primo. Prima ancora che l'evaluator veda qualcosa, un agente dedicato, il jailbreak reviewer, ispeziona il tuo input. Gira con il proprio modello e il proprio prompt, e viene tenuto deliberatamente all'oscuro: vede le opzioni di risposta e il tuo input, ma non il codice né la risposta corretta. Se fiuta un tentativo di manipolazione, la pipeline si ferma lì: l'evaluator principale non viene nemmeno chiamato. È il principio del privilegio minimo applicato a un agente. Meno contesto ha un componente, minore è la superficie su cui un attaccante può lavorare.

L'evaluator è vincolato. Solo se il reviewer dà il via libera, l'evaluator entra in gioco. Il suo compito è mappare la tua risposta in testo libero su una delle opzioni fisse e decidere se è giusta o sbagliata, ma non può farlo in prosa libera: è obbligato a rispondere attraverso uno schema strutturato, una tool call che deve compilare. Così il codice a valle legge una decisione pulita e tipizzata di cui fidarsi, invece di dover interpretare un paragrafo e sperare bene. E porta con sé una seconda guardia anti-jailbreak indipendente, nel caso qualcosa fosse sfuggito alla prima.

Il referee non ha alcuna componente AI. A governare entrambi i modelli è codice puro: limiti di turni, stato della sessione, regole esplicite. Un tentativo di jailbreak, per esempio, costa un turno ma non segna il livello come risolto: devi comunque tornare con una risposta vera. L'esito finale è vincolato a regole, non all'umore del modello del giorno.

Due modelli indipendenti, più uno strato di codice che non si fida di nessuno dei due. L'OWASP Top 10 for LLM Applications mette la prompt injection al primo posto (LLM01), e le difese che raccomanda si leggono come la distinta dei componenti di questa pipeline: strumenti a privilegio minimo, segregazione del contenuto non fidato dal contesto del modello, e uno strato deterministico nel loop per tutto ciò che conta davvero. Non ci siamo messi a costruire un sistema di sicurezza: mettere un LLM davanti a degli sconosciuti l'ha reso tale, e il manuale per farlo esiste già.


Feedback: fuori dal recinto, del tutto

Quando la challenge è finita, raccogliamo la riflessione del partecipante e la inoltriamo. Non c'è alcun modello in quel percorso; solo validazione, una pipeline e un side effect controllato (email). Non tutto deve essere "intelligente". La maturità ingegneristica sta anche nel sapere dove l'AI non aggiunge nulla, e nel lasciarla fuori di proposito.

Il che lascia una domanda

Tutto questo descrive un sistema costruito per tenere un modello al guinzaglio: confini, un reviewer che filtra, un evaluator che può solo scegliere da un menu, un referee che non si fida di niente. Ma un guinzaglio lo si mette alla prova solo quando qualcosa tira. Cosa succede quando qualche centinaio di sviluppatori e sviluppatrici decidono di romperlo, di proposito, è l'argomento del prossimo articolo.

Prova la challenge → AI Debug Challenge

***

Stefano ha raccontato la nascita della challenge: pipeline, la scelta dei confini, il perché di ogni limite imposto al modello.

La prossima settimana ti raccontiamo invece come abbiamo provato a rompere il modello: qualche centinaio di sviluppatori e sviluppatrici ci hanno messo alla prova con tentativi di jailbreak, alcuni prevedibili, altri no. Ti aspettiamo sul blog per scoprirli. 

***

Abbiamo scritto questo articolo con il supporto dell'AI. Se vuoi saperne di più su come usiamo questi strumenti per la scrittura, ecco la spiegazione.