Commit Graph

22 Commits

Author SHA1 Message Date
dom
5d5f119057 feat: quality_tier CPAM (A/B/C) + requires_review + warnings catégorisés
- ControleCPAM enrichi : quality_tier, requires_review, quality_warnings
- _assess_quality_tier() : classification basée sur score adversarial + warnings
  - Tier C (requires_review) : score <4, code hors périmètre, >2 preuves non traçables
  - Tier B : score 4-6, warnings mineurs
  - Tier A : score >=7, 0 critique
- _format_response() : bandeau "REVUE MANUELLE REQUISE" pour tier C,
  sections CRITIQUES/MINEURS séparées
- Badge qualité dans le viewer CPAM (vert A / orange B / rouge C)
- 17 tests : tier A/B/C, bandeau, séparation warnings, backward compat

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:01:21 +01:00
dom
909e051cc9 feat: architecture multi-modèles LLM + quality engine + benchmark
- Multi-modèles : 4 rôles LLM (coding=gemma3:27b-cloud, cpam=gemma3:27b-cloud,
  validation=deepseek-v3.2:cloud, qc=gemma3:12b) avec get_model(role)
- Prompts externalisés : 7 templates dans src/prompts/templates.py
- Cache Ollama : modèle stocké par entrée (migration auto ancien format)
- call_ollama() : paramètre role= (priorité: model > role > global)
- Quality engine : veto_engine + decision_engine + rules_router (YAML)
- Benchmark qualité : scripts/benchmark_quality.py (A/B, métriques CIM-10)
- Fix biologie : valeurs qualitatives (troponine négative) non filtrées
- Fix CPAM : gemma3:27b-cloud au lieu de deepseek (JSON tronqué par thinking)
- CPAM max_tokens 4000→6000, viewer admin multi-modèles
- Benchmark 10 dossiers : 100% DAS valides, 10/10 CPAM, 243s/dossier

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 00:21:09 +01:00
dom
40934fdc39 feat: traçabilité source systématique + viewer interactif
Ajoute source_page/source_excerpt à tous les types (biologie, imagerie,
traitements, actes CCAM, antécédents, complications). Convertit antecedents
et complications en types structurés (Antecedent/Complication) avec
validators backward-compat pour les vieux JSON. Étend _apply_source_tracking
à tous les éléments du dossier. Ajoute un endpoint /api/source-text/ et un
modal interactif dans le viewer avec surlignage du texte source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 20:59:50 +01:00
dom
09a251185e feat: modèle par défaut gemma3:27b-cloud pour meilleure qualité
Le 27b-cloud via Ollama Cloud est plus rapide (2m25 vs 4m) et
produit des résultats nettement supérieurs au 12b local :
- CPAM : plus de confusion Z45.80/Z43.6, preuves non hallucinées
- Contre-argumentation : 5334 chars vs 4394, citations du dossier
- Fallback local possible via OLLAMA_MODEL=gemma3:12b

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:37:17 +01:00
dom
bc0ccbef7c feat: enrichissement contre-argumentation CPAM — libellés CIM-10, RAG ciblé, reprocess complet
- Résolution des libellés CIM-10 pour les codes contestés (dp_ucr, da_ucr, dr_ucr)
- Fallback DP depuis dp_ucr quand le pipeline n'extrait pas de diagnostic principal
- Troncature arg_ucr augmentée de 200 à 500 chars pour conserver les citations de règles
- Requête RAG 4 : définitions CIM-10 (inclusion/exclusion) des codes contestés
- Requête RAG 5 : extraction et recherche des règles nommées (RègleT7, Annexe, etc.)
- Cap résultats RAG de 10 à 12 pour absorber les nouvelles requêtes
- Reprocess viewer : pipeline complet (fusion + GHM + CPAM) pour dossiers multi-PDF
- Affichage structuré response_data dans le viewer (analyse, preuves, références)
- 7 nouveaux tests CPAM, 6 nouveaux tests viewer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 23:24:10 +01:00
dom
94fa4e5f3b feat: résumé clinique enrichi + preuves cliniques + validation QC batch
Améliore la qualité du codage CIM-10 sur 3 axes :
- Contexte clinique enrichi (interprétations bio, traitements indicatifs, marqueurs sévérité)
- Preuves cliniques structurées par diagnostic (evidence linking dans le prompt LLM)
- Validation batch post-codage (1 appel LLM/dossier, ajustement confiance, alertes QC)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 21:47:27 +01:00
dom
aad925ebea fix: suppression mode hybride 27b, prompt CPAM nuancé pour gemma3:12b
Benchmark 4 modèles (gemma3:12b/27b, qwen3:14b, mistral-small3.2:24b)
sur 3 dossiers CPAM : le 12b domine en vitesse (30s vs 231s) et densité
argumentaire. Seul avantage du 27b : nuance (points d'accord 3/3 vs 1/3).

Solution : prompt nuancé qui force l'analyse équilibrée (étape 1 honnête,
points d'accord obligatoires, conclusion reconnaissant les points CPAM).
Résultat 12b-v2 : 3/3 points d'accord, 26s, refs verbatim +17%.

Supprime OLLAMA_MODEL_CPAM et OLLAMA_TIMEOUT_CPAM (gemma3:12b pour tout).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 20:45:53 +01:00
dom
01d47f3c4b feat: mode hybride Ollama — gemma3:27b pour CPAM, 12b pour codage
Le pipeline utilise désormais gemma3:12b (rapide) pour le codage CIM-10
et gemma3:27b (meilleur raisonnement) pour la contre-argumentation CPAM.
Configurable via OLLAMA_MODEL_CPAM et OLLAMA_TIMEOUT_CPAM.

Inclut aussi : traçabilité source/page DAS, niveaux CMA ATIH, sévérité,
page tracker PDF, améliorations fusion et filtres DAS.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 17:53:53 +01:00
dom
8c75941e40 feat: 3 quick wins — source DAS, fallback code parent, filtre anatomique
1. Champ source sur Diagnostic : trackare/edsnlp/regex/llm_das
   - Renseigné dans les 8 constructeurs de cim10_extractor.py
   - Permet l'audit de provenance des DAS dans le JSON de sortie

2. Fallback code parent pour les codes LLM halluccinés :
   - fallback_parent_code() dans cim10_dict.py (D71.9→D71, R69.8→R69)
   - Intégré dans _apply_llm_result_diagnostic() de rag_search.py
   - Récupère les codes rejetés dont le parent 3-char est valide

3. Règle 12 filtre DAS : en-têtes anatomiques + catégories vagues
   - Rejette "Musculaire", "Digestif", "Hépatique" (mots isolés)
   - Rejette "Musculaire - masse musculaire" (catégorie + description)
   - 13 nouveaux tests unitaires au total

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:34:32 +01:00
dom
59365e3af9 feat: re-ranking cross-encoder CPU pour la recherche RAG CPAM
- Nouveau singleton _get_reranker() : CrossEncoder ms-marco-MiniLM-L-6-v2
  forcé sur CPU pour ne pas interférer avec Ollama sur GPU
- Fonction _rerank() : re-classe les résultats FAISS via cross-encoder,
  conserve le score FAISS original dans score_faiss
- Intégré dans search_similar_cpam() après déduplication, avant priorisation
- Config RERANKER_MODEL externalisée via T2A_RERANKER_MODEL (.env)
- Fix fallback CUDA OOM : rattrapage de torch.AcceleratorError en plus
  de torch.OutOfMemoryError

Latence : ~7-12s (incluant chargement one-time du modèle ~80Mo).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:16:58 +01:00
dom
aa397d5360 feat: configuration externalisée via .env + audit requirements
- Externalise 13 variables de config via python-dotenv (chemins PDF,
  modèles Ollama/embedding/NER, FINESS, seuils) avec défauts identiques
- Centralise EMBEDDING_MODEL dans config.py (était hardcodé en 3 endroits)
- Ajoute .env.example documenté et .env au .gitignore
- Ajoute openpyxl et pandas manquants au requirements.txt
- Ajoute data/referentiels au mkdir de run.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 19:46:33 +01:00
dom
e90450903e feat: enrichissement CIM-10 sous-codes + normes biologiques dans prompt DAS
Piste 1 : ajout de cim10_supplements.json (40 sous-codes E10/E11/E13/F10)
fusionné au chargement par load_dict() — E11.9 et autres ne sont plus rejetés.

Piste 2 : export BIO_NORMALS depuis cim10_extractor, inclusion des plages
de référence [N: min-max] dans le contexte LLM et règle explicite dans le
prompt DAS pour éviter les hallucinations sur valeurs biologiques normales.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:46:42 +01:00
dom
f44216b95b feat: pass LLM hybride pour DAS + interface admin référentiels RAG
Chantier 1 — Extraction DAS par LLM :
- Nouveau prompt expert DIM dans rag_search.py (extract_das_llm)
- Phase 4 dans cim10_extractor.py : détection DAS supplémentaires avant enrichissement RAG
- Cache persistant (clé hash du texte), validation CIM-10, déduplication
- Activé uniquement avec use_rag=True (--no-rag le désactive)

Chantier 2 — Admin référentiels :
- Config : REFERENTIELS_DIR, UPLOAD_MAX_SIZE_MB, ALLOWED_EXTENSIONS
- Chunking générique (PDF/CSV/Excel/TXT) + ajout incrémental FAISS dans rag_index.py
- ReferentielManager CRUD dans viewer/referentiels.py
- 5 routes Flask (listing, upload, indexation, suppression, rebuild)
- Template admin avec tableau interactif + lien sidebar

Fix : if cache → if cache is not None (OllamaCache vide évaluait à False)

410 tests passent (27 nouveaux, 0 régression).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:12:39 +01:00
dom
a58398f5d4 feat: cache Ollama + parallélisation ThreadPool + filtrage DAS renforcé + modules GHM/CPAM/export RUM
- Cache persistant JSON thread-safe pour les résultats Ollama (invalidation par modèle)
- Parallélisation des appels Ollama (ThreadPoolExecutor, 2 workers)
- 6 nouvelles règles de filtrage DAS parasites (doublons, ponctuation, OCR, labo, fragments)
- Client Ollama centralisé (mode JSON natif + retry)
- Module GHM (estimation CMD/sévérité)
- Module contrôle CPAM (parser + contre-argumentation RAG)
- Export RUM (format RSS)
- Viewer enrichi (détail dossier)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 13:44:34 +01:00
dom
86d7ec5ea4 feat: mode JSON natif Ollama + modèle gemma3:12b + retry
- Ajout format:"json" dans l'appel API Ollama (force sortie JSON valide)
- Prompt restructuré : raisonnement en champs JSON structurés
  (analyse_clinique, codes_candidats, discrimination, regle_pmsi)
- Parser simplifié : json.loads direct + reconstitution du raisonnement
- Suppression du marqueur ###RESULT### (obsolète avec mode JSON)
- Retry automatique (1 tentative) si parsing échoue
- Stripping des blocs markdown ```json pour compatibilité multi-modèles
- num_predict 1200→2500, modèle gemma3:12b (tient en 12Go VRAM)
- Résultat : 0% échec parsing (était 11% avant)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 02:19:09 +01:00
dom
9d07894c6f feat: Phase 4 — viewer enrichi, non-cumul CCAM, fusion multi-PDFs + rebuild FAISS (21 141 vecteurs)
- Viewer : badges compteurs (DAS, actes, alertes, CMA), raisonnement LLM pliable, regroupement CCAM, navigation patient, alertes NON-CUMUL en rouge
- Non-cumul CCAM : 3 règles heuristiques (même base, même regroupement/jour, paires incompatibles)
- Fusion multi-PDFs : merge_dossiers() avec priorité Trackare, spécificité CIM-10, déduplication, champ source_files
- Index FAISS reconstruit : 21 141 vecteurs (CCAM dict 8 257 + CIM-10 alpha 306)
- 192 tests unitaires passent

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 12:43:34 +01:00
dom
7e69f994b0 feat: dictionnaire CCAM complet (8 257 codes) + index FAISS enrichi + validation actes
Phase 2 (CCAM) :
- Nouveau src/medical/ccam_dict.py : build depuis CCAM_V81.xls via xlrd, lookup 3 niveaux, validation codes
- Intégration dans l'extracteur : fallback ccam_lookup + _validate_ccam() avec alertes
- CLI : --build-ccam-dict, --rebuild-index

Phase 3 (FAISS) :
- Chunks CCAM depuis le dictionnaire JSON (priorité sur le PDF)
- Chunks CIM-10 index alphabétique (terme → code)
- Priorisation cim10_alpha dans la recherche RAG

Viewer : endpoint reprocess + bloc scripts
Tests : 8 tests CCAM + tests raisonnement RAG (161 passed)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 11:41:39 +01:00
dom
9df4465fef feat: règles métier T2A Phase 1 — exclusions diagnostiques, sévérité CMA et alertes codage
Ajout des règles d'exclusion symptôme (R00-R99) vs diagnostic précis (Chapitres I-XIV),
détection heuristique de sévérité CMA sur 25 racines CIM-10, et affichage des alertes
de codage dans le viewer Flask. 153 tests, 0 régression.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 08:53:14 +01:00
dom
12f4479cd2 feat: dictionnaire CIM-10 complet (10 893 codes) + robustesse regex
- Nouveau module cim10_dict.py : extraction depuis metadata.json FAISS,
  lookup intelligent avec normalisation Unicode (accents, trémas, apostrophes)
- cim10_extractor : _lookup_cim10 utilise le dictionnaire complet,
  _find_dp normalisé, _find_das élargi à 20 patterns (cardio, métabo,
  infectieux, rénal...), biologie +6 tests (TGO/TGP, Hb, créatinine),
  traitements sans limite de lignes
- document_classifier : scoring pondéré, classify_with_confidence(), scan 5000 chars
- CLI --build-dict pour regénérer data/cim10_dict.json
- 32 nouveaux tests unitaires (124 total, 0 échec)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 08:09:32 +01:00
dom
037d255aa0 feat: ajout viewer Flask CIM-10 avec config Ollama centralisée et chronométrage
Ajoute une interface web Flask pour visualiser les dossiers médicaux CIM-10,
avec temps de traitement par PDF, sélecteur de modèle Ollama, et centralisation
de la config Ollama dans src/config.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 20:11:07 +01:00
dom
4d6fbef2b9 feat: ajout RAG CIM-10 avec FAISS + Ollama
Implémente un système RAG (Retrieval Augmented Generation) qui indexe
les documents de référence ATIH (CIM-10 FR 2026, Guide Métho MCO,
CCAM PMSI) et utilise Ollama (mistral-small3.2:24b) pour justifier
et valider le codage CIM-10 des diagnostics.

- Nouveaux modèles Pydantic : RAGSource, Diagnostic étendu (confidence,
  justification, sources_rag) — rétrocompatible
- Module rag_index.py : chunking des 3 PDFs, embedding sentence-camembert-large,
  index FAISS IndexFlatIP (3630 vecteurs)
- Module rag_search.py : recherche FAISS + appel Ollama avec fallback double
- Flag CLI --no-rag pour désactiver l'enrichissement RAG
- 18 nouveaux tests (88/88 passent)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 17:47:08 +01:00
dom
4a12cd2676 feat: pipeline T2A - anonymisation, extraction CIM-10 et intégration edsnlp
Pipeline complet de traitement de documents médicaux PDF :
- Extraction texte (pdfplumber) et classification (Trackare/CRH)
- Anonymisation multi-couche (regex + NER CamemBERT + sweep)
- Extraction médicale CIM-10 hybride : edsnlp (AP-HP) enrichit les
  diagnostics, médicaments (codes ATC via Romedi) et négation,
  avec fallback regex pour les patterns spécifiques
- Fix sentencepiece pinné à <0.2.0 pour compatibilité CamemBERT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 15:24:12 +01:00