# RAGCACT और आंतरिक: यह वास्तव में कैसे कार्य करता है

में [पार्ट 1](/blog/rag-primer), हम RG के उद्गम, मूलभूत, और क्यों यह बात है. आप उच्च स्तर की धारणा को समझते हैं: मूल्यवान जानकारी प्राप्त करने के लिए, फिर प्रतिक्रिया बनाने के लिए इसका उपयोग करें। अब हम तकनीकी निर्माण में गहरी कटौती करें - वास्तव में कैसे REG सिस्टमों के तहत, के तहत आंतरिक लक्षणों और KV के रूप में आंतरिक संकेतों और KV.

<datetime class="hidden">2025-11-22T09:30</datetime>

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

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

- [भाग 1: उद्‌गम और मूलतत्त्ववाद](/blog/rag-primer) - इतिहास, प्रेरणा, और मुख्य धारणाएँ
- **पार्ट 2: अ- धातु और आंतरिक** ( इस लेख में दिया गया लेख) - तकनीकी गहराई से गहराई तक बढ़ता है कि कैसे रेजी काम करता है
- [अभ्यास में भाग 3: RAG](/blog/rag-practical-applications) - वास्तविक सिस्टम, चुनौतियों और विस्तृत तकनीकों का निर्माण
- [पार्ट ४डी: एनएनएक्स व क्यूड कार्यान्वयन पर](/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 नहीं पढ़ा है, तो मैं वहाँ समझने के लिए शुरू करने की सलाह देता हूँ:

- रीजी क्या है और क्यों यह बात है
- कीवर्ड की खोज से इतिहास
- RAG vs बढ़िया-चिंग तथा अन्य दृष्टिकोण

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

[TOC]

# RAG कैसे काम करता है: पूरी तसवीर

हम वास्तव में एक RG व्यवस्था में क्या होता है तोड़ देते हैं, पल से आप एक दस्तावेज़ जोड़ जब एक उपयोगकर्ता उत्तर मिल जाता है।

## फेस 1: सूची (ज्ञान आधार को अलग करना)

RG कुछ भी प्राप्त करने से पहले, आपको अपने ज्ञान आधार की सूची करनी होगी. यह एक बार प्रक्रिया है (हालाँकि आप बाद में नए दस्तावेज़ों को जोड़ सकते हैं.

```mermaid
flowchart TB
    A[Source Documents] -->|1. Extract Text| B[Text Extraction]
    B -->|2. Split into Chunks| C[Chunking Service]
    C -->|3. Generate Embeddings| D[Embedding Model]
    D -->|4. Store Vectors| E[Vector Database]

    B -.Metadata.-> E

    subgraph "Example: Blog Post"
        F["Understanding Docker: A containerization platform..."]
    end

    subgraph "Chunks"
        G["Chunk 1: Title + Intro"]
        H["Chunk 2: Benefits Section"]
    end

    subgraph "Embeddings"
        I["0.234, 0.891, 0.567, ..."]
        J["0.445, 0.123, 0.789, ..."]
    end

    F --> G
    F --> H
    G --> I
    H --> J

    style D stroke:#f9f,stroke-width:2px
    style E stroke:#bbf,stroke-width:2px
```

### चरण 1: पाठ निकाला जा रहा है

आपके स्रोत दस्तावेज में से सादा पाठ निकालें. यह हो सकता है:

- फ़ाइलों को चिह्नित करें (मेरे ब्लॉग पोस्ट की तरह)
- पीडीएफ़ ( दस्तावेज़ के लिए)
- एचटीएमएल (मंजिंग के लिए)
- डाटाबेस रिकॉर्ड
- ई-मेल, चैट लॉग, इत्यादि.

**मेरे ब्लॉग से उदाहरण:**

```csharp
// From MarkdownRenderingService
public string ExtractPlainText(string markdown)
{
    // Remove code blocks
    var withoutCode = Regex.Replace(markdown, @"```[\s\S]*?```", "");

    // Convert markdown to plain text
    var document = Markdown.Parse(withoutCode);
    var plainText = document.ToPlainText();

    return plainText.Trim();
}
```

### कदम 2: चाकिंग

यह है जहां सबसे RGEG कार्यान्वयन असफल. आप सिर्फ पैराग्राफ सीमाओं पर विभाजित नहीं कर सकते हैं - आप सिर्फ sematss की आवश्यकता है.

**क्यों ज़रूरी बातों को दोहराना:**

- TLMM के पास टोकन सीमा है (कोई पाठ विंडो)
- छोटा भाग = अधिक सटीक वापसी
- लेकिन विभाजन में काफी संदर्भ होना चाहिए

**खराब रीकरिंग:**

```
Chunk 1: "Docker is a containerization platform. It allows you"
Chunk 2: "to package applications with their dependencies. This"
Chunk 3: "ensures consistency across environments."
```

**अच्छी रेसिंग:**

```
Chunk 1: "Docker is a containerization platform. It allows you to package applications with their dependencies. This ensures consistency across environments."

Chunk 2: "Benefits of Docker:
- Isolation: Each container runs in its own environment
- Portability: Containers run anywhere Docker is installed
- Efficiency: Lightweight compared to virtual machines"
```

**मेरे पैरिक खोज कार्यान्वयन का उदाहरण:**

```csharp
public class TextChunker
{
    private const int TargetChunkSize = 500; // ~500 words
    private const int ChunkOverlap = 50;     // 50 words overlap

    public List<Chunk> ChunkDocument(string text, string sourceId)
    {
        var chunks = new List<Chunk>();

        // Split on section boundaries first (## headers in markdown)
        var sections = SplitOnHeaders(text);

        foreach (var section in sections)
        {
            // If section is small enough, keep it whole
            if (section.WordCount < TargetChunkSize)
            {
                chunks.Add(new Chunk
                {
                    Text = section.Text,
                    SourceId = sourceId,
                    SectionHeader = section.Header
                });
            }
            else
            {
                // Split large sections on sentence boundaries
                var subChunks = SplitOnSentences(section.Text, TargetChunkSize, ChunkOverlap);
                chunks.AddRange(subChunks.Select(c => new Chunk
                {
                    Text = c,
                    SourceId = sourceId,
                    SectionHeader = section.Header
                }));
            }
        }

        return chunks;
    }
}
```

**सामान्यीकरण नीतिः**

- **स्थिर- आकार**: सरल परंतु ब्रेकेटिक सीमाएँ
- **वाक्य आधारित**: व्याकरण का आदर कीजिए लेकिन बहुत छोटा हो सकता है
- **अनुच्छेद आधारित**: प्राकृतिक परंतु चर आकार
- **खण्ड आधारित**: निर्माण सामग्री (मेरी प्राथमिकता) के लिए उत्तम
- **विंडो को एक साथ चालू किया जा रहा है**: सुनिश्चित करें कि कोई संदर्भ सीमा पर गुम है

### चरण 3: एम्बेडिंग तैयार करता है

ये जादू हैं जो एक जादुई खोज संभव बनाता है ।

**कुंजी संकल्पः** समान अर्थ

```
"Docker container" → [0.234, -0.891, 0.567, ..., 0.123]
"containerization platform" → [0.221, -0.903, 0.534, ..., 0.119]
"apple fruit" → [0.891, 0.234, -0.567, ..., -0.789]
```

पहले दो सदिशों को सदिश स्थान (उच्च कोज्या मान) में "बंद" किया जाएगा, जबकि तीसरे दूर तक है.

**कैसे एम्बेडिंग किया जाता है:**
आज के मशहूर मॉडलों की नकल करना, बड़े - बड़े पाठ के डेटा - डाटाओं को सीखने के लिए प्रशिक्षित किया जाता है ।

- **सभी मारनीLM-L6-v2**: 384 आयाम, तेज, अच्छा गुणवत्ता (इस ब्लॉग पर मैं क्या इस्तेमाल करता हूँ)
- **पाठ- घंटी- 3- छोटा** ( OpenOIAER: 1536 आयाम, बहुत उत्तम क्वालिटी
- **BGई- बेस**: 768 आयाम, राज्य- ऑफ- इसके खुले स्रोत

**मेरे ऑनिंगिंग सेवा से उदाहरण:**

```csharp
public async Task<float[]> GenerateEmbeddingAsync(string text)
{
    // Tokenize the input text
    var tokens = Tokenize(text);

    // Create input tensors for ONNX model
    var inputIds = CreateInputTensor(tokens);
    var attentionMask = CreateAttentionMaskTensor(tokens.Length);
    var tokenTypeIds = CreateTokenTypeIdsTensor(tokens.Length);

    // Run ONNX inference
    var inputs = new List<NamedOnnxValue>
    {
        NamedOnnxValue.CreateFromTensor("input_ids", inputIds),
        NamedOnnxValue.CreateFromTensor("attention_mask", attentionMask),
        NamedOnnxValue.CreateFromTensor("token_type_ids", tokenTypeIds)
    };

    using var results = _session.Run(inputs);

    // Extract the output (sentence embedding)
    var output = results.First().AsTensor<float>();
    var embedding = output.ToArray();

    // L2 normalize the vector for cosine similarity
    return NormalizeVector(embedding);
}
```

**क्यों कुछ सामान्य बात नहीं:** L2 को सामान्य रूप से समझने के बाद, कोसाइन संरक्षा एक सरल कार्य्य उत्पाद बन जाती है, जिससे बहुत तेज़ी से खोजती है ।

### चरण 4: सदिश डाटाबेस में भंडारित

सदिश डाटाबेस उच्च- सदिश वेक्टर्स को भंडारित करने और ढूंढने के लिए डेज़ीशन्ड हैं. पारंपरिक डाटाबेस जो एसक्यूएल जांच का उपयोग करता है, सदिश डाटाबेस तुलनात्मक खोज का इस्तेमाल करता है.

**कुंजी संचालन:**

- **ऊपर (C)**: मेटाडाटा युक्त एक सदिश जोड़ें या अद्यतन करें
- **ढूंढें**के- समान सदिश को क्वैरी सदिश पर ढूंढें
- **फ़िल्टर**छवि फ़ाइल नाम प्रदर्शित करने के लिए यह विकल्प सेट करें.

**उदाहरण संपादन कार्यान्वयन:**

```csharp
public async Task IndexDocumentAsync(
    string id,
    float[] embedding,
    Dictionary<string, object> metadata)
{
    var point = new PointStruct
    {
        Id = new PointId { Uuid = id },
        Vectors = embedding,
        Payload =
        {
            ["title"] = metadata["title"],
            ["source"] = metadata["source"],
            ["chunk_index"] = metadata["chunk_index"],
            ["created_at"] = DateTime.UtcNow.ToString("O")
        }
    };

    await _client.UpsertAsync(
        collectionName: "blog_posts",
        points: new[] { point }
    );
}
```

**लोकप्रिय सदिश डाटाबेस:**

- **स्केल्स**: तीव्र, स्व- होस्टेबल, उत्तम C# समर्थन (मेरे चुनाव)
- **पीगवर्टर**: एसक्यूएल विस्तार (यदि आप पहले से ही पोस्टग्रिस का उपयोग कर रहे हैं)
- **पाइन्ड**: सेवा प्रबंधन (सिर्फ अच्छा ही नहीं)
- **वेविएटर**: धन - दौलत, जटिल स्कीमा के लिए
- **क्रोमाडीबी**: पायथन-फ़्ड, हल्का

हम भविष्य के लेखों में इन डाटाबेसओं की जांच करेंगे.

## PRECT 2: relant सूचना ढूँढ़ें (खोज कर रहा है)

जब एक उपयोक्ता सवाल पूछता है, तो रीजी तंत्र को ज्ञान आधार से सबसे संबंधित जानकारी खोजनी चाहिए ।

```mermaid
flowchart LR
    A["User Query:<br/>'How do I use Docker Compose?'"] --> B[Generate Query Embedding]
    B --> C["Query Vector:<br/>[0.445, -0.123, ...]"]
    C --> D[Vector Search]
    D --> E[Vector Database]
    E --> F[Top K Similar Chunks]
    F --> G["Results:<br/>1. Docker Compose Basics 0.92<br/>2. Multi-Container Setup 0.87<br/>3. Service Configuration 0.83"]

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

### चरण 1: क्वैरी एम्बेडिंग तैयार करें

उपयोक्ता का प्रश्न एक सदिश का उपयोग करता है **वही एम्बेडिंग मॉडल** इंडेक्सिंग के लिए उपयोग में लिया जाता है. यह महत्वपूर्ण मॉडल असंगत सदिश बनाता है.

```csharp
public async Task<List<SearchResult>> SearchAsync(string query, int limit = 10)
{
    // Same embedding model used for indexing
    var queryEmbedding = await _embeddingService.GenerateEmbeddingAsync(query);

    // Search in vector store
    var results = await _vectorStoreService.SearchAsync(
        queryEmbedding,
        limit
    );

    return results;
}
```

### चरण 2: एक जैसे खोजQuery

सदिश डाटाबेस क्वैरी सदिश तथा सभी भंडारित सदिश के बीच तुलना करता है. सामान्य नियम:

**कोसाइन** सामान्य सदिशों के लिए सबसे लोकप्रिय (:

```
similarity = (A · B) / (||A|| × ||B||)
```

सीमा: - 1 से अधिक (उच्च = अधिक)

**यूक्लिडियन दूरी** (सामान्य सदिशों के लिए):

```
distance = sqrt(Σ(Ai - Bi)²)
```

सीमा: 0 से बाहर (बड़ा = अधिक)

**उत्पाद बनाएँ (_t)** (जब सदिश पहले से सामान्य किये जाते हैं):

```
similarity = A · B
```

सीमा: - 1 से अधिक (उच्च = अधिक)

**मेरे प्रवरेज सेवा से उदाहरण:**

```csharp
var searchResults = await _client.SearchAsync(
    collectionName: "blog_posts",
    vector: queryEmbedding,
    limit: (ulong)limit,
    scoreThreshold: 0.7f,  // Only return results with >70% similarity
    payloadSelector: true   // Include all metadata
);

return searchResults.Select(hit => new SearchResult
{
    Text = hit.Payload["text"].StringValue,
    Title = hit.Payload["title"].StringValue,
    Score = hit.Score,
    Source = hit.Payload["source"].StringValue
}).ToList();
```

### चरण ३: रीफिंग (वैकल्पिक लेकिन अनुशंश)

फिर से प्राप्त करने का प्रयोग अधिक जटिल मॉडल का उपयोग करके शीर्ष के परिणामों को पुनः प्राप्त करने के लिए करता है।

```mermaid
flowchart LR
    A[Vector Search:<br/>Top 50 Results] --> B[Reranking Model]
    B --> C[Reranked:<br/>Top 10 Results]

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

**फिर से तैयारी करने से हमें क्यों मदद मिलती है:**

- तेज़ गति के लिए मॉडलों का पालन करना, कुछ यथार्थता की बलि करना
- सरफेश मॉडल धीमी हैं लेकिन अधिक यथार्थ हैं
- दो मंच के पास शेष गति और गुणवत्ता

**उदाहरण संपादन कार्यान्वयन:**

```csharp
public async Task<List<SearchResult>> SearchWithRerankAsync(
    string query,
    int initialLimit = 50,
    int finalLimit = 10)
{
    // Stage 1: Fast vector search
    var candidates = await SearchAsync(query, initialLimit);

    // Stage 2: Precise reranking
    var rerankedResults = await _rerankingService.RerankAsync(
        query,
        candidates
    );

    return rerankedResults.Take(finalLimit).ToList();
}
```

## फेस 3: तैयार करना (उत्तर देना)

अब कि हमारे पास संबंधित जानकारी है, हम इसे उपयोक्ता के प्रश्न के साथ साथ के लिए खाते हैं.

```mermaid
flowchart TB
    A[User Query] --> B[Retrieved Context 1]
    A --> C[Retrieved Context 2]
    A --> D[Retrieved Context 3]

    B --> E[Construct Prompt]
    C --> E
    D --> E
    A --> E

    E --> F["System: You are a helpful assistant...\n\nContext:\n1. Docker Compose allows...\n2. Services are defined...\n3. Volumes persist data...\n\nQuestion: How do I use Docker Compose?\n\nAnswer:"]

    F --> G[LLM]
    G --> H[Generated Answer with Citations]

    style E stroke:#f9f,stroke-width:2px
    style G stroke:#bbf,stroke-width:2px
```

### चरण 1: निर्माण से पहले

यह है जहां RAG एक कला बन जाता है. आप की आवश्यकता है ताकि LLM:

- दिए गए संदर्भों का उपयोग करता है (उसका आंतरिक ज्ञान नहीं)
- जब संभव हो सूत्रों का वर्णन करें
- जब संदर्भ में कोई उत्तर नहीं होता है तो स्वीकार करता है
- एक स्थायी स्वर/ शैली बनाए रखता है

**एक उदाहरण प्रायोगिक टैम्प्लेट मेरे वकील जीबीडी तंत्र से:**

```csharp
public string BuildRAGPrompt(string query, List<SearchResult> context)
{
    var sb = new StringBuilder();

    sb.AppendLine("You are a technical writing assistant. Your task is to answer the user's question using ONLY the provided context from past blog posts.");
    sb.AppendLine();
    sb.AppendLine("CONTEXT:");
    sb.AppendLine("========");

    for (int i = 0; i < context.Count; i++)
    {
        sb.AppendLine($"[{i + 1}] {context[i].Title}");
        sb.AppendLine($"Source: {context[i].Source}");
        sb.AppendLine($"Content: {context[i].Text}");
        sb.AppendLine($"Relevance: {context[i].Score:P0}");
        sb.AppendLine();
    }

    sb.AppendLine("========");
    sb.AppendLine();
    sb.AppendLine("INSTRUCTIONS:");
    sb.AppendLine("- Answer the question using the provided context");
    sb.AppendLine("- Cite sources using [1], [2], etc.");
    sb.AppendLine("- If the context doesn't contain enough information, say so");
    sb.AppendLine("- Maintain the technical, practical tone of the blog");
    sb.AppendLine();
    sb.AppendLine($"QUESTION: {query}");
    sb.AppendLine();
    sb.AppendLine("ANSWER:");

    return sb.ToString();
}
```

### चरण 2: गलत

बनाया गया प्राम्प्ट पीढ़ी के लिएLLM में चला जाता है. यह हो सकता है:

- **बंद करें (C)**: ओपन- डिज़ाइन, एन. ए.
- **स्थानीय मॉडल**: llolm.p, nX रन समय पर, या टन का इस्तेमाल करना

**स्थानीयLM का उपयोग कर उदाहरण:**

```csharp
public async Task<string> GenerateResponseAsync(string prompt)
{
    var result = await _llamaSharp.InferAsync(prompt, new InferenceParams
    {
        Temperature = 0.7f,      // Creativity (0 = deterministic, 1 = creative)
        TopP = 0.9f,             // Nucleus sampling
        MaxTokens = 500,         // Response length limit
        StopSequences = new[] { "\n\n", "User:", "Question:" }
    });

    return result.Text.Trim();
}
```

**कुंजी पैरामीटर स्पष्टः**

- **तापक्रम**: नियंत्रण बेतरतीबता (0 = हमेशा सबसे अधिक संभावना, 1 = उदाहरण विशेष)
- **शीर्ष पी**: नॉस्कस पिकिंग - उन संकेतों पर ध्यान दीजिए जो ऊपरी संभावनाएँ उत्पन्‍न करते हैं
- **अधिकतम परफ़ॉर्मेंस**: सीमा जवाब लंबाई
- **अनुक्रम बन्द करें**: कब तैयार करना बंद करें

### चरण 3: पोस्ट- प्रक्रिया

LLM एक प्रतिक्रिया उत्पन्न करने के बाद, हम अक्सर की जरूरत है:

- उल्लेख किए जाने वाले तथा कड़ियों में परिवर्तित करने के लिए उन्हें निकालें
- कोड खंडित करें
- मेटाडाटा जोड़ें (मान, भरोसा अंक)
- डिबगिंग के लिए व्यवहार लॉग करें

**उदाहरण डाक- प्रक्रिया:**

```csharp
public RAGResponse PostProcess(string llmOutput, List<SearchResult> sources)
{
    var response = new RAGResponse
    {
        Answer = llmOutput,
        Sources = new List<Source>()
    };

    // Extract citations like [1], [2]
    var citations = Regex.Matches(llmOutput, @"\[(\d+)\]");

    foreach (Match match in citations)
    {
        int index = int.Parse(match.Groups[1].Value) - 1;
        if (index >= 0 && index < sources.Count)
        {
            var source = sources[index];
            response.Sources.Add(new Source
            {
                Title = source.Title,
                Url = GenerateUrl(source.Source),
                RelevanceScore = source.Score
            });
        }
    }

    // Convert markdown citations to hyperlinks
    response.FormattedAnswer = Regex.Replace(
        llmOutput,
        @"\[(\d+)\]",
        m => {
            int index = int.Parse(m.Groups[1].Value) - 1;
            if (index >= 0 && index < sources.Count)
            {
                var url = GenerateUrl(sources[index].Source);
                return $"[[{m.Groups[1].Value}]]({url})";
            }
            return m.Value;
        }
    );

    return response;
}
```

# संपर्कों को समझने के लिए: कोन, केवी कैश, और कॉन्टेक्स्ट विंडोज़

हम व्यावहारिक अनुप्रयोगों में कदम करने से पहले, यह समझने के लिए जरूरी है कि कैसे LLM आंतरिक काम करता है. यह ज्ञान आपको RELG सिस्टमों को स्तरित करने और आम फन्दों से बचने में मदद करता है.

## इसका क्या मतलब है?

Tomons बुनियादी इकाइयों है कि LLM प्रक्रिया. पाठ सीधे मॉडलों के लिए नहीं खिला रहा है - यह संकेतों में पहले टूट गया है.

**उदाहरण टोकनाइज़ेशन:**

```
Input:  "Understanding Docker containers"
Tokens: ["Under", "standing", " Docker", " containers"]
```

भिन्न मॉडलों का उपयोग भिन्न टोकनीकरण नीतियाँ:

- **जीटी मॉडल**: सन्‌ 1650के शब्दावली के साथ इस्तेमाल करें
- **पटाख**: समान बीपीई के निकट
- **लालाला मॉडल**: वाक्यबद्ध टोकन

**RAG के लिए लक्षणों को क्यों बनाएँ:**

```csharp
public class TokenCounter
{
    // Rough approximation: 1 token ≈ 0.75 words (English)
    public int EstimateTokens(string text)
    {
        var wordCount = text.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length;
        return (int)(wordCount / 0.75);
    }

    public int EstimateTokensAccurate(string text, ITokenizer tokenizer)
    {
        // Use actual tokenizer for precision
        return tokenizer.Encode(text).Count;
    }
}
```

**कॉन्टेक्स्ट विंडो सीमाएँ:**

- GET-3. 5: 16K निशानियाँ
- GES-4: 8के- 28-K टोकन ( अक्सर पर निर्धारित)
- 3.5 सोनानेट: 200K चिन्ह
- एलला 3: 8के चिन्ह (हालाँकि दिखाया जा सकता है)

RAG सिस्टम में, आपको फिट होना चाहिए:

```
Total tokens = System prompt + Retrieved context + User query + Response buffer
```

यदि तुम्हारा RG हर 500 संकेतों के 10 दस्तावेज़ों को खोजता है, तो यह 5,000 संकेत केवल संदर्भ और प्रतिक्रिया के लिए है!

**व्यावहारिक RAG टोकन प्रबंधन:**

```csharp
public class ContextWindowManager
{
    private readonly int _maxContextTokens;
    private readonly int _systemPromptTokens;
    private readonly int _responseBufferTokens;

    public ContextWindowManager(
        int totalContextWindow = 4096,
        int systemPromptTokens = 300,
        int responseBufferTokens = 500)
    {
        _maxContextTokens = totalContextWindow;
        _systemPromptTokens = systemPromptTokens;
        _responseBufferTokens = responseBufferTokens;
    }

    public List<SearchResult> FitContextInWindow(
        List<SearchResult> retrievedDocs,
        string query)
    {
        var queryTokens = EstimateTokens(query);

        // Available tokens for retrieved context
        var availableForContext = _maxContextTokens
            - _systemPromptTokens
            - queryTokens
            - _responseBufferTokens;

        var selectedDocs = new List<SearchResult>();
        var currentTokens = 0;

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

            if (currentTokens + docTokens <= availableForContext)
            {
                selectedDocs.Add(doc);
                currentTokens += docTokens;
            }
            else
            {
                break; // Context window full
            }
        }

        return selectedDocs;
    }

    private int EstimateTokens(string text)
    {
        // Rule of thumb: 1 token ≈ 4 characters
        return text.Length / 4;
    }
}
```

## केवी कैश:

जब एक TLM पाठ तैयार करता है, यह प्रत्येक संकेत के लिए शुरू से सब कुछ फिर से सक्रिय नहीं करता. यह एक का उपयोग करता है **कुंजी- मूल्य (केवी) कैश** याद रखने के लिए क्या वह पहले से ही गणना की है.

### रूपांतरण करनेवाले कैसे काम करते हैं (सरल)

ट्रांसमीटर संदर्भ को समझने के लिए सभी पिछले संकेतों को "क्रमिक" का उपयोग करते हैं।

```mermaid
flowchart TB
    subgraph "Generation Step 1: 'Docker'"
        A1[Input: 'Docker'] --> B1[Compute K,V for 'Docker']
        B1 --> C1[Store in KV Cache]
        C1 --> D1[Generate: 'is']
    end

    subgraph "Generation Step 2: 'is'"
        A2[Input: 'is'] --> B2[Compute K,V for 'is']
        B2 --> C2[Store in KV Cache]
        C2 --> E2[Retrieve KV for 'Docker']
        E2 --> F2[Attend: 'is' to 'Docker']
        F2 --> D2[Generate: 'a']
    end

    subgraph "Generation Step 3: 'a'"
        A3[Input: 'a'] --> B3[Compute K,V for 'a']
        B3 --> C3[Store in KV Cache]
        C3 --> E3[Retrieve KV for 'Docker', 'is']
        E3 --> F3[Attend: 'a' to all previous]
        F3 --> D3[Generate: 'container']
    end

    D1 --> A2
    D2 --> A3

    style C1 stroke:#f9f,stroke-width:3px
    style C2 stroke:#f9f,stroke-width:3px
    style C3 stroke:#f9f,stroke-width:3px
```

**केवी कैश के बगैर:**

- चरण 1: 1 ईएक्सपीएस( 1)
- चरण 2: [2] प्रक्रिया get get revs से 2 निशानियाँ
- चरण 3: प्रक्रिया  मनुष्यत्वशशश ओ(3) से प्रकट होती है
- कुल: O( 1 + 2 + 3 + ... + N) = O( N( N2)

**केवी कैश के साथ:**

- चरण 1: 1 प्रक्रिया टोकन, कैश, वी- 1. 1)
- चरण 2: 1 नया टोकन
- चरण 3: 1 नया टोकन
- कुल: O(N)

यह पीढ़ी बनाता है **तीव्र गति** - 10 चिह्न/second और 100 निशानियाँ/सेकेंड के बीच अंतर है.

### केवी कैश ट्री स्ट्रक्चर

केवी कैश एक "रेरे" का आकार बनाता है कि किस प्रकार रूपांतरणों में काम करता है. मॉडल में हर परत का अपना के-, ववीएस होता है.

```mermaid
graph TB
    A[Input Tokens:<br/>'What is Docker?'] --> B[Layer 1 Attention]
    B --> C[Layer 1 KV Cache]

    B --> D[Layer 2 Attention]
    D --> E[Layer 2 KV Cache]

    D --> F[Layer 3 Attention]
    F --> G[Layer 3 KV Cache]

    F --> H[... up to Layer N]
    H --> I[Output: 'Docker is']

    C -.Key-Value pairs<br/>for all input tokens.-> C
    E -.Key-Value pairs<br/>for all input tokens.-> E
    G -.Key-Value pairs<br/>for all input tokens.-> G

    style C stroke:#bbf,stroke-width:2px
    style E stroke:#bbf,stroke-width:2px
    style G stroke:#bbf,stroke-width:2px
```

**प्रत्येक परत भंडारितः**

- **कुंजियाँ (K)**: ध्यान संख्या की गणना करने के लिए इस्तेमाल किया जाता है
- **मान (V)**: ध्यान के आधार पर एक साथ मिश्रितता प्राप्त होती है

इसके साथ मॉडल के लिए:

- 32 परतों
- 4096 छुपे आयाम
- 32 ध्यान देने वालों के सिर
- 8के संदर्भ विंडो

एक अनुक्रम के लिए केवी कैश है:

```
2 (K and V) × 32 layers × 4096 dimensions × 8192 tokens × 2 bytes (FP16)
≈ 4.3 GB of VRAM!
```

यही कारण है कि लंबे संदर्भ विंडो स्मृति- रचना हैं।

### रीजी तंत्र में केवी कैश

RAG सिस्टमों ने चालाक तरीक़ों से के- वीवी कैश का लाभ उठाया:

**कैशिंग संकेत करें** (कुछ एपीआई के द्वारा Athuts की तरह समर्थित है ):

```csharp
public class CachedRAGService
{
    // System prompt and retrieved context can be cached!
    public async Task<string> GenerateWithCachedContextAsync(
        string systemPrompt,          // Cached
        List<SearchResult> context,   // Cached
        string userQuery)             // Not cached, changes each time
    {
        var contextText = FormatContext(context);

        // The KV cache for systemPrompt + contextText is reused across queries
        var prompt = $@"
{systemPrompt}

CONTEXT:
{contextText}

QUERY: {userQuery}

ANSWER:";

        return await _llm.GenerateAsync(prompt, useCaching: true);
    }
}
```

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

- प्रथम क्वेरी: तंत्र प्राम्प्ट + संदर्भ (धीमा) के लिए केवी कैश की गणना करता है.
- इसी संदर्भ के साथ की गई प्रविष्टियों को फिर से प्रयोग करता है केवीडी (१०x तेजी से!)
- सिर्फ उपयोक्ता क्वेरी भाग को ताजा गणना की आवश्यकता है

**व्यावहारिक उदाहरण:**

```
Query 1: "How do I use Docker?" → 2 seconds (no cache)
Query 2: "What are Docker benefits?" → 0.2 seconds (cache hit!)
Query 3: "Docker vs VMs?" → 0.2 seconds (cache hit!)
```

सभी तीन गढ़ समान संदर्भ का प्रयोग करते हैं, इसलिए कि संदर्भों के लिए केवी कैश फिर से उपयोग किया जाता है ।

## मात्रा और रेचिच को सीमित करने के लिए

लक्षणों और केवीसी कैश को समझने से आपके RGGMPER के फैसलों की जानकारी मिलती है:

### 1. क्लंकिंग आकार

छोटा भाग = अधिक सटीक वापसी, लेकिन अधिक सिर:

```csharp
// Option A: Small chunks (200 tokens each)
// Retrieve 20 chunks = 4,000 tokens
// Pro: Very precise, only relevant info
// Con: More KV cache entries, slower attention

// Option B: Larger chunks (500 tokens each)
// Retrieve 8 chunks = 4,000 tokens
// Pro: Better context coherence, fewer KV entries
// Con: More noise, less precise

public class AdaptiveChunker
{
    public int DetermineChunkSize(int contextWindowSize)
    {
        if (contextWindowSize <= 4096)
            return 200; // Small chunks for limited windows

        if (contextWindowSize <= 16384)
            return 500; // Medium chunks

        return 1000; // Large chunks for big windows
    }
}
```

### 2. कॉन्टेक्स्ट विंडो यूटाइजेशन

संदर्भ विंडो अधिकतम मत करो - पीढ़ी के लिए जगह छोड़ दें:

```csharp
public class SafeContextManager
{
    public int GetSafeContextLimit(int totalContextWindow)
    {
        // Use only 75% for input, reserve 25% for output
        return (int)(totalContextWindow * 0.75);
    }

    // Example: 4K model
    // Total: 4096 tokens
    // Safe input: 3072 tokens
    // Reserved for output: 1024 tokens
}
```

### 3. मल्टी बैक- रे बातचीत

गपशप में, वार्तालाप इतिहास हर मोड़ के साथ बढ़ता है:

```
Turn 1:
System + Context + Query1 = 3000 tokens
Response1 = 300 tokens
Total: 3300 tokens

Turn 2:
System + Context + Query1 + Response1 + Query2 = 3650 tokens
Response2 = 300 tokens
Total: 3950 tokens

Turn 3:
System + Context + Query1 + Response1 + Query2 + Response2 + Query3 = 4250 tokens
ERROR: Context window exceeded!
```

**समाधानः फिर से प्रारंभ किए विंडो के साथ विस्तार किया जा रहा है**

```csharp
public class ConversationalRAG
{
    private readonly int _maxHistoryTokens = 1000;

    public async Task<string> ChatAsync(
        List<ConversationTurn> history,
        string newQuery)
    {
        // Re-retrieve context based on current query
        var context = await RetrieveContextAsync(newQuery);

        // Keep only recent conversation history
        var relevantHistory = TrimHistory(history, _maxHistoryTokens);

        var prompt = BuildPrompt(context, relevantHistory, newQuery);

        return await _llm.GenerateAsync(prompt);
    }

    private List<ConversationTurn> TrimHistory(
        List<ConversationTurn> history,
        int maxTokens)
    {
        var trimmed = new List<ConversationTurn>();
        var currentTokens = 0;

        // Keep most recent turns
        foreach (var turn in history.Reverse())
        {
            var turnTokens = EstimateTokens(turn.Query) + EstimateTokens(turn.Response);

            if (currentTokens + turnTokens <= maxTokens)
            {
                trimmed.Insert(0, turn);
                currentTokens += turnTokens;
            }
            else
            {
                break;
            }
        }

        return trimmed;
    }
}
```

### 4 एन. ए.

एपीआई आधारित आरोप प्रति टोकन. RG को विस्फोटित कर सकते हैं यदि ध्यान नहीं दिया:

```csharp
public class CostAwareRAG
{
    // OpenAI GPT-4 pricing (example):
    // Input: $0.03 per 1K tokens
    // Output: $0.06 per 1K tokens

    public decimal EstimateQueryCost(
        int systemPromptTokens,
        int retrievedContextTokens,
        int queryTokens,
        int expectedResponseTokens)
    {
        var inputTokens = systemPromptTokens + retrievedContextTokens + queryTokens;
        var outputTokens = expectedResponseTokens;

        var inputCost = (inputTokens / 1000m) * 0.03m;
        var outputCost = (outputTokens / 1000m) * 0.06m;

        return inputCost + outputCost;
    }

    // Example:
    // System: 300 tokens
    // Context: 3000 tokens (10 retrieved docs)
    // Query: 50 tokens
    // Response: 500 tokens
    //
    // Cost = ((300 + 3000 + 50) / 1000 * 0.03) + (500 / 1000 * 0.06)
    //      = (3350 / 1000 * 0.03) + (500 / 1000 * 0.06)
    //      = $0.1005 + $0.03
    //      = $0.1305 per query
    //
    // At 1000 queries/day = $130/day = $3,900/month!
}
```

**लागत कमी पॉलिसी:**

1. कम हो गया दस्तावेजों में बेहतर- से- अच्छा सुधार हो रहा है
2. प्राम्प्ट कैशिंग इस्तेमाल करें (A)
3. अंतिम पीढ़ी के लिए कीमतदार मॉडल इस्तेमाल करें
4. कॉन्टेक्स्ट का प्रयोग कर रहा है

## मैकेस के साथ पूर्ण रेग्रेज़ का दृश्‍य करना

यहाँ संकेतों, केवी कैश, और RAG एक साथ फिट है:

```mermaid
flowchart TB
    A[User Query:<br/>'How does Docker work?'<br/>≈ 12 tokens] --> B[Generate Query Embedding]

    B --> C[Vector Search]
    C --> D[Retrieved Docs:<br/>5 docs × 500 tokens<br/>= 2,500 tokens]

    D --> E[Construct Prompt]
    A --> E

    E --> F["Complete Prompt:<br/>System: 300 tokens<br/>Context: 2,500 tokens<br/>Query: 12 tokens<br/>Total: 2,812 tokens"]

    F --> G[Tokenize Prompt]
    G --> H["Token IDs:<br/>[245, 1034, 8829, ...]<br/>2,812 token IDs"]

    H --> I[LLM Layer 1]
    I --> J[Compute K,V]
    J --> K[KV Cache Layer 1:<br/>2,812 K,V pairs]

    I --> L[LLM Layer 2]
    L --> M[Compute K,V]
    M --> N[KV Cache Layer 2:<br/>2,812 K,V pairs]

    L --> O[... Layers 3-32]
    O --> P[Generate Token 1: 'Docker']

    P --> Q[Add to KV Cache]
    Q --> R[Generate Token 2: 'is']
    R --> S[Add to KV Cache]
    S --> T[... until completion]

    T --> U["Response: 'Docker is a containerization platform...'<br/>≈ 400 tokens"]

    style K stroke:#f9f,stroke-width:2px
    style N stroke:#f9f,stroke-width:2px
    style Q stroke:#bbf,stroke-width:2px
    style S stroke:#bbf,stroke-width:2px
```

**मुख्य अंतर्दृष्टि:**

1. **इनपुट टोकन** (2,812) प्रारंभिक केवी कैश बनाने के लिए एक बार प्रोसेस किया जाता है
2. **तैयार किया जा रहा है** एक संकेत एक समय में होता है, केवी कैश का उपयोग कर
3. **प्रत्येक नए टोकन** भविष्य में हाज़िर होने के लिए केवीएस कैश में और भी जोड़ें
4. **कुल वीरैम** सभी आयतों के लिए = मॉडल्स + केवी कैश की आवश्यकता है
5. **आगे का संदर्भ** = बड़े केवी कैश = अधिक वीरैम

## रीजी के लिए व्यावहारिक हमदर्दी

लक्षणों और केवीवी कैश को समझने से रेजी डिज़ाइन बेहतर बनता है:

**1. प्री- एजेंट तथा कैश सामान्य संदर्भ:**

```csharp
// Cache KV for frequently used system prompts + static context
var cachedSystemContext = await _llm.PrecomputeKVCache(systemPrompt + staticContext);

// Reuse for each query (much faster)
foreach (var query in userQueries)
{
    var response = await _llm.GenerateAsync(query, reuseKVCache: cachedSystemContext);
}
```

**2 सापेक्ष सीमाएँ नापते हुए:**

```csharp
// Bad: Arbitrary 500-character chunks
var chunks = text.Chunk(500);

// Good: Chunk on sentence boundaries, measure in tokens
public List<string> ChunkByTokens(string text, int maxTokensPerChunk)
{
    var sentences = SplitIntoSentences(text);
    var chunks = new List<string>();
    var currentChunk = new StringBuilder();
    var currentTokens = 0;

    foreach (var sentence in sentences)
    {
        var sentenceTokens = EstimateTokens(sentence);

        if (currentTokens + sentenceTokens > maxTokensPerChunk && currentTokens > 0)
        {
            chunks.Add(currentChunk.ToString());
            currentChunk.Clear();
            currentTokens = 0;
        }

        currentChunk.Append(sentence).Append(" ");
        currentTokens += sentenceTokens;
    }

    if (currentTokens > 0)
        chunks.Add(currentChunk.ToString());

    return chunks;
}
```

**3. मॉनीटर टोकन उपयोग से उत्पादन में:**

```csharp
public class RAGTelemetry
{
    public void LogRAGQuery(
        string query,
        List<SearchResult> retrievedDocs,
        string response)
    {
        var queryTokens = EstimateTokens(query);
        var contextTokens = retrievedDocs.Sum(d => EstimateTokens(d.Text));
        var responseTokens = EstimateTokens(response);
        var totalTokens = queryTokens + contextTokens + responseTokens;

        _logger.LogInformation(
            "RAG Query: {Query} | Context: {ContextTokens} tokens from {DocCount} docs | " +
            "Response: {ResponseTokens} tokens | Total: {TotalTokens} tokens",
            query, contextTokens, retrievedDocs.Count, responseTokens, totalTokens
        );

        // Alert if approaching context limit
        if (totalTokens > _maxTokens * 0.9)
        {
            _logger.LogWarning("Approaching token limit: {TotalTokens}/{MaxTokens}",
                totalTokens, _maxTokens);
        }
    }
}
```

# उलझन: दिमागी मास्टरी

हमने रेजी सिस्टम की पूरी तकनीकी रचना को कवर कर दिया है:

**फेस 1: निर्देशिकािंग**

- भिन्न स्रोतों से पाठ निकल रहा है
- क्लैम्पिंग नीति (कांट- आधारित, वाक्य- आधारित, साथ ही साथ)
- अंतर्निर्मित पीढ़ी (एनएक्स, एपीआई सेवा)
- वेक्टर भंडार (क्यूवरेज, prvor, Pine)

**फेस 2: reting**

- क्वैरी किया जा रहा है (पंक्तििंग के समान मॉडल!)
- एकरूप खोज (सेप्टन, न्यूक्लिडियन, डॉट उत्पाद)
- बेहतर क्रम के लिए वैकल्पिक रीप्लेिंग
- सुधार परिणाम के लिए मेटाडाटा फ़िल्टरName

**फेस 3: तैयार करना**

- कोड साफ करें (c) (c)
- संकेत (प्रयोग, शीर्ष-p, चिन्ह)
- पोस्ट- प्रोसेसिंग (अनुप्रयोग, फ़ॉर्मेटिंग)

**आंतरिक आंतरिक**

- Toks: बुनियादी इकाई (नहीं अक्षर!)
- केवी कैश: क्यों पीढ़ी तेजी से है (पंक्तिर, नहीं)
- संदर्भ विंडो: RAG में टोकन सीमा पार करना
- लागत समायोजन: कैशिंग, संपीडन, स्मार्ट वापसी

**मुख्य तकनीकी अंतर्दृष्टि:**

1. **वही शामिल किया गया मॉडल** निर्देशिका और वापसी के लिए!)
2. **आप जितना सोचते हैं उससे अधिक बातें बरबाद करना** - स्थायी टिक की रक्षा करता है
3. **सुधरने में सुधार** देर से मुद्रा की कीमत पर
4. **देखरेख के लिए ज़रूरी है** - क्वैरी करने से पहले अनुमान
5. **केवी- कैश रीजी रीग्रेसन बनाता है** - फिर से प्राधिकृत गणना
6. **कॉन्टेक्स्ट विंडो तेज भरें** - 10 डॉकs × 500 टोकन = 5K निशानियाँ

# भाग ३: १७ में अभ्यास करते रहिए

अब आप समझते हैं **RAG काम कैसे करता है** आप इन व्यवस्थाओं का कैसे निर्माण करते हैं?

में **[अभ्यास में भाग 3: RAG](/blog/rag-practical-applications)**हम पुस्तकालय से कार्यान्वयन के लिए स्थानांतरित कर रहे हैं:

**वास्तविक विश्व अनुप्रयोग:**

- इस ब्लॉग में संबंधित पोस्ट सलाह
- चापिक ब्लॉग खोजQuery
- एक "लेवर जीबी" लेखन सहायक बनाने के लिए

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

- संदर्भ को सुरक्षित रखने की योजनाएँ
- अपने डोमेन के लिए प्रदर्शन गुणवत्ता सुधार
- संदर्भ विंडो को खाली करना गतिशीलता से
- संदर्भ रखने के बावजूद अपराध को रोकें
- अपनी निर्देशिका को ऊपर अद्यतन

**विस्तृत तकनीक:**

- हायफ्टल दस्तावेज़ एम्बेडिंग (HyDE)
- मेल- बक्सा फिल्टरों के साथ स्व-किंग
- विस्तृत परिणामों के लिए बहु- विशेषता रीजीGenericName
- टोकन उपयोग को कम करने के लिए कॉन्टेक्स्टडिस्क संपीडन
- जटिल क़ब्रों के लिए बहु-प- पैक रीजी
- लंबी-टर्म वार्तालाप मेमोरी

**प्रारंभ किया जा रहा है:**

- सप्ताह के द्वारा कार्यान्वयन योजना
- व्यावहारिक कोड उदाहरण
- ऑप्टीमाइज़ेशन नीति
- जब RAG का उपयोग नहीं किया जा सकता

**[भाग ३: १७ का अभ्यास करते रहिए](/blog/rag-practical-applications)**

## संसाधन

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

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

**श्रेणी नेविगेशन:**

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

**[भाग 3 में जारी रखें](/blog/rag-practical-applications)**