La mia chat AI locale con Python e Gemma — Parte 2: refactoring

  • Home
  • AI & ChatBot
  • La mia chat AI locale con Python e Gemma — Parte 2: refactoring
Image

La mia chat AI locale con Python e Gemma — Parte 2: refactoring

Quando chiedi a Claude Code di generare un’applicazione, di solito ottieni qualcosa di funzionante. Ma c’è un “ma”… tende a scrivere applicazioni monolitiche, tutto mischiato insieme, bello solido, che fa il suo lavoro, ma poco leggibile e difficile da mantenere.

Private Mind, inizialmente, è stato costruito così: un’unica classe Flask con tutte le rotte, tutta la logica di caricamento del modello, tutto il parsing dei messaggi nello stesso file. Funzionava perfettamente. Ma quando si è trattato di aggiungere nuove funzionalità senza toccare la logica del modello… abbiamo capito che serviva un refactoring strutturale.

Non è un’ammissione di sconfitta di Claude Code, è una lezione importante: il codice che funziona non è il stesso del codice che scala. E imparare a riconoscere questo distacco è una delle prime abilità che un programmatore vero sviluppa.

Perché Claude tende al monolitico?

Claude Code, di default, tende a generare monoliti perché:

  • Velocità: un unico file è più veloce da scrivere e testare all’inizio.
  • Semplicità: niente import tra cartelle, niente dipendenze circolari.
  • Funzionalità prima di forma: Claude prioritizza “che funzioni” su “che sia bello”.
  • Contesto: quando chiedi una feature, Claude la implementa nel file più vicino, senza ripensare la struttura.
  • È come quando un architetto genera il primo abbozzo di una casa: tutto sullo stesso livello, efficiente, ma non vivibile. Serve un secondo round per dividerla in stanze, corridoi, scale.

Questo non è un limite di Claude. È una lezione per tutti i principianti, il codice che funziona non è il codice che scala: un file di 100 righe è leggibile; 500 no. Refactoring non è “riscrivere tutto”, è spostare le responsabilità là dove servono.
Quando usi Claude (o ChatGPT) per generare codice, spesso ottieni qualcosa di funzionante ma grezzo. È il tuo lavoro fare un secondo pass: leggerlo, capirlo, reorganizzarlo, decomporlo. Questo è quello che trasforma un principiante in uno sviluppatore vero.

Struttura delle cartelle

Plaintext
📦 Private Mind

├── 📂 private_mind/                    ← Il cervello dell'app
│   ├── __init__.py                     (rende private_mind un pacchetto Python)
│   ├── config.py                       (costanti: percorsi, limiti, porta)
│   ├── model.py                        (carica e gestisce il modello Gemma)
│   ├── messages.py                     (estrae il contenuto dai messaggi)
│   ├── page_fetch.py                   (scarica e pulisce pagine web)
│   └── web.py                          (le rotte Flask: /api/chat, /api/status, ecc.)

├── 📂 static/                          ← L'interfaccia che vedi nel browser
│   └── index.html                      (una sola pagina HTML/CSS/JavaScript)

├── 📂 models/                          ← Dove metti i file .gguf
│   └── (vuoto all'inizio; tu scarichi i modelli qui)

├── 📂 scripts/                         ← Strumenti per sviluppatori
│   ├── controlla_progetto.py           (esegui test + lint in un comando)
│   └── backup_locale.py                (fai backup della cartella)

├── 📂 tests/                           ← Controlli automatici
│   ├── test_messages.py                (verifica parsing dei messaggi)
│   ├── test_page_fetch.py              (verifica scaricamento di pagine)
│   ├── test_config.py                  (verifica percorsi e costanti)
│   └── test_web.py                     (verifica le rotte HTTP)

├── 📂 docs/                            ← Documentazione e idee
│   └── wishlist.md                     (feature future non ancora implementate)

├── app.py                              ← Punto di partenza: sceglie il modello e avvia il server
├── requirements.txt                    ← Dipendenze Python (pip install -r requirements.txt)
├── setup.json                          ← Configurazioni future (ancora vuoto)
└── .gitignore                          ← Dice a Git cosa non salvare (models/, venv/, ecc.)

Come si collegano:

Plaintext
app.py (avvio)

model.py (carica Gemma)
web.py (riceve richieste HTTP)
  ├→ messages.py (cosa ha scritto l'utente?)
  ├→ model.py (genera risposta)
  ├→ page_fetch.py (se l'utente manda un link)
  └→ config.py (consulta costanti)

Quando chiedi /api/chat:

  1. web.py riceve il messaggio
  2. messages.py lo legge
  3. model.py lo passa a Gemma
  4. web.py streamma la risposta token per token

Se sei arrivato fin qui, hai capito qualcosa di importante: il codice che funziona non è il codice che scala.

Se l’articolo ti è piaciuto restiamo in contatto su linkedin a: https://www.linkedin.com/in/andreatonin/

Releated Posts

La mia chat AI locale con Python e Gemma — Parte 4: salvare le conversazioni senza database

Questa quarta parte racconta come ho aggiunto il salvataggio. Il codice è banal, è JSON su disco, non…

DiByAndrea Tonin Ago 5, 2026

La mia chat AI locale con Python e Gemma — Parte 3: i prompt di sistema multipli

Questa terza parte racconta la prima funzionalità vera costruita sopra quel refactoring: la possibilità di scegliere, prima di…

DiByAndrea Tonin Ago 5, 2026

Gamescom 2026: il futuro dei videogiochi passa dal lavoro degli sviluppatori

Dal 26 al 30 agosto 2026, Colonia tornerà a essere uno dei principali punti d’incontro dell’industria videoludica internazionale.…

DiByAndrea Tonin Ago 3, 2026

La mia chat AI locale con Python e Gemma — Parte 1: il primo prototipo

Se hai mai provato a far girare un modello linguistico sul tuo PC, probabilmente conosci già LM Studio,…

DiByAndrea Tonin Lug 26, 2026