Torna ai progetti

Progetto personale

Money Tracker

Gestione delle spese in linguaggio naturale, con regole deterministiche, workflow AI delimitati e una dashboard locale.

Come ho vincolato un assistente AI alle regole finanziarie

Money Tracker è un assistente personale per le finanze, progettato per funzionare anzitutto in locale. Ne ho definito direzione e architettura, poi ho usato agenti di coding per contribuire all’implementazione. La domanda centrale era come trasformare un’interpretazione incerta in un’operazione finanziaria controllata e autorizzata.

  • Python
  • LangChain / LangGraph
  • llama.cpp
  • PostgreSQL
  • FastAPI / React
  • Langfuse
  • Restic

Un dominio finanziario, due interfacce

Telegram e la dashboard locale convergono sugli stessi servizi applicativi e dati finanziari di riferimento. Il modello interpreta le richieste; le registrazioni sono governate dal dominio. Il diagramma sintetizza componenti implementati e responsabilità.

Servizio esterno

Telegram Bot API

Workstation locale

Gateway · long polling
PostgreSQL · inbox / outbox persistenti
Worker · dispatcher tipizzato
Dashboard React
FastAPI · API locale
Servizi finanziari deterministici
PostgreSQL · finanze + audit

llama.cpp fornisce inferenza locale ai workflow.

Langfuse osserva localmente le chiamate al modello; è opzionale e separato dai dati finanziari di riferimento.

Le frecce indicano elaborazione e chiamate ai servizi; inbox, outbox e finanze sono responsabilità separate nel PostgreSQL applicativo. La risposta torna attraverso outbox e gateway.

Dal messaggio a un’operazione verificabile

Il gateway persiste l’input autorizzato prima di avanzare l’offset di polling. Un worker separato elabora i messaggi in ordine: l’inferenza lenta non ferma la ricezione.

  1. 1Autorizzare e persistere
  2. 2Classificare l’intento
  3. 3Eseguire uno specialista
  4. 4Generare e accodare la risposta

Spesa / correzione

Estrazione tipizzata → validazione del dominio → scrittura autorizzata e idempotente. Le proposte di categoria attendono una decisione esplicita del proprietario.

Domanda / consiglio

Strumenti di sola lettura → aggregazioni deterministiche → risposta del modello. Questo percorso non dispone di strumenti di scrittura finanziaria.

Decisioni e compromessi

Grafi delimitati e dispatcher esplicito

Contratti separati per router e specialisti mantengono profilo, tempo e riferimenti alle azioni nel contesto fidato del runtime.

Un nuovo intento richiede ramo e schema espliciti: l’autorità diventa verificabile, al costo di più codice di orchestrazione.

PostgreSQL applicativo e inbox/outbox

Scritture finanziarie, identificazione dei comandi e audit usano transazioni. I messaggi persistono dopo un riavvio.

Il worker sequenziale può ritardare i messaggi successivi durante un retry. Telegram può ricevere una risposta duplicata; l’idempotenza protegge la scrittura finanziaria.

Inferenza locale e trasporto Telegram

Inferenza e dati finanziari restano sulla workstation. Il long polling evita un endpoint pubblico in ingresso.

La macchina deve essere disponibile per elaborare. Telegram resta un confine esterno: l’interazione completa non è interamente locale.

Criteri di valutazione versionati

Dataset, valutatori deterministici e manifest dei run legano la configurazione accettata alle versioni di modello, prompt, schemi e strumenti.

Cambiare modello o prompt richiede regressioni mirate. Una risposta plausibile o un punteggio di confidenza non bastano come prova.

Come può presentarsi l’interazione

Rappresentazione schematica dell’interazione, non una riproduzione esatta dell’interfaccia attuale. Importi, categorie e formulazioni sono inventati per questo esempio. Il modello finanziario sotto la conversazione spiega le due riconciliazioni.

Simulazione in inglese · dati fittizi · non è uno screenshot
Money Tracker Demo
Example message

Today I spent €36 — €28 on groceries and €8 on household items. I paid with €12 in vouchers and €24 by card.

Illustrative response

Expense draft · €36.00

Groceries €28.00 · Household €8.00
Vouchers €12.00 · Card €24.00

Waiting for your confirmation.

Una spesa, due ripartizioni indipendenti

Le categorie descrivono per cosa è stato speso il denaro. Le fonti di pagamento descrivono come è stato pagato. Entrambe si riconciliano sul totale; i report aggregano la dimensione pertinente senza contare due volte la spesa.

Dati illustrativi, non una transazione reale
Totale del movimento€36.00EUR · 3600

Per categoria

Alimentari€28.00

Casa€8.00

Per fonte di pagamento

Buoni€12.00

Carta€24.00

28 + 8 = 36 · 12 + 24 = 36

  • Gli importi EUR usano centesimi interi: 36,00 € diventano 3600, evitando l’aritmetica in virgola mobile binaria.
  • Le correzioni sostituiscono un aggregato validato e registrano un evento di audit. L’annullamento invalida il movimento senza eliminarne la storia.

