Retour aux projets

Projet personnel

Money Tracker

Suivi des dépenses en langage naturel, avec règles déterministes, flux d’IA encadrés et tableau de bord local.

Comment j’ai soumis un assistant IA à des règles financières

Money Tracker est un assistant personnel de finances conçu d’abord pour un usage local. J’en ai défini l’orientation et l’architecture, puis utilisé des agents de programmation pour contribuer à sa réalisation. La question centrale était de transformer une interprétation incertaine en opération financière vérifiée et autorisée.

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

Un domaine financier, deux interfaces

Telegram et le tableau de bord local utilisent les mêmes services applicatifs et données financières de référence. Le modèle interprète les demandes ; le domaine contrôle les écritures. Ce diagramme résume les composants réalisés et leurs responsabilités.

Service externe

Telegram Bot API

Poste de travail local

Passerelle · long polling
PostgreSQL · inbox / outbox durables
Worker · dispatcher typé
Tableau de bord React
FastAPI · API locale
Services financiers déterministes
PostgreSQL · finances + audit

llama.cpp fournit une inférence locale aux flux.

Langfuse observe localement les appels au modèle ; il reste facultatif et distinct des données financières de référence.

Les flèches indiquent traitement et appels aux services ; inbox, outbox et finances sont des responsabilités distinctes du PostgreSQL applicatif. La réponse revient par l’outbox et la passerelle.

Du message à une opération vérifiable

La passerelle persiste les entrées autorisées avant d’avancer l’offset. Un worker séparé traite les messages dans l’ordre : une inférence lente ne bloque pas leur réception.

  1. 1Autoriser et persister
  2. 2Router l’intention
  3. 3Exécuter un spécialiste
  4. 4Rendre et mettre en file la réponse

Dépense / correction

Extraction typée → validation métier → écriture autorisée et idempotente. Les propositions de catégorie attendent une décision explicite du propriétaire.

Question / conseil

Outils en lecture seule → agrégats déterministes → réponse du modèle. Cette voie ne dispose pas d’outils d’écriture financière.

Décisions et compromis

Graphes encadrés et dispatcher explicite

Des contrats distincts gardent profil, temps et références d’action dans le contexte de confiance du runtime.

Une nouvelle intention exige une branche et un schéma explicites : une autorité vérifiable, avec davantage d’orchestration.

PostgreSQL applicatif et inbox/outbox

Écritures financières, identification des commandes et audit sont transactionnels. Les messages survivent aux redémarrages.

Le worker séquentiel peut retarder les messages suivants lors d’un retry. Telegram peut recevoir une réponse en double ; l’idempotence protège l’écriture financière.

Inférence locale et transport Telegram

Inférence et données financières restent sur le poste. Le long polling évite un point d’entrée public.

Le poste doit être disponible pour traiter les demandes. Telegram reste une frontière externe ; l’interaction complète n’est pas entièrement locale.

Critères d’évaluation versionnés

Jeux de données, évaluateurs déterministes et manifests relient la configuration acceptée aux versions du modèle, des prompts, schémas et outils.

Changer un modèle ou prompt exige des régressions ciblées. Une réponse plausible ou un score de confiance ne suffit pas.

Exemple d’interaction

Représentation schématique, pas une reproduction exacte de l’interface actuelle. Montants, catégories et formulations sont inventés. Le modèle financier sous la conversation explique les deux rapprochements.

Simulation en anglais · données fictives · pas une capture d’écran
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.

Un achat, deux répartitions indépendantes

Les catégories décrivent la destination de la dépense ; les sources de financement décrivent son paiement. Chaque répartition correspond au total. Les rapports agrègent la dimension pertinente sans compter l’achat deux fois.

Données illustratives, pas une transaction réelle
Total du mouvement€36.00EUR · 3600

Par catégorie

Alimentation€28.00

Maison€8.00

Par source de financement

Bons€12.00

Carte€24.00

28 + 8 = 36 · 12 + 24 = 36

  • Les montants EUR utilisent des centimes entiers : 36,00 € est stocké comme 3600, sans calcul monétaire en virgule flottante binaire.
  • Les corrections remplacent un agrégat validé et créent un événement d’audit. L’annulation invalide le mouvement sans effacer son historique.

