Zum Inhalt springen

Retrieval-Augmented Generation (RAG) erklärt: So verbinden Sie große Sprachmodelle mit Ihren eigenen Daten (Python-Tutorial)

Warum LLMs bei privaten Daten scheitern — und warum RAG das löst

Große Sprachmodelle wie GPT-5 oder Claude werden nur mit Daten bis zu einem bestimmten Zeitpunkt trainiert. Sie wissen nicht, was in der internen Dokumentation deines Unternehmens, in deiner Produktdatenbank oder im Verkaufsbericht des letzten Quartals steht. Sie können auch keinen privaten Notion-Workspace durchsuchen oder deine Slack-Nachrichten lesen.

Dadurch entsteht eine ganz reale Lücke: Du hast einen leistungsstarken KI-Assistenten, aber er ist im Grunde blind für die wichtigsten Daten, mit denen er arbeiten soll.

Retrieval-Augmented Generation schließt genau diese Lücke. Statt das Modell zu fine-tunen (teuer, langsam) oder alles in den Prompt zu stopfen (unpraktisch), holt es zur Anfragezeit nur die relevanten Ausschnitte aus deinen Daten und gibt diese dem LLM als Kontext.

Das Ergebnis: Dein LLM beantwortet Fragen auf Basis deiner tatsächlichen Daten, in Echtzeit aktualisiert, ohne dass irgendetwas neu trainiert werden muss.

Was ist RAG? (Die Definition außerhalb des Lehrbuchs)

Vergiss für einen Moment die akademische Definition. Stell es dir so vor:

Stell dir vor, du bist ein Berater, der zwischen Projekten alles wieder vergisst. Vor jedem Kundengespräch zieht dein Assistent die 5 relevantesten Dateien aus dem Archiv und legt sie dir vor. Du gehst vollständig vorbereitet ins Meeting — ohne das gesamte Archiv auswendig zu kennen. Genau das ist RAG.

Technisch besteht es aus drei zentralen Schritten:

  • Indexierung: Deine Dokumente werden in Abschnitte aufgeteilt, in Vektor-Embeddings umgewandelt und in einer Vektordatenbank gespeichert.
  • Abruf: Wenn ein Nutzer eine Frage stellt, wird auch diese Frage eingebettet, und die semantisch ähnlichsten Dokumentenabschnitte werden abgerufen.
  • Generierung: Diese abgerufenen Abschnitte werden als Kontext in den Prompt des LLM eingefügt, und das Modell erzeugt eine fundierte, präzise Antwort.

RAG-Architektur: Das Gesamtbild

Hier siehst du eine visuelle Aufschlüsselung, wie die einzelnen Bausteine zusammenspielen:

Die zentrale Erkenntnis: Das LLM durchsucht niemals selbst die Datenbank. Es sieht nur das, was ihm der Retrieval-Schritt liefert.

Python-Tutorial Schritt für Schritt: Baue ein RAG-System

Schritt 1 — Abhängigkeiten installieren

pip install langchain openai chromadb tiktoken pypdf

Schritt 2 — Dokumente laden und in Abschnitte aufteilen

Wir beginnen mit deinen Dokumenten. So lädst du ein PDF und teilst es in handhabbare Abschnitte auf:

from langchain.document_loaders import PyPDFLoader

from langchain.text_splitter import RecursiveCharacterTextSplitter

# Dokument laden

loader = PyPDFLoader('company_handbook.pdf')

documents = loader.load()

# In Abschnitte aufteilen (Überlappung hilft, Kontext an den Grenzen zu erhalten)

splitter = RecursiveCharacterTextSplitter(

   chunk_size=500,

   chunk_overlap=50

)

chunks = splitter.split_documents(documents)

print(f'{len(chunks)} Abschnitte erstellt')

Warum 500 Zeichen? Das ist ein praktischer Mittelweg — klein genug, um präzise zu sein, aber groß genug, um Bedeutung zu transportieren. Diesen Wert passt du später an deine Daten an.

Schritt 3 — Embeddings erstellen und in einer Vektor-DB speichern

from langchain.embeddings import OpenAIEmbeddings

from langchain.vectorstores import Chroma

embeddings = OpenAIEmbeddings()  # oder ein lokales Modell verwenden

# Alle Abschnitte einbetten und speichern

vectorstore = Chroma.from_documents(

   documents=chunks,

   embedding=embeddings,

   persist_directory='./chroma_db'

)

vectorstore.persist()

print('Vektor-Datenbank erstellt und gespeichert.')

Chroma ist eine großartige lokale Lösung für den Einstieg. Für produktive Systeme kommen auch Pinecone, Weaviate oder pgvector infrage (wenn du ohnehin Postgres nutzt).

Schritt 4 — Die Retrieval- und Generierungs-Chain aufbauen

from langchain.chat_models import ChatOpenAI

from langchain.chains import RetrievalQA

llm = ChatOpenAI(model_name='gpt-4', temperature=0)

qa_chain = RetrievalQA.from_chain_type(

   llm=llm,

   chain_type='stuff',  # 'stuff' = gesamten Kontext in einen Prompt einfügen

   retriever=vectorstore.as_retriever(search_kwargs={'k': 4}),

   return_source_documents=True

)

# Eine Frage stellen

result = qa_chain({'query': 'Wie lautet unsere Regelung zur Elternzeit?'})

print(result['result'])

print('Quellen:', [doc.metadata for doc in result['source_documents']])

Beachte return_source_documents=True — zeige Nutzern immer, woher die Antworten stammen. Das schafft Vertrauen und erleichtert das Debugging.

Schritt 5 — Aus bestehendem Speicher laden (nicht jedes Mal neu indexieren)