La dashboard rende visibile il dominio

L’interfaccia React implementata comprende quadro mensile, gestione dei movimenti e budget per categoria. Questi due esempi schematici condividono un dataset fittizio coerente. La demo illustrativa è presentata in inglese; l’applicazione attuale usa l’italiano.

Simulazione dashboard · dati fittizi · non sono screenshot

Quadro mensile

Money TrackerOverview · March 2026 · Demo

Where your money is going

Posted transactions only · 3 fictitious transactions

Net spending
€120.00
Personal funds
€108.00
Benefits
€12.00
Monthly budgets

Posted spending / monthly target

Groceries€82.00 / €100.00
Household€8.00 / €40.00
Transport€30.00 / €50.00
I movimenti registrati alimentano spesa netta, fondi personali, benefit e consumo dei budget. Le bozze sono escluse da questi totali.

Dettaglio di un movimento

TransactionsIllustrative transaction · Demo

Example purchase

Posted€36.00
Categories

Groceries€28.00

Household€8.00

Total €36.00 · reconciled

Payment sources

Vouchers€12.00

Card€24.00

Total €36.00 · reconciled

Il movimento mantiene distinte categorie e fonti di pagamento. L’interfaccia espone correzione e annullamento; validazione e audit restano nel dominio.

Come si sono svolti gli esperimenti sui modelli

Ho trattato la scelta del modello come una sequenza di esperimenti verificabili sul carico locale. Sono stati esplorati sei modelli tramite profili testuali e, dove configurati, vision. Le prove hanno perimetri diversi: screening del protocollo, esperimenti parziali sui tool, valutazioni complete dei workflow e una decisione esplicita di promozione.

Dallo screening iniziale alla baseline mantenuta

  1. 1–2 set 2026

    Verificare le interfacce locali

    Pesi quantizzati e llama.cpp fissati, contesto di 8.192 token e uno slot di inferenza. Le prove verificavano output strutturato, chiamate ai tool, continuazione dopo il loro risultato e trasporto delle immagini. Superare lo screening permetteva ulteriori prove; non dimostrava accuratezza finanziaria.

  2. 3 set 2026

    Trasformare gli errori in nuove prove

    Qwen3 14B riempiva campi non specificati nel messaggio. Lo screening esteso verificava separatamente omissione dei campi opzionali e output con schemi union. L’omissione falliva, mentre le union funzionavano: un motivo per esplicitare meglio i contratti verso il modello.

  3. 8 set 2026

    Correggere contratti e prove di valutazione

    Schemi, prompt ed etichette di sviluppo venivano revisionati e versionati con motivazioni registrate. La rendicontazione è stata irrigidita per impedire che criteri obbligatori falliti o non misurati risultassero superati. Nuovi profili testuali e prove sui tool hanno ampliato il confronto.

  4. 9 set 2026

    Promuovere una configurazione completa

    Qwen3 14B ha superato tutti i criteri bloccanti applicabili dei workflow testuali dopo le correzioni deterministiche della selezione in lettura e la revisione dei consigli del proprietario. EVD-004 ha fissato modello, prompt, schemi e policy. Le soglie sono rimaste invariate; la registrazione automatica è rimasta disabilitata.

  5. 10 set 2026

    Provare il candidato più grande

    Qwen3.8 27B è stato misurato dopo aver verificato che la configurazione quantizzata entrasse nella workstation. Migliorava la categorizzazione, ma non superava i requisiti di routing, tool e consigli. È rimasto sperimentale; la baseline promossa è stata mantenuta.

Tutti i modelli, con il perimetro delle prove

Tutti i modelli, con il perimetro delle prove
Modello / quantizzazioneEsperimenti svoltiEsito osservatoDecisione
GPT-OSS 20BMXFP4Screening testuale iniziale; successivo esperimento di selezione dei tool.Il profilo iniziale falliva output finale strutturato e continuazione dopo il risultato del tool. Anche il successivo run sui tool non superava i criteri.Non promosso
Qwen3 14BQ5_K_MScreening testuale, prove di omissione/union, contratti iterati e tutte le suite dei workflow testuali.I limiti iniziali sull’omissione restano documentati. I contratti applicativi adattati e la policy di lettura hanno superato tutti i criteri di prodotto applicabili.Baseline testuale promossa
Ministral 3 14BQ5_K_MScreening vision e confronti sui workflow testuali.La continuazione dopo il risultato del tool falliva inizialmente. Estrazione e altri criteri di prodotto fallivano nelle prove successive; il proprietario ha fermato il confronto finale dopo il fallimento dell’ingestion.Non promosso
Qwen3.5 9BUD-Q5_K_XLScreening del protocollo vision; screening testuale esteso e sweep dei workflow.Gli screening superavano le rispettive versioni misurate. L’estrazione testuale passava, mentre routing, categorie, tool e consigli non superavano tutti i criteri.Sperimentale; vision mantenuto per le ricevute future
Gemma 4 12BQAT Q4_0Screening del protocollo vision; esperimento testuale parziale sulla selezione dei tool.Trasporto e protocollo vision passavano. L’esperimento testuale sui tool falliva; le prove registrate non contengono un confronto testuale completo.Sperimentale; vision mantenuto per le ricevute future
Qwen3.8 27BUD-IQ4_XSScreening testuale esteso e tutte le suite dei workflow testuali.Screening, estrazione e categorizzazione passavano. La categorizzazione migliorava rispetto alla baseline; routing, tool e consigli restavano bloccati.Sperimentale; baseline mantenuta

