# Дедупликація графічних сегментів RAG в ***прозора*РАГ**

<datetime class="hidden">2025-12-27T14:00</datetime>

<!-- category -- C#, lucidRAG, Vector Search, Machine Learning, Knowledge Graphs -->
> NOTA: Це не M SK1 це не звичайний блоговий artykuł, а МSK2 це МSK3spec ' Я створив для цієї функції в ***прозора*РАГ**. Потім я доставляю це назад і вперед до коду LLM, щоб отримати раціональний підхід

Це конкретний документ від мого ***прозора*РАГ** проект I'м зараз в розробці

Однією з проблем мого підходу є те, що мені потрібно: 'segmentsM SK1 із 'evidence' МSK4звичай текст МSK5 речення М SK6 абзаци M SK7 заголовки і т.д.

***прозора*РАГ** працює шляхом інтелектуального аналізу та видобутку найкращих сегментів даних з зображень, аудіо , доків чи данихM SK2 На відміну від решти implementaцій RAG, я не зберігаю резюме LLM даних JSUT МSK3 насправді, більшу частину часу LLM не вимагається для вглинанняМSK4, але може бути використаний, якщо є nesessary
Натомість ***прозора*РАГ** використовує багато методів WIDE для отримання шматків тексту і гарантує, що ми зберігаємо лише найкращі шматки тексту.

Найголовнішим є те, як відбувається відокремлення.

