Skip to content

Repository files navigation

eval

REGARD

Copilote de conformité qui branche l'IA sur des données de risque en désordre, avec autocontrôle déterministe, réponses sourcées et refus motivés.

Démo en ligne : regard-wine.vercel.app · Code : github.com/heykelh/regard


En une phrase

Construire un modèle d'IA est devenu une commodité. Le mur, aujourd'hui, c'est de le faire fonctionner sur les données réelles, sales et régulées d'une organisation, sans jamais produire un chiffre faux. REGARD est une démonstration de ce passage : de la donnée brute à une réponse gouvernée, vérifiable et tracée.

Le cas d'usage

Un reporting d'expositions de risque bancaire : les montants qu'une banque risque de perdre sur ses contreparties. Un responsable conformité, non-technique, pose une question en français : « quelle est notre exposition sur telle banque ? », « qui dépasse la limite de concentration ? », et obtient une réponse fiable et sourcée, ou un refus motivé si la donnée ne permet pas de répondre honnêtement.

Le cadre métier de référence est BCBS239 (qualité des données de risque et reporting) et DORA (résilience opérationnelle).

⚠️ Données synthétiques. La vraie donnée d'exposition bancaire est confidentielle. Le jeu de données est généré par un script seedé, conçu pour reproduire fidèlement le désordre du réel, ce qui permet aussi d'en contrôler la démonstration et de la rendre reproductible.

Ce que l'agent sait faire

  1. Exposition sur une contrepartie : total par devise, équivalent euros, et test de dépassement de limite.
  2. Top N des plus exposées : classement des contreparties en équivalent euros.
  3. Exposition totale du portefeuille : en équivalent euros, avec répartition par devise.
  4. Contreparties en dépassement : celles au-dessus de la limite de concentration.
  5. Expositions au-dessus d'un montant : filtrage par seuil.
  6. Liste globale : répartition du portefeuille par devise.
  7. Fraîcheur des données : la donnée est-elle encore à jour ?

Hors de ce périmètre (contrepartie inconnue, question hors sujet), l'agent refuse explicitement plutôt que d'inventer.

Résultats mesurés

Un harnais d'évaluation en Python rejoue 28 questions de référence contre l'agent et calcule les métriques réelles.

Indicateur Valeur
Cas de test réussis 28 / 28
Justesse des décisions (répondre vs refuser) 100 %
Refus justifiés 100 %
Couverture des citations (chaque chiffre sourcé) 100 %
Justesse des intentions 100 %
Latence médiane ~370 ms
Latence p95 ~660 ms
Coût ~0,26 $ / 1000 requêtes
Hallucinations détectées 0–17 % selon le run (voir Limites)

Chiffres reproductibles : python eval/run_eval.py.

Architecture

Principe central : déterministe d'abord, LLM ensuite. Le calcul, les contrôles et les décisions reviennent à du code vérifiable. Le modèle de langage ne sert qu'à comprendre une question floue et à reformuler des faits déjà calculés. Conséquence : sans clé d'API, ou si le modèle est indisponible, l'agent répond quand même, moins fluide, tout aussi fiable.

L'agent est un graphe d'états (LangGraph) :

question → plan → retrieve → crosscheck → verify → finalize
                                             │
                                   ┌─────────┴─────────┐
                                   ▼                   ▼
                          réponse gouvernée      refus motivé
                                   │                   │
                                   └──── journal d'audit ────┘
  • plan : détecte l'intention et la contrepartie par règles déterministes ; le LLM n'intervient qu'en cas d'ambiguïté.
  • retrieve : extrait les lignes pertinentes de la table « gold », avec score de confiance et fraîcheur.
  • crosscheck : calcule les faits (totaux par devise, conversion en euros, dépassements) ; le LLM reformule, il ne calcule rien.
  • verify : l'autocontrôle : garde-fous déterministes (fraîcheur, confiance, citations qui existent), puis un LLM-juge qui vérifie l'ancrage des chiffres. Si non → nouvel essai ou refus.
  • finalize : réponse sourcée avec badges qualité, ou refus motivé. Tout est tracé.

