# अभ्यास में RAG: वास्तविक विश्वव्यापी अनुप्रयोग बनाना

में [पार्ट 1](/blog/rag-primer) और [पार्ट 2](/blog/rag-architecture) इस श्रृंखला के बारे में, हम RAG के उद्गम, बुनियादी और तकनीकी बनावट को कवर करते हैं _BARG क्या है _BAR_ आप समझ सकते हैं, यह क्यों होता है, और कैसे काम करता है _BAR_ अब यह समय है कि ज्ञान को अभ्यास में लाने के लिए _BAR_ यह आपको दिखाता है कि कैसे वास्तविक RRG व्यवस्थाएँ सी# के साथ काम करती हैं _BAR_

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

<!-- category -- AI, RAG, Machine Learning, Semantic Search, LLM, AI-Article -->
# परिचय

**श्रेणी नेविगेशन:** यह RAG श्रृंखला का भाग है:

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

आप भाग 1 और 2 नहीं पढ़ा है, तो मैं वहाँ से शुरू करने की सलाह देता हूँ:

- RAG क्या है और क्यों यह मामले (प्रयोग 1)
- कीवर्ड खोज से इतिहास
- RAGREART: इंडेक्सिंग, प्राप्ति, पीढ़ी (- पार्ट 2)
- आंतरिक आंतरिक: चिह्न, केवी कैश, संदर्भ विंडो ( पार्ट 2)
- RAG vs बढ़िया-चिंग तथा अन्य बहाव ( पार्ट 1)

इस लेख में आपको उन बुनियादी बातों की समझ दी गयी है और उन पर ध्यान दिया गया है **कार्यान्वयन, सुधार, और वास्तविक तंत्र पैटर्न**.

[TOC]

# इस ब्लॉग पर वास्तविक विश्वव्यापी रेजी अनुप्रयोग

मैंने इस ब्लॉग पर RG-C-C-C-R की कई सुविधाओं का निर्माण किया है. मैं आपको ठोस उदाहरण दिखाने के लिए।

## 1. संबंधित पोस्ट की व्याख्या

हर ब्लॉग पोस्ट को "क्लासिक पोस्ट" के प्रयोग से दिखा सकते हैं.

**यह कैसे काम करता है:**

1. जब प्रकाशित हो जाता है तो प्रत्येक ब्लॉग पोस्ट एम्बेड किया जाता है
2. एक पोस्ट देखने पर, हम क्यूडमेंट से इसकी व्यवस्था प्राप्त करते हैं
3. जोडीयॉं ढुॅंढे
4. प्रदर्शक जैसे "Relels"

**क्यों यह टैग से बेहतर है:**

- टैग को मैनुअल बिल्लीज़ की आवश्यकता है
- सेप्टिक खोज को सामान्य रूप से संबंधित पोस्टों को भी मिलते हैं बिना मिलते- जुलते टैग के
- "ककर लिखें" और "स्टोरर ब्राइट" पोस्ट से संबंधित हैं

**कोड:**

```csharp
public async Task<List<SearchResult>> GetRelatedPostsAsync(
    string currentPostSlug,
    string language,
    int limit = 5)
{
    // Get the current post's embedding
    var currentPost = await _vectorStore.GetByIdAsync(currentPostSlug);

    if (currentPost == null)
        return new List<SearchResult>();

    // Find similar posts
    var similarPosts = await _vectorStore.SearchAsync(
        currentPost.Embedding,
        limit: limit + 1,  // +1 because result includes the current post
        filter: new Filter
        {
            Must =
            {
                new Condition
                {
                    Field = "language",
                    Match = new Match { Keyword = language }
                }
            },
            MustNot =
            {
                new Condition
                {
                    Field = "slug",
                    Match = new Match { Keyword = currentPostSlug }
                }
            }
        }
    );

    return similarPosts.Take(limit).ToList();
}
```

## सेडिक ब्लॉग खोज

इस ब्लॉग पर सर्च बक्से RG- शैली खोज का उपयोग करता है (हालाँकि पीढ़ी भाग के बिना - यह सिर्फ वापसी है).

**उपयोक्ता अनुभव:**

- "Sfows" के लिए ढूंढें
- "डिक्सलमेंट" के लिए ढूंढें वेब, होस्टिंग, सीआई/सीडी
- सटीक ग्राफ मिलान के लिए कोई आवश्यकता नहीं

**कार्यान्वयन:** मैं सदिश डाटाबेस पर एक आगामी लेख में इस इमारत को कवर करूंगा.

## 3. "लेय्हेल जीने" लेखन सहायक

मैं नई ब्लॉग पोस्ट लिखने में मेरी मदद करने के लिए एक पूर्ण रेजी प्रणाली बना रहा हूँ।

**केस इस्तेमाल करें:** जब मैं "कुछ करने के लिए प्रमाणीकरण" के बारे में लिखना शुरू करता हूँ. NENT कोर, सिस्टम:

1. मेरे मौजूदा मसौदा को निर्मित करता है
2. सत्यापन के बारे में संबंधित सामग्री के लिए खोज
3. अनिवार्य कोड जो मैंने पहले प्रयोग किया है उसके लिए सलाह देता है
4. संबंधित पोस्ट से आंतरिक लिंक स्वचालित बनाएँ
5. अपने लेखन शैली के साथ सुसंगतता बनाए रखता है

