Uso personale

Studio AI — Caso Studio

Piattaforma AI-native di studio universitario con RAG su pgvector e infrastruttura AI interamente self-hosted, sviluppata in autonomia end-to-end.

Progetto privato — in uso personale
  • Next.js 16
  • React 19
  • TypeScript
  • PostgreSQL
  • pgvector
  • Prisma 7
  • Ollama
  • Docker
Studio AI — Caso Studio

Piattaforma AI-native di studio universitario, progettata e sviluppata in autonomia end-to-end: dall'architettura del backend all'infrastruttura self-hosted per l'inferenza AI, fino al testing automatizzato.

In sintesi

Studio AI è un'applicazione web full-stack che trasforma il materiale di studio universitario (PDF, immagini, pagine HTML) in un ecosistema completo di apprendimento assistito da AI: riassunti, flashcard con ripetizione spaziata, quiz, chat RAG sulle proprie fonti, mappe concettuali, pianificazione dello studio e tracciamento dell'intero percorso di laurea — inclusi calendario, scadenze amministrative, tesi ed esami.

Il progetto nasce e cresce come prodotto reale per un caso d'uso personale (uno studente universitario), non come esercizio dimostrativo: ogni funzionalità è stata guidata da un bisogno concreto, verificata su dati reali e iterata sulla base di problemi effettivamente riscontrati in uso.

  • ~420 file sorgente, 46 modelli dati in un unico schema Prisma coerente
  • 80+ test automatizzati (unit + integrazione con database e AI reali)
  • Infrastruttura AI completamente self-hosted (nessuna dipendenza da API AI a pagamento)
  • Deploy containerizzato, in produzione, in uso quotidiano

~420

file sorgente

46

modelli dati Prisma

80+

test automatizzati

~90

endpoint API

Il problema

Lo studio universitario moderno è frammentato su troppi strumenti: PDF sparsi, note separate, flashcard in un'app, calendario in un'altra, nessun collegamento tra "cosa devo studiare" e "cosa ho già capito". Gli strumenti AI generici (ChatGPT, ecc.) non hanno memoria del materiale specifico dello studente e non si integrano con scadenze, esami e pianificazione reale del semestre.

L'obiettivo: un unico posto in cui caricare le fonti di un esame e ottenere automaticamente materiali di studio derivati e verificabili, più una visione integrata dell'intero percorso di laurea — con un'AI che risponde solo sulla base dei documenti caricati, non per allucinazione.

Architettura

Stack applicativo: Next.js 16 (App Router, React 19) come framework full-stack unico, niente backend separato; PostgreSQL + pgvector per dati relazionali e ricerca semantica nello stesso database; Prisma 7 (con adapter pg nativo) come ORM; Tailwind CSS 4 per lo styling; autenticazione custom (bcrypt + sessioni), niente provider terzi; Web Push per notifiche, Service Worker per supporto offline.

Infrastruttura AI self-hosted end-to-end — la decisione architetturale più caratterizzante del progetto: nessuna chiamata a OpenAI/Anthropic/Google per l'inferenza. Tutto gira su un server remoto dedicato (GPU consumer, 8GB VRAM):

CapacitàTecnologiaDove
Chat / generazione testoOllama, `qwen2.5:7b-instruct`server remoto
Embedding semantico`nomic-embed-text` → pgvectorserver remoto → Postgres
Text-to-speechPiper (leggero) + XTTS-v2 (qualità, opzionale)server remoto
Speech-to-textfaster-whisperserver remoto (CPU)
OCRTesseract.jsin-app

Questa scelta ha richiesto di risolvere problemi che un'API gestita nasconde: gestione del contesto del modello (bug reale di troncamento silenzioso a 4096 token, portato a 16384 su tutti i call site), tuning di temperatura per output strutturati vs. conversazionali, timeout e retry su chiamate di rete lunghe, batching map-reduce per contenuti che superano la finestra di contesto del modello, e condivisione della stessa GPU tra più servizi (Ollama + XTTS).