Le tableau de bord rend le domaine visible

L’interface React réalisée comprend vue mensuelle, gestion des mouvements et budgets par catégorie. Ces deux exemples schématiques partagent un jeu fictif cohérent. La démo illustrative est présentée en anglais ; l’application actuelle utilise l’italien.

Simulation du tableau de bord · données fictives · pas des captures

Vue mensuelle

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
Les mouvements enregistrés alimentent dépense nette, fonds personnels, avantages et consommation des budgets. Les brouillons sont exclus des totaux.

Détail d’un mouvement

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

Le mouvement distingue catégories et sources de financement. L’interface permet correction et annulation ; validation et audit restent dans le domaine.

Le déroulement des expériences sur les modèles

J’ai traité le choix du modèle comme une série d’expériences vérifiables sur la charge locale. Six modèles ont été explorés via des profils texte et, selon la configuration, vision. Les preuves distinguent tests de protocole, essais partiels d’outils, évaluations complètes et décision explicite de promotion.

Du premier test à la configuration conservée

  1. 1–2 sept. 2026

    Tester les interfaces locales

    Poids quantifiés et llama.cpp fixés, contexte de 8 192 tokens et un slot. Les tests couvraient sortie structurée, appels d’outils, continuation après leur résultat et transport d’images. Un succès ouvrait la suite des essais sans prouver la justesse financière.

  2. 3 sept. 2026

    Transformer les erreurs en nouveaux tests

    Qwen3 14B remplissait des champs absents du message. Le test étendu séparait omission des champs facultatifs et sortie union. L’omission échouait ; les unions fonctionnaient, orientant la révision des contrats du modèle.

  3. 8 sept. 2026

    Corriger contrats et preuves

    Schémas, prompts et étiquettes de développement étaient révisés avec versions et motifs. Les rapports ont été renforcés pour refuser un succès lorsque des critères requis échouaient ou restaient non mesurés. De nouveaux profils texte et essais d’outils ont élargi la comparaison.

  4. 9 sept. 2026

    Promouvoir une configuration complète

    Qwen3 14B a satisfait tous les critères bloquants applicables après correction déterministe de la sélection en lecture et revue des conseils par le propriétaire. EVD-004 a fixé modèle, prompts, schémas et politique. Les seuils ont été conservés ; l’enregistrement automatique est resté désactivé.

  5. 10 sept. 2026

    Tester le candidat plus grand

    Qwen3.8 27B a été mesuré après vérification de sa capacité à fonctionner localement. La catégorisation s’améliorait, mais routage, outils et conseils ne satisfaisaient pas les exigences. Il est resté expérimental ; la configuration promue a été conservée.

Tous les modèles et le périmètre des preuves

Tous les modèles et le périmètre des preuves
Modèle / quantificationExpériences réaliséesRésultat observéDécision
GPT-OSS 20BMXFP4Test initial du protocole texte ; essai ultérieur de sélection d’outils.Échec initial de la sortie finale structurée et de la continuation après résultat d’outil. L’essai ultérieur d’outils échouait aussi aux critères.Non promu
Qwen3 14BQ5_K_MTests texte, omission/union, contrats itérés et toutes les suites textuelles.Les limites d’omission initiales restent documentées. Les contrats adaptés et la politique de lecture satisfaisaient tous les critères produit applicables.Configuration texte promue
Ministral 3 14BQ5_K_MTests vision et comparaisons des flux textuels.La continuation après résultat d’outil échouait initialement. Extraction et autres critères échouaient ensuite ; le propriétaire a arrêté la comparaison finale après l’échec d’ingestion.Non promu
Qwen3.5 9BUD-Q5_K_XLProtocole vision ; capacités texte étendues et suites de flux.Les tests de capacités passaient dans leurs versions mesurées. L’extraction texte passait ; routage, catégories, outils et conseils ne satisfaisaient pas tous les critères.Expérimental ; vision conservée pour les reçus futurs
Gemma 4 12BQAT Q4_0Protocole vision ; essai texte partiel de sélection d’outils.Transport et protocole vision passaient. L’essai texte d’outils échouait ; aucune comparaison textuelle complète n’est enregistrée.Expérimental ; vision conservée pour les reçus futurs
Qwen3.8 27BUD-IQ4_XSCapacités texte étendues et toutes les suites textuelles.Capacités, extraction et catégorisation passaient. La catégorisation améliorait la référence ; routage, outils et conseils restaient bloqués.Expérimental ; référence conservée

