Wandeln Sie PDFs für RAG in Markdown um, wenn die Chunks den Abschnitten des Dokuments folgen sollen: Jede Überschrift wird zur Trennstelle, und die Überschriften über einem Chunk wandern als Metadaten mit. Prüfen Sie vor dem Indexieren Überschriften, Tabellen und OCR-Text und testen Sie dann die Suche mit Fragen, deren Antworten Sie schon kennen.
Diese Anleitung richtet sich an Entwickler, die eine Suche über private Dokumente bauen: Richtlinien, Handbücher, Verträge, Forschung. Sie setzt voraus, dass Sie ein Embedding-Modell und einen Vektorspeicher schon im Blick haben.
Warum Überschriften bessere Chunks ergeben
Ein Splitter mit fester Größe schneidet Text in Stücke gleicher Länge, egal wo der Schnitt fällt. Ein Chunk kann mitten in einem Abschnitt beginnen und die Überschrift verlieren, die sagt, worum es geht. „Anfragen sind auf 100 pro Minute begrenzt“ bedeutet unter „Sandbox“ etwas anderes als unter „Production“. Ohne die Überschrift können weder die Suche noch das Modell das unterscheiden.
Markdown bewahrt die Gliederung des Dokuments in Zeilen, die mit #, ## und ### beginnen. Ein Splitter nach Überschriften schneidet an diesen Zeilen, sodass jeder Chunk einen Abschnitt abdeckt, und er speichert die Überschriften über dem Chunk: seinen Abschnittspfad. Der LangChain-Leitfaden zum Aufteilen von Markdown beschreibt dieselbe Idee: Text mit den Überschriften zusammenhalten, zu denen er gehört.
Abschnitte sind unterschiedlich lang, deshalb braucht ein langer Abschnitt trotzdem eine zweite Aufteilung nach Größe. Der Abschnittspfad gilt für jedes seiner Teile.
PDFs konvertieren und Überschriften prüfen
Fügen Sie in MD Factory den Ordner mit Ihren PDFs hinzu. Jede Markdown-Datei wird unter demselben Namen neben ihrer PDF gespeichert, Bilder in einem Ordner daneben. Gescannte PDFs durchlaufen die OCR auf Ihrem PC. Word-Dateien und andere Formate im Ordner werden genauso konvertiert.
Öffnen Sie einige Ergebnisse, bevor Sie Code zum Aufteilen schreiben:
- Achten Sie darauf, dass Kapitel, Abschnitte und Unterabschnitte als #, ## und ### herauskommen. Eine PDF kennzeichnet eine Überschrift oft nur durch eine größere oder fettere Schrift, deshalb muss jeder Konverter erschließen, wo Abschnitte beginnen und wie sie verschachtelt sind. Korrigieren Sie falsche Ebenen.
- In Word-Dateien bleiben Überschriften erhalten, wenn der Autor die Formatvorlagen für Überschriften verwendet hat. Text, der nur fett oder groß ist, bleibt ein normaler Absatz.
- Suchen Sie nach Kopf- und Fußzeilen sowie Seitenzahlen mitten im Text.
- Klicken Sie neben einer Datei auf „Überprüfung erforderlich“, um zu sehen, was zu prüfen ist. Bei einer PDF kann die Liste Seiten enthalten, auf denen die OCR einen Teil des Textes nicht lesen konnte oder gar keinen Text gefunden hat.
Beheben Sie Fehler in der Markdown-Datei, bevor Sie sie indexieren. Jeder Chunk erbt sie.
Im Code nach Überschriften aufteilen
Der MarkdownHeaderTextSplitter von LangChain teilt an den angegebenen Überschriftenebenen und legt jede Überschrift in den Metadaten des Chunks ab. Ein zweiter Splitter begrenzt die Größe innerhalb jedes Abschnitts:
from pathlib import Path
from langchain_text_splitters import (
MarkdownHeaderTextSplitter,
RecursiveCharacterTextSplitter,
)
corpus = Path("corpus")
by_heading = MarkdownHeaderTextSplitter(
[("#", "h1"), ("##", "h2"), ("###", "h3")], strip_headers=False
)
by_size = RecursiveCharacterTextSplitter(chunk_size=1500, chunk_overlap=150)
chunks = []
for path in sorted(corpus.rglob("*.md")):
sections = by_heading.split_text(path.read_text(encoding="utf-8"))
for chunk in by_size.split_documents(sections):
chunk.metadata["source"] = path.relative_to(corpus).as_posix()
chunk.metadata["section"] = " > ".join(
chunk.metadata[h] for h in ("h1", "h2", "h3") if h in chunk.metadata
)
chunks.append(chunk)
Chunk-Größe und Überlappung sind hier nur ein Ausgangspunkt; passen Sie sie an Ihr Embedding-Modell an. Damit die Überschriftenzeilen im Chunk-Text bleiben und der eingebettete Text seinen Abschnitt nennt, setzt das Beispiel strip_headers=False.
Der MarkdownNodeParser von LlamaIndex übernimmt dieselbe Aufteilung nach Überschriften. Wenn Sie Dateien mit SimpleDirectoryReader laden, trägt jeder Knoten außerdem den Dateinamen:
from llama_index.core import SimpleDirectoryReader
from llama_index.core.node_parser import MarkdownNodeParser
documents = SimpleDirectoryReader(
"corpus", recursive=True, required_exts=[".md"]
).load_data()
nodes = MarkdownNodeParser().get_nodes_from_documents(documents)
print(nodes[0].metadata["file_name"], nodes[0].metadata["header_path"])
header_path listet die Überschriften über einem Knoten auf, zum Beispiel /Employee handbook/Expenses/; die eigene Überschrift des Knotens ist die erste Zeile seines Textes.
Die Quelle zu jedem Chunk speichern
Speichern Sie zu jedem Chunk mindestens drei Dinge:
- Die Datei. Eine Markdown-Datei heißt wie ihre PDF, ein Chunk aus handbook.md führt also zu handbook.pdf zurück. Speichern Sie den Pfad relativ zum Korpus-Ordner, denn zwei Dateien namens terms.md in verschiedenen Ordnern sind verschiedene Dokumente.
- Den Abschnittspfad, damit eine Antwort den verwendeten Abschnitt nennen und ein Leser direkt zur Stelle springen kann.
- Die Fassung oder das Datum. Ändert sich eine Richtlinie, löschen Sie die Chunks der alten Datei und indexieren die neuen, statt beide Versionen auszuliefern.
Wenn Personen mit unterschiedlichen Zugriffsrechten denselben Index abfragen, speichern Sie auch, wer welches Dokument lesen darf, und filtern Sie bei der Abfrage danach. Die Suche liefert jeden Chunk, der zur Frage passt.
Das Markdown von MD Factory enthält keine Seitenzahlen. Wenn Antworten Seiten zitieren müssen, schlagen Sie die Stelle in der Original-PDF nach.
Tabellen und OCR-Text sorgfältig behandeln
Eine Markdown-Tabelle hat ihre Kopfzeile nur einmal, ganz oben. Ist eine Tabelle länger als Ihre Chunk-Größe, schneidet der Größen-Splitter sie, und die späteren Teile kommen ohne Spaltennamen an. In unserem Test mit LangChain (langchain-text-splitters 1.1.3) ergab eine Tabelle mit 40 Zeilen bei Chunks von 300 Zeichen vier Teile, und nur der erste enthielt die Kopfzeile.
Dafür gibt es zwei Lösungen: Jede Tabelle in einem Chunk lassen, auch wenn er länger ist als die anderen, oder die Kopfzeile am Anfang jedes Teils wiederholen.
Bei Word- und Excel-Dateien markiert MD Factory ein Dokument mit „Überprüfung erforderlich“, wenn verbundene oder komplexe Zellen vereinfacht wurden. PDF-Tabellen bekommen keine solche Markierung, vergleichen Sie deshalb einige davon mit dem Original, vor allem Tabellen mit verbundenen Kopfzeilen.
OCR-Text braucht eine eigene Prüfung. Falsch erkannte Zahlen, Namen und Codes gehen unverändert in Antworten ein, und dem Chunk sieht man nichts an. Vergleichen Sie die Zahlen in einigen Chunks mit dem Scan und lassen Sie markierte Seiten aus dem Index, bis Sie sie korrigiert haben. Worauf Sie achten sollten, steht in unserer Anleitung zur OCR-Prüfung gescannter PDFs.
Die Suche mit echten Fragen testen
Schreiben Sie Fragen auf, die Menschen tatsächlich stellen werden, und zu jeder die Datei und den Abschnitt mit der Antwort. Beginnen Sie mit ein bis zwei Dutzend.
- Lassen Sie jede Frage durch Ihre Suche laufen und sehen Sie sich die obersten Treffer an.
- Notieren Sie, ob der richtige Abschnitt darunter ist.
- Vergleichen Sie bei jedem Fehlgriff die gelieferten Chunks mit dem, der hätte kommen sollen. Typische Ursachen: eine falsche Überschriftenebene, eine von ihrer Kopfzeile getrennte Tabelle, ein OCR-Fehler im Schlüsselbegriff oder ein so langer Abschnitt, dass die Antwort darin untergeht.
- Ändern Sie jeweils nur eine Sache, etwa die Chunk-Größe, die Überschriftenebenen oder die Aufteilung von Tabellen, und lassen Sie dieselben Fragen erneut laufen.
Bewahren Sie die Fragen in einer Datei neben dem Korpus auf und lassen Sie sie erneut laufen, sobald sich die Dokumente oder der Code zum Aufteilen ändern.
Wann MD Factory und wann eine Bibliothek
MD Factory ist eine Desktop-App für Windows. Sie eignet sich für eine private Sammlung, die Sie auf Ihrem eigenen PC konvertieren und mit eigenen Augen prüfen wollen: Ordner hinzufügen, Status ansehen, Dateien mit Prüfbedarf öffnen und korrigieren, dann Ihr Indexierungsskript auf den Ordner richten.
MD Factory behält die Dokumente beim Konvertieren auf Ihrem PC. Wenn Sie die Chunks danach mit einer gehosteten Embedding-API einbetten oder an ein gehostetes Modell senden, geht ihr Text an diesen Anbieter. Nutzen Sie ein lokales Modell, wenn die Dokumente Ihr Netzwerk nicht verlassen dürfen.
Wenn ständig Dokumente hinzukommen, sie auf einem Server liegen oder ohne Aufsicht konvertiert werden müssen, verwenden Sie stattdessen eine Konvertierungsbibliothek in Ihrem Code. Optionen finden Sie in unserem Vergleich von PDF-zu-Markdown-Konvertern.