**पूरा RAGER:**

```csharp
public async Task<WritingAssistanceResponse> GetSuggestionsAsync(
    string currentDraft,
    string topic)
{
    // 1. Embed the current draft
    var draftEmbedding = await _embeddingService.GenerateEmbeddingAsync(
        currentDraft
    );

    // 2. Retrieve related past content
    var relatedPosts = await _vectorStore.SearchAsync(
        draftEmbedding,
        limit: 5
    );

    // 3. Build context for LLM
    var prompt = BuildWritingAssistancePrompt(
        currentDraft,
        topic,
        relatedPosts
    );

    // 4. Generate suggestions using local LLM
    var suggestions = await _llmService.GenerateAsync(prompt);

    // 5. Extract and format citations
    var response = ExtractCitations(suggestions, relatedPosts);

    return response;
}
```

यह क्रिया - प्राप्ति (सेप्टिक खोज) + संदर्भ में RAG) + पीढ़ी (LM सुझाव) है ।

# आम चुनौतियाँ और समाधान

उत्पादन व्यवस्थाओं का निर्माण करना कम नहीं है. यहाँ मैं समस्याओं का सामना किया है और उन्हें हल करने के लिए कैसे किया है.

## चुनौती: कपड़ा बनाना

**समस्या:** आप दस्तावेज़ों को कैसे विभाजित करते हैं? बहुत छोटा = संदर्भ की क्षति. बहुत बड़ा = ज्यादा बड़ा जानकारी.

**समाधानः** दस्तावेज़ संरचना पर आधारित हाइब्रिड रीब्ड रीग्रेड.

```csharp
public class SmartChunker
{
    public List<Chunk> ChunkDocument(string markdown, string sourceId)
    {
        var chunks = new List<Chunk>();

        // Parse markdown into sections
        var document = Markdown.Parse(markdown);
        var sections = ExtractSections(document);

        foreach (var section in sections)
        {
            var wordCount = CountWords(section.Content);

            if (wordCount < MinChunkSize)
            {
                // Merge small sections
                MergeWithPrevious(chunks, section);
            }
            else if (wordCount > MaxChunkSize)
            {
                // Split large sections
                var subChunks = SplitSection(section);
                chunks.AddRange(subChunks);
            }
            else
            {
                // Just right
                chunks.Add(CreateChunk(section, sourceId));
            }
        }

        return chunks;
    }
}
```

**उत्तम अभ्यास:**

- दस्तावेज़ संरचना का आदर करें (headers, अनुच्छेद)
- दोहरा स्तर जोड़ें (50- 100 शब्द)
- कोड ब्लॉक बरकरार रखें (v)
- संदर्भ के लिए प्रत्येक भाग में भाग हेडर को शामिल करें

## चुनौती: कमज़ोर गुण

**समस्या:** ज़ेनेरिक एम्बेडिंग मॉडल डोमेन विशेष लक्षणों को नहीं पकड़ सकता है.

**समाधानः**

**विकल्प 1: बढ़िया- क्लिकिंग** (अनेड)

```python
# Using sentence-transformers in Python
from sentence_transformers import SentenceTransformer, InputExample, losses

model = SentenceTransformer('all-MiniLM-L6-v2')

# Create training examples from your domain
train_examples = [
    InputExample(texts=['Docker Compose', 'container orchestration'], label=0.9),
    InputExample(texts=['Entity Framework', 'ORM database'], label=0.9),
    InputExample(texts=['Docker', 'apple fruit'], label=0.1)
]

# Fine-tune
train_dataloader = DataLoader(train_examples, shuffle=True, batch_size=16)
train_loss = losses.CosineSimilarityLoss(model)
model.fit(train_objectives=[(train_dataloader, train_loss)], epochs=1)
```

**विकल्प 2: हाइब्रेड एम्बेडिंग** (द्बिनेट कई मॉडलों की तरह हैं)

```csharp
public async Task<float[]> GenerateHybridEmbeddingAsync(string text)
{
    var semantic = await _semanticModel.GenerateEmbeddingAsync(text);
    var keyword = await _keywordModel.GenerateEmbeddingAsync(text);

    // Concatenate or weighted average
    return CombineEmbeddings(semantic, keyword);
}
```

**विकल्प 3: मेटाडाटा फ़िल्टरName**

```csharp
var results = await _vectorStore.SearchAsync(
    queryEmbedding,
    limit: 10,
    filter: new Filter
    {
        Must =
        {
            new Condition { Field = "category", Match = new Match { Keyword = "ASP.NET" } },
            new Condition { Field = "date", Range = new Range { Gte = "2024-01-01" } }
        }
    }
);
```

## चुनौती 3: कॉन्टेक्स्ट विंडो प्रबंधन

**समस्या:** BLMM के पास टोकन सीमा है. विंडो में आप कैसे क्वैरी + संदर्भ + प्राम्प्ट फिट करें?

**समाधानः** गतिशील संदर्भ चयन तथा जाँच.

