spec: Architecture complète avec VLM (5 couches détection)

- Ajout documentation VLM (Ollama qwen2.5vl:7b)
- Pipeline complet: Regex → VLM → EDS-Pseudo → CamemBERT → Contextuel
- Nouvelles exigences REQ-013/REQ-014 pour optimisation VLM
- Tâches Phase 2.5: amélioration prompt, validation croisée, perf
- Document ARCHITECTURE_REELLE.md avec détails complets
- Matériel: AMD Ryzen 9 9950X, 128GB RAM, RTX 5070 12GB
- Objectifs: Rappel ≥99.5%, Précision ≥97%, F1 ≥0.98
This commit is contained in:
2026-03-02 09:52:49 +01:00
parent cb84698c2d
commit 0067738df6
8 changed files with 3251 additions and 0 deletions

View File

@@ -0,0 +1,912 @@
# Design - Optimisation de la Qualité d'Anonymisation
## 1. Vue d'Ensemble de l'Architecture
### 1.1 Architecture Actuelle (Baseline)
```
┌─────────────────────────────────────────────────────────────┐
│ PDF d'entrée │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ EXTRACTION DE TEXTE (5 passes) │
│ pdfplumber → pdfminer → PyMuPDF → docTR OCR → tesseract │
│ + OCR word map (coordonnées normalisées 0→1) │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DÉTECTION PII (4 couches) │
│ ├─ 1. Regex (EMAIL, TEL, NIR, IBAN, etc.) │
│ ├─ 2. VLM Ollama (qwen2.5vl:7b) — si PDF scanné │
│ │ • Analyse visuelle de chaque page (150 DPI) │
│ │ • 20+ catégories PII (manuscrit, mal orienté) │
│ │ • Masquage total si < 100 mots OCR │
│ ├─ 3. NER EDS-Pseudo (13 labels, F1=0.97) │
│ │ ou CamemBERT-NER ONNX (fallback) │
│ └─ 4. Extraction Trackare (champs structurés) │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ CONSOLIDATION GLOBALE │
│ Propagation des PII sur toutes les pages │
│ + Noms compagnons + Rescan sélectif │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ REDACTION PDF │
│ • Vector (PyMuPDF search_for) │
│ • Raster (OCR word map + matching flou pour VLM) │
│ Génération PDF raster + audit.jsonl │
└─────────────────────────────────────────────────────────────┘
```
**Problèmes identifiés** :
- ❌ Pas de validation post-anonymisation
- ❌ Pas de métriques de qualité
- ❌ VLM peut halluciner (pages manuscrites complexes)
- ❌ Pas d'optimisation GPU pour VLM
- ❌ Pas de tests de régression
---
### 1.2 Architecture Cible (Optimisée)
```
┌─────────────────────────────────────────────────────────────┐
│ PDF d'entrée │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ EXTRACTION DE TEXTE (inchangé) │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DÉTECTION HYBRIDE (5 passes + améliorations) │
│ ├─ 1. Regex améliorées (formats structurés) │
│ ├─ 2. VLM optimisé (GPU, prompt amélioré, anti-hallucination) │
│ ├─ 3. EDS-Pseudo (noms, contexte médical) - GPU │
│ ├─ 4. CamemBERT-NER (fallback) - GPU │
│ └─ 5. Détection contextuelle renforcée │
│ │
│ → Masquage progressif pour éviter doublons │
│ → Fusion intelligente des résultats │
│ → Validation croisée VLM ↔ NER pour réduire hallucinations│
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ CONSOLIDATION GLOBALE (inchangé) │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ REDACTION PDF │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ VALIDATION POST-ANONYMISATION (NOUVEAU) │
│ ├─ Scanner de fuite PII │
│ ├─ Vérification métadonnées │
│ ├─ Détection hallucinations VLM (cross-check NER) │
│ └─ Certificat de conformité │
└────────────────────────┬────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ ÉVALUATION QUALITÉ (si ground truth disponible) │
│ ├─ Calcul Précision/Rappel/F1 par méthode │
│ ├─ Identification faux positifs/négatifs │
│ └─ Rapport de qualité │
└─────────────────────────────────────────────────────────────┘
```
---
## 2. Composants Détaillés
### 2.1 Dataset de Test Annoté
#### 2.1.1 Structure des Données
**Format d'annotation** :
```json
{
"pdf_path": "OGC_257/FC14.pdf",
"metadata": {
"annotator": "expert_1",
"annotation_date": "2024-01-15",
"document_type": "compte_rendu_hospitalier",
"page_count": 3,
"difficulty": "medium"
},
"annotations": [
{
"id": "ann_001",
"page": 1,
"type": "NOM",
"text": "DUPONT",
"bbox": [100.5, 200.3, 150.2, 220.8],
"context": "Dr. DUPONT a examiné le patient",
"mandatory": true,
"difficulty": "easy",
"detection_method_expected": ["regex", "ner", "contextual"]
}
],
"medical_terms_to_preserve": [
"Médecin DIM",
"Service de cardiologie",
"Praticien conseil"
],
"statistics": {
"total_pii": 45,
"by_type": {
"NOM": 12,
"PRENOM": 8,
"TEL": 3,
"EMAIL": 2,
"DATE": 15,
"ADRESSE": 5
}
}
}
```
#### 2.1.2 Outil d'Annotation
**Composant** : `annotation_tool.py`
**Fonctionnalités** :
- Interface CLI pour annoter les PDF
- Extraction automatique du texte + affichage
- Saisie guidée des annotations
- Validation du format JSON
- Export au format standardisé
**Workflow d'annotation** :
1. Sélectionner un PDF du corpus
2. Extraire et afficher le texte page par page
3. Pour chaque PII identifié :
- Saisir le type (NOM, TEL, EMAIL, etc.)
- Saisir le texte exact
- Saisir le contexte (fenêtre de 50 caractères)
- Marquer comme obligatoire/optionnel
- Estimer la difficulté (easy/medium/hard)
4. Lister les termes médicaux à préserver
5. Sauvegarder l'annotation
---
### 2.2 Système d'Évaluation
#### 2.2.1 Évaluateur de Qualité
**Composant** : `quality_evaluator.py`
**Classes principales** :
```python
@dataclass
class EvaluationResult:
true_positives: int
false_positives: int
false_negatives: int
precision: float
recall: float
f1_score: float
missed_pii: List[Dict] # Faux négatifs détaillés
false_detections: List[Dict] # Faux positifs détaillés
by_type: Dict[str, Dict] # Métriques par type de PII
class QualityEvaluator:
def evaluate(self, pdf_path: Path, audit_path: Path) -> EvaluationResult
def compare(self, annotations: List, detected: List) -> tuple
def generate_report(self, results: List[EvaluationResult]) -> str
```
**Algorithme de comparaison** :
1. Charger les annotations manuelles (ground truth)
2. Charger l'audit généré (détections)
3. Normaliser les textes (lowercase, strip)
4. Créer des clés de comparaison : `(page, type, texte_normalisé)`
5. Calculer les intersections :
- TP = annotations ∩ détections
- FN = annotations - détections (PII manqués)
- FP = détections - annotations (sur-détection)
6. Calculer les métriques
7. Générer le rapport détaillé
---
#### 2.2.2 Scanner de Fuite
**Composant** : `leak_scanner.py`
**Classes principales** :
```python
@dataclass
class LeakReport:
is_safe: bool
leak_count: int
leaks: List[Dict]
severity_counts: Dict[str, int]
class LeakScanner:
def scan(self, anonymized_pdf: Path, original_audit: Path) -> LeakReport
def scan_text(self, text: str, original_pii: List) -> List[Dict]
def scan_metadata(self, pdf_path: Path) -> List[Dict]
```
**Algorithme de scan** :
1. Extraire le texte du PDF anonymisé
2. Charger les PII originaux depuis l'audit
3. Vérifier que les PII originaux ne sont plus présents
4. Détecter de nouveaux PII non masqués (regex + NER)
5. Scanner les métadonnées PDF
6. Classer les fuites par sévérité :
- CRITIQUE : PII original présent
- HAUTE : Nouveau PII détecté
- MOYENNE : Métadonnée suspecte
---
#### 2.2.3 Benchmark de Performance
**Composant** : `benchmark.py`
**Métriques collectées** :
- Temps de traitement (total, par page, par étape)
- Utilisation CPU (%)
- Utilisation RAM (MB)
- Métriques de qualité (Précision, Rappel, F1)
- Nombre de PII détectés par type
**Format de sortie** :
```json
{
"benchmark_date": "2024-01-15T10:30:00",
"system_info": {
"cpu": "Intel i7-9700K",
"ram_gb": 16,
"python_version": "3.12.0"
},
"results": [
{
"pdf_path": "OGC_257/FC14.pdf",
"processing_time_s": 12.5,
"time_per_page_s": 4.2,
"cpu_usage_percent": 85.3,
"ram_usage_mb": 1024,
"pii_detected": 45,
"quality_metrics": {
"precision": 0.98,
"recall": 0.995,
"f1_score": 0.987
}
}
],
"summary": {
"avg_time_per_doc": 15.2,
"avg_precision": 0.975,
"avg_recall": 0.992,
"avg_f1": 0.983
}
}
```
---
### 2.3 Détecteurs Améliorés
#### 2.3.1 Regex Améliorées
**Composant** : `improved_regex_detector.py`
**Améliorations par type** :
**A) Téléphones** :
```python
RE_TEL_IMPROVED = re.compile(
r"(?<!\d)"
r"(?:"
# Format international
r"(?:\+33|0033)\s*[1-9](?:[\s.\-]?\d){8}"
r"|"
# Format national
r"0[1-9](?:[\s.\-]?\d){8}"
r"|"
# Format fragmenté (max 3 espaces/retours entre groupes)
r"0[1-9][\s.\-]?\d{1,2}[\s.\-]?\d{1,2}[\s\n]{1,3}\d{1,2}[\s.\-]?\d{1,2}[\s.\-]?\d{1,2}"
r")"
r"(?!\d)",
re.MULTILINE
)
```
**B) Emails** :
```python
RE_EMAIL_IMPROVED = re.compile(
r"\b[A-Za-z0-9._%+-]+"
r"@"
r"(?:"
# Domaines médicaux
r"(?:chu|ch|aphp|ap-hm|hospices-civils|clinique|hopital|ehpad)"
r"[\w\-]*\.[a-z]{2,}"
r"|"
# Domaines génériques
r"[A-Za-z0-9.-]+\.[A-Za-z]{2,}"
r")\b",
re.IGNORECASE
)
```
**C) Adresses** :
```python
RE_ADRESSE_IMPROVED = re.compile(
r"\b"
r"(?:\d{1,4}\s*(?:bis|ter|quater|[A-Z])?\s*,?\s*)?"
r"(?:rue|avenue|boulevard|place|chemin|allée|impasse|route|"
r"résidence|lotissement|cité|hameau|quartier)\s+"
r"(?:de\s+(?:la\s+|l['']\s*|les\s+)?|du\s+|des\s+)?"
r"[A-ZÉÈÀÙÂÊÎÔÛa-zéèàùâêîôûäëïöüç\s\-']{2,}"
r"(?:\s*,?\s*(?:Bât(?:iment)?\.?\s*[A-Z0-9]+|Appt?\.?\s*\d+))?"
,
re.IGNORECASE
)
```
**Tests unitaires** :
- Minimum 20 cas de test par regex
- Cas positifs (doit matcher)
- Cas négatifs (ne doit pas matcher)
- Cas limites (formats rares)
---
#### 2.3.2 Détecteur Contextuel
**Composant** : `contextual_detector.py`
**Stratégie** :
1. Détecter les noms avec contexte fort (haute confiance)
2. Détecter les noms en MAJUSCULES (moyenne confiance)
3. Détecter les noms avec contexte faible (basse confiance)
4. Filtrer les faux positifs via stopwords médicaux
5. Dédupliquer et trier par confiance
**Patterns de contexte** :
```python
STRONG_CONTEXTS = [
r"(?:Dr\.?|Docteur|Pr\.?|Professeur)\s+{name}",
r"(?:Mme|Madame|M\.|Monsieur)\s+{name}",
r"Patient(?:e)?\s*:\s*{name}",
r"Nom\s*:\s*{name}",
r"(?:Rédigé|Validé|Signé)\s+par\s+{name}",
]
WEAK_CONTEXTS = [
r"{name}\s+a\s+(?:examiné|consulté|prescrit)",
r"(?:examen|consultation)\s+(?:de|par)\s+{name}",
]
```
**Niveau de confiance** :
- Contexte fort : 0.95
- MAJUSCULES (hors stopwords) : 0.80
- Contexte faible : 0.60
---
#### 2.3.3 Détecteur Hybride
**Composant** : `hybrid_detector.py`
**Architecture** :
```python
class HybridDetector:
def __init__(self):
self.regex_detector = ImprovedRegexDetector()
self.eds_pseudo = EdsPseudoManager()
self.camembert_ner = NerModelManager()
self.contextual_detector = ContextualDetector()
def detect(self, text: str, page: int) -> List[PiiHit]:
# Étape 1 : Regex (priorité haute)
hits = self.regex_detector.detect(text, page)
masked_text = self._mask_zones(text, hits)
# Étape 2 : EDS-Pseudo
if self.eds_pseudo.is_loaded():
eds_hits = self._detect_with_eds(masked_text, page)
hits.extend(eds_hits)
masked_text = self._mask_zones(masked_text, eds_hits)
# Étape 3 : CamemBERT-NER
if self.camembert_ner.is_loaded():
camembert_hits = self._detect_with_camembert(masked_text, page)
hits.extend(camembert_hits)
masked_text = self._mask_zones(masked_text, camembert_hits)
# Étape 4 : Contextuel
context_hits = self.contextual_detector.detect(masked_text, page)
hits.extend(context_hits)
# Fusion et dédoplication
return self._merge_hits(hits)
```
**Stratégie de fusion** :
- Dédupliquer par position (même zone = même PII)
- En cas de conflit de type, garder le plus spécifique
- Tracer la méthode de détection pour chaque PII
---
### 2.4 Validation Post-Anonymisation
**Composant** : `post_validation.py`
**Workflow** :
```python
def validate_anonymized_pdf(
anonymized_pdf: Path,
original_audit: Path,
strict_mode: bool = True
) -> ValidationResult:
# 1. Scanner les fuites
leak_report = leak_scanner.scan(anonymized_pdf, original_audit)
# 2. Vérifier la lisibilité
readability_score = check_readability(anonymized_pdf)
# 3. Générer le certificat
if leak_report.is_safe and readability_score > 0.7:
certificate = generate_certificate(anonymized_pdf)
return ValidationResult(
is_valid=True,
certificate=certificate,
leak_report=leak_report
)
else:
if strict_mode:
raise ValidationError("Document non conforme")
return ValidationResult(
is_valid=False,
leak_report=leak_report
)
```
**Certificat de conformité** :
```json
{
"certificate_id": "CERT-2024-01-15-001",
"pdf_path": "OGC_257/FC14.redacted_raster.pdf",
"validation_date": "2024-01-15T10:30:00",
"is_compliant": true,
"checks": {
"no_pii_leak": true,
"metadata_clean": true,
"readability_ok": true
},
"validator": "LeakScanner v2.0",
"signature": "sha256:abc123..."
}
```
---
### 2.5 Reporting
**Composant** : `quality_reporter.py`
**Rapport HTML** :
- Vue d'ensemble (métriques globales)
- Graphiques (répartition PII, évolution qualité)
- Tableau détaillé par document
- Liste des faux négatifs (si disponible)
- Liste des faux positifs (si disponible)
- Recommandations d'amélioration
**Template Jinja2** :
```html
<!DOCTYPE html>
<html>
<head>
<title>Rapport de Qualité - Anonymisation</title>
<style>/* CSS moderne */</style>
</head>
<body>
<h1>Rapport de Qualité d'Anonymisation</h1>
<section class="summary">
<h2>Vue d'Ensemble</h2>
<div class="metrics">
<div class="metric">
<span class="value">{{ precision|round(3) }}</span>
<span class="label">Précision</span>
</div>
<div class="metric">
<span class="value">{{ recall|round(3) }}</span>
<span class="label">Rappel</span>
</div>
<div class="metric">
<span class="value">{{ f1_score|round(3) }}</span>
<span class="label">F1-Score</span>
</div>
</div>
</section>
<!-- Graphiques, tableaux, etc. -->
</body>
</html>
```
---
## 3. Flux de Données
### 3.1 Flux d'Annotation
```
PDF réel → Extraction texte → Affichage CLI → Saisie annotations
→ Validation format → Sauvegarde JSON → Dataset annoté
```
### 3.2 Flux d'Évaluation
```
PDF + Annotations → Anonymisation → Audit généré
→ Comparaison → Calcul métriques → Rapport qualité
```
### 3.3 Flux de Validation
```
PDF anonymisé + Audit original → Scanner fuite → Vérification métadonnées
→ Check lisibilité → Certificat conformité (si OK)
```
---
## 4. Décisions Techniques
### 4.1 Choix d'Implémentation
**Langage** : Python 3.12 (existant)
**Bibliothèques** :
- `pytest` : Tests unitaires et de régression
- `pydantic` : Validation des données (annotations, config)
- `structlog` : Logging structuré
- `jinja2` : Génération rapports HTML
- `matplotlib` : Graphiques (léger, pas de dépendance JS)
**Format de données** :
- Annotations : JSON (lisible, éditable)
- Rapports : HTML + JSON (double export)
- Certificats : JSON signé (SHA256)
### 4.2 Optimisations Performance
**Accélération GPU** :
- Utiliser CUDA pour EDS-Pseudo et CamemBERT-NER
- Batch processing optimisé pour 12 GB VRAM
- Batch size dynamique selon la taille des documents
- Fallback CPU automatique si GPU indisponible
**Parallélisation CPU** :
- Traitement parallèle de plusieurs PDFs (ProcessPoolExecutor)
- Nombre de workers optimal : 8-12 (sur 16 cœurs / 32 threads)
- Répartition intelligente de la charge
**Mémoire** :
- Pas de contrainte mémoire (128 GB disponibles)
- Possibilité de charger plusieurs modèles simultanément
- Cache des résultats NER pour paragraphes identiques
**Optimisations supplémentaires** :
- Quantification ONNX des modèles NER (optionnel)
- Préchargement des modèles en mémoire
- Pipeline asynchrone (extraction → détection → redaction)
---
## 5. Interfaces et API
### 5.1 API d'Évaluation
```python
# Évaluer un document
evaluator = QualityEvaluator(ground_truth_dir)
result = evaluator.evaluate(pdf_path, audit_path)
# Évaluer un batch
results = evaluator.evaluate_batch(pdf_list, audit_list)
report = evaluator.generate_report(results)
```
### 5.2 API de Validation
```python
# Valider un document anonymisé
scanner = LeakScanner()
leak_report = scanner.scan(anonymized_pdf, original_audit)
if leak_report.is_safe:
print("✅ Document conforme")
else:
print(f"{leak_report.leak_count} fuites détectées")
```
### 5.3 API de Benchmark
```python
# Benchmarker le système
benchmark = Benchmark(test_data_dir)
results = benchmark.run()
benchmark.export_results("benchmark_results.json")
```
---
## 6. Configuration
### 6.1 Fichier de Configuration
**Fichier** : `config/quality_config.yml`
```yaml
evaluation:
ground_truth_dir: "tests/ground_truth"
min_documents: 30
confidence_thresholds:
regex: 1.0
eds_pseudo: 0.85
camembert: 0.90
contextual: 0.80
validation:
strict_mode: true
scan_metadata: true
readability_threshold: 0.7
detection:
enable_regex: true
enable_eds_pseudo: true
enable_camembert: true
enable_contextual: true
# Accélération GPU
gpu:
enabled: true
device: "cuda" # ou "cpu" pour fallback
batch_size: 16 # Ajuster selon VRAM disponible
max_vram_gb: 10 # Limite de VRAM (12 GB disponibles)
regex:
patterns: [EMAIL, TEL, NIR, IBAN, IPP, FINESS, RPPS, OGC, DATE, ADRESSE]
contextual:
strong_context_confidence: 0.95
uppercase_confidence: 0.80
weak_context_confidence: 0.60
performance:
max_workers: 8 # Traitement parallèle de PDFs (16 cœurs / 32 threads disponibles)
max_ram_gb: 32 # Limite RAM par processus (128 GB disponibles)
enable_cache: true
enable_gpu: true
reporting:
output_format: [html, json]
include_graphs: true
export_false_negatives: true
export_false_positives: true
```
---
## 7. Tests
### 7.1 Tests Unitaires
**Couverture** : ≥ 80% pour les composants critiques
**Tests par composant** :
- `test_regex_improved.py` : Tests exhaustifs des regex
- `test_contextual_detector.py` : Tests de détection contextuelle
- `test_hybrid_detector.py` : Tests d'intégration détecteurs
- `test_quality_evaluator.py` : Tests de calcul métriques
- `test_leak_scanner.py` : Tests de détection de fuites
### 7.2 Tests de Régression
**Suite de tests** : `tests/regression/`
**Workflow** :
1. Charger le dataset annoté (30+ documents)
2. Anonymiser chaque document
3. Évaluer la qualité
4. Vérifier que les métriques respectent les seuils :
- Rappel ≥ 99.5%
- Précision ≥ 97%
- F1-Score ≥ 0.98
5. Alerter si dégradation
**Exécution** :
```bash
pytest tests/regression/ --benchmark
```
---
## 8. Monitoring et Observabilité
### 8.1 Logging Structuré
```python
import structlog
logger = structlog.get_logger()
# Log avec contexte
logger.info("detection_started",
pdf_path=str(pdf_path),
page_count=page_count)
logger.info("pii_detected",
pii_type="NOM",
count=12,
method="eds_pseudo",
confidence=0.95)
```
### 8.2 Métriques Collectées
**Par document** :
- Temps de traitement
- Nombre de PII détectés par type
- Méthode de détection utilisée
- Métriques de qualité (si ground truth)
**Agrégées** :
- Temps moyen par document
- Répartition des PII par type
- Taux de faux positifs/négatifs
- Évolution des métriques dans le temps
---
## 9. Sécurité
### 9.1 Protection des Données
- Pas de logs contenant des PII
- Suppression sécurisée des fichiers temporaires
- Pas de transmission réseau
- Traitement local uniquement
### 9.2 Validation des Entrées
- Validation du format PDF (type MIME)
- Limite de taille (< 100 MB)
- Validation du format JSON (annotations)
- Sanitization des chemins (pas de path traversal)
---
## 10. Déploiement
### 10.1 Structure des Fichiers
```
anonymizer/
├── core/
│ ├── __init__.py
│ ├── pipeline.py (existant)
│ └── ...
├── detectors/
│ ├── __init__.py
│ ├── improved_regex.py (nouveau)
│ ├── contextual.py (nouveau)
│ └── hybrid.py (nouveau)
├── evaluation/
│ ├── __init__.py
│ ├── quality_evaluator.py (nouveau)
│ ├── leak_scanner.py (nouveau)
│ └── benchmark.py (nouveau)
├── tools/
│ ├── __init__.py
│ ├── annotation_tool.py (nouveau)
│ └── quality_reporter.py (nouveau)
└── tests/
├── unit/
├── regression/
└── ground_truth/ (nouveau)
```
### 10.2 Installation
```bash
# Installer les nouvelles dépendances
pip install pytest pytest-cov pydantic structlog jinja2 matplotlib
# Créer les répertoires
mkdir -p tests/ground_truth
mkdir -p reports/quality
# Copier la configuration
cp config/quality_config.yml.example config/quality_config.yml
```
---
## 11. Migration depuis la Version Actuelle
### 11.1 Compatibilité Ascendante
- ✅ API existante inchangée
- ✅ Format d'audit `.jsonl` inchangé
- ✅ Configuration YAML compatible
- ✅ Pas de breaking changes
### 11.2 Activation Progressive
**Phase 1** : Mesure (pas d'impact sur production)
- Créer le dataset annoté
- Implémenter l'évaluateur
- Mesurer la baseline
**Phase 2** : Amélioration (opt-in)
- Implémenter les détecteurs améliorés
- Activer via configuration
- Comparer avec baseline
**Phase 3** : Validation (opt-in)
- Implémenter le scanner de fuite
- Activer en mode non-bloquant
- Valider sur corpus complet
**Phase 4** : Production (opt-out)
- Activer par défaut
- Mode strict optionnel
- Monitoring continu
---
## 12. Livrables Techniques
1. **Code source** :
- `detectors/improved_regex.py`
- `detectors/contextual.py`
- `detectors/hybrid.py`
- `evaluation/quality_evaluator.py`
- `evaluation/leak_scanner.py`
- `evaluation/benchmark.py`
- `tools/annotation_tool.py`
- `tools/quality_reporter.py`
2. **Tests** :
- `tests/unit/test_*.py`
- `tests/regression/test_regression.py`
3. **Documentation** :
- `docs/annotation_guide.md`
- `docs/evaluation_guide.md`
- `docs/api_reference.md`
4. **Configuration** :
- `config/quality_config.yml`
5. **Templates** :
- `templates/quality_report.html`
6. **Dataset** :
- `tests/ground_truth/*.pdf`
- `tests/ground_truth/*.annotations.json`