Gli esiti valgono per le combinazioni registrate di modello, runtime e schema. Le prime prove testuali di Ministral caricavano un proiettore vision prima della correzione dei profili. Anche suite e istruzioni sono cambiate nel tempo: queste righe raccontano le prove, non una classifica uniforme.

Cosa rendeva interpretabile un run

Fissare il perimetro del confronto

Ogni run registrava modello, quantizzazione, runtime, template, contesto, prompt, schema, policy dei tool e dataset. Un confronto richiede lo stesso dataset e la stessa versione delle istruzioni. Le regressioni di sviluppo sono distinte da un holdout mai usato per il tuning.

Verificare il comportamento osservabile

Routing, estrazione, categorie, tool e consigli fondati sui dati erano valutati separatamente, con valutatori deterministici e postcondizioni su fixture PostgreSQL dove pertinenti. La revisione delle categorie usava un modello simulato per verificare ripresa del workflow, non qualità del modello.

Esaminare gli errori prima di decidere

Campi mancanti, scambi fra lettura e scrittura, tool vietati, injection, cifre inventate e semantica delle fonti di pagamento erano esaminati per classe di errore. L’utilità dei consigli valutata dal proprietario integrava i criteri automatici senza compensare requisiti finanziari o interpretativi falliti.

La decisione cambiata dagli esperimenti

L’unità selezionata era una configurazione applicativa completa. Contratti espliciti e selezione deterministica in lettura hanno reso Qwen3 14B utilizzabile nel perimetro testuale accettato. Non è stato individuato un sottoinsieme idoneo alla registrazione automatica: i nuovi movimenti restano bozze da confermare dal proprietario.

Il trasporto di immagini non prova l’estrazione delle ricevute, ancora rinviata. Le osservazioni sui tempi dipendevano da workstation e configurazione del run. Le misure mancanti non valgono come esiti positivi. Il caso sintetizza i registri senza riprodurre dataset privati, output o una tabella di punteggi benchmark.

Prove diverse per errori diversi

Test software deterministici

I test controllano somme delle allocazioni, autorizzazione, idempotenza dei comandi e transizioni di audit. Le verifiche con PostgreSQL e i percorsi end-to-end coprono persistenza e recupero; le valutazioni del modello non sostituiscono queste invarianti.

Valutazioni dipendenti dal modello

I workflow testuali sono stati verificati con dataset versionati e soglie esplicite di promozione. I test software controllavano comportamento deterministico e percorsi completi; le valutazioni misuravano routing, uso degli strumenti e consigli dipendenti dal modello. Così la correttezza finanziaria non dipendeva dal punteggio del modello.

Anche l’operatività fa parte del progetto: retry persistenti e stati dead letter, tracciamento locale delle chiamate al modello e backup cifrati con Restic. Il contenuto delle tracce rimane privato. Le prove di accettazione esistono nel progetto; qui non sono riprodotti punteggi prestazionali o artefatti privati.

Dare un contratto agli agenti di sviluppo

Ho usato requisiti di prodotto, roadmap per passi, viste arc42, decisioni architetturali e istruzioni del repository per definire responsabilità e limiti dei componenti. Ogni passo aveva criteri di uscita e prove: la presenza del codice, da sola, non bastava a dichiararlo completo.

Cosa esiste oggi

La V1 personale accettata è testuale. Include un canale Telegram persistente per il proprietario, una dashboard locale protetta, dominio finanziario e persistenza deterministici, workflow testuali valutati e backup cifrato. Archiviazione e revisione delle ricevute esistono; l’estrazione automatica è rinviata. Il repository resta privato.

Cosa dimostra il mio contributo

Il mio contributo collega perimetro di prodotto, architettura e verifica. In Money Tracker, il linguaggio naturale aiuta a interpretare una richiesta, mentre workflow tipizzati, strumenti limitati e regole di dominio deterministiche decidono cosa può cambiare. Ho usato documentazione architetturale e criteri di valutazione per rendere quel confine verificabile nello sviluppo assistito da AI.

Cosa condivido qui

Il repository è privato. Descrivo le scelte progettuali senza esporre dati finanziari personali, codice o screenshot.