Architettura

Client

Browser

Backend

Next.js 16 (App Router)

Full-stack monolite

Dati

PostgreSQL + pgvector

AI

Ollama · qwen2.5:7b

Chat / generazione

nomic-embed-text

Embedding semantico

Piper / XTTS-v2

Text-to-speech

faster-whisper

Speech-to-text

BrowserNext.js 16 (App Router)Next.js 16 (App Router)PostgreSQL + pgvectorNext.js 16 (App Router)Ollama · qwen2.5:7bNext.js 16 (App Router)nomic-embed-textnomic-embed-textPostgreSQL + pgvector· pgvectorNext.js 16 (App Router)Piper / XTTS-v2Next.js 16 (App Router)faster-whisper

Pipeline RAG

La pipeline RAG (retrieval-augmented generation) è il cuore tecnico del prodotto. Le fonti caricate vengono segmentate in chunk, embeddate e indicizzate in pgvector; le domande in chat recuperano i chunk più rilevanti prima di essere passate al modello.

  • Soglia di rilevanza adattiva: un semplice LIMIT N sui risultati causava confusione tra argomenti diversi nella stessa chat; introdotta una soglia sulla distanza coseno (misurata empiricamente, non stimata), con fallback che allarga la ricerca solo quando il pool di risultati è povero (meno di 4 chunk) — verificato a impatto zero sulle query già ben servite.
  • Ricerca ibrida: aggiunta ricerca full-text PostgreSQL come tie-breaker per casi di margine sottile tra chunk quasi duplicati (misurato un caso reale con margine di 0,024 sulla distanza coseno).
  • Retrieval consapevole del contesto conversazionale: le domande di follow-up ("e gli altri due?") arricchiscono la query di ricerca con l'ultima domanda dell'utente — bug reale risolto, con miglioramento misurato della distanza di retrieval (0,37 → 0,20 sul caso riprodotto).
  • Eval di accuratezza vero e proprio: costruita una suite di valutazione su 20 domande reali confrontate con flashcard reali esistenti, non solo test di "il sistema risponde senza errori". Iterando su retrieval, prompt e temperatura, l'accuratezza è passata da 65% a 85-95% (a seconda della soglia di giudizio), con causa radice di ogni fallimento verificata singolarmente prima di intervenire.

Generazione di contenuti e affidabilità

Generazione di contenuti strutturati — flashcard, quiz, guide di studio e mappe concettuali — passano tutti da un unico entry point (ollamaGenerateJson) con temperatura bassa (0,3) e validazione dell'output. Bug di scala reale risolto: un progetto con 45 fonti e un altro con una singola fonte da 170.000 caratteri causavano timeout e troncamento silenzioso; risolto con batching map-reduce e riassunti on-demand per fonte, non con limiti arbitrari.

Generazione asincrona: le generazioni AI girano come job in background con notifica push al completamento, non richieste sincrone bloccanti — risolve un bug reale in cui la navigazione dell'utente durante la generazione interrompeva silenziosamente il processo.

Superficie del prodotto

Circa 90 endpoint API e 27 pagine applicative, organizzati attorno a un modello dati di 46 entità.

  • Materiali di studio per corso: sorgenti multi-formato (PDF con conteggio pagine reale, immagini via OCR, HTML), riassunti automatici, guide di studio, mappe concettuali gerarchiche, flashcard (con creazione manuale oltre a quella AI), quiz a scelta multipla e a risposta aperta, simulazioni d'esame.
  • Chat RAG con citazioni verso le fonti originali, cronologia, retry automatico su risposte vuote.
  • Ripetizione spaziata (algoritmo SM-2) per le flashcard, con modalità di ripasso vocale hands-free (STT + TTS).
  • Percorso di laurea: tracciamento esami richiesti, calcolo media ponderata e proiezione voto di laurea, piano di studio con calcolo automatico delle sessioni, simulatore "what-if".
  • Vita universitaria: scadenze amministrative, tracciamento tesi/tirocinio con milestone, rubrica contatti, certificazioni, spese.
  • Calendario integrato: sincronizzazione bidirezionale con Google Calendar e Apple (CalDAV via tsdav), vista giornaliera/mensile unificata, rilevamento conflitti, emoji per categoria.
  • Collaborazione: condivisione progetti in sola lettura via inviti, con separazione netta tra percorsi di scrittura (proprietario) e lettura (invitati).
  • Osservabilità: digest settimanale via push, log errori applicativo (hook nativo onRequestError di Next.js), streak di studio, statistiche.

Qualità e affidabilità

80+ test automatizzati con Vitest: test unitari su logica pura estratta (algoritmo SM-2, calcolo piano di sessioni, merge del retrieval ibrido, deduplica guide) e test di integrazione contro un database Postgres reale dedicato (mai il database di produzione), inclusi embedding pgvector reali e mock mirati delle chiamate Ollama per testare i percorsi di retry.

Estrazione behavior-preserving: la logica pura è stata estratta da moduli accoppiati a Prisma/Ollama senza introdurre mock pervasivi, verificando ogni estrazione contro un caso reale noto.

Diversi bug reali individuati e corretti attraverso revisioni sistematiche, non solo durante lo sviluppo di nuove feature: un mismatch di hydration React (SSR in UTC vs. browser in ora locale), un bug di sincronizzazione calendario che segnalava sempre "successo" anche in caso di errore silenzioso, un crash da prop-funzione passata da Server a Client Component, un bug di calcolo della media ponderata dei quiz.

Deploy containerizzato, sopravvive a riavvii senza intervento manuale, nessuna apertura di porte non necessaria sull'infrastruttura condivisa.

Decisioni tecniche degne di nota

  • AI self-hosted invece di API a pagamento: scelta guidata da costo e controllo, che ha spostato sul progetto la responsabilità di problemi normalmente astratti da un provider (gestione contesto, retry, condivisione GPU) — trattati come parte integrante dell'ingegneria del prodotto, non come dettagli infrastrutturali a parte.
  • Misurare prima di ottimizzare: ogni intervento sulla pipeline RAG (soglie, ricerca ibrida, prefissi di embedding, quantizzazione del modello) è stato validato con dati reali misurati prima/dopo. Un'idea plausibile (prefissi search_query/search_document per l'embedding) è stata testata e scartata dopo aver dimostrato assenza di beneficio reale.
  • Feature additive, non sostitutive: quando un'alternativa tecnica migliore comporta un trade-off (es. Piper vs. XTTS-v2 per il TTS: velocità vs. qualità), entrambe restano disponibili e selezionabili dall'utente invece di forzare una scelta unica.
  • Resilienza alla scala reale: più bug di troncamento/timeout sono emersi non in sviluppo ma testando con dati reali di dimensione realistica (170k caratteri, 45 fonti) — la classe di bug è stata poi cercata e corretta retroattivamente anche nelle feature già in produzione, non solo dove scoperta.

Stack tecnologico completo

Next.js 16 · React 19 · TypeScript · PostgreSQL · pgvector · Prisma 7 · Tailwind CSS 4 · Ollama (qwen2.5:7b-instruct) · nomic-embed-text · Piper TTS · XTTS-v2 · faster-whisper · Tesseract.js · tsdav (CalDAV) · Google Calendar API · Web Push · Vitest · Docker

Temi

8 temi selezionabili nell'app

Studio AI supporta 8 temi colore selezionabili — questo è lo stesso screen in ognuno.
Calendario
Chat RAG con citazioni
Citazione aperta in chat
Flashcard — lista
Ripasso flashcard — fronte
Ripasso flashcard — retro
Mappa concettuale
Percorso di laurea
Guida di studio
Quiz