Skip to content
BotServBotServ
RAGDokumenteDatenvorbereitungPDFMarkdownBereinigungLokale KI

Dokumente vorbereiten: Daten für RAG aufbereiten

Wie bereitet man Dokumente für RAG vor? Formate, Bereinigung, Strukturierung und Best Practices für saubere RAG-Daten. Praxisguide mit Beispielen.

S

schutzgeist

13 min read
Dokumente für RAG vorbereiten

Dokumente vorbereiten: Daten für RAG aufbereiten

Was dieser Artikel über Dokumentvorbereitung behandelt

  • Welche Formate sich für RAG eignen und welche Probleme jedes Format mitbringt
  • Wie Du Texte aus PDF, DOCX, HTML und anderen Quellen extrahierst
  • Welche Bereinigungsschritte nötig sind, damit RAG brauchbare Antworten liefert
  • Wie Metadaten und Normalisierung die Qualität Deiner RAG-Pipeline verbessern
  • Ein vollständiges Praxisbeispiel mit Code, das Du direkt nachbauen kannst

Einleitung: Dokumente vorbereiten verständlich erklärt

Du hast Dich mit lokalem RAG beschäftigt und willst jetzt loslegen. Die Modelle sind installiert, Ollama läuft, die Vektordatenbank ist bereit. Doch bevor Du loslegen kannst, steht eine Aufgabe an, die viele unterschätzen: Du musst Deine Dokumente vorbereiten.

Dieser Artikel zeigt Dir Schritt für Schritt, wie Du Dokumente so aufbereitest, dass Deine RAG-Anwendung später saubere, relevante Antworten liefert. Wir gehen alle Formate durch, behandeln Bereinigung und Normalisierung und arbeiten ein komplettes Beispiel durch. Wenn Du die RAG Grundlagen noch nicht kennst, lies Dir diesen Artikel zuerst durch.

Warum brauche ich Dokumentvorbereitung?

Stell Dir vor, Du gibst eine rohe PDF-Dokumentation in Dein RAG-System. Die PDF enthält Seitennummern, Wiederholungsheader, Inhaltsverzeichnisse und Fußnoten. Du stellst die Frage: “Wie konfiguriere ich die Datenbankverbindung?”

Das System sucht ähnliche Textabschnitte und findet unter anderem eine Seite mit dem Header “Kapitel 4, Seite 47, Version 2.1”. Die Antwort lautet etwa: “Auf Seite 47 finden Sie Informationen zur Konfiguration.” Das ist keine nützliche Antwort, sondern ein Artefakt aus den Headern und Seitennummern, die nicht bereinigt wurden.

Genau hier beginnt die Dokumentvorbereitung. Ohne sie liefert RAG Müll, egal wie gut Dein Embedding-Modell ist. Die Qualität Deiner Antworten hängt direkt von der Qualität Deiner Daten ab. Das ist keine Übertreibung, sondern die wichtigste Lektion, die Du beim Aufbau einer RAG-Pipeline lernst.

Dokumentvorbereitung kurz erklärt

Die beste Analogie: Dokumentvorbereitung ist wie das Vorbereiten von Zutaten beim Kochen. Bevor Du kochst, wäschst Du Gemüse, schneidest es, entfernst Schalen und mischst die Gewürze ab. Niemand wirft rohe, ungewaschene Zutaten in den Topf und hofft auf ein gutes Ergebnis.

Bei RAG ist es genauso. Du nimmst rohe Dokumente, entfernst alles Störende, strukturierst den Text neu und fügst Metadaten hinzu. Erst dann kommen die Texte in die Vektordatenbank. Der Aufbau der Pipeline, vom rohen Dokument bis zum durchsuchbaren Vektor, läuft in mehreren Schritten ab, die wir in diesem Artikel durchgehen.

Für wen ist dieser Artikel gedacht?

Dieser Artikel richtet sich an Einsteiger, die ihr erstes lokales RAG-System aufbauen. Du brauchst keine Vorkenntnisse in der Datenvorbereitung, solltest aber grundlegend verstehen, was lokale KI ist und wie RAG funktioniert. Wenn Du bereits Erfahrung mit Python hast, kannst Du die Codebeispiele direkt übernehmen. Falls nicht, erklären wir jeden Schritt verständlich.