```csharp
public string BuildContextAwarePrompt(
    string query,
    List<SearchResult> retrievedDocs,
    int maxTokens = 4096)
{
    var promptTemplate = GetPromptTemplate();
    var queryTokens = CountTokens(query);
    var templateTokens = CountTokens(promptTemplate);

    // Reserve tokens for: prompt + query + response
    var availableForContext = maxTokens - queryTokens - templateTokens - 500; // 500 for response

    // Add context until we hit limit
    var selectedContext = new List<SearchResult>();
    var currentTokens = 0;

    foreach (var doc in retrievedDocs.OrderByDescending(d => d.Score))
    {
        var docTokens = CountTokens(doc.Text);

        if (currentTokens + docTokens <= availableForContext)
        {
            selectedContext.Add(doc);
            currentTokens += docTokens;
        }
        else
        {
            // Try summarizing the doc if it's important
            if (doc.Score > 0.85)
            {
                var summary = await SummarizeAsync(doc.Text, maxTokens: 200);
                var summaryTokens = CountTokens(summary);

                if (currentTokens + summaryTokens <= availableForContext)
                {
                    selectedContext.Add(new SearchResult
                    {
                        Text = summary,
                        Title = doc.Title,
                        Score = doc.Score
                    });
                    currentTokens += summaryTokens;
                }
            }
        }
    }

    return FormatPrompt(query, selectedContext);
}
```

## सन्‌ RAG के बावजूद, हाल ही में न्यू यॉर्क शहर में सजग होइए!

**समस्या:** यहाँ तक कि आस - पास की आयतों के साथ - साथ, कभी - कभी इसे नज़रअंदाज़ किया जाता है ।

**समाधानः**

**1. प्रायोगिक इंजीनियरिंग:**

```csharp
var systemPrompt = @"
You are a technical assistant.

CRITICAL RULES:
1. ONLY use information from the provided CONTEXT sections
2. If the context doesn't contain the answer, say 'I don't have enough information in the provided context to answer that'
3. DO NOT use your training data to supplement answers
4. Always cite the source using [1], [2] notation
5. If you're unsure, say so

CONTEXT:
{context}

QUESTION: {query}

ANSWER (following all rules above):
";
```

**2. पोस्ट-पीढ़ी वैध:**

```csharp
public async Task<bool> ValidateResponseAgainstContext(
    string response,
    List<SearchResult> context)
{
    // Check if response contains claims not in context
    var responseSentences = SplitIntoSentences(response);

    foreach (var sentence in responseSentences)
    {
        var isSupported = await IsClaimSupportedByContext(sentence, context);

        if (!isSupported)
        {
            _logger.LogWarning("Hallucination detected: {Sentence}", sentence);
            return false;
        }
    }

    return true;
}
```

**3 अध्ययन:**

```csharp
public async Task<string> GenerateWithValidationAsync(
    string query,
    List<SearchResult> context,
    int maxAttempts = 3)
{
    for (int attempt = 0; attempt < maxAttempts; attempt++)
    {
        var response = await _llm.GenerateAsync(
            BuildPrompt(query, context)
        );

        var isValid = await ValidateResponseAgainstContext(response, context);

        if (isValid)
            return response;

        // Refine prompt for next attempt
        query = $"{query}\n\nPrevious attempt hallucinated. Stick strictly to the context.";
    }

    return "I couldn't generate a reliable answer. Please rephrase your question.";
}
```

## चुनौती 5: निर्देशिका को ऊपर- अंत तक बनाए रखना

**समस्या:** जैसा कि आप नए दस्तावेज़ों को जोड़ते हैं, सदिश डाटाबेस को मौज़ूदा बने रहने की जरूरत है.

**समाधानः** सामग्री पुनः लोड की जा रही है .

```csharp
public class BlogIndexingBackgroundService : BackgroundService
{
    private readonly IVectorStoreService _vectorStore;
    private readonly IMarkdownService _markdownService;
    private readonly ILogger<BlogIndexingBackgroundService> _logger;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await IndexNewPostsAsync(stoppingToken);

                // Check for updates every hour
                await Task.Delay(TimeSpan.FromHours(1), stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in indexing service");
            }
        }
    }

    private async Task IndexNewPostsAsync(CancellationToken ct)
    {
        var allPosts = await _markdownService.GetAllPostsAsync();

        foreach (var post in allPosts)
        {
            var existingDoc = await _vectorStore.GetByIdAsync(post.Slug);

            // Check if content changed
            var currentHash = ComputeHash(post.Content);

            if (existingDoc == null || existingDoc.ContentHash != currentHash)
            {
                _logger.LogInformation("Indexing updated post: {Title}", post.Title);

                var chunks = _chunker.ChunkDocument(post.Content, post.Slug);

                foreach (var chunk in chunks)
                {
                    var embedding = await _embeddingService.GenerateEmbeddingAsync(chunk.Text);

                    await _vectorStore.UpsertAsync(
                        id: $"{post.Slug}_{chunk.Index}",
                        embedding: embedding,
                        metadata: new Dictionary<string, object>
                        {
                            ["slug"] = post.Slug,
                            ["title"] = post.Title,
                            ["chunk_index"] = chunk.Index,
                            ["content_hash"] = currentHash
                        },
                        ct: ct
                    );
                }
            }
        }
    }
}
```

# विस्तृत RAGCATs

के हाल के शोध से काटने-पीआरजी तकनीकों की जाँच करें.

## 1 .. हायफ्लिक दस्तावेज़ एम्बेडिंग (HyD)

