# Déduplication des segments de preuve graphique du RAG dans ***lucide*RAG**

<datetime class="hidden">2026-01-17T14:00</datetime>

<!-- category -- C#, lucidRAG, Vector Search, Machine Learning, Knowledge Graphs -->
> **NOTE:** Ce n’est pas un article de blog conventionnel. C’est une **spécifications techniques** a été rédigé pour une fonction concrète dans ***lucide*RAG**.
> Iterativement, j’alimente ce document en codes-LLM axés sur le commerce au cours de la mise au point pour expliquer les écarts liés au commerceM SK1offs , valider les hypothèsesSSK3 et converger vers une mise en œuvre rationale.

Ce document décrit un sous-système de ***lucide*RAG**, un projet je travaille activement à l’élaboration de .

Une exigence fondamentale de ***lucide*RAG** est la capacité d'extraire **• les segments de preuve** - phrasesM SK1 paragraphes, titres , sous-titres **déléguée** sans détruire un signal utile.

***lucide*RAG** Les travaux d’analyse et d’extraction du *le meilleur* les preuves disponibles provenant de documents, images , audio, et données structuréesM SK3 Contrairement à la plupart des mises en œuvre RAGMSC4 elle le fait **non pas** store LLM-générer des résumés comme artefact primaire. Dans de nombreux cas, l’ingestion de , n’exige aucun LLM M SK3 bien qu’on puisse les utiliser lorsque l’escalade est justifiée

Plutôt que cela, ***lucide*RAG** applique un large éventail de techniques déterministes et probabilistes à

* extraire les segments candidats
* évaluer leur valeur d'information
* et ne conservent que les représentants les plus forts

**La déduplication est un élément essentiel de ce processus.**

L’égalité simple des chaînes n’est pas suffisante. Le même concept est fréquemment exprimé à l’aide d’un libellé différent , Structure, ou modalitéM SK3 Traiter ces éléments comme distincts conduit à un stockage redundant et à un mauvais comportement en aval

**Le problème se compound au moment de la récupération.**