Wichtige Begriffe rund um Dokumentvorbereitung

BegriffErklärung
FormatDie Dateiformat Deines Dokuments, etwa PDF, DOCX oder Markdown. Jedes Format braucht andere Werkzeuge zur Extraktion.
ParsingDas Auslesen und Umwandeln eines Dokuments in reinen Text.
BereinigungDas Entfernen von Störtexten wie Headern, Footern, Seitennummern und Boilerplate.
NormalisierungDas Vereinheitlichen von Formatierung, Encoding und Whitespace für konsistente Daten.
DeduplizierungDas Entfernen doppelter Inhalte, die zu verzerrten Suchergebnissen führen.
MetadatenZusatzinformationen wie Quelle, Datum, Autor und Abschnittstitel, die RAG helfen, Antworten einzuordnen.
MarkdownEin einfaches Textformat mit Strukturierung durch Zeichen wie # für Überschriften.
PDFEin verbreitetes Dokumentformat, das Textextraktion erschwert, weil Layout und Text oft vermischt sind.
HTMLDas Format von Webseiten, das Text mit Markup-Tags vermischt.
OCROptical Character Recognition, also die Texterkennung aus Bildern oder gescannten PDFs.

Unterstützte Formate

Nicht jedes Format eignet sich gleich gut für RAG. Hier findest Du eine Übersicht der gängigsten Formate mit ihren Vor- und Nachteilen.

PDF

PDF ist das am häufigsten verwendete Format für Dokumentationen, Handbücher und Berichte. Der Nachteil: PDF speichert Layout und Text oft vermischt, was die Extraktion erschwert. Mehrspaltige Layouts, eingebettete Bilder und gescannte Seiten machen das Parsing fehleranfällig. Für gescannte PDFs brauchst Du OCR, was wir im Artikel zu PDF und OCR behandeln.

DOCX

DOCX-Dateien aus Word oder LibreOffice lassen sich gut parsen, weil sie intern als XML strukturiert sind. Absätze, Überschriften und Listen bleiben erhalten. Der Nachteil: Formatierungen können komplex sein und nicht alle Strukturen lassen sich sauber in Text umwandeln.

TXT

Klartextdateien sind das einfachste Format. Kein Parsing nötig, Du liest den Text direkt ein. Der Nachteil: TXT bietet keine Strukturierung, Du musst Überschriften und Abschnitte manuell identifizieren.

Markdown

Markdown ist das beste Format für RAG, weil es strukturiert und gleichzeitig einfach ist. Überschriften, Listen und Codeblöcke sind direkt im Text markiert. Wenn Du Dokumente selbst erstellst, nutze Markdown.

HTML

HTML von Webseiten enthält viel Boilerplate: Navigation, Footer, Werbung, Skripte. Du musst das Markup entfernen und nur den Hauptinhalt extrahieren. Mit Tools wie BeautifulSoup geht das gut, erfordert aber Aufwand.

CSV

CSV eignet sich für tabellarische Daten. Jede Zeile wird zu einem Textabschnitt, die Spaltenüberschriften werden als Metadaten genutzt. Der Nachteil: Tabellen lassen sich schlecht als Fließtext darstellen und RAG-Modelle tun sich schwer mit strukturierten Daten.

Schritt 1: Dokumente sammeln und strukturieren

Bevor Du ein einziges Dokument parst, sammle alle Dateien an einem Ort und gib ihnen eine konsistente Struktur. Das klingt banal, spart aber später viel Zeit.

Lege alle Quelldokumente in einen Ordner und benenne sie einheitlich. Ein gutes Namensschema ist datum_thema_version.pdf, also etwa 2026-01-15_doku-api_v2.pdf. So siehst Du auf einen Blick, welche Version Du vorliegen hast und wann sie erstellt wurde.

Lege außerdem für jedes Dokument fest, welche Metadaten Du erfassen willst. Ein einfaches Schema sieht so aus:

metadata_schema = {
    "source": "dateiname.pdf",
    "title": "Titel des Dokuments",
    "author": "Autor oder Organisation",
    "date": "2026-01-15",
    "section": "Abschnitt oder Kapitel",
    "page": 42
}

Dieses Schema nutzt Du später für jedes extrahierte Textstück. Konsistenz hier zahlt sich aus, wenn Deine RAG-Anwendung Quellenangaben liefert, wie wir im Artikel zu Quellenangaben beschreiben.

Schritt 2: Text extrahieren

Für jedes Format gibt es passende Werkzeuge. Hier sind die wichtigsten mit kurzen Codebeispielen.

PDF mit PyPDF2

from pypdf import PdfReader

reader = PdfReader("dokument.pdf")
text = ""
for page in reader.pages:
    text += page.extract_text() + "\n"

PyPDF2 extrahiert den reinen Text, ignoriert aber Layout-Informationen. Für mehrspaltige PDFs kann die Reihenfolge der Textbausteine durcheinander geraten. Komplexere Tools wie pdfplumber oder unstructured bieten hier bessere Ergebnisse.

DOCX mit python-docx

from docx import Document

doc = Document("dokument.docx")
text = ""
for paragraph in doc.paragraphs:
    text += paragraph.text + "\n"

python-docx liest Absätze nacheinander und behält die Reihenfolge bei. Überschriften erkennst Du am Style-Attribut, etwa paragraph.style.name == "Heading 1".

HTML mit BeautifulSoup

from bs4 import BeautifulSoup

with open("seite.html", "r", encoding="utf-8") as f:
    soup = BeautifulSoup(f, "html.parser")
    # Entferne Skripte und Styles
    for tag in soup(["script", "style", "nav", "footer"]):
        tag.decompose()
    text = soup.get_text(separator="\n")

BeautifulSoup entfernt unerwünschte Tags und extrahiert den sichtbaren Text. Passe die Liste der zu entfernenden Tags an Deine Quellen an.

Markdown und TXT

with open("dokument.md", "r", encoding="utf-8") as f:
    text = f.read()

Markdown und TXT liest Du direkt ein, kein spezielles Tool nötig.

Schritt 3: Text bereinigen

Nach der Extraktion enthält Dein Text noch viele Störteile, die RAG verwirren. Die Bereinigung ist der wichtigste Schritt für saubere Daten.

Header und Footer entfernen

PDFs wiederholen auf jeder Seite Header und Footer, etwa den Dokumenttitel oder die Versionsnummer. Entferne diese Muster mit regulären Ausdrücken:

import re

# Seitennummern wie "Seite 12" oder "- 12 -" entfernen
text = re.sub(r"(Seite|Page)\s*\d+", "", text)
text = re.sub(r"-\s*\d+\s*-", "", text)

# Wiederholte Header entfernen (muss an Deine Dokumente angepasst werden)
text = re.sub(r"Kapitel \d+", "", text)

Diese Muster musst Du an Deine spezifischen Dokumente anpassen. Es gibt keine universelle Lösung, weil jedes Dokument andere Header hat.

Encoding-Probleme beheben

Falsches Encoding führt zu Zeichen wie ü statt ü. Konvertiere alles nach UTF-8:

text = text.encode("utf-8", errors="ignore").decode("utf-8")

Boilerplate entfernen

Inhaltsverzeichnisse, Copyright-Hinweise und Disclaimer wiederholen sich auf jeder Seite und verbrauchen Platz in Deiner Vektordatenbank. Entferne sie:

boilerplate_patterns = [
    r"Inhaltsverzeichnis.*?(?=\n\n)",
    r"© \d{4}.*",
    r"Alle Rechte vorbehalten.*",
]
for pattern in boilerplate_patterns:
    text = re.sub(pattern, "", text, flags=re.DOTALL)

Leerzeichen und Leerzeilen normalisieren

# Mehrere Leerzeichen zu einem zusammenfassen
text = re.sub(r"[ \t]+", " ", text)
# Mehrere Leerzeilen zu einer zusammenfassen
text = re.sub(r"\n{3,}", "\n\n", text)
# Leading und trailing Whitespace entfernen
text = text.strip()

Schritt 4: Metadaten hinzufügen

Metadaten sind für RAG wichtiger, als viele denken. Ohne Metadaten weiß Dein System nicht, woher ein Textabschnitt stammt und wie aktuell er ist. Das führt zu Antworten, die veraltete Informationen aus alten Versionen liefern.