**समस्या:** उपयोक्ता कीथ अकसर छोटी होती हैं और खराब बनी हुई है. दस्तावेज़ फिर से विस्तृत हैं तथा अच्छी तरह से मिटाकर लिखना भी लिखा जाता है. यह संयोग से प्राप्त होता है.

**समाधानः** इस सवाल का जवाब देने के लिए, इस दस्तावेज़ की खोज कीजिए ।

```csharp
public async Task<List<SearchResult>> HyDESearchAsync(string query)
{
    // Generate hypothetical answer (even if hallucinated)
    var hypotheticalAnswer = await _llm.GenerateAsync($@"
        Write a detailed, technical paragraph that would perfectly answer this question:

        Question: {query}

        Paragraph:"
    );

    // Embed the hypothetical answer
    var embedding = await _embeddingService.GenerateEmbeddingAsync(
        hypotheticalAnswer
    );

    // Search using this embedding
    return await _vectorStore.SearchAsync(embedding);
}
```

**क्यों यह काम करता है:** इसका जवाब है, ऐसी भाषा और बनावट जो असल में दस्तावेज़ों में पायी जाती है ।

## 2. स्व- स्वार्थीQuery

**समस्या:** उपयोक्ता को प्रायः मेटाडाटा फ़िल्टर के साथ न्यूक्लासिक खोज को मिलाया जाता है.

उदाहरण: "इन्टर के बारे में हालिया पोस्ट" = sandarit" + फ़िल्टर" (तिथि > 2024- 01- 01)

**समाधानः** क्वैरी को सीआरडीएएम + मेटाडाटा फिल्टर में पार्स करने के लिए प्रयोग करें.

```csharp
public async Task<SearchQuery> ParseSelfQueryAsync(string naturalLanguageQuery)
{
    var parsingPrompt = $@"
        Parse this search query into:
        1. Semantic search query (what the user is looking for)
        2. Metadata filters (category, date range, etc.)

        User Query: {naturalLanguageQuery}

        Output JSON:
        {{
            ""semantic_query"": ""the core concept"",
            ""filters"": {{
                ""category"": ""...",
                ""date_after"": ""..."",
                ""date_before"": ""...""
            }}
        }}
    ";

    var jsonResponse = await _llm.GenerateAsync(parsingPrompt);
    var parsed = JsonSerializer.Deserialize<SearchQuery>(jsonResponse);

    return parsed;
}

// Use parsed query
var parsedQuery = await ParseSelfQueryAsync("Recent ASP.NET posts about authentication");
// semantic_query: "authentication"
// filters: { category: "ASP.NET", date_after: "2024-01-01" }

var results = await _vectorStore.SearchAsync(
    embedding: await _embeddingService.GenerateEmbeddingAsync(parsedQuery.SemanticQuery),
    filter: BuildFilter(parsedQuery.Filters)
);
```

## 3. बहु-Query RAG

**समस्या:** एक ही क्वैरी में शायद सम्बन्धित दस्तावेज़ों की कमी हो सकती है जिनका इस्तेमाल करने के लिए किया जाता है ।

**समाधानः** क्वैरी के अनेक भिन्न क़िस्मों को उत्पन्न करें, खोज सभी के साथ, संयोजन परिणामों के साथ.

```csharp
public async Task<List<SearchResult>> MultiQuerySearchAsync(string query)
{
    // Generate query variations
    var variations = await _llm.GenerateAsync($@"
        Generate 3 different ways to phrase this search query:

        Original: {query}

        Variations (one per line):
    ");

    var queries = variations.Split('\n', StringSplitOptions.RemoveEmptyEntries)
        .Prepend(query) // Include original
        .ToList();

    // Search with all variations
    var allResults = new List<SearchResult>();

    foreach (var q in queries)
    {
        var embedding = await _embeddingService.GenerateEmbeddingAsync(q);
        var results = await _vectorStore.SearchAsync(embedding, limit: 10);
        allResults.AddRange(results);
    }

    // Deduplicate and merge scores
    var merged = allResults
        .GroupBy(r => r.Id)
        .Select(g => new SearchResult
        {
            Id = g.Key,
            Text = g.First().Text,
            Title = g.First().Title,
            Score = g.Max(r => r.Score) // Take best score
        })
        .OrderByDescending(r => r.Score)
        .ToList();

    return merged;
}
```

## 4 कॉन्टेक्स्ट संपीडन

**समस्या:** फिर से निकाले जाने के लिए ज़रूरी जानकारी है. इसे सभी बेकार संकेतों को भेजना.

**समाधानः** सिर्फ संबंधित भाग को संदर्भ में वापस लाने के लिए छोटे भाग का उपयोग करें.

```csharp
public async Task<string> CompressContextAsync(
    string query,
    List<SearchResult> retrievedDocs)
{
    var compressed = new List<string>();

    foreach (var doc in retrievedDocs)
    {
        var compressionPrompt = $@"
            Extract only the sentences from this document that are relevant to answering the question.

            Question: {query}

            Document:
            {doc.Text}

            Relevant excerpts (maintain original wording):
        ";

        var relevantExcerpt = await _smallLLM.GenerateAsync(compressionPrompt);

        if (!string.IsNullOrWhiteSpace(relevantExcerpt))
        {
            compressed.Add($"From '{doc.Title}':\n{relevantExcerpt}");
        }
    }

    return string.Join("\n\n", compressed);
}
```

