# लागू करने के लिए RAG: Hyrrod खोज तथा स्वचालित निर्देशिकािंग

<datetime class="hidden">2025-11-22T12:00</datetime>

<!-- category -- ASP.NET, Semantic Search, ONNX, Qdrant, Machine Learning, Vector Search, RAG, AI-Article -->
# परिचय

**RAG वस्तुओं का सबसे बड़ा भाग:** यह पार्ट ५ - निर्माण पैटर्न है:

- [भाग 1: RAG उद्‌गम और मूलतत्त्ववाद](/blog/rag-primer) - क्या बना रहे हैं, क्यों वे बात कर रहे हैं
- [भाग 2: RAGCACT और आंतरिक](/blog/rag-architecture) - शैफिंग, टोकन, सदिश डाटाबेस
- [अभ्यास में भाग 3: RAG](/blog/rag-practical-applications) - पूर्ण RAG सिस्टम बनाना
- [पार्ट ४डी: एनएनएक्स व क्यूड कार्यान्वयन पर](/blog/semantic-search-with-onnx-and-qdrant) - सीपीयूीय खोज आधार
- [भाग ४ख: कार्य में सेप्टिक खोज](/blog/semantic-search-in-action) - प्रकार का हेड, ओपन- पीजीपी खोज, और यूआई अवयव
- **पार्ट 5: Hybd खोज स्वचलित किया जा रहा है** ( इस लेख में दिखाया गया है) - उत्पादों का संयोजन
- [पार्ट 6: ग्राफआरईजी](/blog/graphrag-knowledge-graphs-for-rag) - ज्ञान ग्राफ कोेपी- लेवल्स के लिए

में [पार्ट 4a](/blog/semantic-search-with-onnx-and-qdrant), हम आधार बनाया: एनएनएक्स स्कैनिंग और प्रवरेज भंडारण पर. [पार्ट 4ख](/blog/semantic-search-in-action), हम खोज यूआई और startup खोज कार्यान्वयन कवर. अब हम इसे के साथ तैयार कर देंगे के साथ तैयार **स्वचालित अनुक्रमणिका** फ़ाइलysysystacher के द्वारा (कम से कम) वस्तुओं को अपडेट करता है.

[TOC]

# संपूर्ण संसार का सर्वोत्तम खोज:

SATANitic खोज शक्तिशाली है लेकिन पूर्ण पाठ खोज अभी भी सटीक वाक्यांशों और तकनीकी शब्दों में डिग्री से कहीं अधिक है. **इसका हल?** दोनों का उपयोग करें.

**क्यों?** अलग - अलग चरणों में अलग - अलग ताकत होती है:

