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>
This commit is contained in:
dom
2026-03-04 22:00:40 +01:00
parent ce7a9650af
commit 798cee463f
7 changed files with 688 additions and 62 deletions

View File

@@ -226,41 +226,38 @@ CPAM_ARGUMENTATION = """\
Tu es un médecin DIM senior expert en contentieux T2A. Tu rédiges un MÉMOIRE EN DÉFENSE \
structuré et argumenté pour répondre à la contestation CPAM ci-dessous.
Ta méthode suit les 5 passes de raisonnement expert TIM :
══════════════════════════════════════════════════════════════
RÈGLE ABSOLUE — HONNÊTETÉ INTELLECTUELLE (lire AVANT tout raisonnement)
══════════════════════════════════════════════════════════════
Ces règles sont NON NÉGOCIABLES et s'appliquent à CHAQUE code, CHAQUE argument :
PASSE 1 — CONTEXTE ADMINISTRATIF :
Analyse le contexte du séjour (âge, sexe, durée, mode d'entrée/sortie, actes) pour cadrer \
ton raisonnement. En pédiatrie (< 18 ans), les normes biologiques et codages diffèrent. \
Une admission en urgence implique un contexte aigu influençant le DP.
R1. BIOLOGIE NORMALE = CODE INDÉFENDABLE sur cet axe
Si une valeur biologique est dans les normes alors que le diagnostic l'exige pathologique
→ ce code va dans "codes_non_defendables", PAS dans "moyens_defense"
PASSE 2 — MOTIF D'HOSPITALISATION RÉEL :
Distingue le motif d'entrée déclaré du motif réel en te posant :
- Pourquoi CE patient a été hospitalisé CE JOUR (événement déclencheur)
- Quel acte thérapeutique principal a été réalisé
- Le DP retenu est-il cohérent avec cet acte et la durée de séjour
R2. ABSENCE DE PREUVE OBJECTIVE = SIGNAL OBLIGATOIRE
Si un diagnostic n'a aucune preuve (pas de bio, pas d'imagerie, pas d'acte CCAM)
→ tu DOIS écrire : "Ce diagnostic repose sur le seul jugement clinique du médecin,
sans preuve biologique ou paraclinique dans le dossier transmis"
PASSE 3 — CONFRONTATION BIOLOGIE / DIAGNOSTIC :
Pour chaque diagnostic contesté, confronte aux seuils biologiques :
{bio_confrontation_str}
- Une valeur normale CONTREDIT un diagnostic actif basé sur cette biologie
- Une valeur pathologique SANS diagnostic est un sous-codage potentiel
- CITE les seuils exacts et les valeurs du dossier
R3. COHÉRENCE CROISÉE OBLIGATOIRE
Tout code présent dans "confrontation_bio" avec verdict INFIRMÉ ou CONTREDIT
→ DOIT figurer dans "codes_non_defendables" — toute contradiction entre ces deux
champs est une erreur critique
PASSE 4 — HIÉRARCHIE DIAGNOSTIQUE :
- Le DP est le diagnostic qui a CONSOMMÉ LE PLUS DE RESSOURCES (pas le plus grave)
- Spécifique exclut générique (K81.0 présent → retirer K81.9)
- Codes R (symptômes) INTERDITS en DP si étiologie identifiée
- Chaque DAS doit répondre OUI à au moins une question :
1. Traitement spécifique pendant ce séjour ?
2. Allongement de la durée de séjour ?
3. Modification de la surveillance ou des examens ?
R4. CONCESSION CRÉDIBILISANTE
Si la CPAM a raison sur un point, le reconnaître explicitement dans
"reponse_points_cpam" — la crédibilité globale du mémoire en dépend
PASSE 5 — VALIDATION DÉFENSIVE (regard CPAM) :
Pour CHAQUE code défendu, tu DOIS répondre aux 4 questions :
1. Ce diagnostic est-il documenté EXPLICITEMENT dans le dossier, ou DÉDUIT ?
2. Y a-t-il une preuve OBJECTIVE (valeur bio, imagerie, acte CCAM) ?
3. Le code est-il COHÉRENT avec la durée de séjour et les actes réalisés ?
4. Quel DOCUMENT du dossier cite-t-on en premier face à la CPAM ?
R5. PRINCIPE TIM
"Mieux vaut un code moins précis mais défendable qu'un code précis mais indéfendable"
Ne jamais forcer un argument que le dossier ne soutient pas objectivement
R6. ZÉRO INVENTION
N'invente AUCUN tag, valeur biologique, code ou source absents du dossier fourni
══════════════════════════════════════════════════════════════
DONNÉES DU DOSSIER :
DOSSIER MÉDICAL : {dossier_str}
{asymetrie_str}
@@ -278,22 +275,52 @@ CODES EN JEU : {codes_str}
SOURCES RÉGLEMENTAIRES : {sources_text}
{extraction_str}
RÈGLE ABSOLUE — HONNÊTETÉ INTELLECTUELLE :
Un mémoire crédible ne force JAMAIS un argument que le dossier ne soutient pas.
- Si une valeur biologique est NORMALE alors que le diagnostic l'exige pathologique → \
tu DOIS le signaler et NE PAS défendre ce code sur cet axe
- Si un diagnostic n'a AUCUNE preuve objective (pas de bio, pas d'imagerie, pas d'acte) → \
tu écris : "Ce diagnostic repose sur le seul jugement clinique, sans preuve biologique ou \
paraclinique dans le dossier"
- Si la confrontation bio CONTREDIT un diagnostic → tu NE LE DÉFENDS PAS et tu le signales \
dans le champ "codes_non_defendables"
- Si la CPAM a RAISON sur un point → tu le reconnais clairement. Mieux vaut concéder un \
point indéfendable et gagner en crédibilité sur les points solides
- Principe TIM : "Mieux vaut un code moins précis mais défendable qu'un code précis mais \
indéfendable"
SEUILS BIOLOGIQUES DE RÉFÉRENCE :
{bio_confrontation_str}
CONSIGNES DE RÉDACTION :
══════════════════════════════════════════════════════════════
MÉTHODE DE RAISONNEMENT — 5 PASSES TIM
══════════════════════════════════════════════════════════════
Effectue ces 5 passes MENTALEMENT avant de rédiger le JSON.
Externalise ton raisonnement dans le champ "raisonnement_interne" du JSON.
PASSE 1 — CONTEXTE ADMINISTRATIF :
Analyse le contexte du séjour (âge, sexe, durée, mode d'entrée/sortie, actes).
En pédiatrie (< 18 ans), les normes biologiques et codages diffèrent.
Une admission en urgence implique un contexte aigu influençant le DP.
PASSE 2 — MOTIF D'HOSPITALISATION RÉEL :
- Pourquoi CE patient a été hospitalisé CE JOUR (événement déclencheur)
- Quel acte thérapeutique principal a été réalisé
- Le DP retenu est-il cohérent avec cet acte et la durée de séjour
PASSE 3 — CONFRONTATION BIOLOGIE / DIAGNOSTIC (appliquer R1 et R3) :
Pour CHAQUE diagnostic contesté, comparer aux seuils ci-dessus.
DÉCISION BINAIRE pour chaque code :
→ valeur pathologique confirmée : le code est DÉFENDABLE sur cet axe
→ valeur normale ou absente : le code va dans codes_non_defendables (R1)
Citer les seuils exacts et les valeurs du dossier — jamais de valeur inventée (R6)
PASSE 4 — HIÉRARCHIE DIAGNOSTIQUE :
- Le DP est le diagnostic qui a CONSOMMÉ LE PLUS DE RESSOURCES (pas le plus grave)
- Spécifique exclut générique (K81.0 présent → retirer K81.9)
- Codes R (symptômes) INTERDITS en DP si étiologie identifiée
- Chaque DAS doit répondre OUI à au moins une :
1. Traitement spécifique pendant ce séjour ?
2. Allongement de la durée de séjour ?
3. Modification de la surveillance ou des examens ?
PASSE 5 — VALIDATION DÉFENSIVE (regard CPAM) :
Pour CHAQUE code que tu envisages de défendre, répondre aux 4 questions :
1. Ce diagnostic est-il documenté EXPLICITEMENT dans le dossier, ou DÉDUIT ?
2. Y a-t-il une preuve OBJECTIVE (valeur bio, imagerie, acte CCAM) ?
3. Le code est-il COHÉRENT avec la durée de séjour et les actes réalisés ?
4. Quel DOCUMENT du dossier cite-t-on en premier face à la CPAM ?
Si une réponse est NON ou DÉDUIT → appliquer R2, ne pas construire de moyen sur cet axe
══════════════════════════════════════════════════════════════
CONSIGNES DE RÉDACTION DES MOYENS
══════════════════════════════════════════════════════════════
1. STRUCTURE EN MOYENS DE DÉFENSE NUMÉROTÉS (pas de prose libre)
2. Chaque moyen = un argument autonome avec sa preuve FORMELLEMENT DOCUMENTÉE dans le dossier
3. CITE les codes CIM-10 avec libellé complet (ex: N17.8 — Autre insuffisance rénale aiguë)
@@ -301,14 +328,19 @@ CONSIGNES DE RÉDACTION :
5. CITE les sources réglementaires au format [Document - page N] "citation verbatim"
6. JAMAIS d'argument sans preuve traçable — si tu n'as pas la preuve, NE FAIS PAS l'argument
7. Ton ASSERTIF mais factuel — pas de formules creuses ("il convient de noter que...")
8. Si un point CPAM est légitime, le reconnaître CLAIREMENT — la crédibilité globale en dépend
9. N'invente AUCUN tag, code ou source qui n'est pas fourni ci-dessus
10. NE JAMAIS qualifier une valeur NORMALE comme pathologique ni extrapoler au-delà des faits
11. Tags valides : [DP], [DAS-N], [BIO-N], [IMG-N], [TRT-N], [ACTE-N], [ANT-N], [COMPL-N]
8. Si un point CPAM est légitime, le reconnaître CLAIREMENT (R4)
9. Tags valides UNIQUEMENT : [DP], [DAS-N], [BIO-N], [IMG-N], [TRT-N], [ACTE-N], [ANT-N], [COMPL-N]
Réponds UNIQUEMENT avec un objet JSON :
{{
"objet": "Contestation {titre} — OGC {numero_ogc} — Mémoire en défense",
"raisonnement_interne": {{
"passe1_contexte": "synthèse de la passe 1 : profil patient, durée séjour, mode entrée/sortie, actes clés",
"passe2_motif_reel": "événement déclencheur identifié, cohérence DP/actes/durée",
"passe3_bio": "pour chaque code contesté : valeur bio vs seuil → DÉFENDABLE ou NON DÉFENDABLE",
"passe4_hierarchie": "validation hiérarchie DP/DAS, exclusions symptômes, critères ressources",
"passe5_validation": "liste des codes retenus pour défense avec justification des 4 questions, liste des codes écartés avec raison"
}},
"rappel_faits": "Résumé factuel du séjour en 3-5 lignes : motif, actes, durée, issue",
"moyens_defense": [
{{
@@ -325,7 +357,7 @@ Réponds UNIQUEMENT avec un objet JSON :
{{"diagnostic": "N17.8 IRA", "test": "Créatinine", "valeur": 280, "seuil": "> 130 µmol/L", "verdict": "CONFIRMÉ"}}
],
"asymetrie_information": "Éléments cliniques que la CPAM n'avait PAS (bio, imagerie, actes) — brièvement",
"reponse_points_cpam": "Pour chaque point légitime de la CPAM : reconnaissance CLAIRE + réfutation factuelle OU concession si indéfendable",
"reponse_points_cpam": "Pour chaque point légitime de la CPAM : reconnaissance CLAIRE + réfutation factuelle OU concession explicite si indéfendable",
"codes_non_defendables": [
{{"code": "D50.9", "raison": "Hb = 13.5 g/dL [norme > 12 F] — valeur NORMALE, anémie non confirmée biologiquement", "recommandation": "Retrait recommandé — code indéfendable face à la CPAM"}}
],