# DocSummarizer Part 4 - بناء أنابيب RAG

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

[![غويت](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/)
[![العقد.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 هو ' هو "LLM" . هو كل شيء قبل "LLS"**

ربما رأيتم النمط

- قاموا بتحليل الوثائق لكل صيغة
- المنطق المحاكي الذي يحترم الحدود الدلالية
- توكنالوجيا تتطابق مع نموذج الدمج الخاص بك
- تخزين لخلق دمج فعّال
- تقييم الشفقة بحيث لا يتم التعامل مع جميع الأجزاء بشكل متساوي
- تتبع الاقتباس حتى تعرف من أين جاءت الإجابات

ذلك ' هو الكثير من البنية التحتية قبل أن تكتب سطر واحد من شفرة التطبيق .

**DocSummarizer.Core يعالج كل ذلك في حزمة واحدة** - متاحة لكلا .NET و العقدةM SK2js.

DocSummarizer.Core هو أساسا **طبقة ذكاء الوثائق**: الهيكلات الإفتراضية أولاً, الاستخراج الإحتمالي ثانياً . يحل مشكلة المعلوماتM SK3الهندسة بحيث يمكنك التركيز على مشكلة التفسير

### أنابيب الإمتصاص

هنا ' ما يفعله DocSummarizer - و بشكل حرج *لا '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 (صندوق أخضر):**

- يقوم بتحليل الوثائق التي تحافظ على البنية
- تقسم إلى أجزاء سيمانسية (لا قطع عشوائية)
- ينتج تداخلات محليا مع ONNX
- يحسب نقاط الرابع
- يخصص هوية الإقتباس مع وضعية الحرف

**ما تفعله (صندوق أزرق):**

- تخزين الأجزاء في قاعدة بيانات الفيكتور الخاصة بك
- بناء منطق استرجاعك

**ما الذي يحدث في وقت الاستفسار (صندوق أزرق):**

- دمج السؤال (نفس النموذج)
- استرجاع أجزاء متشابهة
- أرسل إلى LLM للsynthesis

**رؤية أساسية:** LLM (حدود حمراء) يتدخل فقط في وقت الاستفسارM SK2 التدخين هو محدد تماماً - نفس الملف دائماً ينتج نفس الأجزاءMSC4 هذا ما يجعل RAG قابلة للتكرار وقابلة للحل

**بونس التكاثر:** الإمتصاص المعرفي يعني أنه يمكنك إعادة - "index" , " diff" , "and debug your RAG pipeline like any other build artifact" "No prompt variance" "no model temperature" "only pure"

### لماذا لا يوجد LLM للإمتصاص?

من أجل RAG, تريد *جمل حقيقية* من مستنداتكم - ليس LLM- الاقتباسات المولدةM SK2 عندما يسأل أحد المستخدمين " ماذا يقول العقد عن التخلي عن العقدMSC4 تحتاج إلى الحصول على النص الحقيقي للتعاقد

يأتي الـ LLM لاحقاً ــ , ــ في وقت البحث ــ, ــ لتحليل الإجابة من القطعة التي تم استخلاصها ـــ . ــ لكن القطعة نفسها يجب أن تكون مصدراً حرفياً ـــ. ــ ذلك ــ МSK4 ــ هو ما يجعل الإقتباسات ذات معنى

DocSummarizer's `ExtractSegmentsAsync` يعطيك هذا بالضبط: أجزاء النص الأصلية مع المداخلات, جاهزة للإستخراجM SK2 لا يوجد LLM مشارك في الإمتصاص

[TOC]

## إقتراح القيمة

ها هو ما تحصل عليه مع واحدة `dotnet add package`:

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

- **الانقسام الذكي** - تقسم على الرؤوس, يحترم الحدود الدلالية
- **إضافات أونكس** - محلي, لا مفاتيح APIM SK2 نماذج أوتومات -تحميل
- **درجات الشفقة** - مسبقا- الأهمية الحسابية لكل جزء
- **متابعة الاستشهادات** - كل جزء لديه ID فريد
- **العديد من الأشكال** - MarkdownMSC1 HTML, PDFM SK3 DOCX (with DoclingMST5
- **خيارات مخزن الفيكتور** - InMemory , DuckDBM SK2 Qdrant built-in

لا برمجة Python. لا واجهات API خارجية. لا تركيب معقدM SK2 يعمل على أرض الواقع بعد تحميل النموذج الأول .

## استخرج Segments: API الأساسي

أبسط حالة إستخدام - استخرج Segments with embeddings ready for your vector store

```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)]}...");
}
```

**ال sortie:**

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

ذلك 'ه هو . لا ترسيم ,, لا إشارات , , لا رأي .- فقط أجزاء مع المداخلات و provenance .

### أوراق الوثائق

كل جزء '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)
```

**لماذا هذا يهم RAG:**

- الهوية المخصصة تمكنك من ربط الأجزاء مع نظام إدارة الملفات الخاص بك
- المحتوى -hash IDs ensure re-indexing the same document produces identical segment IDs
- كلا المقاربتين يدعمون اقتباسات مستقرة - `[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 يعطيك المداخلات. استخدم أي قاعدة بيانات فيكتورية تحبها.

### كوينت

```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)}]"
        });
}
```

### أو إستخدام "بنى مسك 0" في المتاجر

لا تريد إدارة قاعدة بيانات مستقلة

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

**عوامل ال Salience:**

| عامل | تأثير |
|--------|--------|
| وظيفة | مقدمة | / | جمل الإختبار تعطي علامة أعلى ||
| قرب العنوان | أول جملة بعد العناوين هي جملة موضوعية |
| طول | أجزاء قصيرة جدًا (< 80 تُعاقب اللوحات S)
| نوع الفصول | خلاصة / تحسن في التقديم , مرجعية /تقلص في الملحق |
| نوع المحتوى | بلاك الرمز, اقتباساتM SK3 القوائم الموزعة بشكل مختلف |

هذا يعني أن إستخراجك يمكنه أن يزن `(similarity * salience)` بدلا من التشابه

## تصنيف الوثائق

DocSummarizer automatic-detects document type using heuristics on the content:

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

**التصنيف يؤثر على البحث**: مقاييس عمق البحث مع إنتروبيا الوثائق , ليس رمزاً صلباً TopK | . | Documents Narrative |( | Fiction | , | stories | МSK5 | get a 1.5 | boost to retrieval count because they need more context

نظرة الهيوريستيك على :

- تردد وحدة الرمز (technical)
- الهيكل الرأسي (أكاديمي,سيّنيM SK2
- أنماط الحوار (narrative)
- المصطلحات القانونية (أعمال
- كثافة القائمة (documentation)

إذا كانت الهرسية غير مؤكدة , DocSummarizer يمكن أن يرجع بشكل اختياري إلى ترتيب سريع لـ LLM باستخدام "sentinel" نموذج .. هذا يتطلب من أولاما العمل محليا مع نموذج صغير مثل `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);
```

بالنسبة للكثير من الوثائق , هلuristics وحدها هي دقيقة بما فيه الكفاية - هناك تراجع LLM لقضايا الحواف

## مثال أنابيب RAG الكاملة

هنا "MSC0" هو المؤشر الكامل "MSc1" و "MScs2" خط أنابيب الطلب "MSec3" نحن "MSCS4" سنبنيه بثلاثة خطوات

```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, وهلم جراMSC4 لكن هذا يظهر النمط الأساسيMNK5

### الخطوة 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));
        }
    }
```

ملاحظة: لا وجود لـ LLM . نحن ' نقوم بحفظ *حقيقة* نص документа, لا خلاصات.

### الخطوة 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 الخاص بك كالتالي

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

Context:
{context}

Question: {question}
```

### الرياضيات (متشابهة الكوسين القياسية)

```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` -سرعةM SK1 صغيرة, جودة جيدة . إختيار بناء على إحتياجاتكMSC4

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

| النماذج | يضيئ | | | إرقام اعظمية || | الحجم || | ملاحظات | |
|-------|------|------------|------|-------|
| `AllMiniLmL6V2` | 384 ≥| ≤256 | ~23 MB | លំនាំដើម MSC7 سرعة MSC8
| `BgeSmallEnV15` | 384 ≥| \512 | | | ♪~34 |MB || | أفضل نوعية ♪ / |نسبة الحجم ♪
| `BgeBaseEnV15` |  768
| `JinaEmbeddingsV2BaseEn` | 768 ≥| \8192 | | | ♪~137 |MB || | سندات طويلة |

نماذج اتومات-download from HuggingFace on first useM SK1 Subsequent runs load from disk.

## OpenTelemetry

مراقبة أنابيب 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 يتعامل مع العديد من صيغ الوثائق بكشف و معالجة ذكية.

### المعالجة المباشرة (لا إختلافات خارجية )

هذه الصيغ تُعالج بفطرة - لا حاجة للدواسة أو الخدمات الأخرى :

| الصيغة | الإختصار | | | معالجة ||
|--------|-----------|------------|
| العلامة المنخفضة | `.md`, `.markdown` | تمت تحليلها مع ماركديج, تم الحفاظ على الهيكل |
| النص البسيط | `.txt`, `.text` | تقسم بال odstavات ( خطوط جديدة مضاعفة) |
| HTML  | `.html`, `.htm` | مصحوبة, حولت إلى Markdown |
| آرشيف ZIP | `.zip` | يستخرج فايلات نصية, تلقائياM SK2 يكتشف شكل غوتينبيرغ |

**نص بسيط يحصل على معالجة ذكية**: عندما لا توجد مخطوطات تشير إلى النزول, يتحول المجزأ إلى الفقرة - تم تقسيمها على أساسه M SK3 يكشف عن هيكل الوثائق بشكل عام - إذا كان نصك يحتوي على وقفات فقرية واضحة MSC5 تلك تصبح حدود المجزء

```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, DOCX, PPTXM SK2 XLSXMSC3 وصور (OCRMska5 Mske6 أضف الملاحظات

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

تحتفظ الملاحظات بتركيب الوثائق - العلاماتM SK1 الجداول , قائمة تأتي من خلال علامة مناسبة. هذا يعني أن أفضل تكديس من إستخراج النص الخام

| الصيغة | الإختصار | | | ملاحظات ||
|--------|-----------|-------|
| PDF  | `.pdf` | النص + تم الحفاظ علىレイアウトه, حولت الجداول |
| كلمة  | `.docx` | الصيغة الكاملة, العلاماتM SK2 القوائم |
|PowerPoint  | `.pptx` | تتحول الشرائح إلى أجزاء |
|Excel  | `.xlsx` | الجداول المستخرجة |
| الصور  | `.png`, `.jpg`, `.tiff` | رسم بياني عبر الطباعة |

أنظروا [الجزء 1](/blog/building-a-document-summarizer-with-rag) لمعرفة المزيد عن دمج دوكلينج, أو [العديد من -تحويل الصيغة للឯកសារ](/blog/building-a-lawyer-gpt-for-your-blog-part9) للغوص العميق.

## الأجزاء الصعبة التي تخطيها

| مشكلة | حل DocSummarizer |
|---------|----------------------|
| تدوير في الحدود الدلالية | تقسيمات على الأشرطة, مجموعة المحتوى المرتبطة |
| توكيزة لكل نموذج | يستخدم توكيزا صحيحة لكل جيل ONNX |
| تداخل الخزبة | حجم الخزعة قابلة للضبط, الذاكرةM SK3 فعال |
| تتبع الاقتباس | كل جزء يحصل على فريد من نوعه `SegmentId` |
| تحويل الصيغ | العلامة المنخفضة , HTMLM SK3 PDF, DOCX من خلال API واحد |
| تحميل النموذج/ تخزين المخازن | أوتوماتMSC3downloadsM SK4 مخازن في `~/.docsummarizer` |

## الخلاصة

أنابيب RAG تحتاج إلى البنية التحتية قبل الجزء المثير

1. **Segments with embeddings** - جاهزة لأي مخزن فيكتوري
2. **درجات الفضول** - ليست جميع الجسيمات متساوية
3. **متابعة الاستشهادات** - تعرف من أين تأتي الإجابات
4. **محلي-أول** - لا يوجد مفاتيح API, يعمل خارج نطاق الإنترنت
5. **قياس الإنتاج** - OpenTelemetry مبني

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

تم التوصيل بالماء . بناء تطبيق RAG الخاص بك .

## المقالات المرتبطة

### سلسلة DocSummarizer

- [الجزء 1 - العمارة & الأنماط](/blog/building-a-document-summarizer-with-rag) - لماذا ينجح مقاربة الأنبوب
- [الجزء 2 - باستخدام الأداة](/blog/docsummarizer-tool) - تركيب الـ CLI, اشكال الـ , قوالب
- [الجزء 3 - المفاهيم المتقدمة](/blog/docsummarizer-advanced-concepts) - مداخلات بيرت, أونكسM SK2 البحث الهجين
- [الجزء 5 - DoomSummarizer: البحث العميق](/blog/doomsummarizer-deep-research) - متعددة- إستخراج المصدرM SK2 Profiles of entityMSC3 discovery semantic graph , and parallel longMST5 synthesis form

### RAG الغوصات العميقة

- [مبدئي RAG](/blog/rag-primer) - مبادئ أساسية للبحث- الجيل المتزايد
- [معمار RAG](/blog/rag-architecture) - نمط تصميم النظام لـ RAG
- [البحث الهجين والإستنتاج](/blog/rag-hybrid-search-and-indexing) - الجمع بين البحث الكثيف والبحث الضئيل
- [تطبيقات عمليّة RAG](/blog/rag-practical-applications) - حقيقية- حالات عالمية الاستخدام

### GraphRAG

- [رسم بيانيRAG: رسوم بيانية لمعرفة RAG](/blog/graphrag-knowledge-graphs-for-rag) - عندما يكون البحث فيكتوري غير كاف
- [GraphRAG الحد الأدنى لتطبيق قابل للتطبيق](/blog/graphrag-minimum-viable-implementation) - بناء نظام GraphRAG يعمل

### أدوات مرتبطة

- [البحث الدلالي مع ONNX و Qdrant](/blog/semantic-search-with-onnx-and-qdrant) - أجزاء البناء
- [الذاتي-أبحاث الفيكتور المستقرة: Qdrant](/blog/self-hosted-vector-databases-qdrant) - تعمل Qdrant محلياً
- [تحليل الملفات الكبيرة CSV مع LLMs المحلية](/blog/analysing-large-csv-files-with-local-llms) - نفس النمط, مجال مختلف
- [جلب وتحليل المحتوى على شبكة الإنترنت مع LLMs](/blog/fetching-and-analysing-web-content-with-llms) - تدوير الإنترنت لـ RAG
- [العديد من - خدمة تحويل الصيغة للوثائق](/blog/multi-format-document-conversion-service) - الغوص العميق

## الروابط

- [حزمة نوجيت](https://www.nuget.org/packages/Mostlylucid.DocSummarizer)
- [مكتبة GitHub - الأساسية](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.DocSummarizer.Core)
- [أداة GitHub - CLI](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.DocSummarizer)