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>
This commit is contained in:
@@ -112,6 +112,10 @@ def extract_medical_info(
|
||||
_extract_imagerie(anonymized_text, dossier)
|
||||
_extract_complications(anonymized_text, dossier, edsnlp_result)
|
||||
|
||||
# Phase 4 : pass LLM pour détecter des DAS supplémentaires
|
||||
if use_rag:
|
||||
_extract_das_llm(anonymized_text, dossier)
|
||||
|
||||
if use_rag:
|
||||
_enrich_with_rag(dossier)
|
||||
|
||||
@@ -133,6 +137,79 @@ def extract_medical_info(
|
||||
return dossier
|
||||
|
||||
|
||||
def _extract_das_llm(text: str, dossier: DossierMedical) -> None:
|
||||
"""Extrait des DAS supplémentaires via un pass LLM (avant enrichissement RAG)."""
|
||||
try:
|
||||
from .rag_search import extract_das_llm
|
||||
from .ollama_cache import OllamaCache
|
||||
from ..config import OLLAMA_CACHE_PATH, OLLAMA_MODEL
|
||||
except ImportError:
|
||||
logger.warning("Module RAG non disponible pour l'extraction DAS LLM")
|
||||
return
|
||||
|
||||
try:
|
||||
cache = OllamaCache(OLLAMA_CACHE_PATH, OLLAMA_MODEL)
|
||||
|
||||
# Construire le contexte
|
||||
contexte = {
|
||||
"sexe": dossier.sejour.sexe,
|
||||
"age": dossier.sejour.age,
|
||||
"duree_sejour": dossier.sejour.duree_sejour,
|
||||
"imc": dossier.sejour.imc,
|
||||
"antecedents": dossier.antecedents[:5],
|
||||
"biologie_cle": [(b.test, b.valeur, b.anomalie) for b in dossier.biologie_cle],
|
||||
"imagerie": [(i.type, (i.conclusion or "")[:200]) for i in dossier.imagerie],
|
||||
"complications": dossier.complications,
|
||||
}
|
||||
|
||||
# DAS existants (texte + code)
|
||||
existing_das = []
|
||||
existing_codes = set()
|
||||
if dossier.diagnostic_principal and dossier.diagnostic_principal.cim10_suggestion:
|
||||
existing_codes.add(dossier.diagnostic_principal.cim10_suggestion)
|
||||
for d in dossier.diagnostics_associes:
|
||||
label = d.texte
|
||||
if d.cim10_suggestion:
|
||||
label += f" ({d.cim10_suggestion})"
|
||||
existing_codes.add(d.cim10_suggestion)
|
||||
existing_das.append(label)
|
||||
|
||||
dp_texte = dossier.diagnostic_principal.texte if dossier.diagnostic_principal else ""
|
||||
|
||||
das_results = extract_das_llm(text, contexte, existing_das, dp_texte, cache=cache)
|
||||
|
||||
added = 0
|
||||
for das in das_results:
|
||||
texte = clean_diagnostic_text(das.get("texte", ""))
|
||||
if not texte or not is_valid_diagnostic_text(texte):
|
||||
continue
|
||||
|
||||
code = das.get("code_cim10")
|
||||
if code:
|
||||
code = normalize_code(code)
|
||||
is_valid, _ = cim10_validate(code)
|
||||
if not is_valid:
|
||||
logger.info("DAS LLM : code %s invalide pour « %s », ignoré", code, texte)
|
||||
continue
|
||||
if code in existing_codes:
|
||||
continue
|
||||
existing_codes.add(code)
|
||||
|
||||
dossier.diagnostics_associes.append(Diagnostic(
|
||||
texte=texte,
|
||||
cim10_suggestion=code,
|
||||
justification=das.get("justification"),
|
||||
))
|
||||
added += 1
|
||||
|
||||
if added:
|
||||
logger.info("DAS LLM : %d diagnostics supplémentaires ajoutés", added)
|
||||
|
||||
cache.save()
|
||||
except Exception:
|
||||
logger.warning("Erreur lors de l'extraction DAS LLM", exc_info=True)
|
||||
|
||||
|
||||
def _enrich_with_rag(dossier: DossierMedical) -> None:
|
||||
"""Enrichit les diagnostics via le RAG (FAISS + Ollama)."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user