Lorenzo Angelini.
← Articoli

Engineering · Dentro Kibbo

Kibbo: dall’AI a un’avventura reale

Generare una storia è solo l’inizio. La sfida è trasformarla in un’esperienza che funzioni fuori dallo schermo.

Kibbo

Kibbo è un’app mobile che trasforma l’esplorazione di una città in un’avventura personalizzata. L’utente indica la città, il tipo di esperienza, il tempo disponibile e come vuole muoversi. Da questi elementi nasce un percorso con checkpoint, una narrazione e sfide da affrontare nei luoghi reali.

L’AI dà flessibilità al racconto e alle attività: quiz, indovinelli di osservazione e sfide fotografiche fanno parte dei tipi di checkpoint gestiti dal sistema. Ma il valore del prodotto dipende da qualcosa di molto concreto: riuscire a passare da una proposta interessante a un’esperienza utilizzabile sul telefono, mentre si è in giro.

Le prime sfide tecniche si concentrano proprio su questo passaggio. Ho organizzato il sistema intorno a cinque pilastri: collegare la generazione al mondo reale, definire contratti chiari, coinvolgere l’utente nelle decisioni, gestire le richieste in modo affidabile e rendere i risultati misurabili.

In questo articolo

01 / Luoghi reali

Una tappa deve esistere, non soltanto sembrare plausibile

Un modello può produrre il nome convincente di un luogo senza che quel luogo sia quello giusto. In Kibbo questo problema si traduce in un checkpoint: un punto che una persona dovrebbe raggiungere. Per questo la pipeline include ricerca e verifica dei luoghi tramite Google Places, seguite dalla selezione dei candidati da fornire alla generazione.

Quando i candidati sono sufficienti, la modalità strict limita i checkpoint alla lista verificata e controlla i place ID restituiti. Quando non lo sono, il flusso è meno restrittivo: non sarebbe corretto presentare il grounding come una garanzia universale. Le coordinate vengono risolte e la loro assenza è un errore da gestire, non un dettaglio da nascondere.

La sfida è tenere insieme libertà narrativa e vincoli geografici. Un luogo individuato su una mappa, inoltre, non dimostra da solo che il percorso sia percorribile o accessibile in ogni momento.

02 / Contratti espliciti

Il risultato del modello è un input da validare

L’app non può dipendere da un testo libero da interpretare ogni volta. La generazione restituisce un’avventura strutturata, con campi e tipi di checkpoint definiti. Il backend verifica elementi come campi obbligatori, ordine delle tappe, nomi duplicati e struttura dei quiz.

Un JSON valido non equivale a un’avventura valida. Per esempio, un quiz a scelta multipla deve avere quattro opzioni e una sola risposta corretta. I controlli applicativi fanno rispettare queste regole e la pipeline prevede tentativi limitati con feedback sugli errori.

Anche le responsabilità sono separate: l’orchestratore distingue creazione dell’avventura, validazione dei checkpoint, contestazione di una risposta e ripresa di una sessione. Il modello contribuisce al contenuto; lo stato e le regole del prodotto restano responsabilità del software.

03 / Controllo umano

L’utente conferma prima della generazione completa

Prima di generare l’avventura completa, il flusso può chiedere informazioni e presentare un’anteprima da confermare. È un passaggio human-in-the-loop: la persona partecipa alla decisione invece di ricevere soltanto il risultato finale.

Perché questo funzioni, la pausa deve essere rappresentata nel backend. Le sessioni conservano contesto e stato in database; la ripresa verifica utente, scadenza e versione dello stato. Una conferma deve riferirsi alla proposta corretta, anche quando arriva in una richiesta successiva.

La sfida non è semplicemente mostrare un pulsante Conferma. È modellare ciò che accade prima e dopo quel pulsante, compresi i casi in cui la sessione non è più utilizzabile.

04 / Affidabilità

Un doppio tap non deve avviare due generazioni

La conferma di un’anteprima è un esempio piccolo ma significativo. Due richieste possono arrivare quasi insieme: disabilitare il pulsante nell’interfaccia aiuta l’esperienza, ma il controllo decisivo deve essere sul server.

Kibbo usa un aggiornamento condizionale atomico sul run: solo la richiesta che riesce a portarlo da waiting_human a running procede con la generazione. Le altre ricevono una risposta che segnala l’elaborazione già in corso. È una protezione specifica contro le conferme concorrenti, non una promessa di esecuzione exactly-once dell’intero sistema.

Questa scelta lega l’esperienza mobile alla gestione dello stato persistente. Nello stack, React Native ed Expo coprono l’app; Supabase e le Edge Functions ospitano il backend; PostgreSQL conserva i dati e PostGIS supporta le operazioni geografiche, come la ricerca di avventure vicine.

05 / Qualità misurabile

Osservare le esecuzioni, confrontare le modifiche

Quando una generazione fallisce, serve capire dove: parsing, schema, coordinate, vincoli sui luoghi o chiamate ai servizi esterni. I log dei run e delle chiamate ai tool, insieme a token, costi stimati e latenza, rendono questi passaggi osservabili.

La generazione registra anche un fingerprint con versioni e configurazione. Accanto ai log c’è una suite di eval che richiama direttamente la pipeline su casi fissi e confronta esecuzioni diverse. I controlli coprono struttura, grounding, compatibilità delle distanze con il percorso, regole di sicurezza ed esperienza di gioco.

Questi punteggi sono indicatori automatici, non una certificazione del divertimento o della sicurezza sul campo. La sfida è usarli per individuare regressioni e confrontare le modifiche senza scambiare una singola buona risposta per la qualità dell’intero prodotto.

La parte che rende il prodotto reale

Il filo comune è che l’AI non elimina il lavoro di progettazione dei sistemi: lo rende più evidente. Ogni contenuto generato deve attraversare confini chiari prima di diventare qualcosa su cui l’utente può fare affidamento.

Questo primo articolo racconta le fondamenta di Kibbo. Sono anche i punti da cui partire per approfondire il progetto: come scegliere i luoghi, come gestire una conferma e come valutare una generazione oltre la sua prima impressione.