## 5. इम्प्शन रिपरेशन रि- रेजी)

**समस्या:** जटिल प्रश्नों के लिए अनेक स्रोतों से जानकारी की ज़रूरत होती है जो जुड़े हुए हैं.

उदाहरण: " ब्लॉग का कौन सा डाटाबेस उपयोग करता है और कैसे एनिमिक सर्च लागू किया जाता है?"

- हॉप 1: ढूंढें कि कौन सा डाटाबेस इस्तेमाल किया जाए (प्रेषित- एसक्यूएल)
- पैरामीटर 2: ढूंढें कैसे उस डाटाबेस के साथ काम करता है

**समाधानः** . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

```csharp
public async Task<string> MultiHopRAGAsync(string complexQuery, int maxHops = 3)
{
    var currentQuery = complexQuery;
    var allContext = new List<SearchResult>();

    for (int hop = 0; hop < maxHops; hop++)
    {
        // Retrieve for current query
        var results = await SearchAsync(currentQuery, limit: 5);
        allContext.AddRange(results);

        // Check if we have enough information
        var synthesisPrompt = $@"
            Original question: {complexQuery}

            Context so far:
            {FormatContext(allContext)}

            Can you answer the original question with this context?
            If yes, provide the answer.
            If no, what additional information do you need? (be specific)
        ";

        var synthesis = await _llm.GenerateAsync(synthesisPrompt);

        if (synthesis.Contains("yes", StringComparison.OrdinalIgnoreCase))
        {
            // We have enough information
            return ExtractAnswer(synthesis);
        }

        // Extract what we need for next hop
        currentQuery = ExtractNextQuery(synthesis);
    }

    // Final synthesis with all gathered context
    return await GenerateFinalAnswerAsync(complexQuery, allContext);
}
```

## 6. लंबा-टर्म संदर्भ मेमोरी RG + सममारीकरण के साथ

**समस्या:** आप एआई तंत्रों को कैसे बनाते हैं जो महीनों या साल पहले से वार्तालाप को याद रखते हैं?

**समाधानः** लगातार, खोज योग्य स्मृति बनाने के लिए प्रगतिशील रूप से रीग्रेसन के साथ जोड़िए ।

यह तरीका यहाँ इस्तेमाल किया गया है **डिथरिंग (प्रयोगात्मक सिंथेटेड एवोल्यूशन)** - एक उन्नत प्रणाली मैं निर्माण कर रहा हूँ कि RG-G-आधारित संदर्भ स्मृति हमेशा के लिए साझा वार्तालाप इतिहास रखने के लिए उपयोग कर रहा हूँ।

**उदाहरण के लिए:**

```
User (Today): "Remember George's specs?"
AI: "Yes, you discussed George's prescription requirements in our conversation
     from 5 years ago (2019-03-15). He needed progressive lenses with..."
```

**यह कैसे काम करता है:**

```mermaid
flowchart TB
    A[User Message] --> B[Store in RAG Memory]
    B --> C[Extract Key Entities & Topics]
    C --> D[Link to Past Conversations]

    E[Periodic Summarization] --> F[Summarize Old Conversations]
    F --> G[Store Summary with High-Level Tags]
    G --> H[Keep Original for Retrieval]

    I[Future Query: 'George's specs'] --> J[Semantic Search in RAG]
    J --> K[Find: 2019 conversation]
    K --> L[Retrieve Original Context]
    L --> M[LLM generates response with 5-year-old context!]

    style B stroke:#f9f,stroke-width:3px
    style J stroke:#bbf,stroke-width:3px
```

**कार्यान्वयन पासः**

```csharp
public class LongTermConversationalMemory
{
    private readonly IVectorStoreService _vectorStore;
    private readonly IEmbeddingService _embeddingService;

    public async Task StoreConversationAsync(
        string conversationId,
        string userId,
        List<ConversationTurn> turns,
        DateTime timestamp)
    {
        // Extract key entities and topics
        var entities = await ExtractEntitiesAsync(turns);
        var topics = await ExtractTopicsAsync(turns);

        // Create searchable representation
        var conversationText = string.Join("\n", turns.Select(t =>
            $"{t.Speaker}: {t.Message}"));

        // Generate embedding
        var embedding = await _embeddingService.GenerateEmbeddingAsync(
            conversationText);

        // Store in RAG with rich metadata
        await _vectorStore.IndexDocumentAsync(
            id: $"conv_{conversationId}",
            embedding: embedding,
            metadata: new Dictionary<string, object>
            {
                ["user_id"] = userId,
                ["timestamp"] = timestamp.ToString("O"),
                ["entities"] = entities,  // ["George", "specs", "prescription"]
                ["topics"] = topics,      // ["healthcare", "eyewear"]
                ["full_text"] = conversationText,
                ["turn_count"] = turns.Count
            }
        );
    }

    public async Task<List<PastContext>> RetrieveRelevantPastAsync(
        string currentQuery,
        string userId,
        int limit = 5)
    {
        // Embed the current query
        var queryEmbedding = await _embeddingService.GenerateEmbeddingAsync(
            currentQuery);

        // Search past conversations
        var results = await _vectorStore.SearchAsync(
            queryEmbedding,
            limit: limit,
            filter: new Filter
            {
                Must =
                {
                    new Condition { Field = "user_id", Match = new Match { Keyword = userId } }
                }
            }
        );

        return results.Select(r => new PastContext
        {
            ConversationId = r.Id,
            Timestamp = DateTime.Parse(r.Metadata["timestamp"].ToString()),
            Entities = (List<string>)r.Metadata["entities"],
            FullText = r.Metadata["full_text"].ToString(),
            Relevance = r.Score
        }).ToList();
    }

    // Periodic summarization to keep memory manageable
    public async Task SummarizeOldConversationsAsync(DateTime olderThan)
    {
        var oldConversations = await _vectorStore.FindByDateRangeAsync(
            endDate: olderThan);

        foreach (var conv in oldConversations)
        {
            // Generate summary using LLM
            var summary = await _llm.GenerateAsync($@"
                Summarize this conversation, preserving key facts and entities:

                {conv.FullText}

                Summary:");

            // Update document with summary while keeping original
            await _vectorStore.UpdateAsync(
                id: conv.Id,
                additionalMetadata: new Dictionary<string, object>
                {
                    ["summary"] = summary,
                    ["summarized_at"] = DateTime.UtcNow.ToString("O")
                }
            );
        }
    }
}
```

**यह क्यों शक्‍तिशाली है:**

1. **असीमित स्मृति की अवधि** - साल पहले से बातचीत कर रहे हैं कल की तरह
2. **सेमेन्टिक खोज** - "Gegenss" दृश्य" बातचीत मिल जाता है, तो भी अगर "Gegigosssinininins parer की आवश्यकताओं के रूप में जमा किया गया है"
3. **एंटिटी लिंकिंग** - सभी बातचीत "Geke" संबंधित हैं
4. **गोपनीयता-pane** - प्रति-उपयोक्ता स्मृति अलग कर सकते हैं
5. **लागत- प्रभाव** - सुमामारीकरण भंडार विस्फोट को रोक नहीं सकता जबकि खोज क्षमता बनाए रखें

**डिथरिंग से वास्तविक विश्व उदाहरण:**

हमें यह याद रखना चाहिए:

- **औजार प्रार्थना** महीनों पहले (क्या काम किया, क्या असफल रहा)
- **कोड पैटर्न** अतीत के परियोजनाओं में सफल हुए
- **उपयोक्ता वरीयताएँ** पहले बातचीत में स्थापित
- **डोमेन ज्ञान** समय से ज्यादा भंडारित करें

यह एक एआई तंत्र तैयार करता है कि वास्तविक रूप से हर सम्पर्क तथा संगठनात्मक स्मृति से "जान" बनाता है, बल्कि प्रत्येक सत्र को ताज़ा करने के बजाय.

**चुनौतियों पर गौर करना:**

1. **गोपनीयता**: पुरानी बातचीत को हर उपयोक्ता को उचित रूप से अलग किया जाना चाहिए
2. **रिविंग सड़न**: सभी पुरानी जानकारी का आधार नहीं होता
3. **भंडारण लागत**: स्केल के लिए प्रायोगिक रणनीति चाहिए
4. **संगतता ही**: मूल - तत्वों के साथ मेल - जोल रखना
5. **पुनःप्राप्त कर रहा है**: हाल ही में और ऐतिहासिक संदर्भों के बीच बालियाँ

यह तकनीक RG "अपने दस्तावेज़ों को खोज" से बदल देती है "जो कुछ हमने कभी चर्चा की है उसे याद रखना" - लंबे अटल एआई सहायकों के लिए एक खेल परिवर्तन.

# आरजी इस्तेमाल करने के लिए नहीं

RG हमेशा जवाब नहीं है. इसे दूर करने के लिए यहाँ है:

**1 सामान्य ज्ञान प्रश्‍न**

- " फ्रांस की राजधानी क्या है?" - लीएम पहले से ही यह जानता है
- रेजी आगे कहता है और कोई फायदा नहीं पाने के लिए खर्च भी करता है

**2. अज़ाब लिखने वाला लेखन**

- कवि, कथा, मस्तिष्क तूफान
- रीजी को मौजूदा पाठ में निर्भर करता है

**3. रीयल- टाइम डाटा की आवश्यकता है**

- स्टॉक्स, खेल अंक
- एन. ए.

**4 गणितीय तर्क**

- "सी अनुमान लगाया जा रहा है 15% 40,000 "
- LLMMEL यह अंकगणित कर सकते हैं, RG मदद नहीं करता

**5 बहुत छोटा ज्ञान आधार**

- यदि आपका ज्ञान संदर्भ विंडो में उचित बैठता है, तो इसमें सभी शामिल हों
- REGOG मुख्य रूप से 5 दस्तावेज़ों के लिए इसके लायक नहीं है

**6 जब आपLLL के प्रशिक्षण को नियंत्रित करते हैं.**

- आप अपने डेटा पर reting से एक मॉडल प्रशिक्षण कर रहे हैं, ठीक हो सकता है
- RAG सबसे अच्छा है जब आप नियंत्रण नहीं करते मॉडल का उपयोग करते हैं

# RAG से प्रारंभ होना: एक व्यावहारिक मार्गदर्शक

