Projet 4 : Structuration et synthèse agentique de comptes rendus de radiologie Les comptes rendus de radiologie sont généralement rédigés sous forme de texte libre, ce qui rend leur exploitation automatique difficile. Dans ce projet, nous devrons concevoir un système agentique à base de modèles de langage capable d’analyser un rapport radiologique
Jupyter Notebook
0
3 commits
updated Apr 8, 2026
RadioAI Pro est un système multi-agents basé sur LangGraph et LLMs open-source pour :
Le pipeline utilise 6 agents spécialisés orchestrés par LangGraph :
Rapport brut
↓
1️⃣ PreprocessorAgent (détection langue, qualité)
↓
2️⃣ ExtractorAgent (NER médical)
↓
3️⃣ StructurerAgent (JSON FHIR)
↓
4️⃣ VerifierAgent (fidélité clinique)
↓
5️⃣ MedicalSummaryAgent (synthèse pro) → 6️⃣ PatientSummaryAgent (vulgarisation)
↓
Rapports structurés + synthèses
# Cloner et configurer l'environnement
cd /workspaces/ProjetI3AFD
# Installer les dépendances
pip install -r requirements.txt
# Optionnel : pré-télécharger les dépendances nltk
python -c "import nltk; nltk.download('punkt')"
Ollama permet d'exécuter les modèles LLM entièrement en local sans dépendre de services cloud.
# macOS/Linux
curl -fsSL https://ollama.ai/install.sh | sh
# Ou visitez https://ollama.ai
# Démarrer le serveur Ollama (une seule fois)
ollama serve
# Dans un autre terminal, télécharger les modèles
python setup_ollama.py --pull-models
# Vérifier l'installation
python setup_ollama.py --health
Modèles utilisés :
# Télécharger OpenI/IU X-Ray (3996 rapports)
# Le notebook inclut le code de téléchargement automatique
# Ou charger depuis HuggingFace Datasets
python loader.py # Vérifier la classe OpenILoader
# Fichier attendu : data/rapports_clean.csv
# - uid : ID du rapport
# - findings : corps principal
# - impression : résumé de référence (gold)
jupyter notebook "RadioAI Pro.ipynb"
Le notebook contient :
# Vérification de la configuration
python run_experiment.py --setup
# Évaluation simple (10 rapports)
python run_experiment.py --eval --samples 10 --backend ollama
# Ablation study (comparaison mono vs multi-agents)
python run_experiment.py --ablation --samples 5
# Avec HuggingFace au lieu d'Ollama (nécessite GPU)
python run_experiment.py --eval --samples 10 --backend huggingface
from loader import OpenILoader
from model_manager import ModelManager
from pipeline import process_report
# 1. Charger un rapport
loader = OpenILoader(source="local", path="data/rapports_clean.csv")
report = next(loader.iter_reports(max_samples=1))
# 2. Initialiser le modèle (Ollama)
mm = ModelManager(backend="ollama", ollama_host="http://localhost:11434")
# 3. Traiter
result = process_report(
raw_text=report["findings"],
uid=report["uid"],
model_manager=mm,
)
# 4. Afficher les résultats
print("Résumé clinique :", result["medical_summary"])
print("Vulgarisation :", result["patient_summary"])
print("Fidélité :", result["verified"]["fidelity_score"])
ROUGE-L (chevauchement séquentiel)
BERTScore (similarité sémantique)
Fidélité Clinique
Compare deux architectures :
| Aspect | Monolithique | Multi-agents |
|---|---|---|
| Approche | 1 LLM, 1 prompt | 6 agents spécialisés |
| Qualité | Baseline | Amélioration attendue |
| Robustesse | Hallucinations fréquentes | Vérification intégrée |
| Temps | Rapide | Peut être plus lent |
| Erreurs | Moins détectables | Gestion dégradée |
Commande :
python run_experiment.py --ablation --samples 10
Résultats sauvegardés en : data/exports/ablation_*.json
ProjetI3AFD/
├── agents.py # 6 agents du pipeline
├── pipeline.py # Orchestration LangGraph
├── model_manager.py # Gestion modèles (Ollama + HF)
├── loader.py # Chargement datasets
├── metrics.py # ROUGE-L, BERTScore, fidélité
├── setup_ollama.py # Config Ollama
├── run_experiment.py # Scripts d'exécution
├── RadioAI Pro.ipynb # Notebook complet
├── requirements.txt # Dépendances
├── README.md # Ceci
├── data/
│ ├── rapports_clean.csv # Dataset (auto-téléchargé)
│ ├── resultats_evaluation.csv # Résultats sauvegardés
│ ├── exports/ # Résultats JSON
│ └── reports/ # Rapports bruts XML OpenI
└── __pycache__/ # Cache Python
Nécessite un GPU avec au minimum 24GB VRAM pour la quantification 4-bit.
mm = ModelManager(
backend="huggingface",
use_4bit=True,
device="cuda"
)
Pour les tests CI/CD :
from model_manager import MockModelManager
mm = MockModelManager()
result = process_report("rapport test", "uid_001", mm)
config = {
"preprocessor": "openbiollm", # Utiliser OpenBioLLM pour preprocess
"extractor": "openbiollm",
"structurer": "openbiollm",
"verifier": "openbiollm",
"med_summary": "biomistral",
"pat_summary": "mistral-instruct",
}
result = process_report(raw_text, uid, mm, config=config)
Le pipeline détecte automatiquement et gère les rapports de mauvaise qualité :
État dégradé indiqué par state["degraded"] = True.
agents.pyChaque agent expose une interface run(state) → state où state est un dict enrichi à chaque étape.
Agents :
PreprocessorAgent : Détection langue, qualité, sectionsExtractorAgent : NER médical (anomalies, mesures, organes)StructurerAgent : Conversion JSON FHIRVerifierAgent : Vérification fidélité cliniqueMedicalSummaryAgent : Synthèse professionnellePatientSummaryAgent : Vulgarisation patientpipeline.pyOrchestre les 6 agents via un graphe LangGraph avec :
model_manager.pyAbstraction pour charger/générer avec :
loader.pyClasse OpenILoader pour charger :
metrics.pyÉvaluation quantitative :
compute_rouge_l() : ROUGE-L sur corpuscompute_bert_score() : BERTScore (F1 sémantique)compute_clinical_fidelity() : Score fidélité cliniqueAblationStudy : Comparaison mono vs multi-agentsformat_results_table() : Formatage pour rapports# Test rapide (mode mock, données factices)
python -c "
from model_manager import MockModelManager
from pipeline import process_report
mm = MockModelManager()
result = process_report('Patient has mild cardiomegaly', 'test_001', mm)
print('✓ Pipeline opérationnel')
print('Résumé médical :', result['medical_summary'][:100])
"
# Vérifier les imports
python -c "import langgraph, langchain, rouge_score, bert_score; print('✓ Dépendances OK')"
# Vérifier Ollama
python setup_ollama.py --health
{
"uid": "001",
"findings": "Chest X-ray shows mild cardiomegaly with no acute cardiopulmonary disease.",
"impression": "Mild cardiomegaly.",
"split": "test"
}
{
"uid": "001",
"raw_text": "Chest X-ray shows...",
"preprocessed": {
"language": "en",
"quality": "good",
"completeness": 0.9,
"sections_found": ["FINDINGS", "IMPRESSION"]
},
"extracted": {
"findings": ["mild cardiomegaly"],
"anomalies": [{"name": "cardiomegaly", "severity": "mild", "certainty": "definite"}],
"organs": ["heart", "lungs"]
},
"structured": {
"report_id": "001",
"status": "final",
"findings": {"heart": "mildly enlarged"},
"impression": "Mild cardiomegaly without acute process",
"anomalies": [...]
},
"verified": {
"fidelity_score": 0.92,
"missing_findings": [],
"hallucinations": []
},
"medical_summary": "Mild cardiomegaly. Lungs clear. No acute disease.",
"patient_summary": "Votre coeur est légèrement agrandi mais vos poumons sont en bonne santé.",
"degraded": false,
"errors": []
}
| Métrique | Baseline Mono | Multi-agents | Amélioration |
|---|---|---|---|
| ROUGE-L F1 | ~0.35 | ~0.42 | +20% |
| BERTScore F1 | ~0.45 | ~0.53 | +18% |
| Fidélité | ~0.60 | ~0.80 | +33% |
| Taux pass (≥0.75) | ~35% | ~75% | +114% |
| Hallucinations | ~0.8/rapport | ~0.2/rapport | -75% |
Résultats indicatifs — varient selon dataset et configuration.
# Vérifier l'installation
ollama --version
# Démarrer manuellement
ollama serve
# Vérifier la connexion
curl http://localhost:11434/api/tags
# Lister les modèles disponibles
ollama list
# Télécharger manuellement
ollama pull biomistral
ollama pull mistral
--backend ollama au lieu d'HuggingFaceDéveloppé pour le projet I3AFD (Master Ingénierie 3A, INPT/ENSEEIHT).
Composants clés :
Projet académique. Utilisation libre pour la recherche et l'éducation.
Questions ? Consultez le notebook RadioAI Pro.ipynb pour une démonstration interactive.
Projet 4 : Structuration et synthèse agentique de comptes rendus de radiologie Les comptes rendus de radiologie sont généralement rédigés sous forme de texte libre, ce qui rend leur exploitation automatique difficile. Dans ce projet, nous devrons concevoir un système agentique à base de modèles de langage capable d’analyser un rapport radiologique
Projet 4 : Structuration et synthèse agentique de comptes rendus de radiologie Les comptes rendus de radiologie sont généralement rédigés sous forme de texte libre, ce qui rend leur exploitation automatique difficile. Dans ce projet, nous devrons concevoir un système agentique à base de modèles de langage capable d’analyser un rapport radiologique
Jupyter Notebook
0
3 commits
updated Apr 8, 2026
RadioAI Pro est un système multi-agents basé sur LangGraph et LLMs open-source pour :
Le pipeline utilise 6 agents spécialisés orchestrés par LangGraph :
Rapport brut
↓
1️⃣ PreprocessorAgent (détection langue, qualité)
↓
2️⃣ ExtractorAgent (NER médical)
↓
3️⃣ StructurerAgent (JSON FHIR)
↓
4️⃣ VerifierAgent (fidélité clinique)
↓
5️⃣ MedicalSummaryAgent (synthèse pro) → 6️⃣ PatientSummaryAgent (vulgarisation)
↓
Rapports structurés + synthèses
# Cloner et configurer l'environnement
cd /workspaces/ProjetI3AFD
# Installer les dépendances
pip install -r requirements.txt
# Optionnel : pré-télécharger les dépendances nltk
python -c "import nltk; nltk.download('punkt')"
Ollama permet d'exécuter les modèles LLM entièrement en local sans dépendre de services cloud.
# macOS/Linux
curl -fsSL https://ollama.ai/install.sh | sh
# Ou visitez https://ollama.ai
# Démarrer le serveur Ollama (une seule fois)
ollama serve
# Dans un autre terminal, télécharger les modèles
python setup_ollama.py --pull-models
# Vérifier l'installation
python setup_ollama.py --health
Modèles utilisés :
# Télécharger OpenI/IU X-Ray (3996 rapports)
# Le notebook inclut le code de téléchargement automatique
# Ou charger depuis HuggingFace Datasets
python loader.py # Vérifier la classe OpenILoader
# Fichier attendu : data/rapports_clean.csv
# - uid : ID du rapport
# - findings : corps principal
# - impression : résumé de référence (gold)
jupyter notebook "RadioAI Pro.ipynb"
Le notebook contient :
# Vérification de la configuration
python run_experiment.py --setup
# Évaluation simple (10 rapports)
python run_experiment.py --eval --samples 10 --backend ollama
# Ablation study (comparaison mono vs multi-agents)
python run_experiment.py --ablation --samples 5
# Avec HuggingFace au lieu d'Ollama (nécessite GPU)
python run_experiment.py --eval --samples 10 --backend huggingface
from loader import OpenILoader
from model_manager import ModelManager
from pipeline import process_report
# 1. Charger un rapport
loader = OpenILoader(source="local", path="data/rapports_clean.csv")
report = next(loader.iter_reports(max_samples=1))
# 2. Initialiser le modèle (Ollama)
mm = ModelManager(backend="ollama", ollama_host="http://localhost:11434")
# 3. Traiter
result = process_report(
raw_text=report["findings"],
uid=report["uid"],
model_manager=mm,
)
# 4. Afficher les résultats
print("Résumé clinique :", result["medical_summary"])
print("Vulgarisation :", result["patient_summary"])
print("Fidélité :", result["verified"]["fidelity_score"])
ROUGE-L (chevauchement séquentiel)
BERTScore (similarité sémantique)
Fidélité Clinique
Compare deux architectures :
| Aspect | Monolithique | Multi-agents |
|---|---|---|
| Approche | 1 LLM, 1 prompt | 6 agents spécialisés |
| Qualité | Baseline | Amélioration attendue |
| Robustesse | Hallucinations fréquentes | Vérification intégrée |
| Temps | Rapide | Peut être plus lent |
| Erreurs | Moins détectables | Gestion dégradée |
Commande :
python run_experiment.py --ablation --samples 10
Résultats sauvegardés en : data/exports/ablation_*.json
ProjetI3AFD/
├── agents.py # 6 agents du pipeline
├── pipeline.py # Orchestration LangGraph
├── model_manager.py # Gestion modèles (Ollama + HF)
├── loader.py # Chargement datasets
├── metrics.py # ROUGE-L, BERTScore, fidélité
├── setup_ollama.py # Config Ollama
├── run_experiment.py # Scripts d'exécution
├── RadioAI Pro.ipynb # Notebook complet
├── requirements.txt # Dépendances
├── README.md # Ceci
├── data/
│ ├── rapports_clean.csv # Dataset (auto-téléchargé)
│ ├── resultats_evaluation.csv # Résultats sauvegardés
│ ├── exports/ # Résultats JSON
│ └── reports/ # Rapports bruts XML OpenI
└── __pycache__/ # Cache Python
Nécessite un GPU avec au minimum 24GB VRAM pour la quantification 4-bit.
mm = ModelManager(
backend="huggingface",
use_4bit=True,
device="cuda"
)
Pour les tests CI/CD :
from model_manager import MockModelManager
mm = MockModelManager()
result = process_report("rapport test", "uid_001", mm)
config = {
"preprocessor": "openbiollm", # Utiliser OpenBioLLM pour preprocess
"extractor": "openbiollm",
"structurer": "openbiollm",
"verifier": "openbiollm",
"med_summary": "biomistral",
"pat_summary": "mistral-instruct",
}
result = process_report(raw_text, uid, mm, config=config)
Le pipeline détecte automatiquement et gère les rapports de mauvaise qualité :
État dégradé indiqué par state["degraded"] = True.
agents.pyChaque agent expose une interface run(state) → state où state est un dict enrichi à chaque étape.
Agents :
PreprocessorAgent : Détection langue, qualité, sectionsExtractorAgent : NER médical (anomalies, mesures, organes)StructurerAgent : Conversion JSON FHIRVerifierAgent : Vérification fidélité cliniqueMedicalSummaryAgent : Synthèse professionnellePatientSummaryAgent : Vulgarisation patientpipeline.pyOrchestre les 6 agents via un graphe LangGraph avec :
model_manager.pyAbstraction pour charger/générer avec :
loader.pyClasse OpenILoader pour charger :
metrics.pyÉvaluation quantitative :
compute_rouge_l() : ROUGE-L sur corpuscompute_bert_score() : BERTScore (F1 sémantique)compute_clinical_fidelity() : Score fidélité cliniqueAblationStudy : Comparaison mono vs multi-agentsformat_results_table() : Formatage pour rapports# Test rapide (mode mock, données factices)
python -c "
from model_manager import MockModelManager
from pipeline import process_report
mm = MockModelManager()
result = process_report('Patient has mild cardiomegaly', 'test_001', mm)
print('✓ Pipeline opérationnel')
print('Résumé médical :', result['medical_summary'][:100])
"
# Vérifier les imports
python -c "import langgraph, langchain, rouge_score, bert_score; print('✓ Dépendances OK')"
# Vérifier Ollama
python setup_ollama.py --health
{
"uid": "001",
"findings": "Chest X-ray shows mild cardiomegaly with no acute cardiopulmonary disease.",
"impression": "Mild cardiomegaly.",
"split": "test"
}
{
"uid": "001",
"raw_text": "Chest X-ray shows...",
"preprocessed": {
"language": "en",
"quality": "good",
"completeness": 0.9,
"sections_found": ["FINDINGS", "IMPRESSION"]
},
"extracted": {
"findings": ["mild cardiomegaly"],
"anomalies": [{"name": "cardiomegaly", "severity": "mild", "certainty": "definite"}],
"organs": ["heart", "lungs"]
},
"structured": {
"report_id": "001",
"status": "final",
"findings": {"heart": "mildly enlarged"},
"impression": "Mild cardiomegaly without acute process",
"anomalies": [...]
},
"verified": {
"fidelity_score": 0.92,
"missing_findings": [],
"hallucinations": []
},
"medical_summary": "Mild cardiomegaly. Lungs clear. No acute disease.",
"patient_summary": "Votre coeur est légèrement agrandi mais vos poumons sont en bonne santé.",
"degraded": false,
"errors": []
}
| Métrique | Baseline Mono | Multi-agents | Amélioration |
|---|---|---|---|
| ROUGE-L F1 | ~0.35 | ~0.42 | +20% |
| BERTScore F1 | ~0.45 | ~0.53 | +18% |
| Fidélité | ~0.60 | ~0.80 | +33% |
| Taux pass (≥0.75) | ~35% | ~75% | +114% |
| Hallucinations | ~0.8/rapport | ~0.2/rapport | -75% |
Résultats indicatifs — varient selon dataset et configuration.
# Vérifier l'installation
ollama --version
# Démarrer manuellement
ollama serve
# Vérifier la connexion
curl http://localhost:11434/api/tags
# Lister les modèles disponibles
ollama list
# Télécharger manuellement
ollama pull biomistral
ollama pull mistral
--backend ollama au lieu d'HuggingFaceDéveloppé pour le projet I3AFD (Master Ingénierie 3A, INPT/ENSEEIHT).
Composants clés :
Projet académique. Utilisation libre pour la recherche et l'éducation.
Questions ? Consultez le notebook RadioAI Pro.ipynb pour une démonstration interactive.
Projet 4 : Structuration et synthèse agentique de comptes rendus de radiologie Les comptes rendus de radiologie sont généralement rédigés sous forme de texte libre, ce qui rend leur exploitation automatique difficile. Dans ce projet, nous devrons concevoir un système agentique à base de modèles de langage capable d’analyser un rapport radiologique