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>
This commit is contained in:
dom
2026-02-20 07:53:43 +01:00
parent 5cf7d74fa3
commit 6c036ed7f1
3 changed files with 30 additions and 2 deletions

View File

@@ -55,5 +55,11 @@
"Z93.3": "Colostomie",
"Z93.0": "Trachéostomie",
"Z98.0": "État consécutif à une dérivation intestinale ou à une anastomose",
"Z98.1": "État consécutif à une arthrodèse"
"Z98.1": "État consécutif à une arthrodèse",
"R33": "Rétention d'urine",
"R33.0": "Rétention d'urine due à un obstacle mécanique",
"R33.8": "Autre rétention d'urine",
"R33.9": "Rétention d'urine, sans précision",
"F17.1": "Troubles mentaux et du comportement liés à l'utilisation de tabac, utilisation nocive pour la santé",
"F17.2": "Troubles mentaux et du comportement liés à l'utilisation de tabac, syndrome de dépendance"
}

View File

@@ -494,6 +494,15 @@ def _apply_llm_result_diagnostic(diagnostic: Diagnostic, llm_result: dict) -> No
if code:
code = normalize_code(code)
# Garde-fou : rejeter un code sans raisonnement ni justification
# (corrélation forte avec les hallucinations LLM)
if not raisonnement and not justification:
logger.warning(
"RAG : code %s rejeté pour « %s » — raisonnement et justification vides",
code, diagnostic.texte,
)
code = None
if code:
is_valid, _ = cim10_validate(code)
if is_valid:
diagnostic.cim10_suggestion = code

View File

@@ -12,6 +12,8 @@ import re
import unicodedata
from typing import Optional
import logging
from ..config import (
CodeDecision,
Diagnostic,
@@ -21,6 +23,9 @@ from ..config import (
load_bio_rules,
rule_enabled,
)
from ..medical.cim10_dict import validate_code as cim10_validate
logger = logging.getLogger(__name__)
# --- Règles "étiologiques" : ne pas affirmer sans preuve spécifique ---
@@ -317,7 +322,15 @@ def apply_decisions(dossier: DossierMedical) -> None:
def _set_default_final(diag: Diagnostic):
if diag.cim10_suggestion and diag.cim10_final is None:
diag.cim10_final = diag.cim10_suggestion
is_valid, _ = cim10_validate(diag.cim10_suggestion)
if is_valid:
diag.cim10_final = diag.cim10_suggestion
else:
logger.warning(
"Code %s absent du dictionnaire CIM-10 pour « %s » — cim10_final non rempli",
diag.cim10_suggestion, diag.texte,
)
diag.cim10_final = None
# DP
if dossier.diagnostic_principal: