# GraphRAG Part 2: Minimum Viable Graph RAG

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

<!-- category -- ASP.NET, GraphRAG, DuckDB, Vector Search, Machine Learning, Knowledge Graphs -->
في [الجزء 1](/blog/graphrag-knowledge-graphs-for-rag), استكشفنا لماذا يهم GraphRAG **GraphRAG الأقل قابلة للحياة** مع ثلاثة اشكال استخراج:

| الطريقة | إتصالات الـ LLM | الأفضل ل|
|------|-----------|----------|
| **الهيوريستيكس** (លំនាំដើម) | ♫0 لكل قطعة ♫
| **الهجين** | 1 لكل سند | توازن السرعة والدقة S|
| **LLM** | 2 لكل قطعة | جودة الكيان الأعلى |

جميع الادوات تستخدم

- **DuckDB** للخزين الموحد (vectors + رسم بياني في ملف واحد
- **BM25 + بحث بيرت هجين** من خلال الإنصهار RRF
- **أولاما** من أجل التركيب وتصنيف حزمة إختيارية (تكلفة API صفرة)

**السلسلة Navigation:**

- [الجزء 1: أساسيات GraphRAG](/blog/graphrag-knowledge-graphs-for-rag)
- **جزء 2: GraphRAG الأقل قابلة للحياة** (هذا المقال)

> **الرمز:** [الأكثر وضوحا.GraphRag](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.GraphRag) على GitHub

[TOC]

## نظرة عامة على العمارة

```mermaid
flowchart LR
    subgraph Indexing
        MD[Markdown Files] --> CH[Chunker]
        CH --> EMB[BERT Embeddings]
        CH --> EXT[Entity Extractor]
        EXT --> |heuristics + links| ENT[Entities]
        ENT --> REL[Relationships]
        REL --> COM[Communities]
    end
    
    subgraph Storage
        EMB --> DB[(DuckDB)]
        ENT --> DB
        REL --> DB
        COM --> DB
    end
    
    subgraph Query
        Q[Query] --> CLASS{Classify}
        CLASS --> |local| HS[Hybrid Search]
        CLASS --> |global| CS[Community Search]
        CLASS --> |drift| BOTH[Both + Synthesis]
        HS --> LLM[Ollama]
        CS --> LLM
        BOTH --> LLM
    end
    
    DB --> HS
    DB --> CS
    
    style MD stroke:#22c55e,stroke-width:2px
    style DB stroke:#3b82f6,stroke-width:2px
    style LLM stroke:#a855f7,stroke-width:2px
```

## لماذا DuckDB?

مايكروسوفت's GraphRAG يستخدم تخزيناً منفصلاً للميكتورات M SK1LanceDB), الكائنات ♫(ParquetMSC4 والعلاقات |(المزيد Parquet | ). | DuckDB يبسط هذا |

- واحد `.duckdb` ملف لكل شيء
- البحث عن вектор HNSW الأصلي من خلال غضون VSS
- SQL لكلا البحث الفيكتوري والرسم البياني
- تعقيد تنفيذي صفر

**DuckDB ليس قاعدة بيانات رسمية - وأن ' هو النقطة** هذا ليس ' "Neo" 4 "J" . الترانزيون سطحي "M SK3" "SQL" "MSSK4" مبني "MSC5" و متعمد "Mスク6" هذه القيود تجعل النظام قابل للحل والتكلفة المنخفضة

## تخطيط المخزن

يستخدم الرسم البياني **إنضمام الجداول للمستوطن** - يمكننا أن نسأل " أي قطعة تشير إلى كيان XM SK2 مباشرة:

```mermaid
erDiagram
    documents ||--o{ chunks : contains
    chunks ||--o{ entity_mentions : has
    chunks ||--o{ relationship_mentions : has
    entities ||--o{ entity_mentions : mentioned_in
    entities ||--o{ relationships : source
    entities ||--o{ relationships : target
    relationships ||--o{ relationship_mentions : mentioned_in
    communities ||--o{ community_members : contains
    entities ||--o{ community_members : belongs_to
    
    chunks {
        varchar id PK
        varchar document_id FK
        text text
        float[] embedding
    }
    
    entities {
        varchar id PK
        varchar name
        varchar type
        int mention_count
    }
    
    entity_mentions {
        varchar entity_id FK
        varchar chunk_id FK
    }
```

قرار التصميم الرئيسي: **لا `VARCHAR[]` من provenance**. Join tables (`entity_mentions`, `relationship_mentions`) تمكن الاستبيانات الفعالة مثل " تحصل على جميع الأجزاء التي تشير إلى "دوكر"

### البحث فيكتوري: حصلت على HNSW

مؤشر DuckDB's HNSW ينشط فقط مع `array_cosine_distance` + `ORDER BY` + `LIMIT`:

```csharp
// GraphRagDb.cs - SearchChunksAsync
cmd.CommandText = $"""
    SELECT id, document_id, text, chunk_index, 
           array_cosine_distance(embedding, $1::FLOAT[{_dim}]) as distance
    FROM chunks 
    WHERE embedding IS NOT NULL
    ORDER BY distance
    LIMIT $2
    """;
// Convert distance to similarity: 1.0f - distance
```

**إستخدام `array_cosine_similarity` لن يستخدم المؤشر** - لقد فاز ’ لم ي trigger HNSW index. On nonM SK3trivial corporaMSC4 this turns a ♫~5ms indexed query into a full table scan ♫

## إستخراج Entity

هذا هو المكان الذي نبتعد عنه من مقاربة مايكروسوفت **LLM-per-ممرات استخراج القمامة** تستخدم في مرجع مايكروسوفت' أنابيب GraphRAG **استخراج إحصائي مبني على IDF-**. الهدف هو *مستقرة, كتلة- إشارات نسبية* التي لا تحتاج لـ LLM لإنتاج ــ . . هذا يتقاسم مع بعض ال recall من أجل التفاضل والتكامل ــ, . قابلة للتحقق ـــ , . وتكلفة متوقعة . . - . خيار مصمم للمؤسسات التقنية .

```mermaid
flowchart TB
    subgraph "Phase 1: Signal Collection"
        TEXT[All Chunks] --> IDF[Compute IDF Scores]
        TEXT --> STRUCT[Structural Signals]
        STRUCT --> HEAD[Headings]
        STRUCT --> CODE[Inline Code]
        STRUCT --> LINKS[Links]
        IDF --> RARE[High-IDF = Rare Terms]
        RARE --> CAND[Candidates]
        HEAD --> CAND
        CODE --> CAND
        LINKS --> |explicit rels| LINKREL[Link Relationships]
    end
    
    subgraph "Phase 2: Dedup"
        CAND --> EMBED[BERT Embeddings]
        EMBED --> SIM[Similarity > 0.85]
        SIM --> MERGE[Merge Duplicates]
    end
    
    subgraph "Phase 3: Classify"
        MERGE --> LLM{LLM Available?}
        LLM --> |yes| BATCH[Single Batch Call]
        LLM --> |no| HEUR[Heuristic Types]
    end
    
    style IDF stroke:#f59e0b,stroke-width:2px
    style BATCH stroke:#a855f7,stroke-width:2px
```

### لماذا IDF, ليست قائمة مشفرة

المقاربة البسيطة هي برمجة صلبة `HashSet<string> KnownTech = { "Docker", "Kubernetes", ... }`. هذا يقطع ل:

- التكنولوجيات الجديدة (you'd need to update the listM SK2
- Domain-مصطلحات محددة M SK1كتاب مختلف = الكيانات المختلفة)
- الإختلافات

**IDF (تردد العكس للوثائق)** يحل هذا إحصائياً

$$\textM SK1IDF}(tMSC3 = | | \log |\frac |

أين:

- $N$ = مجموع القطع
- Documents containing term $t$

IDF عالي = **كلمة نادرة** = محتمل أن كيان . "Docker" يظهر في 5 من 100 الجسيمات لديه IDF أعلى من \"the \ " يظهر فى \100 من الـ 100.

لمعرفة المزيد عن TF-IDF و BM25, انظروا إلى بريدي على [البحث الهجين مع BM25](/blog/rag-hybrid-search-and-indexing).

### إشارات هيكلية

تخبرنا هيكلة العلامات التجارية ما هو مهم

- **الرؤوس** (`## Docker Setup`)  → كيان
- **البرمجة داخلية** (`` `docker-compose` ``)  → كيان
- **الروابط** (`[Docker](https://docker.com)`) → كيان + علاقة

```csharp
// EntityExtractor.cs - structural signal extraction
private void ExtractStructuralEntities(string chunk, string chunkId)
{
    // Headings: ## Docker Compose Setup → "Docker Compose Setup"
    foreach (Match m in Regex.Matches(chunk, @"^#{1,3}\s+(.+)$", RegexOptions.Multiline))
    {
        var heading = m.Groups[1].Value.Trim();
        AddCandidate(heading, chunkId, weight: 2.0); // Higher weight
    }
    
    // Inline code: `docker-compose` → "docker-compose"
    foreach (Match m in Regex.Matches(chunk, @"`([^`]+)`"))
    {
        AddCandidate(m.Groups[1].Value, chunkId, weight: 1.5);
    }
}
```

### استخراج الروابط (عالة-ملاقات الجودةM SK2

الروابط المخصصة للتسويق **بوضوح** العلاقات التي لا تحتاج إلى استنتاج LLM

```csharp
// EntityExtractor.cs - ExtractLinks  
foreach (Match m in Regex.Matches(chunk, @"\[([^\]]+)\]\((/blog/[^)]+)\)"))
{
    var linkText = m.Groups[1].Value;  // "semantic search"
    var slug = m.Groups[2].Value;       // "/blog/semantic-search-with-qdrant"
    yield return new Relationship(linkText, $"blog:{slug}", "references", chunkId);
}
```

### تفكيك عن طريق مداخلات بيرت

أسماء الوحدات مثل "Docker Compose", "dockerM SK3composeMSC4 و "DokerCompose" ينبغي أن تدمجMST7 نحن نستخدم **مداخلات بيرت** لإكتشاف التشابه الدلالي:

```csharp
// EntityExtractor.cs - DeduplicateAsync
var embeddings = await _embedder.EmbedBatchAsync(candidates.Select(c => c.Name), ct);

for (int i = 0; i < candidates.Count; i++)
{
    for (int j = i + 1; j < candidates.Count; j++)
    {
        var similarity = CosineSimilarity(embeddings[i], embeddings[j]);
        if (similarity > 0.85)
        {
            // Merge into canonical entity (keep higher mention count)
            canonical.MentionCount += duplicate.MentionCount;
            canonical.ChunkIds.UnionWith(duplicate.ChunkIds);
        }
    }
}
```

هذه الخطوة هي O(n²) ضمن مجموعة من المرشحين المحدودةM SK2 لكن أعداد المرشحون محدودة من خلال التصفية IDF و الإشارات الهيكلية - ليس حجم الجسم . لمعرفة المزيد عن تداخلات BERTMSC5 consulte [البحث الدلالي مع ONNX و BERT](/blog/semantic-search-with-onnx-and-qdrant).

## اشكال استخراج

ال CLI يدعم ثلاثة طرق استخراج من خلال `--extraction-mode`:

### الطريقة الهيuristic (Default)

```bash
dotnet run --project Mostlylucid.GraphRag -- index ./Markdown --extraction-mode heuristic
```

يستخدم IDF + إشارات هيكلية للكشف عن الكائنات, مع التصنيف الخيالي لحزمة LLMM SK2 **صفر لكل مكالمات -** - فقط ~1 إتصال لكل 50 كيانات لتصنيف الأنواع.

### الطريقة الهجينة (توصيل)

```bash
dotnet run --project Mostlylucid.GraphRag -- index ./Markdown --extraction-mode hybrid
```

أفضل من كلا العالمين:

1. **إكتشاف هدري**: IDF + إشارات هيكلية تبحث عن كائنات متقدمة (منterministic)
2. **تحسين LLM**: إتصال واحد لكل *وثيقة* ي Valides Entities and extracts semantic relationships

```mermaid
flowchart LR
    subgraph "Per Document"
        CHUNKS[Document Chunks] --> HEUR[Heuristic Extraction]
        HEUR --> CAND[30 Candidates]
        CAND --> LLM[Single LLM Call]
        LLM --> ENT[Validated Entities]
        LLM --> REL[Semantic Relationships]
    end
    
    style HEUR stroke:#22c55e,stroke-width:2px
    style LLM stroke:#a855f7,stroke-width:2px
```

في 5 الوثائق مع 62 قطع ,, režim الهجين يجعل **5 مكالمات LLM** (vs 124 لنظام LLM الكامل). تحصل على

- تغطية الكائنات القطعية من علم الرعاش
- LLM-استخراج العلاقة ال qualitéية M SK1سيمانتي, ليس فقط كـ
- الوصفات و الأنواع التي تم اعتبارها

### طريقة LLM (Microsoft-StyleM SK2

```bash
dotnet run --project Mostlylucid.GraphRag -- index ./Markdown --extraction-mode llm
```

النهج الكامل لMicrosoft GraphRAG: **2 مكالمات LLM لكل قطعة** (استخراج الكائنات +استخلاص العلاقات). أغلى الثمنM SK3 لكن أعلى جودة للنص الغير منظمMSC4

### متى تستخدم كل واحدة

| الطريقة | إتصالات الـ LLM | الأفضل ل|
|------|-----------|----------|
| **الهيوريستيكس** MSC0 MSC1 لكل SMC2 كيان | إحصاء سريعMSc4 جيدMScs5 تخفيض منظم msc6
| **الهجين** | 1 لكل سند | توازن الغطاء والكفاءة SSK3
| **LLM** | 2 لكل قطعة | نص غير منظم, جودة عالية |

للوثائق التقنية, تبدأ مع **المزيج** mode. إنه يعطيك علاقات سيمانسية دون مقابلة **تأملي** للسرعة النقية, أو **الـ Llm** للنص الروائي.

## البحث الهجين: BM25 M SK2 BERT

البحث الهجين يجمع مقاربتين متكاملتين:

**كثافة (BERT):** يفهم المعنى. "وعاء الدوكرM SK2 تطابق "containerizationMSC4
**المعزوفة (BM25):** يتطابق المصطلحات الدقيقة. "HNSWM SK2 تتطابق فقط "HN SWMSC4

```mermaid
flowchart LR
    Q[Query] --> BERT[BERT Embedding]
    Q --> BM25[BM25 Tokenize]
    
    BERT --> DENSE[Dense Search<br/>HNSW Index]
    BM25 --> SPARSE[Sparse Search<br/>TF-IDF Scoring]
    
    DENSE --> RRF[RRF Fusion]
    SPARSE --> RRF
    
    RRF --> TOP[Top K Results]
    TOP --> ENR[Enrich with<br/>Entities + Rels]
    
    style RRF stroke:#f59e0b,stroke-width:2px
```

### ما هو BM25?

BM25 (أفضل تطابق 25) يسجل الدرجات للأدوات اعتماداً على فرط مصطلح البحثM SK3 المعادلةMSC4

$$\textM SK1score}(D+,Q+) = \\sum_{iM SK1n} \textMSC4IDFMNK5qMRK6i+) ==\cdot \fracMMK10fMEK11q=_i&, DMST14 \\cdo MSSK16kMsek17 ♪+ |1)}{f~(q+_ |I&, D\) ♫+ k | _1 ,\ cdot \ (1 . .- b . + b

المعتقدات الرئيسية:

- **إسم "DF"**: الكلمات النادرة تُهم أكثر ("HNSW"
- **تضخيم TF**: كلمة تظهر 10x ليست 't 10x أكثر أهمية من S1x
- **قياس طول**: الوثائق الطويلة لا تحصل على ميزة غير عادلة

للتطبيق الكامل بـ BM25ـ , , см. [البحث الهجين والمؤشر](/blog/rag-hybrid-search-and-indexing).

### التخليق المتقابل للرتبة (RRF)

RRF يدمج التصنيفات من مختلف أنظمة البحث. كل مكان في المرتبة يحصل على النتيجة:

$$\textM SK1RRF}(dMSC3 = \\summa_{r \in RM SK2 \frac{1}{k M+ rMSC6dMST7

حيث $k$ (معتاداً |60) prevents overweighting the top result **كلاهما** تحسن التصنيفات

```csharp
// SearchService.cs - RRF fusion
const int k = 60;

foreach (var (chunk, rank) in denseResults.Select((c, i) => (c, i)))
    scores[chunk.Id] = 1.0 / (k + rank + 1);

foreach (var (chunk, rank) in sparseResults.Select((c, i) => (c, i)))
{
    var rrfScore = 1.0 / (k + rank + 1);
    if (scores.TryGetValue(chunk.Id, out var existing))
        scores[chunk.Id] = existing + rrfScore;  // Boost for appearing in both!
    else
        scores[chunk.Id] = rrfScore;
}
```

مثال: سند يصنف #1 في الكثافة و #3 في الضباب

- الكثافة
- المعزوفة: $1/(60+3) |= | 0.0159$
- **المركبة: 0.0323** ( أعلى من أي واحد

## اشكال الاسئلة

```mermaid
flowchart TB
    Q[Query] --> CLASS[Classify Query]
    
    CLASS --> |"How do I use X?"| LOCAL[Local Search]
    CLASS --> |"What are the themes?"| GLOBAL[Global Search]  
    CLASS --> |"How does X relate to Y?"| DRIFT[DRIFT Search]
    
    LOCAL --> HS[Hybrid Search] --> CTX1[Chunk + Entity Context]
    GLOBAL --> CS[Community Summaries] --> MAP[Map-Reduce]
    DRIFT --> BOTH[Local + Communities] --> SYN[Synthesize]
    
    CTX1 --> LLM[LLM Answer]
    MAP --> LLM
    SYN --> LLM
    
    style LOCAL stroke:#22c55e,stroke-width:2px
    style GLOBAL stroke:#3b82f6,stroke-width:2px
    style DRIFT stroke:#a855f7,stroke-width:2px
```

### تصنيف الأسئلة

```csharp
// QueryEngine.cs
private static QueryMode ClassifyQuery(string query)
{
    var q = query.ToLowerInvariant();
    if (q.Contains("main theme") || q.Contains("summarize") || q.Contains("overview"))
        return QueryMode.Global;
    if (q.Contains("relate") || q.Contains("connect") || q.Contains("compare"))
        return QueryMode.Drift;
    return QueryMode.Local;
}
```

هذا التصنيف بسيط بشكل قصدي - وسهل استبداله مع نموذج لهدف صغير لاحقاً . إذا لم تتطابق كيانات الـ , فإن النظام يتحلل بوضوح إلى إستخراج هجين نقي | .

## إستخدام CLI

### التصنيف

```bash
# Heuristic mode (default) - fast, no per-chunk LLM
dotnet run --project Mostlylucid.GraphRag -- index ./test-markdown

# LLM mode - Microsoft-style classification
dotnet run --project Mostlylucid.GraphRag -- index ./test-markdown --extraction-mode llm
```

```text
GraphRAG Indexer
  Source: test-markdown
  Database: graphrag.duckdb
  Model: llama3.2:3b
  Extraction: Heuristic (IDF + signals)

Initializing...
Indexing docker-development-deep-dive.md: 0%
Indexing docker-swarm-cluster-guide.md: 40%
Indexing dockercomposedevdeps.md: 80%
Indexing complete: 100%
Classifying entities...: 0%
Extracted 168 entities, 315 rels (4 LLM calls): 100%
Found 10 communities: 100%
Summarizing c_0_2 (12 entities): 20%
Summarizing c_0_8 (4 entities): 80%

────────────────── Indexing Complete ───────────────────
┌───────────────┬───────┐
│ Metric        │ Count │
├───────────────┼───────┤
│ Documents     │ 5     │
│ Chunks        │ 62    │
│ Entities      │ 168   │
│ Relationships │ 312   │
│ Communities   │ 10    │
└───────────────┴───────┘
```

### تسأل

```bash
dotnet run --project Mostlylucid.GraphRag -- query "How do I use Docker Compose?"
```

```text
──────────────────── Local Search ────────────────────

Query: How do I use Docker Compose?

╭─Answer────────────────────────────────────────────────╮
│ To run the services defined in the                    │
│ devdeps-docker-compose.yml file, you need to run the  │
│ following command in the same directory as the file:  │
│                                                       │
│ docker compose -f .\devdeps-docker-compose.yml up -d  │
│                                                       │
│ This command will start the containers in detached    │
│ mode.                                                 │
╰───────────────────────────────────────────────────────╯

Related Entities: Docker, container, services, image

Sources: 5 chunks (top score: 0.016)
```

### الإحصائيات

```bash
dotnet run --project Mostlylucid.GraphRag -- stats
```

```text
─────────────── GraphRAG Database Stats ────────────────
┌───────────────┬───────┐
│ Metric        │ Count │
├───────────────┼───────┤
│ Documents     │     5 │
│ Chunks        │    62 │
│ Entities      │   168 │
│ Relationships │   312 │
│ Communities   │    10 │
└───────────────┴───────┘

Database size: 7.76 MB
```

## مقارنة التكلفة

من أجل 100 المدونات (~500 المقطوعات, ~100 الوثائقM SK4

| عمليات | MSFT GraphRAG
|-----------|---------------|-----------|--------|-----|
| إستخراج الكائنات | 1,000 الإتصالات | | | |0 |
| تحسن الوثائق | - | | | \- ♪| |100 | إتصالات
| التصنيف | بما فيه | ~4 بستة S| | | - | | |~4 | بستة
| إحصائيات المجتمع | ~20 | | | ♫ |~20 ♫
| **كل مكالمات LLM** | ~1,020 | ~24 | ~120 | ~1,024 |
| **جودة العلاقات** | الدلالية | المصاحبة - الحدوث | المفهوم الدلالي | المفاهيم الدلالتي |
| **التكلفة (gpt-4oM SK2mini )** | ~$5-10 | ~$0.15 | ~$0.75 | ~$5-10 |
| **التكلفة (Ollama)** | N/A

**المزيج هو النقطة الحلوة** للكثير من المحتويات التقنية : تحصل على العلاقات الدلالية ( ليس فقط كـ . .

> طلب دقيق-of-estimate ofmagnitudeM SK2التكلفة الدقيقة تعتمد على حجم القطعة والشكل الفوري

## المقايضات

| وجهة نظر | هدرية MSSK2 هجين | LLM | | | MSFT GraphRAG ||
|--------|-----------|--------|-----|---------------|
| الكشف عن الكائنات | الهيكل IDF | + | الهيكل | | IDF
| العلاقات | ثنائي الـ- المصادفة | | | LLM |- | غير مصادمة | | | ثنايي الـ - | المصادمة
| إتصالات الـ LLM
| جودة العلاقات | منخفضة | عالية | من basse | عالية
| يعمل خارج نطاق الإنترنت | | | نعم || | أجل | МSK3 | أولاما | ماسك4 | الـ | |نعم | الماسك6 | اولاما ٬ ماسك7 | ماسك8 | API مطلوب |
| الأفضل لM SK1 السرعة-critical | **المُوصيل** | موصل قديم | نص غير منظم |

من الناحية النظرية , هذا هو نفس خط الأنابيب [DocSummarizer](/blog/docsummarizer-tool): بناء الهيكل أولا, ثم ترك LLM يشرحها

> **أين ينكسر هذا؟** النص الخيالي أو القصصي بدون علامة هيكلية. علاقات غير واضحة بدون إشارة لفظية . أسماء كيانات غامضة جداً التي تتطلب معرفة عالمية لتفكيك التفاوت. في هذه الحالاتM SK3 استخدام نظام LLM أو مايكروسوفت

## الرمز

التنفيذ هو الحد الأدنى - ~2,000 خطوط على طول هذه الملفات:

```
Mostlylucid.GraphRag/
├── Storage/GraphRagDb.cs              # DuckDB with HNSW + provenance
├── Services/EmbeddingService.cs       # ONNX BERT wrapper
├── Services/OllamaClient.cs           # LLM client
├── Extraction/
│   ├── IEntityExtractor.cs            # Extractor interface
│   ├── EntityExtractor.cs             # Heuristic mode
│   ├── HybridEntityExtractor.cs       # Hybrid mode (recommended)
│   └── LlmEntityExtractor.cs          # Full LLM mode
├── Search/SearchService.cs            # BM25 + BERT hybrid
├── Graph/CommunityDetector.cs         # Leiden + summarization
├── Query/QueryEngine.cs               # Local/Global/DRIFT
├── Indexing/MarkdownIndexer.cs        # Chunking
├── GraphRagPipeline.cs                # Orchestration
├── Models.cs                          # Shared types + ExtractionMode enum
└── Program.cs                         # CLI
```

**المصدر:** [`Mostlylucid.GraphRag/`](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.GraphRag)

## الملاحظات المترابطة

- [الجزء 1: أساسيات GraphRAG](/blog/graphrag-knowledge-graphs-for-rag) - لماذا تحسن الرسوم البيانية للمعرفة RAG
- [البحث الهجين مع BM25](/blog/rag-hybrid-search-and-indexing) - الغوص العميق في BM25 درجات ومؤشرات
- [البحث الدلالي مع ONNX و BERT](/blog/semantic-search-with-onnx-and-qdrant) - مداخلات بيرت في .NET
- [أداة DocSummarizer](/blog/docsummarizer-tool) - أداة تلخيص مستنداتي التي تتشارك البرمجة مع هذا

## الموارد الخارجية

- [توسع "DuckDB VSS"](https://duckdb.org/docs/extensions/vss.html) - بحث فيكتور HNSW
- [وثيقة خوارزمية ليدن](https://arxiv.org/pdf/1810.08473.pdf) - الكشف المجتمعي
- [ورق RRF](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf) - توصيل الرتبة المتقابلة