Lorsque les résultats sont obtenus (par l'entremise de SQL , embeddings vectoriels, BMM SK3 ou hybridesMSC4 la distribution d'un LLM à plusieurs segments qui expriment toutes la même idée sous-jacente produit des réponses répétées , bornesMska6 cinq prèsM Ska7 tronçons identiques provenant de différents documents ne ajoutent pas de clarté Mska8 ils le diluent M Ska9

Pour y répondre, ***lucide*RAG** La déduplication est considérée comme une **problème de compilation de la classe first-**, pas de posteM SK1filtre d'eau courante.

Le reste de ce document décrit comment cette stratégie a été conçue. ['Spécification agile'](https://www.mostlylucid.net/blog/writingfeaturespecs) adapté aux besoins du code LLMS.

Cela cristallise les pensées, les concepts différents et oblige le LLM à les documenter. *Builds the right thing*.

[Voir plus sur ***lucide*RAG** ici. ](https://www.lucidrag.com)

# Stratégie de déduplication

***lucide*RAG** utilise une stratégie de déduplication en deux phases- pour éliminer le contenu redundant tout en préservant des signaux importants. **signal-filtre préservatif**, non normalisation du contenu.

## Vue d'ensemble

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           INGESTION (Per Document)                          │
│                                                                             │
│  Document → Extract → Embed → DEDUPE (intra-doc) → Index to Vector Store   │
│                                   │                                         │
│                                   ├─ Near-duplicates: boost salience        │
│                                   └─ Exact duplicates: drop (no boost)      │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                          RETRIEVAL (Cross Document)                         │
│                                                                             │
│  Query → Search → Rank (RRF) → DEDUPE (cross-doc) → Top K → LLM Synthesis  │
│                                   │                                         │
│                                   └─ Keep segment with highest RRF score    │
└─────────────────────────────────────────────────────────────────────────────┘
```

---


## Garanties de conception

Ces invariantes sont maintenues par le système de déduplication:

| Garantie | Description
|-----------|-------------|
| **Ordonnance préservée** | La déduplication ne modifie jamais l'ordre sémantique après le classement RRF |
| **Aucune perte de concept** | La déduplication ne supprime jamais toutes les instances d'un concept.
| **Limite du document respectée** | La déduplication ne traverse jamais les frontières du document lors de l'ingestion.
| **Contenu immuable** | La déduplication ne modifie jamais les embeddings ou le contenu du texteM SK1 seule la sélection et les notes de salience |
| **Déterministe** | Étant donné que les intrants sont identiques et que la déduplication de configM SK1 produit des sorties identiques |

---


## Objectifs non -

Ce système fait explicitement **non pas** tenter de:

- **Détecter la contradiction fondée sur les faits** - Deux segments disant des choses opposées ne sont pas reproduits
- **Canoniser la vérité** - Nous ne choisissons pas une version ' correcte
- **Collapse des paraphrases à travers les documents lors de l'ingestion** - Chaque document conserve ses propres segments
- **Normaliser la terminologie** - "ML" et "apprentissage de la machineM SK4 sont conservés séparément dans différents dossiers
- **Remplacer la résolution de l'entité** - Que 's GraphRAG's jobM SK3 opérant à un niveau différent

---


## Déterminisme & Reproductibilité

La déduplication est entièrement déterministe:

- **Les emplacements sont immuables** une fois calculé au moment de l'extraction
- **Le classement est stable** Les segments - dont la salience est égale conservent l'ordre initial
- **Aucun caractère aléatoire** - pas d'échantillonnage , pas de valeur approximative ANNM SK2 aucun seuil probabiliste
- **Aucun état extérieur** - Les décisions de déduction dépendent uniquement du segment actuel.

**Pourquoi cela importe:** Les résultats de recherche de débugging des utilisateurs peuvent s'assurer que re-la conduite avec les mêmes entrées produit les sames sorties. ***lucide*RAG**'s plus larges "constrained fuzzinessM SK2 philosophie - fuzzy matching with deterministic behavior.

---


## Pourquoi deux phases?

### Phase 1: Déduplication de l’ingestion

**Objectif:** Réduire l’entreposage et prévenir la redundance intra-documents-

**Problème:** Les documents contiennent souvent un contenu répété:

- Texte de la plaque à chaud (en-têtes,en bas de pageM SK2dénonciations de responsabilités )
- Copy-sections jointes
- Le même concept explique plusieurs façons

**Solution:** Dupliquer dans chaque document avant d'indexer.

**Perspectives clés:** Les copies près de - sont traitées comme *preuves indépendantes d'importance*Si un auteur explique un concept de trois façons différentes, ce concept est important. Nous captons ce signal en augmentant la salience.

### Déduplication de la phase 2: Retrieval

**Objectif:** Prévenir que le LLM ne reçoive pas de renseignements redundants dans les documents.

**Problème:** Lors de la recherche sur plusieurs documents, les paragraphes similaires peuvent apparaître dans différentes sources.

**Solution:** Après le classement par RRF (qui combine la similitude sémantique , match des mots clésM SK2 salience, et fraîcheurMSC4 doubler les documents en gardant le plus haut niveau de cote

**Pourquoi après RRF?** Le score du RRF représente la meilleure mesure globale de la pertinence.

### Pourquoi la salience augmente seulement à l'ingestion

La séparation est intentionnelle:

| Phase | Ce qu’il capte |
|-------|------------------|
| **Augmentation de l'ingestion** | L'auteur insiste sur le fait que le document souligne une notion
| **Cote de récupération** | Relevance de la question - mesure dans laquelle le contenu correspond à l'intention de l'utilisateur

Le fait de les mélanger lors de la recherche entraînerait une confusion entre l’intention du document et celle de l’utilisateur. Un concept répété M SK1 fois dans un document est important *à ce document*, mais peut ne pas être pertinent *à cette demande*. En stimulant à l’ingestion,, nous préservons le signal de l’auteur ' sans biaiser les résultats de la rechercheM SK3

---


## Phase 1: Déduplication de l’ingestion

### Endroit

`src/Mostlylucid.DocSummarizer.Core/Services/BertRagSummarizer.cs`

### Méthode

`DeduplicateSegments()`

### Algorithme

```
1. Filter segments by minimum salience threshold (0.05)
2. Sort by salience score (highest first)
3. For each segment:
   a. If no embedding → keep (can't compare)
   b. Check cosine similarity against all selected segments
   c. If similarity >= 0.90:
      - If same ContentHash → exact duplicate, drop silently
      - If different ContentHash → near-duplicate, boost kept segment's salience
   d. If no match → add to selected list
4. Apply salience boosts: +15% per near-duplicate merged
5. Cap salience at 1.0 to prevent any single concept from dominating
```

### Paramètres

| Paramètre | Défault MSC2 Description MSC3
|-----------|---------|-------------|
| `similarityThreshold` | 0.90 ≥| Similarité de cosine au-dessus desquelles les segments sont considérés comme dupliqués
| `salienceThreshold` | 0.05 ≥| La salience minimale à prendre en considération
| `boostPerNearDuplicate` |  0.15

### Exemples

**Exact Duplicate (No Boost)**

```
Segment A: "Contact us at support@example.com" [hash: abc123]
Segment B: "Contact us at support@example.com" [hash: abc123]  ← same hash
Result: Keep A, drop B, no boost (likely boilerplate)
```

**PrÃ ̈s-Dupliqué M SK1AppliquÃ©e au point d'ancrage)**

```
Segment A: "Machine learning models require training data" [hash: abc123]
Segment B: "ML systems need data for training" [hash: def456]  ← different hash, 0.92 similarity
Segment C: "Training data is essential for ML" [hash: ghi789]  ← different hash, 0.91 similarity
Result: Keep A with +30% salience boost (concept emphasized 3 ways)
```

### Justification des seuils

- **0.90 similitudeM SK1** Sur la base des recherches (NVIDIA NeMo utilise une norme industrielle pour le dédoupage sémantique 0.90-0.92,
- **0.05 salienceM SK1** Filtre les segments de valeur très faibles- tout en gardant la plupart du contenu
- **15% renforcementM SK1** Signaux significatifs sans dépassement-poids répété des concepts

---


## Déduplication de la phase 2: Retrieval

### Endroit

`src/LucidRAG.Core/Services/AgenticSearchService.cs`

### Méthode

`DeduplicateByEmbeddingPostRanking()`

### Algorithme

```
1. Receive ranked results (already sorted by RRF or dense score)
2. For each segment (in score order):
   a. If no embedding → keep
   b. Check cosine similarity against all selected segments
   c. If similarity >= 0.90 → skip (higher-scored duplicate already selected)
   d. If no match → add to selected list
3. Return deduplicated list (maintains score ordering)
```

### Paramètres

| Paramètre | Défault MSC2 Description MSC3
|-----------|---------|-------------|
| `similarityThreshold` | 0.90 ≥| Seuil de similitude des cosine pour le croisementM SK3doc dédup

### Pourquoi Post-RRFM SK1

RRF (Fusion de rang réciproqueM SK1 combine quatre signaux:

1. **Note dense:** Similarité sémantique à la demande
2. **BM25 scoreM SK1** Lexical/combinaison de mots clés
3. **Résultat de Salience:** Importance du document
4. **Note de fraîcheur:** Augmentation de la réceptivité

Le dédoublement AFTER RRF signifie que nous maintenons le segment qui correspond le mieux à la demande dans toutes les dimensions.

### Exemple :

```
Query: "How do I configure authentication?"

Results before dedup:
1. [Doc A] "Authentication is configured via config.yaml..." (RRF: 0.052)
2. [Doc B] "Configure auth using the config.yaml file..." (RRF: 0.048, similarity to #1: 0.93)
3. [Doc A] "Set the API key in environment variables..." (RRF: 0.041)

Results after dedup:
1. [Doc A] "Authentication is configured via config.yaml..." (RRF: 0.052)
2. [Doc A] "Set the API key in environment variables..." (RRF: 0.041)

Doc B's similar paragraph dropped - Doc A's version had higher RRF score.
```

---


## Modes de défaillance & Traitement-Offs

### Limites connues

| Mode de défaillance | Description MSC2 Atténuation MSC3
|--------------|-------------|------------|
| **Faux positifs (over-dedupM SK2** | Deux concepts distincts mais étroitement liés peuvent dépasser 0.90 la similitude
| **Fausse négative (à l'dessousM SK1dédoublement)** | Les segments très courts peuvent être embarqués de façon médiocre , la similitude sémantique manquante
| **Intégration de la dérive** | Changer les modèles d'implantation invalide les hypothèses de déduption | Exige une recommandation complète
| **Sensibilité à l'ordre** | La sélection aveugle signifie que le segment de la satisfaction est le premier à atteindre un niveau élevéM SK1 Le segment de l’attention gagne | Mitigated by stable sorting; highest

### Commerce accepté-offs

- **Précision sur le rappel:** Parfois, nous préférons garder des copies près de - plutôt que d’enlever accidentellement un contenu distinct.
- **Entreposage sur précision:** Nous stockons le document par - plutôt que la déduction globale pour préserver l’attribution de source
- **Simplicité par rapport à l’optimisation:** O(nM SK1 est acceptable pour les tailles typiques de documents; LSH ajoute la complexité

---


## Considérations multilingues

Le comportement de déduplication avec un contenu multilingue:

| Scénario | Comportement MSC2 Justification MSC3
|----------|----------|-----------|
| **La même langue** | Le dédoublement normal s'applique | La similitude sémantique des embeddings est saisie
| **Paraphrases cross-language** | N'est pas reproduit | Préserve la source- La diversité linguistique |
| **Document de langue mixte-** | Déduption à l'intérieur des grappes linguistiques | La similitude de l'intégration sépare naturellement les langues

**Choix de conception:** Cross-le dédoupage linguistique n'est pas explicitement supporté. Cela préserve la capacité de récupérer le même fait dans l'utilisateur ' sa langue préférée ou de comparer comment les différentes sources de phrases des choses

Améliorations futures: Cross-La déduction linguistique pourrait être stratifiée par la traduction -Invariant embeddings, s'il y a lieu

---


## Sécurité & Considérations adverses

Le système de déduplication comprend des protections implicites:

| Vector d'attaque | Protection |
|---------------|------------|
| **Inflation de la salinité par répétition** | Boost capped at 1.0; exact duplicates donM SK2t boost |
| **Copy-paste spam à travers les documents** | CrossM SK1doc dedup à la recherche supprime les résultats redundants |
| **Manipulation du score par injection double** | Des déductions se produisent après le classement
| **Inondation de plaques chaudières** | La détection exacte des matchs de hash diminue sans accroissement |

**Note:** La déduplication n’est pas une limite de sécurité. Le contenu malveillant qui passe les filtres d’ingestion sera indexé . Le filtrage du contenu devrait se faire en amont.

---


## Interaction avec GraphRAG

Deduplication et GraphRAG sont intentionnellement orthogonaux:

| Système | Fonctionne sur MSC2 But SMC3
|--------|-------------|---------|
| **Déduplication** | Segments ( tronçons de texte) | Supprimer les résultats de recherche redundants SSK4
| **GraphRAG** | Entités & Relations MSC2 Graphique de connaissances de construction SMC3 Références de résolution MSC4

**Pourquoi séparer:**

- Un segment qui mentionne "Apple" et un autre qui mentionnait "la sociétéM SK3 peut dédouper comme texte similaire mais représente la même entité - que le GraphRAGMSC5 dont il faut résoudre
- Dedup n’a pas besoin de sensibilisation à l’entité, mais fonctionne uniquement sur la similitude sémantique.
- L’entité-aware dedup pourrait être ajoutée ultérieurement comme une amélioration, non comme un remplacement

---


## Observabilité & Mesures

### Enregistrement actuel

Ingestion:

```
[dim]Deduplication: 150 → 98 segments[/]
```

Récupération:

```
Post-ranking deduplication: 50 → 42 segments (removed 8 cross-doc duplicates)
```

### Mesures recommandées

Pour la surveillance de la production, considérer le suiviM SK1

| Metrique | Description MSC2 Range saine MSC3
|--------|-------------|---------------|
| `dedup_ratio_ingestion` | % les segments retirés lors de l'ingestion
| `dedup_ratio_retrieval` Les segments | % ont été retirés lors de la récupération.
| `avg_salience_boost` | Augmentation moyenne appliquée par document
| `max_salience_boost` | Le plus grand accroissement dans un document
| `dedup_by_doc_type` | Taux de déduction segmenté par type de document | Variations

### Conseils de débugging

- **Déduction élevée de l’ingestion (>50%):** Le document peut avoir une plaque de chaudière excessive ou être généré à l’auto-
- **Réduction de l’ingestion faible (<5%):** Le document a un contenu varié (goodM SK1 ou les embeddings sont médiocres (investigate)
- **Déduption de recherche élevée (>30%):** La question peut être trop large, ou le corpus a de nombreux documents similaires
- **Salence à l’approche 1.0:** Le concept a été fortement mis en évidence.

---


## Configuration

La déduplication est configurée par `DocSummarizerConfig.Deduplication` section dans `appsettings.json`:

```json
{
  "DocSummarizer": {
    "Deduplication": {
      "Ingestion": {
        "Enabled": true,
        "SimilarityThreshold": 0.90,
        "SalienceThreshold": 0.05,
        "EnableSalienceBoost": true,
        "BoostPerNearDuplicate": 0.15,
        "MaxSalienceBoost": 1.0,
        "BoostDecayMode": "Logarithmic",
        "LogBase": 2.0
      },
      "Retrieval": {
        "Enabled": true,
        "SimilarityThreshold": 0.90,
        "MinRelevanceScore": 0.25
      },
      "Analytics": {
        "EnableLogging": true,
        "EnableMetrics": true,
        "HighIngestionDedupThreshold": 0.50,
        "HighRetrievalDedupThreshold": 0.30,
        "HighSalienceBoostThreshold": 0.60
      }
    }
  }
}
```

### Configuration de l'ingestion

| Paramètre | Défault MSC2 Description MSC3
|-----------|---------|-------------|
| `Enabled` | `true` | ActiverM SK1 désactiver la déduplication de l'ingestion |
| `SimilarityThreshold` | `0.90` | seuil de similitude cosine pour la détection du double |
| `SalienceThreshold` | `0.05` | La salience minimale à prendre en considération
| `EnableSalienceBoost` | `true` | Accroître la salience pour les copies près de -
| `BoostPerNearDuplicate` | `0.15` | Augmentation de la base par rapport à l’approche -dupliqué MSC2 MSC3
| `MaxSalienceBoost` | `1.0` | Cap de salience maximal |
| `BoostDecayMode` | `Logarithmic` | `Linear` ou `Logarithmic` décomposition |
| `LogBase` | `2.0` | Base pour la dégradation logarithmique |

### Configuration de la recherche

| Paramètre | Défault MSC2 Description MSC3
|-----------|---------|-------------|
| `Enabled` | `true` | Activer/ désactiver la déduplication de la recherche |
| `SimilarityThreshold` | `0.90` | seuil de similitude cosine |
| `MinRelevanceScore` | `0.25` | Cote minimale de RRF pour inclure |

### Configuration de l'analyse

| Paramètre | Défault MSC2 Description MSC3
|-----------|---------|-------------|
| `EnableLogging` | `true` | Opérations de déduplication du log |
| `EnableMetrics` | `true` | Collecte de mesures pour la surveillance |
| `HighIngestionDedupThreshold` | `0.50` | Avertissement si >50% est reproduit lors de l'ingestion
| `HighRetrievalDedupThreshold` | `0.30` | Avertissement si >30% est reproduit lors de la récupération
| `HighSalienceBoostThreshold` | `0.60` | Avertissez-vous si l'accroissement est supérieur à

### Favoriser les modes de défaillance

**Mode linéaire** (simple , prévisibleM SK2

```
boost = boostPerNearDuplicate × count
```

Exemple: M SK1 près de-dupes × ≥0.15 ≤= ±+45% accroissement

**Mode logarithmique** (rétroaction décroissante , par défautM SK2

```
boost = boostPerNearDuplicate × log₂(1 + count)
```

Exemple: M SK1 près de-dupes → ≥0.15 ≤× log

Le mode logarithmique est recommandé parce:

- Les premiers exemplaires ont le signal le plus fort (accent de l’auteurM SK1
- De nombreux répliques peuvent indiquer que la plaque de boiler, n’est pas importante
- Prévient l'inflation de la salience en fuite

---


## Considérations relatives au rendement

### Complexité

| Phase | Complexité MSC2 Taille typique MSC3 Impact SMC4
|-------|------------|--------------|--------|
| Ingestion | OM SK2n² | ≥50-500 segments
| Récupération | OmM SK3 MSC4 \MSC5 segments MSC6 |MSC7 | MSC8ms |SMC9

### Étalonnage du chemin

Pour les documents très grands (10,000+ segmentsM SK1

1. **LSH (Localité-Hashing sensibleM SK2** O(nM SK1 déduction approximative
2. **Comparaison de lots:** Processus en blocs pour réduire la mémoire
3. **Filtration précoce:** Seuil de salience plus agressif

La mise en œuvre actuelle est optimisée pour les tailles typiques des documents. LSH ajoute de la complexité sans avantage pour la plupart des cas d'utilisation.

---


## Comparaison avec la recherche

| Approche
|----------|-----------|--------|
| lucidRAG | 0.90 ≥| Cette mise en œuvre MSC4
| NVIDIA NeMo Curator [Dossiers SemDeDup](https://docs.nvidia.com/nemo/curator/latest/curate-text/process-data/deduplication/semdedup.html) |
| MinHash LSH (standard) | ≥0.80 Jaccard MSC5 [Google C4, GPT-3 papier](https://huggingface.co/blog/dedup) |
| SemHash [GitHub](https://github.com/MinishLab/semhash) |

Notre seuil de 0.90 est conforme aux meilleures pratiques industrielles en matière de déduplication sémantique.

---


## Ce qui n'est pas dédouplété

| Type de contenu | Raison |
|--------------|--------|
| Résolution de source et d'attribution du document à l'ingestion, en croisement avec le - | Préserves par -
| De faible teneur en similitude -Content de la similarité
| Différents types de segments | Les positions par rapport au paragraphe ont des rôles structurels différents
| Paraphrases langagières croiséesM SK1 | Préserve la diversité linguistique |

---


## État de la mise en œuvre

| Caractéristique | État MSC2 Lieu MSC3
|---------|--------|----------|
| seuils configurables | `DeduplicationConfig` Classe |
| Dégradation accrue échelle de l'échantillonnageM SK2 | | 3 | 4 | Mise en œuvre | 5 | `BoostDecayMode.Logarithmic` |
| Analyse de déductionsM SK1métrie | ✅ Mise en œuvre SSK4 `DeduplicationResult<T>` enregistrement |
| Intégration des services d'ID | `IDeduplicationService` |

## Améliorations à venir

1. **Dedup analytics dashboard:** Traçage visuel des taux par type de document
2. **Cross-option linguistique:** Traduction-invariant embeddings for multilingual dedup
3. **Entité-déduction informéeM SK1** Utiliser les entités GraphRAG comme signal additionnel (non remplacementM SK1
4. **Prometheus/OpenTelemetry:** Exporter des mesures pour les moniteurs de surveillance

---


## Résumé

Cette stratégie de déduplication:

- **Préserve le signal** - Près deM SK1 les copies augmentent l’importance plutôt que d’être discardées
- **Respecter les frontières** - Les documents conservent des ensembles de segments indépendants
- **Les rangs sont ensuite filtrés** - Utilise le signal RRF complet avant la déduption de doc
- **Défaut sans danger** - Préconise le maintien du contenu plutôt que la suppression agressive
- **Reste déterministe** - Les mêmes intrants produisent toujours les mêmes résultats