Потім, коли отримані результати: ( за допомогою звичайного SQL , векторних вбудований кодів МSK2 БМ, МSK3 і т.д. МСК4 нам потрібно переконатися, що LLM не має МСК5 багато фрагментів, які говорять одне й те саме, МКС6 MСК7 фрагменти різних документів, які по суті говорять те ж саме,

# Стратегія розмноження

***прозора*РАГ** використовує дві стратегії - фазного відокремлення, щоб уникнути надлишкового наповнення, зберігаючи важливі сигналиM SK1 Це **сигнал-фільтр, що зберігає**, ненормалізація змістуM SK1

## Перегляньмо

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           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    │
└─────────────────────────────────────────────────────────────────────────────┘
```

---


## Гарантії дизайну

Ці інваріанти підтримуються системою дедукції:

МSK0 Гарантія | Описание МSK2
|-----------|-------------|
| **Збережений порядок** | Дедупликація ніколи не змінює семантичного порядку після рейтингу РР МSK1
| **Жодна втрата концепції** | Дедупликація ніколи не видаляє усіх instanцій концепції |
| **Дослідження** | Дедупликація ніколи не перетинає границі документу під час введення
| **Невідмінний зміст** | Дедупликація ніколи не змінює вбудований або текстовий зміст , лише відбір та показники значущості
| **Детермінізм** | Враховуючи однакові вхідні дані і конфігурацію, МSK1 дублування створює однакові вихідні дані.

---


## Жодні цілі

Ця система чітко робить **не** спробувати:

- **Визначати фактичну протиріччя** — Два сегменти, які говорять протилежні речі, не дублюються
- **Канонилізувати правду** — Ми не вибираємо ' версію МSK2правильнуM SK3 в усіх джерелах
- **Згортати парафразе через документи при вглинанні** — Кожен документ зберігає власні сегменти
- **Нормалізувати термінологію** — "ML" і МSK3 машинне навчанняM SK4 в різних Docs зберігаються окремо
- **Заміняємо розбір об 'єктів** — Те, що МСК1 ГрафRAG МСК2 робота МSK3 працює на іншому рівні

---


## Детермінізм & Reproducibility

Дедупликація повністю детерміністична:

- **Вбудова - незмінна** після обчислення в часі видобутку
- **Роз sortування стабільне** — сегменти з однаковою привабливістю підтримують оригінальний порядок
- **Немає випадковості** — без зразковування , без приблизної एनН МSK2 без ймовірністичного порогу
- **Ніяких зовнішніх умов** — рішення щодо дедупу залежать лише від набору сегментів

**Чому це важливо:** Використовуючи результати відтворення неполадів, можна довіряти тому, що ре-запуск з тими ж вхідних генерує ті самі вихідні даніM SK1 Це співпадає з ***прозора*РАГ**' з ширшою концепцією МSK1 обмежена невизначеність МSK2 філософія — невизначено співпадіння з детерміністичними поведінками

---


## Чому дві фази?

### Фаза 1: Дедупликація поглинання

**Мета:** Скорінити зберігання і запобігти надлишкам всередині-документівM SK1

**Проблема:** Документи часто містять повторений зміст:

- Текст на панелі котла (headersM SK1 footers , disclaimers МSK3
- Копуйте-розібрані секції
- Те ж саме поняття пояснилося багатьма способами:

**Рішення:** Дедулікувати кожен документ перед indeksуванням.

**Key Insight:** Близькі - копії вважаються *незалежні докази важливості*, не надлишковість МSK1 Якщо автор пояснює концепцію трьома різними способами , ця концепція має значення

### Фаза 2: Дедупликація пошуку

**Мета:** Захищати LLM від отримання надлишкових даних через документи.

**Проблема:** Коли ви шукаєте різні документи, схожі абзаци можуть з 'являтися в різних джерелах.

**Рішення:** Після рейтингу РАФ (, що об 'єднує семантичне подібність , співпадіння ключевих слів МSK2 значущість M SK3 та свіжість

**Чому після RRF?** Оцінка рейтингу RRF є найкращим всеохопним показником значущості.

### Чому салінція збільшується лише під час вживання

Розрив навмисно:

| Фаза МSK1 Що він захоплює МSK2
|-------|------------------|
| **Приштовхування** | Автор підкреслює — наскільки документ підкреслює концепцію
| **Результат відтворення** | Relevance of query — how well content matches user intent МSK2

Якщо їх помішати при відшуці, то ціль dokumentu заплутається з думкою користувача. Важливо повторити концепцію M SK1 раз у документі *до цього документа*,, але може не бути відповідним *до цього запиту*. Підштовхуючи при вживці ,, ми зберігаємо сигнал автору МSK2, не упереджуючи результати запитів

---


## Фаза 1: Дедупликація поглинання

### Место розташування

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

### Metodа

`DeduplicateSegments()`

### Алгоритм

```
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
```

### Параметри

| Параметр МSK1 По замовчуванню МSK2 Описание |
|-----------|---------|-------------|
| `similarityThreshold` | 0.90 МSK2 Схожість косину, над якою сегменти вважаються подібними
| `salienceThreshold` МSK0 0.05 ♫ ♫ МSK2 ♫ Minimalний відсоток, який треба взяти до уваги ♫ ( ♫ шуми фільтрів ♫
| `boostPerNearDuplicate` МSK0 0.15 ♫ ♫ МSK2 ♫ Підтримка привабливості за майже ♫ - ♫ Двухразовий об 'єднання ♫

### Приклади

**Точное копіювання (Невведення**

```
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)
```

**Близько-Duplicate M SK1Boost Applied)**

```
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)
```

### Припущення для обмежень

- **0.90 подібністьM SK1** На основі досліджень (NVIDIA NeMo використовує промисловий стандарт для семантичного дедупу 0.90-0.92,
- **0.05 ясністьM SK1** Фильтрує дуже низькі сегменти цінності, зберігаючи більшість контенту
- **15% підштовхуванняM SK1** Знайомий сигнал без перебільшення

---


## Фаза 2: Дедупликація пошуку

### Место розташування

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

### Metodа

`DeduplicateByEmbeddingPostRanking()`

### Алгоритм

```
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)
```

### Параметри

| Параметр МSK1 По замовчуванню МSK2 Описание |
|-----------|---------|-------------|
| `similarityThreshold` | 0.90 МSK2 Проміжок схожості косину для перетинівM SK3doc відхилення МSK4

### Чому? Поштина

РРФ (Реципрочний рейтинг об 'єднанняМSK1 об' єднує чотири сигналиM SK2

1. **Точний результат:** Семантична подібність до запиту
2. **БММSK0 бал:** Lexical/погони з ключевыми словами
3. **Результат Salence:** Важливість у документі
4. **Рейтинг свіжості:** Підштовхування рецепції

Дедуплексування AFTER RRF означає, що ми зберігаємо сегмент, який найкраще підходить до запиту у всіх вимірах.

### Наприклад,

```
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.
```

---


## Моди невдачі & Торгівля МSK1Offs

### Знані обмеження

| Режим непрацездатності | Description МSK2 Mitigation МSK3
|--------------|-------------|------------|
| **Поганий позитивний результат (впередуM SK1вгоруМSK2** | Два різні, але тісно пов 'язані поняття можуть перевершити МSK1 подібність МSK2 Прийнята торгівля - відхилення, що сприяє зменшенню зайнятості
| **Поганий негативний (внизуM SK1вгоріМSK2** | Дуже короткі сегменти можуть не вміщуватись добре , бракує семантичного подібності
| **Введення дрейфу** | Зміняння моделей вбудованості заперечує припущення про дедуп МSK1 Потрібно повне переM SK2введення МSK3 вбудова є невідмінною, як тільки зберігається |
| **Відчутність до порядку** | Знепокоєння означає, що перший високого сегменту виграє - успішний сегмент виграв МSK2 Стриманий стабільним сортуванням

### Прийняті торги

- **Precision over recall:** Ми віддаємо перевагу, коли-небудь тримаючи близькі - копії, аніж випадково usuwaти різні вмісти
- **Утримка надточністю:** Ми зберігаємо кожен документ замість глобального дедупу, щоб зберегти припис джерела
- **Простіше за оптимізацію:** O(nM SK1 прийнятний для типових розмірів документу ; LSH додає складності

---


## Мільйовні мовні погляди

Подібне поведінку з мультиlinguальним змістом:

| сценарій МSK1 поведінка МSK2 логіка |
|----------|----------|-----------|
| **Та ж мова** | Застосовується нормальна дедукція МSK1 Вбудова захоплює семантичні подібності МSK2
| **Парафрази на мові** | Не подібне до МSK1 Захищає джерело МSK2 різноманіття мов |
| **М 'язовий dokument** | Дедуп у мовних кластеріях | Схожість вбудованого коду природно розділяє мови МSK2

**Вибір дизайну:** Кросс- тлумачення мови явно не піддерюється . Це зберігає здатність отримувати той самий факт в обраному для користувача мові МSK2 або порівнювати те, як різні джерела формулюють речі

Майбутнє покращення: КроссM SK1зрозуміло, що мовні відхилення можна покласти за допомогою перекладу

---


## Безпека & Заперечення

Система відокремлення включає в себе імпульсивну захисту:

| Атаковий вектор МSK1 Захорона МSK2
|---------------|------------|
| **Інфляція язика через повторення** | Підштовхування закріплене на МSK1 точні подібні копії не МSK2 не підштовхуєш |
| **Copy- вставляйте спам на всі документи** | CrossM SK1doc дедуп при відтворення видаляє надлишкові результати |
| **Маніпуляція оцінкою за допомогою подібного введення** МSK0 Скидка відбувається після рейтингу, запобігає інфляції балів M SK2
| **Затоплення котла** | Точное виявлення хаш-погони втрачається без підштовхування

**Nota:** Дедупликація не є загрозою безпеки. Зловна zawartość, яка проходить через фільтри поглинання, буде відображана в Індексі . Filtrування контенту повинно відбуватися вгорі МSK2

---


## Взаємодія з GraphRAG

Дедупликація та граф-RAG навмисно ортогональні:

| Система МSK1 Працює на МSK2 Цюди |
|--------|-------------|---------|
| **Дедупликація** | сегменти МSK1 текстові фрагментиM SK2 МSK3 Вилучити надлишкові результати пошуку |
| **GraphRAG** | Об 'єкти МSK1 Реляції МSK2 Граф збудування знань , Відтворювані відмітки မ်SK4

**Чому розділити:**

- Зразок, який називає "AppleM SK1 і інший, що називає
- Дедуп не потребує усвідомлення сутності, він працює лише на семантичній подібності
- Втілення-aware dedup може бути додано пізніше як доповненняM SK1 не заміна

---


## Обсервабельність & Метріка

### Текучий журнал

Вживання:

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

Видобуток:

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

### Рекомендовані метрики

Для моніторингу виробництва

МSK0 Метрічний | Описание МSK2 Здоровий діапазон |
|--------|-------------|---------------|
| `dedup_ratio_ingestion` МSK0 % сегменти видалені під час вживання
| `dedup_ratio_retrieval` МSK0 % сегменти відібрані при відшуці
| `avg_salience_boost` | Середньостатистичний приріст за документом МSK1 МSK2
| `max_salience_boost` | Найвищий приріст у документі
| `dedup_by_doc_type` | Рівень відхилення поділений на типи документів | Варіації МSK2

### Вказівки для розв 'язання проблем

- **високий відхилення від споживання (>50%):** Документ може мати надмірну панель котла або бути генерований автоматично
- **Низкий відхилення від споживання (<5%):** Документ має різноманітний зміст (goodM SK1 або poors are poor (investigate)
- **Вищий дедуп відтворення (>30%):** Попит може бути надто простим, або корпус має багато схожих документів
- **Наближається 1.0:** Концепція була сильно підкреслена: МСК0 , перевірити його, "'", « легітимний », ,", а не спам

---


## Konfiguracja

Дедупликація конфігурована за допомогою `DocSummarizerConfig.Deduplication` розділити `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
      }
    }
  }
}
```

### Konfiguration Ingestion

| Параметр МSK1 По замовчуванню МSK2 Описание |
|-----------|---------|-------------|
| `Enabled` | `true` | ВвімкнутиM SK1ввімкнути відхилення поглинання МSK2
| `SimilarityThreshold` | `0.90` | Проміжок схожості косину для виявлення подібності
| `SalienceThreshold` | `0.05` | Найменша відмінність, яку треба взяти до уваги ( шум фільтрів
| `EnableSalienceBoost` | `true` | Підвищення привабливості для близькоїM SK1утвори МSK2
| `BoostPerNearDuplicate` | `0.15` | Базовий приріст на близько МSK1замінник МSK2 |
| `MaxSalienceBoost` | `1.0` | Максимальна верхівка salience
| `BoostDecayMode` | `Logarithmic` | `Linear` або `Logarithmic` зруйнування |
| `LogBase` | `2.0` | Основа для логарифмічного розпаду

### Налагодження пошуку

| Параметр МSK1 По замовчуванню МSK2 Описание |
|-----------|---------|-------------|
| `Enabled` | `true` | ввімкнутиM SK1отключити відокремлення пошуку |
| `SimilarityThreshold` | `0.90` | Проміжок схожості косину |
| `MinRelevanceScore` | `0.25` | Minimum RRF score to include |

### Konfiguracja

| Параметр МSK1 По замовчуванню МSK2 Описание |
|-----------|---------|-------------|
| `EnableLogging` | `true` | Операції відокремлення журналу
| `EnableMetrics` | `true` | Збирати метрики для моніторингу МSK1
| `HighIngestionDedupThreshold` | `0.50` | Застерегти, якщо МSK1 утворюється при вживці МSK2
| `HighRetrievalDedupThreshold` | `0.30` | Застерегайте, якщо >30% відтворюється при пошуці МSK2
| `HighSalienceBoostThreshold` | `0.60` | Застерегти, якщо прискорення перевищує МSK1 МSK2

### Підштовхувати режими провалу

**Лінійний режим** (простий, передбачуванийM SK2

```
boost = boostPerNearDuplicate × count
```

До прикладу: M SK1 біля-dupes × \0.15 | | МSK5 \ | +45% прискорення

**Логарифмічний режим** (знижуються результатиM SK1 по замовчуваннюМSK2

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

До прикладу:: M SK1 біля-dupes → \0.15 | | МSK5 журнальна записьна інформація

Рекомендується логарифмічний режим, тому що

- Перші кілька копій мають найсильніший сигнал (аuthor emphasisM SK1
- Багато копійок можуть означати, що плита котла не має значення
- Забігає інфляція salience

---


## Рівень ефективності

### Складність

МSK0 Фаза | Сложність МSK2 Типова величина | Вплив мSK4
|-------|------------|--------------|--------|
| Введення | OM SK2n² МSK4 | | 5 | сегменти | МSK6 | < |100 | ms |МSK9
| Діагностика | OmM SK3 МSK4 ♫ ♫ МSK5 ♫ сегменти ♫ | ♫

### Шкала шляху

Для дуже великих документів (10,000+ сегментиM SK1

1. **LSH (Locality-Sensitive HashingM SK2** ОМSK0n) приблизне відхилення
2. **Порівняння пакетів:** Процес в кусках, щоб зменшити пам 'ять
3. **Раннє фільтрування:** Більше агресивного значення

Текуча implementaція оптимізована для типових розмірів документу. LSH додає складності без жодної переваги для більшості випадків використання.

---


## Порівняння з дослідженням

| Дослідження МSK1 Перехідний бар 'єр МSK2 Źródło |
|----------|-----------|--------|
| lucidRAG МSK1 МSK2 \| Це введення |
| Куратор NVIDIA NeMo | МSK2 МSK3 [Доки SemDeDup](https://docs.nvidia.com/nemo/curator/latest/curate-text/process-data/deduplication/semdedup.html) |
| MinHash LSH [Google C4, GPT-3 папір](https://huggingface.co/blog/dedup) |
МSK0 SemHash | МSK2 | [GitHub](https://github.com/MinishLab/semhash) |

Наше значення 0.90 співпадає з найкращою практикою в галузі семантичного відокремлення

---


## Що не подібне

| Тип змісту МSK1 Причина МSK2
|--------------|--------|
| КрестніM SK1документи при вглинанні МSK2 Захищають роздільну здатність та приналежність до джерела МSK4
| Невеликий МSK1 Содержание схожості МSK2 | Зважається семантично розрізненим
| Різні типи сегментів МSK1 Напис та абзац мають різні структурні ролі |
| Парафразе мов МSK1 МSK2 Захищає різноманіття мов

---


## Статус втілення

| Funkція МSK1 Статус МSK2 Местонахождение |
|---------|--------|----------|
| Сконфигуровані пороги | МSK2 Втілені МSK3 `DeduplicationConfig` клас |
| Пришвидшений розпад МSK1шкала журналу МSK2 | `BoostDecayMode.Logarithmic` |
| Аналітика відхиленняM SK1метрія МSK2 МSK3 Втілення | `DeduplicationResult<T>` запис |
| Інтеграція DI-сервисів `IDeduplicationService` |

## Дальне покращення

1. **Панель аналітики Dedup:** Виглядове відстеження тарифів за типовий документ
2. **Кросс-вибір лінгвісуM SK1** Перетворення-інваріантні вбудова для багатомовного дедупу
3. **Об 'єкт-informed dedupM SK1** Використовуйте GraphRAG-елементи як додатковий сигнал (не замінникM SK1
4. **ПрометеусМSK0OpenTelemetry:** Ви Export metrics for monitoring dashboards

---


## Підсумок

Ця стратегія розмноження:

- **Захищає сигнал** — БлизькоM SK1 копії підвищують важливість, а не викидають
- **Поважає кордони** — Документи зберігають окремі сегменти
- **Після цього ранги відфільтровуються** — Використовує повний сигнал РРФ перед відхиленням
- **Безпечно не спрацьовує** — Краще зберігати контент, аніж агресивну видалення
- **Залишається детерміністичним** — Те ж саме введення завжди створює те ж саме.