- **एसक्यूएल फुल- पाठ** ([यहाँ खिसकाएँ](/blog/textsearchingpt1): सटीक मिलान, तकनीकी शर्तों, बूलियन ऑपरेटर्स
- **सेमी सदिश खोजQuery**: अर्थ, संदर्भ,ynynyys, सामान्य रूप से संबंधित सामग्री

## उल्टा (आरआरएफ)

हम उपयोग **उल्टा वर्ग Fusance. kgm** बहुत से खोज स्रोत से परिणाम मिलाने के लिए:

```mermaid
flowchart TB
    A[User Query: 'docker containers'] --> B[PostgreSQL Full-Text Search]
    A --> C[Semantic Vector Search]

    B --> D["Results:<br/>1. 'Docker Basics' (rank 1)<br/>2. 'Containerizing Apps' (rank 2)<br/>3. 'Docker Compose' (rank 3)"]
    C --> E["Results:<br/>1. 'Containerizing Apps' (rank 1)<br/>2. 'Kubernetes Guide' (rank 2)<br/>3. 'Docker Basics' (rank 3)"]

    D --> F[RRF Algorithm]
    E --> F

    F --> G["Combined Results:<br/>1. 'Containerizing Apps'<br/>   (1/61 + 1/62 = 0.0328)<br/>2. 'Docker Basics'<br/>   (1/61 + 1/63 = 0.0322)<br/>3. 'Docker Compose'<br/>   (1/63 = 0.0159)"]

    style A stroke:#10b981,stroke-width:2px
    style B stroke:#3b82f6,stroke-width:2px
    style C stroke:#6366f1,stroke-width:2px
    style D stroke:#3b82f6,stroke-width:2px
    style E stroke:#6366f1,stroke-width:2px
    style F stroke:#ec4899,stroke-width:4px
    style G stroke:#8b5cf6,stroke-width:2px
```

**आरआरएफ सूत्रः** `score = Σ(1 / (k + rank))`

- `k` = 60 (ऊपर के वर्ग को रोकने के लिए भारी)
- `rank` = कि खोज विधि के परिणाम में स्थिति
- परिणाम **दोनों** प्रत्येक जोड़े से कई स्रोत प्राप्त करें

**क्यों RRF काम करता है:**

- **डी- बस्टर- कमांड**: दोनों स्रोतों में समान परिणाम
- **उचितता**: कोई खोज विधि सही नहीं
- **सिमुलेटिकता**: कोई जटिल डायटिंग की ज़रूरत नहीं

## कार्यान्वयन

```csharp
public class HybridSearchService : IHybridSearchService
{
    private readonly ISemanticSearchService _semanticSearchService;
    private const int RrfConstant = 60;

    public async Task<List<SearchResult>> SearchAsync(
        string query,
        string language = "en",
        int limit = 10,
        CancellationToken cancellationToken = default)
    {
        // Execute both searches in parallel
        var semanticResults = await _semanticSearchService.SearchAsync(
            query, limit * 2, cancellationToken);

        // Filter by language and apply RRF
        var filteredResults = semanticResults
            .Where(r => r.Language == language)
            .ToList();

        return ApplyReciprocalRankFusion(filteredResults)
            .Take(limit)
            .ToList();
    }

    private List<SearchResult> ApplyReciprocalRankFusion(List<SearchResult> results)
    {
        var rrfScores = new Dictionary<string, RrfScore>();

        for (int i = 0; i < results.Count; i++)
        {
            var result = results[i];
            var key = $"{result.Slug}_{result.Language}";

            if (!rrfScores.ContainsKey(key))
                rrfScores[key] = new RrfScore { Result = result };

            // RRF formula: 1 / (k + rank)
            rrfScores[key].Score += 1.0 / (RrfConstant + i + 1);
        }

        return rrfScores.Values
            .OrderByDescending(x => x.Score)
            .Select(x => x.Result)
            .ToList();
    }
}
```

> **टिप्पणीः** यह एडिस्किक खोज सिर्फ दिखाई देती है. उत्पादन में, एसक्यूएल पूर्ण पाठ खोज को समानांतर करता है तथा उन परिणामों को RRF गणना में शामिल करता है.

## संयोजन

यदि आप पहले से ही संपूर्ण पाठ खोज को लागू कर चुके हैं (संपार पाठ खोज)[जैसे छा रहा है,](/blog/textsearchingpt1), जोड़ते हुए अतिरिक्त खोज सीधा है:

```csharp
// Program.cs
services.AddSemanticSearch(configuration);
services.AddSingleton<IHybridSearchService, HybridSearchService>();
```

```csharp
[HttpGet("search/hybrid")]
public async Task<IActionResult> HybridSearch(string query, string language = "en")
{
    var results = await _hybridSearchService.SearchAsync(query, language);
    return PartialView("_SearchResults", results);
}
```

# फ़ाइल सिस्टम पहरेदार के साथ स्वचालित निर्देशिका बनाना

सबसे शक्तिशाली विशेषता: **स्वचालित अनुक्रमणिका**ब्लॉग पोस्ट सहेजें, यह तत्काल खोज योग्य है - कोई हस्तचालित हस्तक्षेप नहीं है.

## यह कैसे कार्य करता है

```mermaid
flowchart TB
    A[Save Markdown File] --> B[FileSystemWatcher Detects Change]
    B --> C{File in Main Directory?}
    C -->|Yes| D[Save to Database]
    C -->|No| E[Save to Database Only]
    D --> F[Create BlogPostDocument]
    F --> G[Generate Embedding via ONNX]
    G --> H[Store in Qdrant]
    H --> I[Post Searchable Immediately]

    style A stroke:#10b981,stroke-width:2px
    style B stroke:#f59e0b,stroke-width:2px
    style C stroke:#ec4899,stroke-width:3px
    style D stroke:#3b82f6,stroke-width:2px
    style E stroke:#6b7280,stroke-width:2px
    style F stroke:#8b5cf6,stroke-width:2px
    style G stroke:#6366f1,stroke-width:3px
    style H stroke:#ef4444,stroke-width:2px
    style I stroke:#10b981,stroke-width:2px
```

**कुंजी डिज़ाइन निर्णय:** सिर्फ निर्देशिका फ़ाइल इंच **मुख्य मार्क डिरेक्ट्री**सब्सक्राइब न करें (h)`translated/`, `drafts/`, `comments/`. यह खोज इंडेक्स साफ रखता है.

## फ़ाइल पहरेदार संवाद

ब्लॉग पहले ही एक है `MarkdownDirectoryWatcherService`.. हम इसे ट्रिगर करने के लिए स्विच करें:

```csharp
// In MarkdownDirectoryWatcherService.cs
private async Task OnChangedAsync(WaitForChangedResult e)
{
    if (e.Name == null) return;

    await retryPolicy.ExecuteAsync(async () =>
    {
        var savedModel = await blogService.SavePost(slug, language, markdown);

        // Index ONLY if file is in main directory (no path separators in name)
        if (!e.Name.Contains(Path.DirectorySeparatorChar) &&
            !e.Name.Contains(Path.AltDirectorySeparatorChar))
        {
            await IndexPostForSemanticSearchAsync(scope, savedModel, language);
        }
    });
}

private async Task IndexPostForSemanticSearchAsync(
    IServiceScope scope,
    BlogPostDto post,
    string language)
{
    var semanticSearchService = scope.ServiceProvider.GetService<ISemanticSearchService>();
    if (semanticSearchService == null) return; // Not configured

    var document = new BlogPostDocument
    {
        Id = $"{post.Slug}_{language}",
        Slug = post.Slug,
        Title = post.Title,
        Content = post.PlainTextContent,
        Language = language,
        Categories = post.Categories?.ToList() ?? new List<string>(),
        PublishedDate = post.PublishedDate
    };

    await semanticSearchService.IndexPostAsync(document);
    _logger.LogInformation("Indexed {Slug} ({Language}) in semantic search", post.Slug, language);
}
```

## मिटाना संवादों को अनदेखा करें

जब पोस्ट मिटाया जाता है, इसे मिटाएँ

```csharp
private async Task OnDeletedAsync(WaitForChangedResult e)
{
    await blogService.Delete(slug, language);

    // Delete from semantic search ONLY if file was in main directory
    if (!e.Name.Contains(Path.DirectorySeparatorChar) &&
        !e.Name.Contains(Path.AltDirectorySeparatorChar))
    {
        var semanticSearchService = scope.ServiceProvider.GetService<ISemanticSearchService>();
        await semanticSearchService?.DeletePostAsync(slug, language);
    }
}
```

# आरंभिक इंडेक्सिंग के लिए पृष्ठभूमि सेवा

प्रारंभ में, एक पृष्ठभूमि सेवा इंडेक्स अभी तक क्यूवर में नहीं है:

```mermaid
flowchart TB
    A[Application Starts] --> B[Wait 10 seconds]
    B --> C[Initialize Semantic Search]
    C --> D{Model Exists?}
    D -->|No| E[Download from Hugging Face]
    D -->|Yes| F[Load ONNX Model]
    E --> F
    F --> G[Scan Main Markdown Directory]
    G --> H{For Each .md File}
    H --> I[Compute Content Hash]
    I --> J{Hash Changed?}
    J -->|Yes| K[Generate Embedding]
    J -->|No| L[Skip - Already Indexed]
    K --> M[Store in Qdrant]
    M --> H
    L --> H
    H -->|Done| N[Indexing Complete]

    style A stroke:#10b981,stroke-width:2px
    style C stroke:#6366f1,stroke-width:2px
    style E stroke:#f59e0b,stroke-width:2px
    style F stroke:#6366f1,stroke-width:3px
    style G stroke:#8b5cf6,stroke-width:2px
    style J stroke:#ec4899,stroke-width:3px
    style K stroke:#6366f1,stroke-width:2px
    style M stroke:#ef4444,stroke-width:2px
    style N stroke:#10b981,stroke-width:2px
```

```csharp
public class SemanticIndexingBackgroundService : BackgroundService
{
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // Wait for app to be ready
        await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);

        // Initialize (downloads model if needed)
        await _semanticSearchService.InitializeAsync(stoppingToken);

        // Get all posts from main directory only
        var markdownFiles = Directory.GetFiles(
            _markdownConfig.MarkdownPath,
            "*.md",
            SearchOption.TopDirectoryOnly);  // NOT subdirectories

        foreach (var file in markdownFiles)
        {
            var needsIndexing = await _semanticSearchService.NeedsReindexingAsync(
                slug, language, contentHash, stoppingToken);

            if (needsIndexing)
                await _semanticSearchService.IndexPostAsync(document, stoppingToken);
        }
    }
}
```

**यह सुनिश्चित करता है:**

1. **zy मॉडल लोड किया जा रहा है** - पहले उपयोग पर डाउनलोड, प्रारंभ में ब्लॉक नहीं
2. **INVEL निर्देशिका बनाना** - केवल नया/ बदलने वाले पोस्ट फिर से लिखा गया (वीआई सामग्री हैएओ)
3. **सिर्फ मुख्य निर्देशिका** - मसौदा और अनुवादित फ़ाइल निर्देशिका को दूषित नहीं करते

# हमने क्या बनाया है

भाग 4a, 4ख, और 5 के पार अब हमारे पास है:

- ✅ **सीपीयू- मित्रीय खोजQuery** - कोई जीपीयू आवश्यक नहीं
- ✅ **सम्बन्धित पोस्ट खोज** - एक ही तरह की सामग्री
- ✅ **स्वाभाविक भाषा खोज** - मतलब से ढूंढें, सिर्फ बीजशब्द नहीं
- ✅ **हाइब्रिड खोजQuery** - सर्वश्रेष्ठ इटेलिक + पूर्ण पाठ
- ✅ **स्वचालित इंडेक्सिंग** - शून्य तुल्यकालन सामग्री अद्यतन
- ✅ **स्व- होस्ट्ड** - आपका डाटा आपके सर्वर पर रहता है

**भविष्य में सुधार:**

- **श्रेणी खोज** - बूस्ट परिणाम विशिष्ट श्रेणी से
- **मल्टीिंग एम्बेडिंग** - भाषा विशेष मॉडल
- **खोज का एकीकरण खोलें** - ओपन- पीजीपी मिश्रण में ढूंढें (S)[एस., अमरीका](/blog/textsearchingpt3))

