Commit Graph

49 Commits

Author SHA1 Message Date
dom
214a5d1914 fix: qualité codage — anti-hallucination LLM + négation regex + veto calibration
- Prompt DAS_EXTRACTION : ajout consignes anti-hallucination (zero invention,
  pas d'inférence de comorbidités, exiger citation exacte du texte)
- Prompt CODING_CIM10 : ajout consignes conditionnel et négation
- diagnostic_extraction.py : détection de négation avant les patterns regex DAS
  (bloque "pas d'embolie", "absence de sepsis", "sans signe d'IRC", etc.)
- veto_engine.py : VETO-03 conditionnel cherche maintenant PRÈS du concept
  (40 chars), "si" isolé ne déclenche plus de faux positif, ajout cues
  (possible, risque de, aspect de, à confirmer, à rechercher)
- veto_engine.py : négation enrichie (ne retrouve pas, sans signe/argument,
  écarté, infirmé, pas mis en évidence)

Batch analysis: VETO-02 63% from LLM hallucinations, VETO-03 63% false positives

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:59:02 +01:00
dom
a371626f40 feat: dictionnaire de codage + détection anomalies statistiques
- Script build_coding_dict.py génère le dictionnaire depuis le batch (240 dossiers)
- coding_dictionary.json : co-occurrences DP→DAS, fréquences, associations bio
- anomaly_stats.py : 8 checks (DP/DAS rare, DAS manquant, bio-DAS, âge atypique)
- Intégré dans le pipeline cim10_extractor post-DIM-senior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:48:36 +01:00
dom
4b6e3cf6d5 feat: optimisations pipeline médical (bio_normals, GHM, DP selector, CIM-10)
- bio_normals: table de normes biologiques étendue (+200 analytes)
- bio_extraction: amélioration parsing valeurs biologiques
- cim10_extractor: règles supplémentaires extraction codes
- dp_selector: affinement sélection diagnostic principal
- ghm: estimation sévérité GHM enrichie
- validation_pipeline: correctifs mineurs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:14:13 +01:00
dom
63f61f196b feat: 8 optimisations vitesse + qualité pipeline CIM-10
1. Parallélisation intra-dossier (RAG + DP selector en parallèle)
2. Cache embeddings FAISS (_embed_cached avec LRU)
3. Lazy loading edsnlp (déjà singleton, vérifié)
4. Prompt DP amélioré avec règles PMSI/ATIH
5. Validation croisée Bio↔DAS (cohérence biologie/diagnostics)
6. Resélection DP après vetos/exclusions (reselect_dp_after_vetos)
7. Pré-filtrage R-codes (déjà implémenté dans exclusion_rules)
8. Cache embeddings texte (intégré dans rag_search)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 22:18:07 +01:00
dom
1e837c2758 feat: interface admin regles, refactoring viewer, README, pyproject.toml
- Nouveau module rules_manager.py : CRUD YAML pour les regles metier
- Nouveau blueprint bp_rules.py + template admin_rules.html :
  interface web pour activer/desactiver/ajouter/supprimer des regles
- Extraction helpers.py depuis app.py (filtres Jinja2, statistiques,
  scan dossiers, status systeme) — app.py passe de 1585 a 482 lignes
- Suppression backward-compat re-exports dans cim10_extractor et
  cpam_response (imports corriges dans les tests)
- README.md : architecture, modules, installation, utilisation
- pyproject.toml : dependencies completes, config ruff, pytest, coverage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 19:11:27 +01:00
dom
4e2b4bd946 refactor: réorganisation référentiels, nouveaux modules extraction, nettoyage code obsolète
- Réorganisation data/referentiels/ : pdfs/, dicts/, user/ (structure unifiée)
- Fix badges "Source absente" sur page admin référentiels
- Ré-indexation COCOA 2025 (555 → 1451 chunks, couverture 94%)
- Fix VRAM OOM : embeddings forcés CPU via T2A_EMBED_CPU
- Nouveaux modules : document_router, docx_extractor, image_extractor, ocr_engine
- Module complétude (quality/completude.py + config YAML)
- Template DIM (synthèse dimensionnelle)
- Gunicorn config + systemd service t2a-viewer
- Suppression t2a_install_rag_cleanup/ (copie obsolète)
- Suppression scripts/ et scripts_t2a_v2/ (anciens benchmarks)
- Suppression 81 fichiers _doc.txt de test
- Cache Ollama : TTL configurable, corrections loader YAML
- Dashboard : améliorations templates (base, index, detail, cpam, validation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 16:48:10 +01:00
dom
798cee463f feat: guardian déterministe + config modèles locaux + prompt TIM R1-R6
Guardian déterministe post-LLM (0 appel modèle, <1ms) :
- Corrige les valeurs bio hallucinées via confrontation dossier
- Step 1b : vérifie l'association test↔diagnostic via _BIO_THRESHOLDS
- Chemin bidirectionnel : CONFIRMÉ↔NON CONFIRMÉ selon bio réelle
- Force R3 : codes bio-infirmés → codes_non_defendables
- Step 2b : retire les codes bio-confirmés de codes_non_defendables
- Retire les moyens défendant des codes bio-contredits
- _safe_bio_replace() : regex protégeant les normes [X-Y]
- Nettoyage texte libre (conclusion, rappel, codes_nd, raisonnement)
- Score factuel déterministe avec pénalités

Config modèles pour déploiement local (DGX Spark) :
- CPAM : mistral-small3.2:24b (TIM complet, bonne précision bio)
- Validation : qwen3:32b (rapide, LOGIC-3 actif)
- Timeout : 120s → 600s pour modèles locaux

Ollama : migration /api/generate → /api/chat (messages format)

Prompt CPAM_ARGUMENTATION restructuré :
- R1-R6 non-négociables en tête (avant données)
- Champ raisonnement_interne (chain-of-thought structuré)
- 5 passes TIM avec références explicites aux règles

Test cpam_quality : métriques guardian dans le résumé

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 22:00:40 +01:00
dom
ce7a9650af feat: méthode TIM experte CPAM + moteur de règles étendu
CPAM — Méthode TIM (mémoire en défense) :
- Réécriture CPAM_ARGUMENTATION avec raisonnement 5 passes TIM
  (contexte admin → motif réel → confrontation bio → hiérarchie → validation défensive)
- _BIO_THRESHOLDS (19 entrées) + _build_bio_confrontation() pour
  confrontation biologie/diagnostic avec seuils chiffrés et verdicts
- _format_response() dual format : nouveau TIM (moyens numérotés, tableau
  bio, codes non défendables, conclusion dispositive) + rétrocompat legacy
- CPAM_ADVERSARIAL mis à jour pour vérifier honnêteté intellectuelle
- Tests adaptés + 12 nouveaux tests (bio confrontation, format TIM)

Moteur de règles :
- Nouvelles règles YAML : demographic, diagnostic_conflicts,
  procedure_diagnosis, temporal, parcours
- Bio extraction FAISS (synonymes vectoriels)
- Veto engine enrichi (citations, Trackare skip, règles démographiques)
- Decision engine : _apply_bio_rules_gen() + matchers analytiques

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 11:57:07 +01:00
dom
c7317af447 feat: dp_finalizer — arbitrage Trackare vs CRH-only avec traçabilité audit
Nouveau module src/medical/dp_finalizer.py :
- 5 règles d'arbitrage (R1-R5) : CRH CONFIRMED override, Trackare corroboré,
  symptôme R* override/review, ambigu REVIEW, Z-code/R-code interdits auto-confirm
- Traçabilité : dp_trackare, dp_crh_only, dp_final sur DossierMedical
- quality_flags dict (merge sans écraser) + alertes_codage (append)

Modèles config.py :
- DPCandidate, DPSelection (NUKE-3)
- get_dp_ranker_llm_enabled(), check_adversarial_model_config()
- Champs DossierMedical : dp_trackare, dp_crh_only, dp_final, quality_flags

Intégration :
- main.py : appel finalize_dp() après vetos/GHM (individuel + fusionné)
- benchmark : finalizer dans _rebuild_and_select(), dp_final dans output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:50:07 +01:00
dom
06a1be5425 feat: alias diagnostiques CIM-10 + scoring conclusion + garde-fou Trackare R-code
- DIAGNOSIS_ALIASES : mapping acronymes cliniques → CIM-10 (DLBCL→C83.3, SCA→I25.1, EP→I26.9, IDM→I21.9, etc.)
- Scoring 4b étendu : conclusion (+2) ajouté aux sections diagnostiques, matching par alias en plus du terme/code
- _collect_evidence : détection alias dans les sections pour preuves plus complètes
- Garde-fou Trackare : si DP est un R-code (symptôme) et que les sections CRH mentionnent un diagnostic étiologique via alias → verdict REVIEW au lieu de CONFIRMED, alerte DIM
- Case 74 : verdict attendu REVIEW (conclusion mentionne les 2 diagnostics, delta insuffisant)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 14:35:15 +01:00
dom
2701efb1d2 feat: CRH diag sections + DP scoring bonus + evidence by code
- crh_parser: 3 nouvelles sections (diag_sortie, diag_principal, synthese)
  avec garde-fou début de ligne pour éviter faux positifs mid-sentence
- dp_selector: NUKE-3 sélecteur DP déterministe (548 lignes)
  - build_candidates/score_candidates/select_dp
  - bonus +4 pour mention dans diag_sortie/diag_principal
  - bonus +2 pour mention dans synthese
  - hardening DIM : A1 evidence, A2 mono-fragile, A3 confidence cap
  - _collect_evidence match par terme OU code CIM-10
  - LLM tiebreaker optionnel (DP_RANKER_CONSTRAINED)
- fusion: propagation dp_selection depuis le dossier source du DP retenu

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 13:28:31 +01:00
dom
8e0ed1220d fix: max_tokens CPAM 6000→16000 + diagnostic troncature Ollama
- Argumentation + correction : max_tokens porté à 16000 (num_predict)
- ollama_client : log done_reason=length pour détecter les troncatures serveur
- Résultat live : 1/3 Tier B (dossier 132 passé de C à B, score 5/10)
- Les 2 Tier C restants sont bloqués par hallucination de codes et
  absence de données bio, pas par max_tokens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 15:00:08 +01:00
dom
e77c10da7d fix: réparation JSON tronqué + retry 429 + whitelist codes CPAM anti-hallucination
- parse_json_response : réparation JSON tronqué par max_tokens (fermeture
  auto des structures ouvertes), meilleur stripping des blocs fencés avec
  texte superflu après la fermeture ```
- call_ollama : retry avec backoff exponentiel (1s/2s/4s) pour les erreurs
  429 rate limit, 3 tentatives au lieu de 2
- Validation adversariale : max_tokens 800 → 1500
- Prompt CPAM : whitelist PÉRIMÈTRE DE CODES AUTORISÉS (dossier DP+DAS +
  UCR) avec interdiction explicite des codes hors périmètre
- Tests : 19 tests parse_json/_repair_truncated_json, 6 tests whitelist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:33:39 +01:00
dom
77ffbc56d4 feat: CODE_CORRECTIONS 12 règles déterministes + sentinel REJECT
- CODE_CORRECTIONS passe de 1 à 12 règles (corrections + rejets)
- REJECT_SENTINEL pour codes trop vagues (R69, R69.8, Z53.9, D71.9) ou inexistants
- Corrections : J96.0→J96.00, I50.9→I50.1 (IC gauche), N17.9→N17.0 (NTA),
  E11.9→E11.65 (DT2 insuline), K92.2→K92.0 (hématémèse), G40.9→G40.3 (épilepsie)
- _apply_code_corrections() gère REJECT : DP→None, DAS→supprimé + alerte
- 21 tests paramétrés (corrections, rejets, non-corrections)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:01:06 +01:00
dom
1a3c523987 feat: BIO_NORMALS 33 analytes + interprétations cliniques + cohérence DAS/bio étendue
- BIO_NORMALS passe de 13 à 33 tests (cardio, infectio, métabo, thyroïde, hémato, hépatique)
- _BIO_INTERPRETATION synchronisé (33 entrées, 3 clés high/low/normal chacune)
- _DAS_BIO_CHECKS étendu de 13 à 38 patterns (sepsis, infarctus, EP, diabète, thyroïde, etc.)
- lab_value_sanity.yaml étendu avec 20 garde-fous plausibilité nouveaux tests
- tests/test_bio_normals.py : 32 tests (complétude, concordance, _is_abnormal)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:00:53 +01:00
dom
e760b12961 refactor: split cim10_extractor → bio_normals, bio_extraction, diagnostic_extraction, validation_pipeline
Découpe le monolithe cim10_extractor.py (1356L) en 4 modules spécialisés :
- bio_normals.py : constante BIO_NORMALS + _is_abnormal() (feuille)
- bio_extraction.py : extraction biologie structurée
- diagnostic_extraction.py : extraction DP/DAS/actes CCAM
- validation_pipeline.py : validation CIM-10/CCAM + règles métier

Le cim10_extractor.py reste orchestrateur (~450L) avec re-exports
backward-compat. Imports mis à jour dans clinical_context, rag_search,
fusion. 748 tests passent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:06:18 +01:00
dom
1b680e9592 feat: qualité DP Phase 2 — filtre OCR étendu, abréviations médicales, promotion DAS→DP
- Filtre OCR : regex étendu (opérateurs +-*/), artefacts temporels (années),
  seuil digits abaissé 0.50→0.48
- Dictionnaire 41 abréviations médicales françaises (BMR, BPCO, SDRA, OAP,
  IDM, SCA, AVC, ACFA, SIDA, TDAH, etc.) avec expand_medical_abbreviations()
  appelé sur diagnostics Trackare et DAS LLM
- Promotion DAS→DP : si aucun DP extrait, le meilleur DAS (scoring
  pertinence/confiance/spécificité) est promu avec traçabilité RULE-DAS-TO-DP
- 95 nouveaux tests (OCR, abréviations, promotion, scoring, non-régression)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 08:37:10 +01:00
dom
6c036ed7f1 fix: garde-fous qualité Phase 1 — codes invalides et raisonnements vides
- Ajout R33, R33.0, R33.8, R33.9, F17.1, F17.2 au dictionnaire supplémentaire
- Rejet des codes CIM-10 avec raisonnement ET justification vides (corrélation hallucinations)
- Validation du code contre le dictionnaire CIM-10 avant copie suggestion → final

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 07:53:43 +01:00
dom
5cf7d74fa3 feat: parallélisation pipeline --workers N (ThreadPoolExecutor)
- Fix thread-safety FAISS index (Lock + double-check sur _loaded)
- Fix thread-safety reranker (Lock + double-check sur _reranker_model)
- main.py : flag --workers, extraction _process_group(), ThreadPoolExecutor
- benchmark_quality.py : flag --workers, subprocess en parallèle
- Validé sur 10 dossiers gold standard --workers 3 : 0 crash, codes identiques

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 01:30:51 +01:00
dom
0b94299975 feat: fix extraction DP Trackare + 5 règles ATIH (veto engine)
- Fix DP : les diagnostics Trackare marqués "principal" ne sont plus
  filtrés par is_valid_diagnostic_text() (3 dossiers récupérés)
- VETO-20 : Z code interdit en DP (sauf whitelist Z09/Z51/Z54/Z75...)
- VETO-21 : Code R (symptôme) en DP → alerte CMD 23
- VETO-22 : Même catégorie 3 chars en DP+DAS (redondance)
- VETO-23 : Exclusions mutuelles (E10↔E11, I10↔I11-I13)
- VETO-24 : Lésion traumatique (S/T) sans cause externe (V/W/X/Y)
- 24 tests unitaires, 699 tests passent sans régression

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 00:39:07 +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
fe22c0f0f5 fix: filtre bruit Trackare — antécédents parasites + répétitions DAS
- das_filter: regex anti-répétition gère les espaces entre mots concaténés
  ("VentilationVentilation Ventilation..." désormais rejeté)
- cim10_extractor: regex antécédents s'arrête à "Signes Vitaux" (ne capture
  plus le tableau de surveillance)
- Nouveau _is_valid_antecedent() filtre noms de service, mots de surveillance
  isolés, infos admin (RPPS), répétitions, Mode de vie
- 28 nouveaux tests (TestIsValidAntecedent + das_filter repetition)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 19:20:50 +01:00
dom
e74064a2e1 fix: thread-safety embedding singleton + QC alertes string
- Ajout threading.Lock sur _get_embed_model() pour empêcher les
  chargements concurrents depuis ThreadPool(2) — élimine les erreurs
  "meta tensor" et les doubles CUDA OOM
- Sentinelle _embed_failed évite les retries infinis après échec
- NotImplementedError ajouté aux exceptions capturées (meta tensor)
- Fallback CPU protégé par try/except avec _embed_failed
- QC: alertes_globales string wrappée en liste (évite itération par
  caractère quand le LLM retourne une string au lieu d'une liste)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 11:42:14 +01:00
dom
44118f69aa fix: SentenceTransformer meta tensor avec accelerate + torch 2.10
low_cpu_mem_usage=False évite les meta tensors lors du chargement
de l'embedding (sentence-transformers 5.x + accelerate 1.12).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 01:16:01 +01:00
dom
8c1b5a243e fix: prompt CPAM exige codes CIM-10 explicites, RAG résilient aux erreurs embedding
- Prompt : consigne de toujours citer les codes CIM-10 avec libellé (jamais
  "codage initial" sans préciser le code), appliquée dans conclusion et partout
- RAG résilient : _search_rag_for_control attrape toute exception (meta tensor,
  CUDA OOM, index absent) et génère la contre-argumentation sans sources plutôt
  que de perdre silencieusement tout le contrôle CPAM
- Embedding fallback : condition élargie pour couvrir "meta tensor" en plus de
  "memory" dans le message d'erreur RuntimeError

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 23:38:46 +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
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
4ef42dd3d3 fix: filtre DAS décimaux, dédup parents CIM-10, tiebreak enrichissement
- Rule 3 das_filter étendue pour rejeter "K 3.6", "B 12,5" (valeurs labo)
- Suppression codes parents dans la fusion (K85 retiré si K85.9 présent)
- Préférence du diagnostic enrichi RAG à confiance égale lors de la dédup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 15:05:26 +01:00
dom
4c6c0d25bd feat: fallback Anthropic Haiku quand Ollama est indisponible
Quand Ollama refuse la connexion ou timeout, call_ollama() bascule
automatiquement sur l'API Anthropic (Haiku par défaut). Configurable
via ANTHROPIC_API_KEY et ANTHROPIC_FALLBACK_MODEL dans .env.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 09:42:32 +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
50a77c9f61 feat: RAG CPAM dédié avec requêtes multi-ciblées + prompt 3 axes
- Nouvelle search_similar_cpam() : priorité Guide Méthodo, seuil 0.40,
  déduplication par code CIM-10, fetch élargi top_k*3
- _search_rag_for_control() refactoré : 2-3 requêtes ciblées (codes
  contestés, argument CPAM, contexte clinique) au lieu d'1 fourre-tout
- Fusion dédupliquée par (document, code, page), top 10 résultats
- Prompt CPAM enrichi : 3 axes (médical, asymétrie, réglementaire),
  section asymétrie d'information, format réponse structuré
- 9 nouveaux tests unitaires pour la logique RAG multi-requêtes

Élimine les sources CIM-10 hors-sujet (F45, F98.1, F50.5 sur pancréatite)
au profit de résultats Guide Méthodo et référentiels pertinents.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 11:08:15 +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
837bdaca76 fix: filtre DAS=DP + correction D55.9→D64.9 + enrichissement supplements CIM-10
- Filtre DAS identique au DP (violation règle PMSI) dans extracteur et fusion
- Correction automatique D55.9 → D64.9 pour "Anémie" non qualifiée (70 cas)
- 17 codes ajoutés aux supplements (K59.0, Z93.1, H92.0, A87.0, D64.9, etc.)
- 436 tests OK (+14 nouveaux)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 14:03:10 +01:00
dom
0d3cb83f12 fix: fallback CPU embedding + protection CPAM contre crash OOM
- SentenceTransformer : fallback CPU si CUDA OOM (Ollama peut occuper la VRAM)
- Bloc CPAM dans main.py : try/except pour éviter crash fatal du pipeline

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 06:11:38 +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
931b6c5d1c feat: embeddings sur GPU (CUDA) pour l'indexation et la recherche RAG
Détection automatique GPU/CPU avec fallback. Index FAISS reconstruit
en 1min (GPU) au lieu de 16min (CPU).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:42:46 +01:00
dom
31c29078a1 feat: filtrage des DAS parasites (artefacts OCR trackare)
Nouveau module das_filter.py avec 7 règles de rejet (trop court, chiffres,
lettre+chiffres OCR, mots concaténés/répétés, fragments non-médicaux) +
nettoyage newlines/ponctuation. Filtrage appliqué aux 3 sources de DAS :
trackare, regex et edsnlp. 31 tests unitaires.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 17:48:25 +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