Architecture¶
Composants du domaine¶
Le pipeline est organisé en composants à responsabilité unique. Chacun expose
une interface stable et reste testable indépendamment.
| Composant | Module Python | Responsabilité |
|---|---|---|
| Entity Extractor | src/services/entity_extractor.py |
Émet les candidats typés (place, person, org, acronym, typo) depuis le texte des segments. |
| RAG Enricher | src/services/reliability_rag_enricher.py |
Récupère les entités canoniques de la transcription depuis Qdrant et applique un bonus de confiance par similarité floue. |
| Identity History | src/services/reliability_identity_history.py |
Stocke dans Redis les rejets historiques d'identité par utilisateur pour court-circuiter les appels LLM répétitifs. |
| Constrained LLM Reasoner | src/services/reliability/constrained_llm_reasoner.py |
Décision binaire correct / abstain via un schéma JSON strict, sans confiance auto-déclarée. |
| LLM Client | src/services/reliability_llm_client.py |
Wrapper provider-agnostic Qwen / OpenAI avec ordering configurable et fallback automatique. |
| Geo Validator | src/services/reliability/geo_validator.py |
Validation géographique des lieux via Photon self-host. |
| Geo Ranking | src/services/reliability/geo_ranking.py |
Fonctions pures de filtrage, scoring composite et variante phonétique pour les résultats Photon. |
| Wikidata Enricher | src/services/reliability/wikidata_enricher.py |
Enrichit un résultat Photon avec un identifiant Wikidata stable, libellé et population. |
| Multi-Signal Scorer | src/services/reliability/multi_signal_scorer.py |
Fusionne les signaux RAG / Geo / LLM avec pondération par type d'entité et pénalité de variance. |
| Decision Gate | src/services/reliability/decision_gate.py |
Décide entre HUMAN_REVIEW (persistance) et REJECT selon le score fusionné et le veto d'abstention. |
| Signal Adapter | src/services/reliability/v5_signal_adapter.py |
Bridge entre les modules d'enrichissement et le scorer. |
| Validator | src/services/reliability_validator.py |
Chaîne de règles déterministes appliquée en dernier recours avant persistance. |
| Corrections Memory | src/services/reliability/correction_memory_writer.py, corrections_memory_reader.py, corrections_memory_bootstrap.py, corrections_memory_cleanup.py |
Mémoire des corrections utilisateur passées : double écriture Qdrant + mirror PostgreSQL, lecture pour boost de confiance, bootstrap idempotent au démarrage, cascade RGPD. |
| Reliability Service | src/services/reliability_service.py |
Orchestrateur : pilote l'ensemble du pipeline, persiste les suggestions et calcule les snapshots de score. |
| Reliability Worker | src/workers/reliability_worker.py |
Consumer Redis Streams dédié, gestion des locks, retries durables et DLQ. |
| Router API | src/routers/reliability.py |
Endpoints REST /api/reliability/*. |
Vue de dépendances¶
Frontières du domaine¶
En amont¶
Le pipeline de transcription publie un événement reliability.analysis.requested
sur le stream Redis reliability:events à la fin du post-processing
(transcription + enrichissement terminés, segments persistés).
En aval¶
- Corrections Hub (frontend) : lit les suggestions via l'API REST et soumet
les actions utilisateur. - Sidebar score (frontend) : affiche le snapshot de score le plus récent par
transcription.
Sortie¶
Le pipeline n'expose pas d'événement de complétion sortant : la fin du
traitement est observée via le hash Redis de progression
(reliability_progress:{transcript_id}) et l'API /progress.
Frontière de transaction¶
- Une seule session SQLAlchemy par exécution du pipeline.
- Les effets Qdrant et LLM ne sont pas transactionnels avec PostgreSQL : la
compensation est explicite dans le Corrections Memory Writer (rollback du point
Qdrant si l'écriture PostgreSQL échoue). - L'application des actions utilisateur (
apply_actions_batch) est entièrement
transactionnelle côté PostgreSQL.
Modes d'exécution¶
Le pipeline opère en deux profils selon la richesse du contexte canonique
disponible pour la transcription :
| Mode | Conditions d'activation | Seuil de confiance LLM | Plafond de score global |
|---|---|---|---|
RAG_ENHANCED |
Contexte canonique riche (≥ N entités et ≥ M types distincts) | 0.75 | 100 % |
CONTEXT_FREE |
Contexte insuffisant ou absent | 0.55 | 85 % |
Le mode est déterminé une fois par transcription en début de pipeline et propagé
à tous les composants en aval. Le mode est encodé dans le champ
calculation_version du snapshot de score (suffixes __ragenh et __ctxfree).