# कंटेनमेंट

यह RAG- शैली खोज का व्यावहारिक कार्यान्वयन पूरा करता है. [पार्ट 4a](/blog/semantic-search-with-onnx-and-qdrant) (पैंट) और [पार्ट 4ख](/blog/semantic-search-in-action) ( सर्च यूआई), आपके पास आपके लिए बुद्धिमान खोज जोड़ने के लिए आवश्यक सब कुछ है अपने .ERT अनुप्रयोग - सीपीयू पर पूरी तरह से चल रहा है, शून्य के अतिरिक्त लागत पर.

## लगातार सीखते रहें

- **[RAG भाग 1: उद्‌गम और मूलतत्त्ववाद](/blog/rag-primer)** - स्कैनिंग के पीछे सिद्धांत
- **[RAG पार्ट 2: magio और आंतरिक](/blog/rag-architecture)** - RAG सिस्टम में गहराई से आगे बढ़ें
- **[RAG पार्ट ३: व्यावहारिक अनुप्रयोग](/blog/rag-practical-applications)** - पूर्ण रेजी के साथ एकीकरण
- **[पार्ट ४डी: एनएनएक्स व क्यूड कार्यान्वयन पर](/blog/semantic-search-with-onnx-and-qdrant)** - आधार: स्कैनिंग और सदिश भंडारण
- **[भाग ४ख: कार्य में सेप्टिक खोज](/blog/semantic-search-in-action)** - टाइप हेड, ओपन- पीजीपी खोज, और यूआई
- **[एसक्यूएल के साथ पूर्ण पाठ खोज](/blog/textsearchingpt1)** - ग्रोन खोज का पूरा पाठ पक्ष

