# DocSummarizer Part 4 - Проектування трубопроводів RAG

<!--category-- AI, LLM, RAG, C#, Embeddings, ONNX, Semantic Search -->
<datetime class="hidden">2025-12-30T17:00</datetime>

[![NuGet](https://img.shields.io/nuget/v/Mostlylucid.DocSummarizer?label=NuGet)](https://www.nuget.org/packages/Mostlylucid.DocSummarizer)
[![npm](https://img.shields.io/npm/v/@mostlylucid/docsummarizer?label=npm)](https://www.npmjs.com/package/@mostlylucid/docsummarizer)
[![.NET](https://img.shields.io/badge/.NET-8.0%20%7C%2010.0-512BD4)](https://dotnet.microsoft.com/)
[![Node.js](https://img.shields.io/badge/Node.js-18%2B-339933)](https://nodejs.org/)

Це **Частина 4** з серії DocSummarizer. Погляньте [Частина 1](/blog/building-a-document-summarizer-with-rag) для архітектури, [Частина 2](/blog/docsummarizer-tool) для інструмента CLI, або [Частина 3](/blog/docsummarizer-advanced-concepts) для глибоких занурень на вбудовах.

> **Гарна частина RAG - це МСК0 , а не ЛЛМ . ".". Це МСК2 - це все, що було до LМ , і так далі.**

Ви, мабуть, бачили цю модель. МСК1 - розділити документи на шматочки. МSK2 - генерувати вбудовані додатки. , - зберігати їх у векторній базі даних.

- Дослідники для кожного формату
- Логіка, яка поважає семантичні межі
- Токенізація, яка відповідає вашій моделі вбудованості
- Batching для ефективного генерування вбудованих
- Оцінки за доброту, так що не всі шматочки ставляться однаково
- Прослідження цитат, щоб ви знали, звідки прийшли відповіді

Це - багато інфраструктури, перш ніж написати один ряд коду застосування.

**DocSummarizer.Core обробляє все це в одному пакеті** - доступний для обох систем: .NET та Node

DocSummarizer.Core є по суті **здатність документувати**: детерміністична структура по-перше

### Трубопровод запилення

Ось що робить DocSummarizer: *doesn't* do:

```mermaid
flowchart TB
    subgraph INPUT["Input (Your Document)"]
        DOC[/"PDF / DOCX / Markdown / HTML / URL"/]
    end
    
    subgraph DOCSUMMARIZER["DocSummarizer.Core (Deterministic)"]
        direction TB
        PARSE["Parse & Structure"]
        SEGMENT["Segment by Semantics"]
        EMBED["Generate Embeddings<br/>(ONNX - Local)"]
        SCORE["Compute Salience"]
        CITE["Assign Citation IDs"]
        
        PARSE --> SEGMENT
        SEGMENT --> EMBED
        EMBED --> SCORE
        SCORE --> CITE
    end
    
    subgraph OUTPUT["Output (ExtractionResult)"]
        SEGMENTS[/"Segments[]<br/>• Original text (verbatim)<br/>• float[384] embedding<br/>• Salience score<br/>• StartChar / EndChar<br/>• Section context"/]
    end
    
    subgraph YOURS["Your Code"]
        STORE[("Vector Store<br/>(Qdrant / pgvector / etc)")]
    end
    
    subgraph QUERY["Query Time (Later)"]
        Q["User Question"]
        RETRIEVE["Retrieve Top-K"]
        LLM["LLM Synthesis"]
        ANS["Answer + Citations"]
        
        Q --> RETRIEVE
        RETRIEVE --> LLM
        LLM --> ANS
    end
    
    DOC --> PARSE
    CITE --> SEGMENTS
    SEGMENTS --> STORE
    STORE --> RETRIEVE
    
    style DOCSUMMARIZER stroke:#27ae60,stroke-width:3px
    style YOURS stroke:#3498db,stroke-width:2px
    style QUERY stroke:#9b59b6,stroke-width:2px
    style LLM stroke:#e74c3c,stroke-width:2px
```

**Що робить DocSummarizer (зелена скринькаM SK1**

- Розшифровує документи, зберігаючи структуру
- Розділюється на семантичні сегменти (не довільні шматочкиM SK1
- генерує вбудова локально за допомогою ONNX
- Вираховує показники salience
- Приписує ідентичні знаки цитацій з позиціями символів

**Що ви робите (блакитна скринькаM SK1**

- Поміщайте сегменти в вашій векторній базі даних
- Збудувати логіку пошуку

**Що відбувається в часі запиту (пурпурна скринькаM SK1**

- Вставляйте питання (та сама модельM SK1
- Згадайте подібні сегменти
- Посилати на LLM для синтезу

**Ключеві ідеї:** LLM ( червона межа МSK1 залучена лише в час пошуку МSK2 Введення є повністю детерміністичним - один і той самий документ завжди виробляє ті самі сегменти

**Бонус на репродукцію:** Детерміністичне втягування означає, що ви можете переглянути схему RAG0, індикцію ,, дифференцію МSK2 і деbugувати її так само, як будь-який інший будівельний артефакт.

### Чому немає LLM для вживання?

Для RAG, ви хочете *справжні речення* з ваших документів. - не LLM.

LLM з 'являється пізніше , у часі запиту, для синтезу відповіді з отриманих фрагментів МSK2 Але самі фрагменти мають бути дослівним джерелом M SK3 Це те, що makes citations meaningful .

DocSummarizer's `ExtractSegmentsAsync` дає вам саме це: оригіналні текстові сегменти з вбудовами, готовий до відтворенняM SK2 Ніяких LLM, що брали участь у поглинанні .

[TOC]

## Пропозиція цінності

Ось що ви отримуєте з ним `dotnet add package`:

```bash
dotnet add package Mostlylucid.DocSummarizer
```

- **Розумна сегментація** - Розриви на заголовкахM SK1 визначає семантичні межі
- **Вбудова в систему ONNX** - локальний , без API ключів M SK2 моделі автоматизовані МSK3 завантажити МSK4 МБ МСК5
- **Оцінка за доброзичливість** - ДоM SK1 обчислюваність важливості для кожного сегменту
- **Переслідування цитат** - Кожен сегмент має унікальну ID
- **Багато форматів** - Марка-даун МSK1 HTML МSK2 PDF , DOCX
- **Опції для зберігання вектора** - InMemory , DuckDBM SK2 Qdrant built-in

Ні Pythonа. Ні зовнішніх APIM SK1 Ні складної настановки . Працює в офлайні після першого завантаження моделі МSK3

## Витягування сегментів: Кораовий API

Найпростіший застосовний випадок - виділення сегментів з вбудовами, готових для вашого векторного магазину

```csharp
using Microsoft.Extensions.DependencyInjection;
using Mostlylucid.DocSummarizer;

// Setup DI
var services = new ServiceCollection();
services.AddDocSummarizer();
var provider = services.BuildServiceProvider();

var summarizer = provider.GetRequiredService<IDocumentSummarizer>();

// Extract segments with embeddings
string markdown = File.ReadAllText("document.md");
var extraction = await summarizer.ExtractSegmentsAsync(markdown);

foreach (var segment in extraction.AllSegments)
{
    Console.WriteLine($"[{segment.Type}] {segment.SectionTitle}");
    Console.WriteLine($"  ID: {segment.Id}");
    Console.WriteLine($"  Salience: {segment.SalienceScore:F2}");
    Console.WriteLine($"  Embedding: float[{segment.Embedding?.Length}]");
    Console.WriteLine($"  Text: {segment.Text[..Math.Min(80, segment.Text.Length)]}...");
}
```

**Виход:**

```
[Heading] Introduction
  ID: a1b2c3d4e5f6g7h8_h_0
  Salience: 0.85
  Embedding: float[384]
  Text: This document describes the architecture of our new microservices platform...

[Sentence] Introduction  
  ID: a1b2c3d4e5f6g7h8_s_1
  Salience: 0.72
  Embedding: float[384]
  Text: The system is designed to handle 10,000 requests per second with sub-100ms...
```

МSK0 - це воно, МSK1 - без оркестрування, МСК2 - без пропону, М СК3 - без думки, M СК4 - лише сегменти з вбудовами та провинцією, М S К5 - готовий до вашої векторної бази даних

### Іденти dokumentu

Кожен сегмент's `Id` збудований з ID-документу плюс тип та індекс: `{docId}_{type}_{index}`.

Ви можете запропонувати власний документ ID, або дозволити DocSummarizer обчислити один із контенту hash:

```csharp
// Option 1: Provide your own ID (useful for tracking documents in your system)
var extraction = await summarizer.ExtractSegmentsAsync(markdown, documentId: "contract-2024-001");
// Segments get IDs like: contract_2024_001_s_0, contract_2024_001_h_1, ...

// Option 2: Auto-generated from content hash (default)
var extraction = await summarizer.ExtractSegmentsAsync(markdown);
// Segments get IDs like: a1b2c3d4e5f6g7h8_s_0, a1b2c3d4e5f6g7h8_h_1, ...
// Same document = same hash = same IDs (deterministic)
```

**Чому це важливо для РАГ:**

- Custom ID дають змогу співвідносити сегменти з системою управління документами
- Конtent-hash IDs гарантують, що реM SK1indexування одного й того ж dokumentu виробляє ідентичні ID сегментів
- Обидві методи підтримують стабільні цитації - `[s42]` завжди вирішує до того ж джерела тексту

## Що в сегменті

Кожен виділений сегмент містить все, що вам потрібно для RAG:

```csharp
public class Segment
{
    string Id;              // Unique ID: "mydoc_s_42" (for citations)
    string Text;            // The actual content
    SegmentType Type;       // Sentence, Heading, ListItem, CodeBlock, Quote, TableRow
    int Index;              // 0-based order in document
    
    // Source location tracking
    int StartChar;          // Character offset where segment starts
    int EndChar;            // Character offset where segment ends
    int? PageNumber;        // Page number (for PDFs)
    int? LineNumber;        // Line number (for text/markdown)
    
    // Section context
    string SectionTitle;    // "Introduction" - immediate heading
    string HeadingPath;     // "Chapter 1 > Introduction > Overview"
    int HeadingLevel;       // 1-6 (heading depth)
    
    // Computed during extraction
    float[] Embedding;      // 384-dim vector (default model)
    double SalienceScore;   // 0-1 importance score
    string ContentHash;     // Stable hash for citation tracking across re-indexing
    
    // For retrieval (set during query)
    double QuerySimilarity; // Similarity to the query
    double RetrievalScore;  // Combined score: similarity + salience
    
    string Citation { get; } // Auto-generated: "[s42]", "[h3]", etc.
}
```

І `Id` це ключ до відстеження цитат. Коли ваш LLM виводить `[s42]`, ви можете повернути його до точного місця джерела за допомогою `StartChar`/`EndChar`.

**Бонус:** І `ExtractionResult` включає в себе допоміжні методи для відтворення цитацій:

```csharp
var extraction = await summarizer.ExtractSegmentsAsync(markdown);

// Fast O(1) lookups
var segment = extraction.GetSegment("mydoc_s_42");
var segmentByIdx = extraction.GetSegmentByIndex(42);

// Find segment at a character position
var segmentAtPos = extraction.GetSegmentAtPosition(5432);

// Get all segments on page 5 (for PDFs)
var pageSegments = extraction.GetSegmentsOnPage(5);

// Get source location for highlighting
var location = extraction.GetSourceLocation("mydoc_s_42");
// Returns: StartChar, EndChar, LineNumber, PageNumber, SectionTitle, HeadingPath

// Extract highlighted text with context
var highlight = extraction.GetHighlightedText(originalMarkdown, "mydoc_s_42", contextChars: 50);
Console.WriteLine(highlight.ToHtml());  // <span class="highlight">...</span>
Console.WriteLine(highlight.ToMarkdown()); // **...**
```

## Введення в векторні магазини

DocSummarizer дає вбудовані додатки. Використовуйте будь-яку векторну базу даних, яку хочетеM SK1

### Кдрант

```csharp
var points = extraction.AllSegments.Select((s, i) => new PointStruct
{
    Id = (ulong)i,
    Vectors = s.Embedding,
    Payload = 
    {
        ["text"] = s.Text,
        ["section"] = s.SectionTitle,
        ["salience"] = s.SalienceScore,
        ["segment_id"] = s.Id,
        ["start_char"] = s.StartChar,
        ["end_char"] = s.EndChar
    }
}).ToList();

await qdrantClient.UpsertAsync("documents", points);
```

### PostgreSQL + pgvector

```csharp
foreach (var segment in extraction.Segments)
{
    await connection.ExecuteAsync(
        @"INSERT INTO documents (segment_id, text, heading, salience, embedding) 
          VALUES (@id, @text, @heading, @salience, @embedding::vector)",
        new { 
            id = segment.Id,
            text = segment.Text, 
            heading = segment.SectionTitle,
            salience = segment.SalienceScore,
            // NOTE: String interpolation is for demo simplicity only.
            // For production, use NpgsqlParameter with Vector type for better
            // performance and to avoid culture-dependent decimal separators.
            embedding = $"[{string.Join(",", segment.Embedding)}]"
        });
}
```

### Або використати Built- в магазинах

Не хочете керувати окремою базою даних

```csharp
services.AddDocSummarizer(options =>
{
    // In-memory (fastest, no persistence)
    options.BertRag.VectorStore = VectorStoreBackend.InMemory;
    
    // DuckDB (embedded file-based, default)
    options.BertRag.VectorStore = VectorStoreBackend.DuckDB;
    
    // Qdrant (external server)
    options.BertRag.VectorStore = VectorStoreBackend.Qdrant;
    options.Qdrant.Host = "localhost";
    options.Qdrant.Port = 6334;
});
```

## Чому щирість має значення

Більшість RAG-систем провалюються не тому, що вбудова є поганою,, а тому що всі фрагменти вважаються однаково важливими.

```mermaid
flowchart LR
    subgraph DOC["Document"]
        H1["# Title"]
        P1["First paragraph<br/>(intro)"]
        H2["## Methods"]
        P2["Technical details..."]
        P3["More details..."]
        H3["## Results"]
        P4["Key findings here"]
        H4["## Appendix"]
        P5["Reference data..."]
    end
    
    subgraph SCORES["Salience Scores"]
        S1["0.95"]
        S2["0.85"]
        S3["0.70"]
        S4["0.65"]
        S5["0.60"]
        S6["0.80"]
        S7["0.30"]
    end
    
    H1 --> S1
    P1 --> S2
    H2 --> S3
    P2 --> S4
    P3 --> S5
    P4 --> S6
    P5 --> S7
    
    style S1 stroke:#27ae60,stroke-width:3px
    style S2 stroke:#27ae60,stroke-width:2px
    style S6 stroke:#27ae60,stroke-width:2px
    style S7 stroke:#e74c3c,stroke-width:2px
```

речення у абстрактному значенні важливіше, ніж речення в приписі.

```csharp
// Get the top 20% most salient segments
var topSegments = extraction.Segments
    .OrderByDescending(s => s.SalienceScore)
    .Take((int)(extraction.Segments.Count * 0.2));
```

**Різовики слизистості:**

| Фактор МSK1 Ефект МSK2
|--------|--------|
МSK0 Позиция | В вступі МSK2сумовні речення отримують більше балів |
| Близькість заголовку | Перші речення після заголовків - це теорічні речення
МSK0 Длина | Дуже короткі сегменти
МSK0 Тип секції | Абстракт МSK2Введення збільшено , Референції
| Тип наповнення МSK1 Блоки коду МSK2 цитати , листи з різним значенням

Це означає, що ваше відтворення `(similarity * salience)` замість простої схожості.

## класифікація документів

DocSummarizer auto- визначає тип dokumentu, використовуючи гуристику на основі контентуM SK1

```csharp
var extraction = await summarizer.ExtractSegmentsAsync(markdown);

// Document type detected from content
Console.WriteLine($"Type: {extraction.DocumentType}");     // Technical, Narrative, Legal, etc.
Console.WriteLine($"Confidence: {extraction.Confidence}"); // High, Medium, Low
```

**класифікація впливає на пошук**: Шкала глибини відтворення з ентропією dokumentu , не зашифрований ВерхнийKM SK2 Розмовні документи МSK3 вигадка МSK4 історії М SK5 отримують МСК6 x підштовхування до числа відтворення, тому що їм потрібен більше контексту М СК7 Технический документ з чіткою структурою потребує менше М S К8

Геуристичні дослідження на :

- Частота кодового блоку ( технічнаM SK1
- Структура заголовку (академічнийM SK1 технічнийМSK2
- Patternи діалогу (наративM SK1
- Юридична термінологія (контрактиM SK1
- щільність списку (документаціяM SK1

Якщо геризтика непевна, DocSummarizer може повернутися до швидкої класифікації LLM, використовуючи модель "sentinel". Це вимагає того, щоб Ollama працювала локально з маленькою моделлю, наприклад `tinyllama`. Увімкніть його за допомогою конфігурації

```csharp
services.AddDocSummarizer(options =>
{
    options.Ollama.BaseUrl = "http://localhost:11434";
    options.Ollama.Model = "tinyllama";
});

// Then use with LLM fallback enabled
var extraction = await summarizer.ExtractSegmentsAsync(markdown, useLlmFallback: true);
```

Для більшості документів , геуристика сама по собі є достатньо точною - зворотній зв 'язок LLM існує для крайних випадків МSK2

## До прикладу повного трубопроводу RAG

Тут – це повний індекс – МСК1, МСК2, труба запиту, МSK3. Ми – МSK4 – збудуємо її за три кроки

```mermaid
sequenceDiagram
    participant User
    participant App as Your App
    participant DS as DocSummarizer
    participant VS as Vector Store
    participant LLM
    
    Note over DS: INGESTION (No LLM)
    App->>DS: ExtractSegmentsAsync(markdown)
    DS->>DS: Parse structure
    DS->>DS: Split into segments
    DS->>DS: Generate embeddings (ONNX)
    DS->>DS: Compute salience
    DS-->>App: ExtractionResult
    App->>VS: Store segments + vectors
    
    Note over LLM: QUERY TIME (LLM involved)
    User->>App: "What about X?"
    App->>DS: EmbedAsync(question)
    DS-->>App: float[384]
    App->>VS: Search(vector, topK=5)
    VS-->>App: Top segments
    App->>LLM: Question + Context
    LLM-->>App: Answer with [citations]
    App-->>User: Answer
```

### Шаг 1: Структури даних

```csharp
public class SimpleRagService
{
    private readonly IDocumentSummarizer _summarizer;
    
    // In-memory segment store - maps "docId:segmentId" to the full segment
    private readonly Dictionary<string, ExtractedSegment> _segments = new();
    
    // In-memory vector index - pairs of (id, embedding vector)
    private readonly List<(string Id, float[] Vector)> _index = new();
```

В процесі виробництва ви використовуєте реальну векторну базу даних: (QdrantM SK2 pgvector, і т.д.

### Шаг 2: Індексування документів

```csharp
    public async Task IndexAsync(string markdown, string docId)
    {
        // Extract segments with embeddings - this is where DocSummarizer does the work
        var extraction = await _summarizer.ExtractSegmentsAsync(markdown);
        
        // Store each segment and its vector
        foreach (var segment in extraction.Segments)
        {
            // Composite key: document + segment for citation tracking
            var id = $"{docId}:{segment.SegmentId}";
            
            // Keep the full segment for retrieval
            _segments[id] = segment;
            
            // Add to vector index for similarity search
            _index.Add((id, segment.Embedding));
        }
    }
```

Зверніть увагу, ми зберігаємо *справжня* текст dokumentu, не підсумкиM SK1

### Шаг 3: Попит

```csharp
    public async Task<string> QueryAsync(string question, int topK = 5)
    {
        // Embed the question using the same model as documents
        // This ensures vectors are in the same space
        var embedding = await _summarizer.EmbedAsync(question);
        
        // Find top-K most similar segments
        var results = _index
            .Select(x => (x.Id, Similarity: CosineSimilarity(embedding, x.Vector)))
            .OrderByDescending(x => x.Similarity)
            .Take(topK)
            .Select(x => _segments[x.Id])
            .ToList();
        
        // Build context with citation markers
        // The LLM can reference [chunk-3] and we can trace it back
        var context = string.Join("\n\n", results.Select(s => 
            $"[{s.SegmentId}] {s.Text}"));
        
        return context; // Send this + the question to your LLM
    }
```

Повернений контекст містить *справжній* текст документа з ідеями сегменту. Ваша LLM про prompt може виглядати так, як

```
Answer the question based on the following context.
Cite sources using the [chunk-N] markers.

Context:
{context}

Question: {question}
```

### Математика (Standard Cosine SimilarityM SK1

```csharp
    private static float CosineSimilarity(float[] a, float[] b)
    {
        float dot = 0, normA = 0, normB = 0;
        for (int i = 0; i < a.Length; i++)
        {
            dot += a[i] * b[i];
            normA += a[i] * a[i];
            normB += b[i] * b[i];
        }
        return dot / (MathF.Sqrt(normA) * MathF.Sqrt(normB));
    }
}
```

DocSummarizer включає `VectorMath.CosineSimilarity()` якщо ви не хочете писати це самостійно

DocSummarizer також відкриває `IEmbeddingService` безпосередньо, якщо вам потрібно вмонтувати пошуки окремо від повної схеми підсумування.

## Вбудова моделей

За замовчанням `AllMiniLmL6V2` - швидко , маленьке МSK2 хороша якість M SK3 Вибирати в залежності від ваших потреб

```csharp
services.AddDocSummarizer(options =>
{
    options.Onnx.EmbeddingModel = OnnxEmbeddingModel.BgeBaseEnV15;
});
```

МSK0 Модель | Dims | Max Tokens | МSK3 | Rozmiar | | | Примітки ||
|-------|------|------------|------|-------|
| `AllMiniLmL6V2` МSK0 384
| `BgeSmallEnV15` МSK0 384 ♫ ♫ МSK2 ♫
| `BgeBaseEnV15` МSK0 768 ♫ ♫ МSK2 ♫
| `JinaEmbeddingsV2BaseEn` МSK0 768 ♫ ♫ МSK2 ♫

Моделі автоматизовано- завантажити з HuggingFace при першій користуванні . Далі запускає навантаження з диска M SK2

## Відкрита телеметрія

Наблюдайте за вашими трубопроводами RAG в процесі виробництва:

```csharp
services.AddOpenTelemetry()
    .WithTracing(tracing => tracing
        .AddSource("Mostlylucid.DocSummarizer")
        .AddSource("Mostlylucid.DocSummarizer.Ollama")
        .AddSource("Mostlylucid.DocSummarizer.WebFetcher")
        .AddOtlpExporter())
    .WithMetrics(metrics => metrics
        .AddMeter("Mostlylucid.DocSummarizer")
        .AddMeter("Mostlylucid.DocSummarizer.Ollama")
        .AddMeter("Mostlylucid.DocSummarizer.WebFetcher")
        .AddPrometheusExporter());
```

**Ключові метрики:**

- `docsummarizer.summarizations` - Перерахунки запитів
- `docsummarizer.summarization.duration` - Час обробки в ms
- `docsummarizer.document.size` - розміри документів
- `docsummarizer.ollama.embed.requests` - Введення API дзвінків

## Поддержка формату

DocSummarizer обробляє багато форматів документу з розумним виявленням та обробкою.

### Пряма обробка (Не має зовнішніх обов 'язківM SK1

Ці формати оброблені наtively - не потрібні документування чи інші послугиM SK1

| Формат МSK1 Поширення МSK2 Обробка |
|--------|-----------|------------|
| Замітка МSK1 `.md`, `.markdown` | Розшифровано за допомогою Маркдіґа МSK1 структуру зберігають МSK2
| Plain Text МSK1 `.txt`, `.text` | Подібно до абзаців
МSK0 HTML | `.html`, `.htm` | СанітаризованийM SK1 перетворений на Markdown |
| Архиви ЗIP МSK1 `.zip` | Витягує текстові файли , автоматичний МSK2 розпізнає формат Гутенберґа

**Простий текст отримує розумне оброблення**: Коли немає заголовків з відмітками, , chunker переключається на абзац МSK2 базується на розрізі \ . Він виявляє структуру dokumentu у найпростішому розумінні. МSK4 якщо у вашому тексті є чіткі прориви абзацу \, вони стають межами блока

```csharp
// Plain text works the same way
var plainText = File.ReadAllText("notes.txt");
var extraction = await summarizer.ExtractSegmentsAsync(plainText);
// Chunks split by paragraphs, embeddings generated
```

### Богаті документи з документуванням

Для PDF, DOCXM SK1 PPTX, XLSXMSC3 і зображеннях (OCRMska5 M Ska6 додайте DoclingMske7

```bash
docker run -d -p 5001:5001 quay.io/docling-project/docling-serve
```

```csharp
services.AddDocSummarizer(options =>
{
    options.Docling.BaseUrl = "http://localhost:5001";
});

// PDF, DOCX, PPTX, images all work
var pdfBytes = await File.ReadAllBytesAsync("document.pdf");
var extraction = await summarizer.ExtractSegmentsAsync(pdfBytes, "document.pdf");
```

Docling зберігає структуру dokumentu - заголовкиM SK1 таблиці , листи просуваються як правильне Markdown. Це означає, що краще відокремлення, ніж видобуток сирого тексту

| Формат МSK1 Поширення МSK2 Замітки |
|--------|-----------|-------|
| PDF МSK1 `.pdf` | Текст МSK1 макет зачуваний МSK2 таблички конвертовані |
| Слово МSK1 `.docx` | Полне форматування МSK1 заголовки МSK2 листи |
| PowerPoint  | `.pptx` | Сліпи стають розділами МSK1
| Excel  | `.xlsx` | Переведені таблички МSK1
| Фото МSK1 `.png`, `.jpg`, `.tiff` | ОCR через Docling |

Подивіться [Частина 1](/blog/building-a-document-summarizer-with-rag) для більшої інформації про інтеграцію Docling, або [Мультиконвертація формату dokumentu](/blog/building-a-lawyer-gpt-for-your-blog-part9) для глибоких погружений.

## Складні частини, які ви перекидаєте

| Проблема | DocSummarizer Solution МSK2
|---------|----------------------|
| Спілкування на семантичних кордонах МSK1 Розриви на заголовкахM SK2 вміст, пов 'язаний з групами МSK3
| Токенізація за модель | Використовує правильний токенізер для кожної моделі ONNX МSK2
| Вбудова пакету МSK1 Конфигурований розмір пакета МSK2 пам 'ять - ефективний
| Переслідування цитат | Кожен сегмент стає унікальним `SegmentId` |
| Конвертація формату МSK1 Марка-даун МSK2 HTML , PDF
| Скачаймо модельM SK1Cachering |Auto-downloadsМSK4 Cache in `~/.docsummarizer` |

## Підсумок

До цікавої частини трубопроводу RAG потрібна інфраструктура.

1. **Зрізки з вбудовами** - Готовий для будь-якого векторного магазину
2. **Результати ФК  Соланс ** - Не всі фрагменти однакові
3. **Переслідування цитат** - Знайте, звідки приходять відповіді
4. **Місцеві-перша** - Ніяких API ключів , запускається в офлайн
5. **Телеметрія виробництва** - Вбудована OpenTelemetry

```bash
dotnet add package Mostlylucid.DocSummarizer
```

Вимикання завершено. Збудувати вашу RAG програмуM SK1

## Подібні статті

### Серія DocSummarizer

- [Частина 1 - Архітектура МSK2 Patterns](/blog/building-a-document-summarizer-with-rag) - Чому цей підхід працює
- [Частина 2 - Використовуючи інструмент](/blog/docsummarizer-tool) - Установка CLI МSK1 режими МСК2 шаблони
- [Частина 3 МSK1 Заawansовані концепції](/blog/docsummarizer-advanced-concepts) - BERT вбудованіM SK1 ONNX, гібридний пошук
- [Частина 5 МSK1 ДоумСummarizerM SK2 Глубоке дослідження](/blog/doomsummarizer-deep-research) - Мультифріалізація МSK1 відтворення джерела МSK2 профілі об 'єктів , відкриття семантичного графу ХМSK4 і паралельна довгота ГМSK5 синтез форми

### РАГ Deep Dives

- [Примар RAG](/blog/rag-primer) - Фундаментальні концепції для отримання - збільшена генерація
- [Архітектура РАГ](/blog/rag-architecture) - Моделі дизайну системи для RAG
- [Гібридні пошуки та індексування](/blog/rag-hybrid-search-and-indexing) - Об 'єднання щільного та розсіяного пошуку
- [Практичні застосування RAG](/blog/rag-practical-applications) - РеальнийM SK1 світові приклади використання

### GraphRAG

- [ГрафRAG: Знання графи для RAG](/blog/graphrag-knowledge-graphs-for-rag) - Коли пошук вектора не достатньо
- [Minimum Viable Implementation GraphRAG](/blog/graphrag-minimum-viable-implementation) - Збудувати працюючу систему GraphRAG

### Подібні інструменти

- [Семантичний пошук за допомогою ONNX та Qdrant](/blog/semantic-search-with-onnx-and-qdrant) - Збудовані блоки
- [Само собою-Схований векторні бази данихM SK1 Qdrant](/blog/self-hosted-vector-databases-qdrant) - Працюючий Qdrant локально
- [Анализ великих CSV-файлів з локальними LLM](/blog/analysing-large-csv-files-with-local-llms) - Те ж саме, МSK1 різна домена
- [Перехоплення та аналіз веб-контенту з LLM](/blog/fetching-and-analysing-web-content-with-llms) - Веб-скапування для RAG
- [Multi-Format Document Conversion Service](/blog/multi-format-document-conversion-service) - Глибокий дайвинг Docling

## Ліки

- [Пакет NuGet](https://www.nuget.org/packages/Mostlylucid.DocSummarizer)
- [Бібліотека ядра GitHub -](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.DocSummarizer.Core)
- [Програмне забезпечення GitHub -](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.DocSummarizer)