Ces résultats concernent les combinaisons enregistrées de modèle, runtime et schéma. Les premiers essais texte Ministral chargeaient un projecteur vision avant correction des profils. Suites et instructions ont aussi évolué : ce tableau retrace des preuves, pas un classement uniforme.

Ce qui rendait un essai interprétable

Fixer le périmètre de comparaison

Chaque essai identifiait modèle, quantification, runtime, template, contexte, prompt, schéma, outils et données. Les comparaisons exigent les mêmes données et instructions. Les régressions de développement sont distinctes d’un holdout jamais utilisé pour ajuster les prompts.

Vérifier les comportements observables

Routage, extraction, catégories, outils et conseils fondés sur les données étaient évalués séparément, avec règles déterministes et postconditions PostgreSQL. La revue de catégories utilisait un modèle scripté pour tester la reprise du flux, pas sa qualité.

Examiner les échecs avant de décider

Champs absents, confusion lecture/écriture, outils interdits, injection, chiffres inventés et sources de paiement étaient examinés par classe d’erreur. L’utilité humaine des conseils complétait les critères sans compenser un échec financier ou d’interprétation.

La décision modifiée par les expériences

La sélection portait sur une configuration applicative complète. Contrats explicites et sélection déterministe en lecture ont rendu Qwen3 14B utilisable dans le périmètre texte accepté. Aucun sous-ensemble admissible à l’enregistrement automatique n’a été établi : les nouveaux mouvements restent des brouillons à confirmer.

Le transport d’images ne prouve pas l’extraction des reçus, encore différée. Les temps dépendaient du poste et de la configuration. Une mesure absente ne vaut pas succès. Ce résumé ne reproduit ni données privées, ni sorties, ni tableau de scores benchmark.

Des preuves adaptées aux modes de défaillance

Tests logiciels déterministes

Les tests vérifient sommes des répartitions, autorisation, idempotence des commandes et transitions d’audit. Les tests PostgreSQL et de bout en bout couvrent persistance et reprise ; les évaluations du modèle ne remplacent pas ces invariants.

Évaluations dépendantes du modèle

Les flux textuels ont été évalués avec des jeux de données versionnés et des seuils explicites. Les tests logiciels vérifiaient les règles déterministes et les parcours complets ; les évaluations mesuraient routage, usage des outils et conseils dépendants du modèle. La justesse financière ne dépendait donc pas d’un score de modèle.

L’exploitation fait partie du projet : retries durables, états dead letter, traces locales des appels au modèle et sauvegardes chiffrées Restic. Les traces restent privées. Les preuves d’acceptation existent dans le projet ; aucun score de performance ou artefact privé n’est reproduit ici.

Donner un contrat aux agents de développement

J’ai utilisé exigences produit, feuille de route par étapes, vues arc42, décisions d’architecture et instructions du dépôt pour définir responsabilités et limites. Chaque étape avait des critères de sortie et des preuves : la seule présence de code ne suffisait pas à la déclarer terminée.

État actuel

La V1 personnelle acceptée est centrée sur le texte. Elle comprend un canal Telegram durable pour le propriétaire, un tableau de bord local protégé, un domaine financier déterministe avec persistance, des flux textuels évalués et une sauvegarde chiffrée. L’archivage et la révision des reçus existent ; leur extraction automatique est différée. Le dépôt reste privé.

Ce que montre ma contribution

Ma contribution relie périmètre produit, architecture et vérification. Dans Money Tracker, le langage naturel aide à comprendre la demande, tandis que des flux typés, des outils limités et des règles déterministes décident de ce qui peut changer. Documentation d’architecture et critères d’évaluation rendent cette frontière vérifiable.

Ce qui est présenté ici

Le dépôt est privé. Cette présentation expose des choix de conception sans données financières personnelles, code ni captures d’écran.