Du brut au « gold »

Le pipeline transforme une donnée sale en donnée de confiance :

Étape Résultat
Lignes brutes générées 207
Retenues (table gold) 140
Rejetées (irréparables) 38
Doublons écartés 29
Score de qualité moyen 0,75

Montants, devises et dates sont normalisés ; les doublons fusionnés ; les lignes irréparables rejetées avec leur motif ; chaque ligne reçoit un score de qualité de 0 à 1.

Stack

Next.js 15 · TypeScript strict · Tailwind 4 · shadcn/ui · LangGraph.js · Groq (Llama 3.3 70B) + repli Gemini 2.0 Flash · DuckDB-WASM (navigateur) + lecture fs (serveur) · Python + pytest pour l'évaluation.

Lancer le projet

# 1. Dépendances
npm install

# 2. Générer et nettoyer les données
npm run gen:raw       # génère les données brutes synthétiques
npm run build:gold    # nettoie, score, produit la table gold

# 3. Lancer le site + l'agent
npm run dev           # http://localhost:3000

Les clés d'API sont optionnelles : sans elles, l'agent fonctionne en mode déterministe. Pour activer la reformulation par LLM, copier .env.example en .env.local et renseigner GROQ_API_KEY (et/ou GEMINI_API_KEY).

Évaluation :

python -m venv eval/.venv
eval/.venv/Scripts/Activate.ps1      # Windows (source .../activate sur Unix)
pip install -r eval/requirements.txt
python eval/run_eval.py              # serveur lancé en parallèle

Le parcours d'ingénierie

Ce projet a été construit par itérations, chaque décision validée par le harnais d'évaluation. Quelques problèmes réels qu'il a fait remonter et leur correction :

  • Totaux multidevises. Le premier calcul additionnait EUR + USD + GBP + CHF en un seul chiffre, produisant un total financièrement faux et une fausse alerte de dépassement. Corrigé en agrégeant par devise, puis en introduisant une conversion en euros à taux fixes documentés (assumés comme indicatifs).
  • Sourcing incohérent. Sur les questions de type « top N », les citations affichaient des contreparties absentes de la réponse. Corrigé pour que chaque réponse ne cite que les enregistrements qui la fondent.
  • Conflit de règles. L'ajout de l'intention « dépassement de limite » a détourné à tort les questions « expositions au-dessus de X millions ». Détecté par l'éval (une régression d'intention), corrigé par une condition de priorité.
  • Latence. Certaines requêtes atteignaient 60 s à cause de la limitation de débit du LLM ; ajout d'un timeout et d'un repli déterministe, ramenant la latence médiane sous 400 ms.

Limites assumées

Un système fiable connaît ses propres limites :

  • Le LLM-juge est non-déterministe. Sur une réponse identique, il peut répondre « ancré » ou « non ancré » d'un run à l'autre. Le taux d'hallucinations détectées est donc une mesure bruitée (0–17 % observé), à interpréter sur plusieurs runs, pas un chiffre gravé.
  • Données synthétiques. Le jeu reproduit le désordre du réel mais pas son volume (millions de lignes), ni la complexité des produits financiers, ni les corrélations entre contreparties.
  • Conversion FX à taux fixes. Les taux de change sont figés et documentés, à titre indicatif, pas des taux de marché temps réel.
  • Périmètre volontairement restreint. L'agent répond à un type de questions précis et refuse le reste, par conception.

Auteur

Heykel Hachiche GitHub · Portfolio

About

Système IA agentique de conformité : pipeline RAG déterministe-first, orchestration LangGraph, multi-LLM (Groq Llama 3.3 70B + Gemini 2.0 Flash), autocontrôle LLM-juge, refus motivés avec journal d'audit, observabilité Langfuse. 28/28 cas de test validés. Architecture donnée brute vers gold vers réponse gouvernée.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages