This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
RAG in der Praxis-:-Gebäude-Real---Welt-Anwendungen
Saturday, 22 November 2025
Im Teil dieser RAG-SerieWir befassten uns mit den Grundlagen der Retrieval--Augmented Generation, was es ist, wie es funktioniert, und die zugrunde liegende Technologie., und die darunterliegende Technologie. Dieser Artikel zeigt Ihnen, wie man reale RAG-Systeme mit arbeitendem C...
Einleitung
Wenn Sie nicht gelesen haben Teil 1:-RAG erklärtIch empfehle, dort zu beginnen, um die grundlegenden Konzepte zu verstehen.
- Was RAG ist und warum es zählt
- Wie Einbettungen und Vektorsuche funktionieren
- LLM-interne Datenverarbeitungsgeräte (MSK)
- RAG vs fine---Tuning und andere Ansätze
Dieser Artikel geht davon aus, dass Sie diese Grundlagen verstehen und konzentriert sich auf Implementierung: Optimierung: , und reale Muster von -.
Real--.World RAG Anwendungen auf diesem Blog
I''ve baute mehrere RAG--'powered Funktionen auf diesem Blog, lassen Sie mich Ihnen konkrete Beispiele zeigen.
Empfehlung zu verwandten Artikeln
Jeder Blog-Post kann zeigen, verwandte Beiträge, die mit semantischen Ähnlichkeiten.
Wie es funktioniert
- Jeder Blog-Post wird eingebettet, wenn veröffentlicht
- Beim Betrachten eines Posts erhalten wir seine Einbettung aus Qdrant
- Finden Sie die ähnlichsten Post-Embeddings
- Als Verwandte Beiträge anzeigen
Warum es besser ist als Tags
- Tags erfordern manuelle Kategorisierung
- Semantische Suche findet konzeptuell verwandte Beiträge auch ohne passende Tags
- BESCHLÜSSE UND BESCHLEUNIGUNG
Code-Schnipsel, :
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();
}
Suche nach semantischen Blogs
Das Suchfeld auf diesem Blog verwendet RAG-- , Stil semantische Suche ,( , obwohl ohne die Generation Teil , - , it .' , nur retrieval
Benutzererfahrung
- Suche nach einer Datenbank zum Einrichten von Einträgen über PostgreSQL.MSK.3. Entitäts-Framework-Migrationen
- Suche nach "-Deployment - " - findet Beiträge über Docker -, - Hosting-, - CI./ -CD
- Keine Notwendigkeit für exakte Schlüsselwort-Matches
Umsetzung I'-ll decken Gebäude dieses in einem kommenden Artikel auf Vektordatenbanken .
Schriftliche Assistentin
I'®m Gebäude ein komplettes RAG-System, um mir zu helfen, neue Blogposts zu schreiben
Fall verwenden Wenn ich beginne, über die Authentifizierung zu ASP...NET Core.",. das System zu schreiben
- Einbetten meines aktuellen Entwurfs
- Durchsucht vergangene Beiträge nach verwandten Inhalten über Authentifizierung.
- schlägt vor, relevante Code-Schnipsel I'-ve verwendet vor
- Autorisiert interne Links zu verwandten Beiträgen
- Hält Konsistenz mit meinem Schreibstil
Vollständige RAG-Pipeline
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;
}
Dies ist RAG in der Aktion Retrieval von ( [Semantische Suche]) + Augmentation [MSC4] Kontext hinzufügen [MSSK5] Generation Vorschläge für ( [LLM]
Häufige Herausforderungen und Lösungen der RAG
Gebäudeproduktion RAG-Systeme ist banal , . , Hier sind Herausforderungen I' , wie sie zu lösen , . ,
Herausforderung Strategie für das Chunking
Problemstellung Wie spaltest du Dokumente? - Zu klein? - Verlust des Kontexts? - zu groß? - irrelevant.
Lösung Hybride Krümmung auf Basis der Dokumentenstruktur
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;
}
}
Bewährte Verfahren
- Respektieren Sie die Dokumentenstruktur
- Überlappung zwischen Brocken hinzufügen
- Codeblöcke intakt bewahren
- Abschnittskopfzeilen in jedem Block für Kontext einbinden
Herausforderung Qualität einbetten
Problemstellung Generische Einbettungsmodelle dürfen keine Domäne erfassen
Lösungen
Option Einbettungen von Fein--Tune ,('fortgeschritten ,)"
# 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)
Option "Hybrid-Einbettungen" Mehrteilige Modelle für die Kombinierung von )
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);
}
Option "Metadatenfilterung hinzufügen"
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" } }
}
}
);
Herausforderungen im Kontext Fensterverwaltung
Problemstellung LLMs haben Token-Grenzen.. , Wie passen Sie Abfrage?+ , Kontext , + , prompt im Fenster.
Lösung Dynamische Kontextauswahl und Zusammenfassung
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);
}
Herausforderung - Halluzination trotz RAG
Problemstellung Selbst bei Kontexten werden LLMs manchmal ignoriert und halluziniert
Lösungen
Schnellmaschinenbau
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):
";
Nach der Validierung der --Generation
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;
}
Iterative Verfeinerung
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.";
}
Herausforderung, den Index nach oben zu halten
Problemstellung Wie Sie neue Dokumente hinzufügen, muss die Vektordatenbank aktuell bleiben.
Lösung Automatisierte Indexierungs-Pipeline
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
);
}
}
}
}
}
Fortgeschrittene RAG-Techniken
Lassen Sie uns die neuesten RAG-Techniken aus neuerer Forschung erforschen
Hypothetische Dokument-Embeddings
Problemstellung Benutzer-Abfragen sind oft kurz und schlecht gebildet .. . Dokument Stücke sind detailliert und gut geschrieben , . . Diese Fehlanpassung verletzt Retrieval .
Lösung Generieren Sie ein hypothetisches ideales Dokument, das die Abfrage beantworten würde.
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);
}
Warum es funktioniert Die hypothetische Antwort benutzt ähnliche Sprache und Struktur zu den tatsächlichen Dokumenten.
Selbstbefragung
Problemstellung Benutzeranfragen mischen oft semantische Suche mit Metadaten-Filtern
Beispiel: " Neueste Beiträge über Docker, " = semantisch](" [Docker, ")] filter:(>
Lösung Verwenden Sie LLM, um die Abfrage in semantische Metadatenfilter zu parsieren.
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)
);
Mehrsprachige RAG
Problemstellung Eine einzelne Abfrage könnte relevante Dokumente aufgrund der Phrasierung vermissen.
Lösung Generieren Sie mehrere Variationen der Suche nach dem Suchergebnis mit allen Ergebnissen kombinieren
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;
}
Kontextkompression
Problemstellung Abrufene Brocken enthalten irrelevant Informationen, die es alle Abfälle Tokens schicken
Lösung Verwenden Sie ein kleineres LLM, um den abgerufenen Kontext auf nur relevante Teile zu komprimieren.
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);
}
Iteratives Retrieval von (, Multi--, Hop RAG®),
Problemstellung Komplexe Fragen erfordern Informationen aus mehreren Quellen, die angeschlossen werden müssen
Beispiel::-Datei Welche Datenbank nutzt das Blog und wie ist semantische Suche implementiert??"-Datei:
- Hop Suche welche Datenbank verwendet wird
- Hop - Finden Sie, wie semantische Suche funktioniert mit dieser Datenbank
Lösung iterative Retrieval und Synthese
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);
}
Kurzbeschreibung des Langzeitspeichers mit RAG
Problemstellung Wie baut man KI-Systeme, die sich an Gespräche vor Monaten oder Jahren erinnern??. Traditionelle Chatbots verlieren nach jeder Sitzung den Kontext...
Lösung Kombinieren Sie RAG mit progressiver Zusammenfassung, um persistent zu erstellen.
Dies ist der Ansatz, der in DiSE - Synthetische Evolution Ein fortschrittliches System, das RAG-- based context memory verwendet, um die gemeinsame Gesprächsgeschichte auf unbestimmte Zeit zu erhalten.
Beispielszenario
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..."
Wie es funktioniert
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
Umsetzungsansatz-:-
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")
}
);
}
}
}
Warum dies mächtig ist
- Unendliche Speicherspanne Gespräche von vor Jahren sind so zugänglich wie gestern
- Semantische Suche "George'Spezifikationen " finden das Gespräch, auch wenn es als "George 's verschreibungspflichtige Brillenanforderungen gespeichert ist
- Einrichtung, die eine Verbindung herstellt Alle Gespräche, die erwähnt werden, sind miteinander verbunden.
- Datenschutz Benutzerspeicher-Isolierung kann per-- user implementieren
- Kosteneffektiv Summarisierung verhindert eine Explosion des Speichers bei Aufrechterhaltung der Durchsuchbarkeit
Reale messk0-Welt Beispiel aus DiSE-:
DiSE verwendet diesen Ansatz, um sich zu erinnern
- Aufrufen von Werkzeugen Vor Monaten (, was funktionierte ,, was fehlschlug
- Code-Muster die in vergangenen Projekten erfolgreich waren
- Benutzereinstellungen etabliert in früheren Gesprächen
- Kenntnisse im Bereich im Laufe der Zeit angesammelt
Dies erzeugt ein KI-System, das aus jeder Interaktion wirklich " lernt und statt jede Sitzung neu zu starten, institutionelles Gedächtnis baut.
Herausforderungen zu berücksichtigen
- PrivatsphäreAlte Gespräche müssen pro Benutzer richtig isoliert werden
- BedeutungszerfallNicht alle alten Informationen bleiben relevant
- LagerkostenNotwendigkeit der Zusammenfassungsstrategie für die Skala
- KohärenzZusammenfassungen mit Originalen ausgerichtet halten
- Genauigkeit des WiederauftretensAusgewogenheit zwischen aktuellem und historisch bedeutsamem Kontext
Diese Technik transformiert RAG aus meiner Suche nach Dokumenten " in "Erinnern Sie sich an alles, was wir jemals diskutiert haben "Aus einem Spiel -Wechsler für lange KI-Assistenten .
Wenn RAG NICHT verwendet werden soll
RAG ist immer die Antwort, wenn es zu vermeiden
Allgemeine Wissensfragen
- Was ist die Hauptstadt von Frankreich? - ?"? - LLM weiß das schon.
- RAG erhöht Latenz und Kosten ohne Nutzen
Kreatives Schreiben
- Poesie, MSK, Fiktion, Brainstorming
- RAG schränkt Kreativität durch Erdung in bestehenden Texten ein
Anforderungen an Echtzeit-Daten
- Vorratspreise,. Live-Sport Ergebnisse
- Besser von API-Integrationen bedient
Mathematische Argumentation
- Berechnen Sie die Spitze auf der Spitze.
- LLMs können arithmetisch tun
Sehr kleine Wissensgrundlagen
- Wenn Ihre Wissensbasis in das Kontextfenster passt
- RAG Overhead ist es wert für Dokumente
Wenn du das LLM-Training kontrollierst
- Wenn du ein Modell von Grund auf an deinen Daten lernst, könnte es besser sein
- RAG ist am besten, wenn Sie Pre---trainierte Modelle verwenden, die Sie Don-'-Steuerung
Erste Schritte mit einem praktischen Leitfaden
Möchten Sie Ihr eigenes RAG-System bauen??. Hier ist ein Schritt.-.von -.step approach
Woche Einfach starten
Ziel Erhalten Sie grundlegende Retrieval arbeiten ohne LLM-.
// 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
Woche - Datenbank für Vektoren hinzufügen
Ziel Skala zu echten Dokumentensammlungen
Nächste Schritte zum Implementieren
- Qdrant im Docker ausführen
- Indexieren Sie Ihre Dokumente
- Suchendpunkt implementieren
I'-ll decken dies im Detail in einem bevorstehenden Artikel auf Vektordatenbanken ab.
Woche - 3:-LLM-Generierung hinzufügen
Ziel Ergänzen Sie die RAG-Pipeline
// 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;
Woche Optimieren und Polnisch
- Caching hinzufügen, auf API Kosten speichern
- Verbesserung der Chunking-Strategie
- Metadatenfilterung hinzufügen
- Hybride Suche durchführen
- Zitationsextraktion hinzufügen
Lokales Lernen
Sobald die Grundlagen arbeiten, migrieren Sie zur lokalen Inferenz.
- Lokale LLM-Inferenz mit GPU-Beschleunigung
- CPU-fähige Einbettungen mit ONNX Laufzeit
Schlußfolgerung
RAG (-Retrieval---Augmented Generation - )- ist eine leistungsstarke Technik, um LLMs genauer zu machen ,-Up--To--Date,- und vertrauenswürdig durch Erdung ihrer Antworten in tatsächlichen Dokumenten ? .-Statt auf das Modell verlassen ?' Trainingsdaten allein ? ,-RAG-Systeme ?
- Abrufen relevante Informationen aus einer Wissensdatenbank mit semantischer Suche
- Erweiterung die Eingabeaufforderung LLM-' mit dem abgerufenen Kontext
- Erzeugen Antworten, die in realen Quellen mit Zitaten geerdet sind
Die wichtigsten Vorteile von RAG-:
- Immer up---to---date aktualisieren Sie einfach Ihre Wissensbasis
- Geerdet in Quellen, reduziert die Halluzination
- Erklärbare Quellen können zitieren
- Kostenwirksame Kosten keine teuren Umschulungen
- Datenschutz- Konservierung ( kann ganz lokal ausgeführt werden
- Domäne: --spezifisches Dokument verwenden Sie Ihre eigenen Dokumente
Wann Sie RAG-: verwenden möchten
- Wissens---intensive Aufgaben
- Häufig aktualisierte Informationen
- Private, proprietäre Daten
- Notwendigkeit von Zitationen und Auditierbarkeit
- Kosten und Einfachheit
Wann zu vermeiden RAG-:
- Fragen des allgemeinen Wissens
- Kreatives Schreiben
- Echtzeit-Daten von (Verwenden Sie stattdessen APIs
- Sehr kleine Wissensgrundlagen
Das Feld entwickelt sich schnell mit fortschrittlichen Techniken wie HyDE-, , multi...- query retrieval , , , und Kontextkompression ,, , aber das Kernkonzept bleibt einfach .: , geben LLMs Zugang zu den richtigen Informationen zur rechten Zeit ?. ,
Starten Sie einfache Messergebnisse, und iterate-Messungen. RAG ist eine der praktischsten Möglichkeiten, um zuverlässige KI-Systeme heute zu bauen
Was ist das nächste?
Nun, da Sie beide die Grundlagen verstehenTeil) und praktische Anwendungen von RAG-, in kommenden Artikeln zeigen Ihnen, wie man komplette , produktionsbereite RAG Systeme in C
Bald kommt:
- CPU®--Friendly Semantic Suche Erstellen semantischer Suche mit ONNX-Einbettungen, die auf jedem VPS ohne GPU-Anforderungen laufen
- Selbstbeleuchtete Vektordatenbanken Vollständiger Setup-Leitfaden für Qdrant mit Docker, einschließlich Indexierung, , und Optimierungsstrategien
- Aufbau eines RAG-Schreibassistenten Eine vollständige Serie über die Erstellung eines AIR- powered Schreibassistenten, der Ihre vorhandenen Inhalte als Wissensbasis nutzt
Diese Artikel werden Sie von der Theorie in die Praxis bringen... mit komplettem Arbeitscode... Einsatzstrategien... und echte Optimierungen, basierend auf dem Betrieb dieser Systeme in Produktion auf diesem Blog...
Bleiben Sie auf Hands abgestimmt.--on-Implementierungsanleitungen, die dieses RAG-Wissen in funktionierende Systeme verwandeln
Aufkommen
Grundlagenpapiere
- Retrieval---Augmentierte Generation für Wissen---Intensive NLP Aufgaben Das ursprüngliche RAG-Papier
- Dense Passage Retrieval für Open---Domain-Fragebeantwortung DPR Stiftung für die Retrievalzeit
- Achtung ist alles, was du brauchst Transformer, die sich auf das Fundament von ( beziehen
Werkzeuge und Frameworks
- Qdrant Vector Datenbank Ich verwende
- ONNX Laufzeit Für lokale Einbettungen
- LLamaSharp Für lokale LLM-Inferenz
- Satztransformatoren Einbetten von Modellen
Weiteres Lesen
- Anthropoglykisches Syndrom Erweiterte RAG-Techniken
- Wie neurale maschinelle Übersetzung funktioniert Die KI-Modelle hinter Einbettungen verstehen
- RAG erklärter Teil Die Grundgrundierung
Glückliches Gebäude