Ho automatizzato le finanze di famiglia con un assistente che capisce l’italiano e la voce 100% in locale

Argomenti

Animazioni e UI Automazione n8n Estensioni Google Chrome Linux Progetti SEO e Dati Strutturati Sicurezza e Distribuzione Uncategorized

Accessibilità AI Automazione GSAP Gutenberg JavaScript Linux Owl Carousel Performance PHP REST API SEO Sicurezza WordPress

Premessa

Ogni sera la stessa scena: aprire il foglio di calcolo, ricordare cosa avevo speso, digitare riga per riga. Finiva sempre allo stesso modo — mi dimenticavo, e dopo due settimane il foglio era incompleto e inutile. Oggi mando un messaggio vocale «benzina trentacinque euro» mentre sono ancora alla pompa, e la riga compare nel foglio con la conferma sul telefono. In mezzo c’è un assistente che capisce l’italiano scritto e parlato, e che gira interamente su un PC di casa, senza mandare un solo movimento finanziario nel cloud.

Il problema: i gestori di spese hanno troppa frizione

Le app di finanza personale non falliscono per mancanza di funzioni. Falliscono perché ogni inserimento costa troppo: apri l’app, scegli la categoria da un menu, digiti l’importo, confermi. Dieci secondi che, moltiplicati per ogni caffè, diventano un attrito che vince sempre. La soluzione non era un’app più bella, ma azzerare l’inserimento: scrivere o dire la spesa come la racconteresti a una persona.

L’idea: parlare, non compilare un form

L’interfaccia è Telegram, che ho già sul telefono. Scrivo «spesa supermercato 23,40» oppure mando un vocale, e il sistema fa il resto: capisce che è un’uscita, estrae l’importo, sceglie la categoria, scrive nel foglio dell’anno giusto e mi risponde con la conferma. Niente form, niente menu. Lo stesso canale gestisce anche le consultazioni: /mese, /totale, /ultimi 5, o persino in linguaggio naturale «quanto ho speso questo mese?».

L’architettura in un colpo d’occhio

Il flusso è una catena di pezzi semplici, ognuno con un compito solo:

Telegram → n8n (Docker) → LLM/Whisper locali → Google Sheets → conferma su Telegram.

n8n fa da orchestratore: un workflow in polling legge i messaggi da Telegram ogni minuto e li mette in una tabella-coda su Google Sheets; un secondo workflow svuota la coda, passa il testo al modello, valida il risultato e scrive nel libro mastro. Google Sheets non è solo il database finale: la sua tab _coda fa da buffer offline, così i messaggi mandati a PC spento non si perdono e vengono elaborati al primo avvio.

Perché tutto in locale

I dati finanziari sono tra i più sensibili che esistano, e la maggior parte dei tutorial di «finance bot» li spedisce a OpenAI per capire il testo e a un aggregatore bancario per i movimenti. Io volevo l’opposto: nessun dato fuori casa, nessun costo per chiamata. La comprensione del testo la fa Ollama con gemma3:4b; la trascrizione vocale la fa Whisper. Entrambi girano su una GPU consumer, una RTX 3060. Il costo marginale di ogni spesa registrata è zero, e il foglio resta l’unico posto dove vivono i numeri della famiglia.

Le tre decisioni che hanno cambiato il progetto

1. Polling invece di webhook. La prima versione usava il classico webhook Telegram verso un Google Apps Script. Sintomo: lo stesso messaggio compariva nel foglio fino a 4 volte. Causa: l’endpoint di Apps Script risponde sempre con un 302, Telegram lo interpreta come errore e ritenta la consegna. La soluzione è stata rimuovere del tutto il webhook e passare a un polling idempotente: salvo l’offset dell’ultimo update nello stato del workflow e lo avanzo prima di scrivere nel foglio. Niente più duplicati. La lezione vale ovunque ci sia un retry di mezzo: progetta per il rispetto del replay, non sperare che non avvenga.

2. Il modello piccolo batte quello grande. Ero partito con un modello da 9,6 GB: accurato, ma ~13 s a messaggio a caldo e pesante da tenere in RAM. Sono passato a gemma3:4b (3,3 GB): ~3,5–4,8 s a caldo, un terzo del peso. Da solo sbagliava qualche caso limite (un «rimborso» classificato con un tipo inventato), ma il problema non si risolve con un modello più grande: si risolve con un prompt più rigido più uno strato di validazione dopo l’LLM — whitelist delle categorie, importo > 0, default espliciti. Il risultato deve essere un record pulito, sempre:

{ "tipo": "uscita", "importo": 20, "categoria": "alimentari" }

3. Un libro mastro per anno. I movimenti non si cancellano mai — lo storico è piccolo e prezioso. Così ogni persona ha una scheda per anno (Davide 2026), creata automaticamente dal workflow alla prima transazione di un anno nuovo. La coda, invece, è effimera: si autopulisce dopo 30 giorni.

La voce: la feature che ha eliminato l’ultima frizione

Scrivere è già veloce, ma parlare lo è di più. Un vocale Telegram viene scaricato da n8n e passato a un container Whisper locale che lo trascrive in italiano. Il trucco architetturale è semplice e potente: la voce diventa testo all’ingresso, e da lì riusa esattamente la stessa pipeline del testo — registrazione, comandi, linguaggio naturale. La sorpresa è stata la qualità sui numeri parlati: Whisper medium scrive «dodici» come 12 e aggiunge pure la punteggiatura. Un vocale reale «spesa farmacia dodici euro» è diventato «Spesa farmacia 12 euro.» → registrato come uscita di 12 € in categoria salute. L’unico costo nascosto è il peso: l’immagine Docker GPU è ~25,7 GB (esiste l’alternativa CPU, ~1,5 GB, ottima per vocali brevi).

Cosa farei diversamente, e la roadmap

Il sistema è in produzione e lo uso ogni giorno. I prossimi passi sono il multi-utente pulito (oggi gli utenti autorizzati sono mappati a mano), una vista di budget per categoria e qualche report periodico inviato in automatico. Ma il principio resta: ogni nuova funzione deve togliere frizione, non aggiungerne.

Se ti interessa questo progetto, vuoi i dettagli tecnici o lo stack completo, scrivimi a info@davidemugnaini.it.