# Bei späteren Ausführungen von der Festplatte laden statt alles neu einzubetten

vectorstore = Chroma(

   persist_directory='./chroma_db',

   embedding_function=OpenAIEmbeddings()

)

Praxisbeispiel: Abfrage eines Produkthandbuchs

Stell dir vor, du hast ein 200-seitiges Produkthandbuch. Ein Support-Mitarbeiter schreibt: „Wie setze ich das Gerät auf die Werkseinstellungen zurück?“

Ohne RAG: Das LLM rät entweder (und halluziniert dabei oft) oder sagt, dass es die Antwort nicht kennt.

Mit RAG: Das System ruft die 4 relevantesten Abschnitte aus dem Handbuch ab, das LLM liest genau diese Stellen und antwortet präzise — oft sogar mit Verweis auf die exakte Seite oder den entsprechenden Abschnitt.

Der Unterschied ist deutlich. In produktiven Anwendungen beseitigt das eine große Kategorie typischer LLM-Fehler.

Häufige Fehler, die du vermeiden solltest

  • Zu große Chunks: Abschnitte mit 1.000+ Zeichen liefern oft zu viel irrelevantes Rauschen zurück.
  • Keine Überlappung zwischen den Chunks: Ohne Überlappung verliert ein Satz, der an einer Grenze getrennt wird, seinen Kontext.
  • Zu wenige Abschnitte abrufen: k=1 oder k=2 verpasst oft relevante Informationen; starte mit k=4 und optimiere dann.
  • Den abgerufenen Kontext nie prüfen: Protokolliere während der Entwicklung, was tatsächlich abgerufen wird. Garbage in, garbage out.
  • Quellenangaben überspringen: Nutzer können Antworten nicht vertrauen, wenn sie sie nicht überprüfen können.

Wann solltest du RAG statt Fine-Tuning verwenden?

Das ist eine der häufigsten Fragen bei der praktischen Arbeit mit LLMs:

  • Verwende RAG, wenn: deine Daten sich häufig ändern, du Quellenangaben brauchst oder schnell starten möchtest.
  • Verwende Fine-Tuning, wenn: du einen bestimmten Schreibstil oder Tonfall brauchst oder das Modell bei einem bestimmten Aufgabentyp trotz guten Kontexts regelmäßig scheitert.

Für die meisten Business-Anwendungsfälle — interne Suche, Kundensupport, Dokumenten-Q&A — ist RAG der richtige Ausgangspunkt.

FAQ

Brauche ich einen OpenAI-API-Key, um RAG zu nutzen?

Nein. Du kannst Open-Source-Embedding-Modelle (wie sentence-transformers) und lokale LLMs (über Ollama oder LM Studio) verwenden, um eine vollständig lokale RAG-Pipeline ohne API-Kosten aufzubauen.

Wie viel kostet es, RAG mit OpenAI zu betreiben?

Die Kosten für Embeddings sind sehr gering — typischerweise nur Bruchteile eines Cents pro Dokumentenseite. Der Hauptkostenfaktor sind die LLM-Aufrufe zur Anfragezeit. Für GPT-4 kannst du je nach Kontextgröße mit etwa 0,01–0,05 US-Dollar pro Anfrage rechnen. Für die meisten Business-Anwendungen ist das vernachlässigbar.

Was ist der Unterschied zwischen RAG und dem einfachen Einfügen von Dokumenten in den Prompt?

Alles einzufügen stößt schnell an Kontextgrenzen und ist teuer. RAG arbeitet selektiv — es holt nur die relevanten Teile. Ein 500-seitiges Dokument würde jedes Kontextfenster sprengen; RAG geht damit elegant um.

Wie gehe ich mit Dokumenten um, die sich häufig ändern?

Führe die Neu-Indexierung nach einem Zeitplan aus oder löse sie bei Dokumentenänderungen automatisch aus. Viele Teams lassen nachts Re-Indexierungsjobs laufen. Chroma und die meisten Vektor-Datenbanken unterstützen das Löschen und erneute Hinzufügen bestimmter Dokumentenabschnitte.

Kann RAG auch ohne LangChain funktionieren?

Absolut. LangChain ist nur eine Komfortschicht. Du kannst RAG auch mit rohen OpenAI-SDK-Aufrufen, einem Vektor-DB-Client und ein paar Dutzend Zeilen Python bauen. LangChain beschleunigt lediglich das Grundgerüst.

Was ist, wenn mein abgerufener Kontext trotzdem falsch ist?

Das liegt meistens an der Chunking-Strategie, der Qualität der Embeddings oder dem Retrieval-k-Wert. Beginne damit, genau zu protokollieren, was abgerufen wird, und passe dann Chunk-Größe, Überlappung oder Retrieval-Parameter an.

Niklas Lang

Seit 2020 bin ich als Machine Learning Engineer und Softwareentwickler tätig und beschäftige mich leidenschaftlich mit der Welt der Daten, Algorithmen und Softwareentwicklung. Neben meiner Arbeit in der Praxis unterrichte ich an mehreren deutschen Hochschulen, darunter die IU International University of Applied Sciences und die Duale Hochschule Baden-Württemberg, in den Bereichen Data Science, Mathematik und Business Analytics.

Mein Ziel ist es, komplexe Themen wie Statistik und maschinelles Lernen so aufzubereiten, dass sie nicht nur verständlich, sondern auch spannend und greifbar werden. Dabei kombiniere ich praktische Erfahrungen aus der Industrie mit fundierten theoretischen Grundlagen, um meine Studierenden bestmöglich auf die Herausforderungen der Datenwelt vorzubereiten.

Cookie Consent mit Real Cookie Banner