Für jeden Textabschnitt solltest Du mindestens diese Felder erfassen:

  • source: Dateiname oder URL des Originaldokuments
  • title: Titel des Dokuments oder Abschnitts
  • date: Erstellungs- oder Änderungsdatum
  • author: Autor oder herausgebende Organisation
  • section: Kapitel oder Abschnittsüberschrift
  • page: Seitennummer bei PDFs

In Python speicherst Du Metadaten als Dictionary zusammen mit dem Text:

chunk = {
    "text": "Der extrahierte Textabschnitt...",
    "metadata": {
        "source": "handbuch_v2.pdf",
        "title": "Datenbankverbindung konfigurieren",
        "date": "2026-01-15",
        "author": "BotServ",
        "section": "Kapitel 4",
        "page": 47
    }
}

Wenn Du später suchst, kannst Du Metadaten filtern, etwa nur aktuelle Versionen oder nur bestimmte Kapitel. Das macht Deine RAG-Anwendung präziser und die Antworten nachvollziehbar.

Schritt 5: Normalisierung

Normalisierung sorgt dafür, dass alle Deine Dokumente dasselbe Format haben, egal woher sie stammen. Das vereinfacht das Chunking und die spätere Suche.

Die wichtigsten Normalisierungsschritte:

  1. Encoding vereinheitlichen: Alles nach UTF-8 konvertieren
  2. Zeilenenden vereinheitlichen: \r\n und \r zu \n umwandeln
  3. Whitespace normalisieren: Mehrfache Leerzeichen und Leerzeilen reduzieren
  4. Sonderzeichen bereinigen: Unsichtbare Zeichen wie Zero-Width-Spaces entfernen
def normalize_text(text):
    # Zeilenenden vereinheitlichen
    text = text.replace("\r\n", "\n").replace("\r", "\n")
    # Zero-Width-Spaces und ähnliche unsichtbare Zeichen entfernen
    text = re.sub(r"[\u200b\u200c\u200d\ufeff]", "", text)
    # Whitespace normalisieren
    text = re.sub(r"[ \t]+", " ", text)
    text = re.sub(r"\n{3,}", "\n\n", text)
    return text.strip()

Wende diese Funktion auf jeden extrahierten Text an, bevor Du ihn weiterverarbeitest. Konsistenz an dieser Stelle zahlt sich aus, wenn Du später verschiedene Dokumenttypen in einer Vektordatenbank kombinierst.

Best Practices für saubere RAG-Daten

Hier sind die wichtigsten Tipps, die Dir in der Praxis helfen:

  • Fange klein an: Beginne mit 5 bis 10 Dokumenten, nicht mit 500. So findest Du Probleme früh.
  • Prüfe extrahierten Text manuell: Lies Dir die ersten extrahierten Texte durch. Wenn sie für Dich unleserlich sind, sind sie für RAG auch unbrauchbar.
  • Nutze Markdown als Zwischenformat: Konvertiere alles nach Markdown, bevor Du es in die Vektordatenbank lädst. So behältst Du Struktur und kannst Änderungen nachvollziehen.
  • Dokumentiere Deine Pipeline: Schreib auf, welche Schritte Du in welcher Reihenfolge ausführst. Wenn etwas schiefgeht, kannst Du den Fehler eingrenzen.
  • Versioniere Deine Daten: Wenn Du Dokumente aktualisierst, behalte alte Versionen. So kannst Du vergleichen, ob neue Daten bessere Antworten liefern.
  • Entferne Duplikate: Gleiche Inhalte in mehreren Dokumenten verzerren Suchergebnisse. Prüfe auf Duplikate, bevor Du Daten lädst.
  • Teste mit echten Fragen: Stell Deiner RAG-Anwendung Fragen, die echte Nutzer stellen würden. So merkst Du, ob die Vorbereitung ausreicht.

Beispiel: Eine PDF-Dokumentation aufbereiten

Wir gehen jetzt ein vollständiges Beispiel durch. Du hast eine PDF-Dokumentation mit 50 Seiten und willst sie für RAG aufbereiten.

Schritt 1: PDF laden und Text extrahieren

from pypdf import PdfReader
import re