अपने खुद RGyy प्रणाली बनाना चाहते हैं? यहाँ एक कदम के माध्यम से कदम कदम है।

## सप्ताह 1: प्रारंभ सरल

**लक्ष्य:** कोई LLLM के साथ काम करने के बुनियादी वापसी प्राप्त करें.

```csharp
// 1. Choose an embedding service (start with API for simplicity)
var openAI = new OpenAIClient(apiKey);

// 2. Embed a few test documents
var docs = new[]
{
    "Docker is a containerization platform",
    "Kubernetes orchestrates containers",
    "Entity Framework is an ORM for .NET"
};

var embeddings = new List<float[]>();
foreach (var doc in docs)
{
    var response = await openAI.GetEmbeddingsAsync(
        new EmbeddingsOptions("text-embedding-3-small", new[] { doc })
    );
    embeddings.Add(response.Value.Data[0].Embedding.ToArray());
}

// 3. Implement basic search (in-memory for now)
var query = "container orchestration";
var queryEmbedding = await GetEmbeddingAsync(query);

var results = embeddings
    .Select((emb, idx) => new
    {
        Text = docs[idx],
        Score = CosineSimilarity(queryEmbedding, emb)
    })
    .OrderByDescending(r => r.Score)
    .ToList();

// 4. Verify search works
foreach (var result in results)
{
    Console.WriteLine($"{result.Score:F3}: {result.Text}");
}
// Expected: Kubernetes scores highest
```

## सप्ताह 2: सदिश डाटाबेस जोड़ें

**लक्ष्य:** दस्तावेज़ संग्रहों के लिए स्केल करें.

लागू करने के लिए अगला चरण:

1. डॉकएटर में क्यूकेट चलाएँ
2. अपने दस्तावेज़ों की सूची दें
3. खोज अंत बिन्दु लागू करें

मैं सदिश डाटाबेस पर एक आनेवाले लेख में इस बात को विस्तार से कवर करूंगा.

## सप्ताह 3:LLM पीढ़ी जोड़ें

**लक्ष्य:** रेग्रेजी पूर्ण.

```csharp
// 1. Retrieve context
var context = await SearchAsync(query, limit: 3);

// 2. Build prompt
var prompt = $@"
    Answer the question using this context:

    {FormatContext(context)}

    Question: {query}

    Answer:";

// 3. Generate (start with API)
var response = await openAI.GetChatCompletionsAsync(new ChatCompletionsOptions
{
    Messages =
    {
        new ChatMessage(ChatRole.System, "You are a helpful assistant."),
        new ChatMessage(ChatRole.User, prompt)
    },
    Temperature = 0.7f,
    MaxTokens = 500
});

return response.Value.Choices[0].Message.Content;
```

## सप्ताह ४: ऑपुल्‌स तथा पोलिश

- कैशिंग जोड़ें ( एपीआई लागत पर सहेजें)
- अच्छी तरह से सुधार करने की रणनीति
- मेटाडाटा फ़िल्टर जोड़ें
- समर्थित खोज
- एक्सपोजर जोड़ें

## स्थानीय (वैकल्पिक) जा रहा है

मूल कार्य में एक बार, स्थानीय ज्ञान में उत्प्रवासित होता है (मैं भविष्य के लेखों में इस बात को कवर करता हूँ):

- GPS त्वरण के साथ स्थानीय सारांश
- ऑन एनईएक्स रन समय के साथ सीपीयू फिटिंग

# कंटेनमेंट

RGEG (पुष्टि-रहित पीढ़ी) एक प्रभावशाली तकनीक है कि अधिक सही है, ऊपर-से-अंत्र, और वास्तविक दस्तावेज़ों में उनकी प्रतिक्रिया स्थापित करके. मॉडल के प्रशिक्षण डेटा पर निर्भर करने के बजाय, RGIGyyyyyyyyyyyyyyyyyD:

1. **पुनःप्राप्त करें** ज्ञान आधार से संबंधित जानकारी
2. **अग.** LLM उस प्राप्त संदर्भ के साथ प्राधिकृत है
3. **बनाएँ (G)** जवाब जो उल्लेख के साथ वास्तविक स्रोतों में आधारित हैं

**RAG के मुख्य लाभ:**

- हमेशा अद्यतन (सिर्फ अपने ज्ञान आधार को अद्यतन करें)
- स्रोत में आधारित (संत्रित)
- व्याख्यायोग्य (फ़िक स्रोतों का उल्लेख करें)
- लागत- प्रभाव (कोई महँगी मरम्मत)
- गोपनीयता- गोपनीयता (सिर्फ स्थानीय रूप से चला सकते हैं)
- डोमेन विशिष्ट (अपने स्वयं के दस्तावेज़ों का प्रयोग करें)

**RAG प्रयोग करने के लिए:**

- ज्ञान- रचना कार्य
- बार बार अद्यतन जानकारी
- निजी/व्यस्त डाटा
- उल्लेख किए जाने की आवश्यकता है तथा निष्क्रियता के लिए
- क़ीमत और सरल मामला

**जब हम RAG से दूर रहें:**

- जीग आधार

क्षेत्र HyDE के रूप में विस्तृत तकनीकों के साथ तेजी से तेजी से बढ़ रहा है, बहु-चांजी वापसी, और PRCOCT संपीडन, लेकिन मुख्य धारणा सरल रहती है: सही समय पर सही जानकारी के लिए पहुँच दे.

