Eine Retrieval‑Augmented Generation (RAG)‑Anwendung kombiniert ein Sprachmodell mit einer durchsuchbaren Dokumentensammlung. Statt dass sie sich nur auf während des Trainings kodierte Informationen verlässt, ruft sie zur Abfragezeit relevante Passagen ab und gibt diese dem Modell als Kontext. Dadurch bleibt das System stets auf dem neuesten Stand, weil es aktuelle Texte einbindet, anstatt auf das statische Wissen des Modells beschränkt zu sein. Dies ermöglicht es dem System, Fragen zu eigenen Dokumenten wie Dokumentationen, Runbooks, Richtlinien und Besprechungsnotizen zu beantworten, ohne dass das Modell feinabgestimmt werden muss.
Dieser Artikel verwendet LangChain und ChromaDB als konkrete Beispiele. Beide sind echte, aktiv gepflegte Bibliotheken. Ähnliche Konzepte gelten für LlamaIndex, Haystack oder jedes andere RAG‑Framework.
Der Kernablauf
Jedes RAG‑System folgt denselben fünf Schritten:
- Dokumente in nützliche Chunks aufteilen.
- Chunks in Embeddings (dichte Vektordarstellungen) umwandeln.
- Diese Embeddings in einem Vektor‑Index speichern.
- Zur Abfragezeit die Frage einbetten und die ähnlichsten Chunks abrufen.
- Die abgerufenen Chunks an ein Sprachmodell übergeben und es bitten, anhand dieses Kontextes zu antworten.
Jeder Schritt baut auf dem vorherigen auf: Ohne sinnvolle Chunks gäbe es keine brauchbaren Embeddings, und ohne Embeddings ließe sich kein effizienter Ähnlichkeitsvergleich durchführen. Retrieval kann Aktualität und Nachvollziehbarkeit verbessern, kann aber unvollständige oder widersprüchliche Dokumente nicht korrekt machen. Die Qualität der Antworten ist durch die Qualität des Quellmaterials begrenzt. Fehlende oder gegensätzliche Informationen führen dazu, dass das Modell entweder lückenhafte Antworten generiert oder unbegründete Behauptungen aufstellt, weil es keinen verlässlichen Anker hat.
Ein minimales funktionierendes Beispiel
from langchain_community.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
# 1. Dokumente aus einem lokalen Verzeichnis laden
loader = DirectoryLoader("./wissensbasis", glob="**/*.md")
docs = loader.load()
# 2. In Chunks aufteilen (Überlappung bewahrt Kontext über Grenzen hinweg)
splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.split_documents(docs)
# 3. Einbetten und in einer lokalen Vektordatenbank speichern
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(chunks, embeddings, persist_directory="./chroma_db")
# 4 & 5. Abrufen und generieren
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
qa = RetrievalQA.from_chain_type(
llm=llm,
retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
)
answer = qa.invoke("Wie setze ich mein Passwort zurück?")
print(answer["result"])
Eine Produktionsimplementierung benötigt auch Dokumentaktualisierungen, Zugangskontrolle, Observability, Rate Limits, Prompt‑Injection‑Abwehr und Evaluationsdatensätze. Dokumentaktualisierungen stellen sicher, dass neu hinzugefügte oder geänderte Dateien schnell neu eingebettet werden; Zugangskontrolle verhindert, dass unberechtigte Nutzer Inhalte einsehen können; Observability ermöglicht das Monitoring von Latenz, Fehlerraten und Nutzungsmustern; Rate Limits schützen die nachgelagerten APIs vor Überlastung; Prompt‑Injection‑Abwehr reduziert das Risiko, dass bösartige Eingaben das Modell zu gefährlichen Ausgaben verleiten; und Evaluationsdatensätze erlauben, die Recall‑ und Precision‑Leistung systematisch zu messen.
Reale Anwendungsfälle
Kundensupport
Ein Dokumentationsassistent kann Fragen zu einer API beantworten und den Gesprächskontext bewahren. Er sollte Quellmaterial zitieren oder verlinken, wo möglich, und unsichere Fälle an einen Menschen weitergeben. Durch das Zitieren lässt sich jede Antwort auf die zugrunde liegende Seite zurückverfolgen, was die Vertrauenswürdigkeit erhöht. Ohne Quellenangaben können Benutzer Antworten nicht verifizieren, und das Modell wird gelegentlich falsch liegen.
Interne Wissensdatenbanken
Teams können Richtlinien, Runbooks und Besprechungsnotizen mit natürlicher Sprache durchsuchen. Zugangskontrolle muss beim Retrieval angewendet werden: Ein Modell sollte keine Dokumente preisgeben, nur weil es sie abrufen kann. Deshalb filtern wir nach Benutzerberechtigungen, bevor Chunks an das Modell übergeben werden. Dabei prüfen wir die Metadaten jedes Chunks – etwa den Zugriffs‑Tag oder das Erstellungsdatum – und schließen alles aus, das der anfragende Nutzer nicht sehen darf.
Code‑Review‑Unterstützung
Ein System kann eine Änderung zusammenfassen, relevante Konventionen abrufen und Fragen für Reviewer vorschlagen. Es sollte Tests, Sicherheitsscans oder die Genehmigung des Eigentümers nicht ersetzen; stattdessen liefert es kontextuelle Hinweise, etwa wo im Style‑Guide ein bestimmtes Muster beschrieben wird, sodass der Reviewer gezielter prüfen kann.
Wie die Komponenten funktionieren
Embedding‑Schicht
Ein Embedding‑Modell bildet Text auf Vektoren ab, die semantische Beziehungen erfassen. Ähnliche Bedeutung erzeugt ähnliche Vektoren, sodass eine Frage über „Passwort zurücksetzen“ Chunks über „Kontowiederherstellung“ abruft, auch wenn der genaue Ausdruck nicht übereinstimmt. Damit wird die Suche tolerant gegenüber Synonymen und Paraphrasierungen, weil die Distanz im Vektorraum die inhaltliche Nähe widerspiegelt.
Retrieval‑Schicht
Ein Vektor‑Index gibt Kandidatenpassagen nach Ähnlichkeit zurück. Approximate‑Nearest‑Neighbor‑Indizes wie HNSW (verwendet von ChromaDB und pgvector) machen große Suchen schnell. Retrieval‑Qualität hängt von Chunking‑Strategie, Metadatenfiltern und Evaluation ab, nicht nur vom Index‑Algorithmus.
Generierungsschicht
Die ausgewählten Passagen werden in das Kontextfenster des Modells eingefügt. Die Anwendung sollte das Modell anweisen, Belege von Schlussfolgerungen zu unterscheiden, Quellen zu zitieren und sich zu enthalten, wenn der Kontext unzureichend ist:
from langchain.prompts import PromptTemplate
PROMPT = PromptTemplate(
template="""Verwende nur den unten stehenden Kontext, um die Frage zu beantworten.
Wenn die Antwort nicht im Kontext steht, sage "Diese Information habe ich nicht."
Zitiere das Quelldokument für jede Aussage.
Kontext:
{context}
Frage: {question}
Antwort:""",
input_variables=["context", "question"],
)
Durch diese strikte Vorgabe zwingt man das Modell, ausschließlich das übergebene Material zu nutzen und im Zweifel das Unwissen zuzugeben, wodurch Halluzinationen reduziert werden.
Kompromisse
Antwortqualität hängt von Quell‑ und Retrieval‑Qualität ab. Veraltete Dokumente, schlechtes Chunking, mehrdeutige Passagen und fehlende Berechtigungen können alle schlechte Antworten produzieren. Wenn ein Chunk mehrere Themen vermischt, kann das Modell irrelevante Informationen kombinieren und damit ungenaue Antworten erzeugen.
Latenz und Kosten: Jede Runde beinhaltet Embedding, Suche und Generierung. Caching und vorberechnete Embeddings helfen, müssen aber invalidiert werden, wenn sich Inhalte oder Berechtigungen ändern. Ein veralteter Cache würde sonst falsche oder unautorisierte Inhalte liefern.
Halluzination: RAG reduziert einige Formen von Halluzination, indem das Modell in abgerufenem Text verankert wird. Es eliminiert sie nicht. Ein Modell kann eine Passage falsch lesen, nicht zusammenhängende Passagen kombinieren oder über die verfügbaren Belege hinaus antworten.
Das Fazit
Eine leichtgewichtige RAG-Anwendung dient der Dokumentensuche, internen Wissenszugang und domänenspezifischer Unterstützung. Ihr Erfolg hängt weniger vom Framework als von disziplinierter Datenvorbereitung, Retrieval-Evaluation, Zugangskontrolle und menschlicher Eskalation für unsichere Fälle ab. Die meisten Stolpersteine liegen bereits in der Phase der Datenaufbereitung; ein sauber strukturiertes Metadaten-Schema spart später unzählige Fehlalarme.

Comments (0)
Please sign in to leave a comment