reader = PdfReader("handbuch.pdf")
pages = []
for i, page in enumerate(reader.pages):
    text = page.extract_text()
    pages.append({"text": text, "page": i + 1})

Schritt 2: Text bereinigen

def clean_page(text):
    # Seitennummern entfernen
    text = re.sub(r"-\s*\d+\s*-", "", text)
    text = re.sub(r"Seite\s*\d+", "", text)
    # Wiederholten Header entfernen (anpassen!)
    text = re.sub(r"Handbuch v\d\.\d", "", text)
    # Whitespace normalisieren
    text = re.sub(r"[ \t]+", " ", text)
    text = re.sub(r"\n{3,}", "\n\n", text)
    return text.strip()

for page in pages:
    page["text"] = clean_page(page["text"])

Schritt 3: Metadaten hinzufügen

for page in pages:
    page["metadata"] = {
        "source": "handbuch.pdf",
        "title": "Systemhandbuch",
        "date": "2026-01-15",
        "author": "BotServ",
        "page": page["page"]
    }

Schritt 4: In Chunks aufteilen

Hier nutzen wir eine einfache Aufteilung nach Absätzen. Für Produktionssysteme solltest Du dedizierte Chunking-Strategien verwenden, wie im Artikel zu Chunking beschrieben.

chunks = []
for page in pages:
    paragraphs = page["text"].split("\n\n")
    for para in paragraphs:
        if len(para.strip()) > 50:  # Zu kurze Absätze überspringen
            chunks.append({
                "text": para.strip(),
                "metadata": page["metadata"]
            })

print(f"{len(chunks)} Chunks erstellt")

Schritt 5: Embeddings generieren

Jetzt wandelst Du die bereinigten Chunks in Vektoren um. Welche Modelle sich eignen, erfährst Du im Artikel zu Embedding-Modellen.

# Pseudocode, Details siehe Artikel zu Embedding-Modellen
for chunk in chunks:
    chunk["embedding"] = embed(chunk["text"])

Dieses Beispiel zeigt den kompletten Ablauf. In der Praxis wirst Du die Bereinigungsmuster an Deine spezifischen Dokumente anpassen müssen, aber die Struktur bleibt gleich.

Typische Stolpersteine bei der Dokumentvorbereitung

  1. Header und Footer ignorieren: Viele Anfänger übersehen, dass wiederholte Header die Suche verfälschen. Entferne sie konsequent.
  2. Encoding nicht prüfen: Wenn Du Umlaute nicht testest, landen kaputte Zeichen in der Datenbank und verschlechtern die Embedding-Qualität.
  3. Zu große Chunks: Wenn ein Chunk zu lang ist, verliert das Embedding-Modell den Fokus. Halte Chunks zwischen 200 und 800 Wörtern.
  4. Metadaten weglassen: Ohne Metadaten kannst Du keine Quellen angeben und keine Filter setzen. Das macht RAG unbrauchbar für ernsthafte Anwendungen.
  5. Duplikate nicht entfernen: Wenn derselbe Text mehrfach in der Datenbank steht, taucht er in jeder Antwort auf. Das ist nicht hilfreich.
  6. Inhaltsverzeichnisse mitladen: Diese enthalten nur Seitenverweise und keine echten Inhalte. Sie verschwenden Platz und verfälschen Suchen.
  7. Tabellen als Fließtext: Tabellen verlieren beim Parsen ihre Struktur. Überlege, ob Du sie als strukturierte Daten behandelst statt als Text.
  8. Keine Tests mit echten Fragen: Wer nur die Pipeline baut, aber nie echte Fragen testet, merkt nicht, wo die Daten lückenhaft sind.

Hardware, Kosten und Sicherheit bei der Dokumentvorbereitung

Die Dokumentvorbereitung selbst ist rechenarm. Textextraktion und Bereinigung laufen problemlos auf einem normalen Laptop. Du brauchst keine GPU für diese Schritte.

Kosten entstehen hauptsächlich durch Speicherplatz für die verarbeiteten Daten und durch die Embedding-Berechnung, die im nächsten Schritt kommt. Wenn Du lokale Embedding-Modelle nutzt, fallen keine API-Kosten an.