रेजी आज भरोसेमंद एआई सिस्टम बनाने के लिए एक बहुत ही कारगर तरीका है ।

# विज्ञापन: उत्पादों से

आप अब तीन- भाग RAG श्रृंखला पूरा कर लिया है:

**[भाग 1: उद्‌गम और मूलतत्त्ववाद](/blog/rag-primer)**

- रीजी क्या है और क्यों यह बात है
- ग्राफिक समझ की खोज से इतिहास
- RAG vs vs बढ़िया, लंबे संदर्भ, और अन्य दृष्टिकोण

**[पार्ट 2: अ- धातु और आंतरिक](/blog/rag-architecture)**

- RAGREART: इंडेक्सिंग, वापसी, पीढ़ी
- आंतरिक आंतरिक: चिह्न, केवी कैश, संदर्भ विंडो
- C# कोड के साथ तकनीकी कार्यान्वयन विवरण

**अभ्यास में भाग 3: RAG (यह लेख)**

- रीयल- वर्ल्ड कार्यान्वयन (डेलिक खोज, सेप्टिक खोज, लेखन सहायक)
- सामान्य चुनौतियों और समाधान (चकिंग, नृत्य विशेषता, दोषरहित)
- विस्तृत तकनीकों (HyE, स्व-ता-Query, मल्टी-Query, कॉन्टेक्स्ट संपीडन, लंबी मेमोरी)
- जब RAG का उपयोग नहीं किया जा सकता
- शुरू में मार्गदर्शक प्राप्त करना

**अब आपके पास संपूर्ण चित्र है:** RG के उद्गम से उत्पादन प्रणालीओं को विस्तृत अनुकूलनों के साथ बनाने के लिए।

# अगला क्या है?

अब कि आप सिद्धांत से अभ्यास करने के लिए ReG को समझते हैं, आगामी आलेख आपको दिखाएगा कि कैसे पूरा, C# में निर्माण व्यवस्थाओं को तैयार करने के लिए तैयार करें:

**जल्द ही आ रहा है:**

- **सीपीयू- शुक्र- सेमी खोजQuery** - जीयूपी आवश्यकताओं के बिना किसी भी वीपीएस पर चलता है कि किसी भी वीपीएस के साथ खोज निर्माण
- **स्व-Hed सदिश डाटाबेस** - डॉकएटर के लिए पूर्ण सेटअप गाइड, जिसमें इंडेक्सिंग, खोज, और अनुकूलन योजना सम्मिलित हैं
- **RAG लेखन सहायक का निर्माण करना** - एक एआई- शक्ति युक्त लेखन सहायक बनाने पर पूरा श्रृंखला जो एक ज्ञान आधार के रूप में अपनी मौजूदा सामग्री का उपयोग करता है

ये आलेख इस ब्लॉग के उत्पादन पर आधारित इन सिस्टमों को चलाने पर आधारित कार्य कोड, तैनाती, और वास्तविक प्रणालीओं के साथ आपको सिद्धांत से ले लेंगे.

हाथ कार्यान्वयन गाइड के लिए धुन जारी रखें जो इस RAG ज्ञान को कार्य तंत्रों में बदल देता है!

## संसाधन

**आधारित कागज:**

- [ज्ञान- इन लिंड एनएलपी कार्य के लिए निकाल दिया जा रहा है](https://arxiv.org/abs/2005.11401) - मूल रेजी कागज
- [ओपन- डोमेन प्रश्न उत्तर के लिए डीफिक्सेज](https://arxiv.org/abs/2004.04906) - फ्यूप (उंटी- निरंतर नींव)
- [सभी पर ध्यान देना ज़रूरी है](https://arxiv.org/abs/1706.03762) - ट्रांसपर्स (सेंड आधार)

**औज़ार तथा फ्रेमवर्क:**

- [स्केल्स](https://qdrant.tech/) - सदिश डाटाबेस मैं इस्तेमाल करता हूँ
- [ऑन NNX रन समय](https://onnxruntime.ai/) - स्थानीय एम्बेडिंग के लिए
- [एलएचएआ तीव्र](https://github.com/SciSharp/LLamaSharp) - स्थानीय गंभीरता के लिए
- [वाक्य रूपांतरण](https://www.sbert.net/) - एम्बेडिंग मॉडल

**आगे पढ़ा जा रहा है:**

- [एडिक्टिक: कॉन्टेक्स्ट रिपरलैक्स](https://www.anthropic.com/index/contextual-retrieval) - विस्तृत RAG तकनीक
- [तंत्रिका मशीन अनुवाद कैसे काम करता है](/blog/how-neural-machine-translation-works) - एम्बेडिंग के पीछे एआई मॉडलों को समझना

**इस रीजी सेवर्स:**

- [भाग 1: उद्‌गम और मूलतत्त्ववाद](/blog/rag-primer) - इतिहास, प्रेरणा, मुख्य धारणा
- [पार्ट 2: अ- धातु और आंतरिक](/blog/rag-architecture) - तकनीकी गहरी गति
- **अभ्यास में भाग 3: RAG** ( इस लेख की शुरूआत में दी तसवीर देखिए ।)

क्या ही शानदार इमारत!