## संसाधन

### स्ट्रिगी व सदिश डाटाबेस

- [क्यूवर के साथ स्व-Hed सदिश डाटाबेस](/blog/self-hosted-vector-databases-qdrant) - Qdrovivent, Howinging, फिल्टर, और C# ग्राहक में गहराई से रोल
- [क्यूसेवर पिब्रिड खोजComment](https://qdrant.tech/documentation/concepts/hybrid-queries/) - क्यूवरेज का देशी समर्थन

### एचब्रिएड खोजQuery

- [उल्टा वर्ग Fusion कागज](https://plg.uwaterloo.ca/~gvcormac/cormacksigir09-rrf.pdf) - RRF एल्गोरिदम

### फ़ाइल तंत्र दर्शन

- [फ़ाइल तंत्र चेतावनी वर्ग](https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher) - .नेटटी दस्तावेज़
- [पृष्ठभूमि सेवा क्लास](https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.hosting.backgroundservice) - अज्ञात में होस्ट्ड सेवाओं.

### कोड पूरा करें

सभी कोड उपलब्ध हैं: [gdyb.com/sek/ allyptib](https://github.com/scottgal/mostlylucidweb)

- `Mostlylucid.SemanticSearch/` - कोरलिक खोज लाइब्रेरी
- `Mostlylucid/Blog/WatcherService/` - फ़ाइल गार्डियन इंडेक्सिंग के साथ