Sicherheit ist bei der Dokumentvorbereitung besonders wichtig, wenn Du sensible Dokumente verarbeitest. Da alles lokal auf Deinem Rechner läuft, bleiben Deine Daten bei Dir. Das ist einer der größten Vorteile von lokaler KI. Achte trotzdem darauf, dass verarbeitete Zwischendateien nicht ungesichert herumliegen, besonders wenn Du Metadaten mit Personenbezügen speicherst.

FAQ: Dokumente vorbereiten, typische Fragen

Muss ich jedes Dokument manuell bereinigen?

Nein, Du automatisierst die Bereinigung mit Skripten. Einmal geschrieben, laufen sie über alle Dokumente. Du prüfst nur Stichproben, um die Qualität zu kontrollieren.

Welches Format ist am besten für RAG?

Markdown ist das beste Format, weil es Struktur und Einfachheit kombiniert. Wenn Du Dokumente selbst erstellst, nutze Markdown. Bei bestehenden Dokumenten konvertiere sie nach Markdown als Zwischenformat.

Brauche ich OCR für alle PDFs?

Nein, nur für gescannte PDFs, die Text als Bild enthalten. Digitale PDFs, die aus Textverarbeitungsprogrammen exportiert wurden, enthalten auswählbaren Text und brauchen kein OCR.

Wie groß sollten meine Chunks sein?

Eine gute Richtlinie ist 200 bis 800 Wörter pro Chunk. Zu kleine Chunks verlieren Kontext, zu große verlieren Fokus. Teste verschiedene Größen mit echten Fragen und vergleiche die Ergebnisse.

Was mache ich mit Tabellen in Dokumenten?

Tabellen lassen sich schlecht als Fließtext darstellen. Du kannst sie als Markdown-Tabellen beibehalten oder als strukturierte Metadaten speichern. Manche RAG-Systeme können mit strukturierten Daten umgehen, andere nicht. Teste, was für Deinen Anwendungsfall besser funktioniert.

Wie gehe ich mit mehreren Sprachen um?

Wenn Deine Dokumente mehrsprachig sind, nutze ein Embedding-Modell, das mehrere Sprachen unterstützt. Bereinige die Texte sprachspezifisch, etwa mit unterschiedlichen Mustern für Header und Footer. Du kannst auch eine Spracherkennung vorschalten und Dokumente nach Sprache trennen.

Kann ich Dokumente nachträglich aktualisieren?

Ja, und das solltest Du auch. Wenn sich ein Dokument ändert, entferne die alten Chunks aus der Vektordatenbank und lade die neuen. Metadaten helfen Dir hier, gezielt alte Versionen zu finden und zu ersetzen.

Wie viele Dokumente brauche ich für ein brauchbares RAG-System?

Das hängt vom Anwendungsfall ab. Für eine spezifische Dokumentation reichen 10 bis 50 Dokumente. Für eine breite Wissensbasis brauchst Du mehr. Wichtiger als die Menge ist die Qualität der aufbereiteten Daten.

Was ist der Unterschied zwischen Bereinigung und Normalisierung?

Bereinigung entfernt unerwünschte Inhalte wie Header und Boilerplate. Normalisierung vereinheitlicht das Format, etwa Encoding und Whitespace. Beide Schritte sind nötig und ergänzen sich.

Brauche ich Programmierkenntnisse für die Dokumentvorbereitung?

Für automatisierte Pipelines ja, Du brauchst grundlegende Python-Kenntnisse. Für kleine Mengen kannst Du Dokumente auch manuell bereinigen, das skaliert aber nicht. Die Codebeispiele in diesem Artikel sind so geschrieben, dass Du sie auch als Einsteiger nachvollziehen kannst.

Quellen und weiterführende Literatur

  • PyPDF2 Dokumentation: github.com/py-pdf/pypdf
  • python-docx Dokumentation: python-docx.readthedocs.io
  • BeautifulSoup Dokumentation: crummy.com/software/BeautifulSoup
  • LangChain Dokumentation zur Document-Verarbeitung: python.langchain.com
  • Unstructured Library: github.com/Unstructured-IO/unstructured
  • Artikel zu RAG Grundlagen in dieser Reihe
  • Artikel zu Chunking in dieser Reihe
Zurück zum KI Blog
Share:

Ähnliche Beiträge