Vom Naiven Ansatz zur produktiven RAG-Anwendung bei SEC-10-K-Meldungen: Teilbereichserstellung und hybride Suche.
Warum ein Standard-RAG-Workflow bei 300-seitigen 10-K-Berichten versagte und die Lösungen: sektionsspezifische Teilbereiche, hybride Suche, erneutes Rangieren mit Cross-Encoder sowie Validierung und Verwendung von Metadaten.
Quellen: **How I Built a RAG Pipeline on Legal & Financial Documents and What Actually Broke?**
Ein scheinbar korrekter Pipeline, der falsche Ergebnisse liefert
Stellen Sie sich einen RAG-Pipeline für SEC 10-K-Meldungen vor, deren Entwicklung drei Wochen in Anspruch nahm – mit LangChain zur Verknüpfung der Komponenten, ChromaDB als Vektordatenspeicher, einem sauberen Python-Skript zur Dateneingabe sowie einer ansprechenden Streamlit-Oberfläche. Ein einfacher Ersttest fragt nach den kritischen Prüfungspunkten im Zusammenhang mit der Umsatzbemessung. Das System antwortet völlig zuversichtlich mit Informationen zu der Vergütung der Geschäftsleiter aus einem völlig anderen Abschnitt des Dokuments. „Halluzination“ ist hier nicht ganz das richtige Wort – der Text existiert tatsächlich, stammt aber aus dem falschen Bereich eines 300-seitigen Dokuments, und das System hat nichts bemerkt.
So auszusehen wie ein RAG-System und wie eines zu funktionieren, sind zwei verschiedene Dinge. Im Folgenden finden Sie die Entscheidungen zur Aufteilung in Fragmente, die Suchfehler, die Embedding-Experimente, den aus Notwendigkeit entstandenen Bewertungssatz sowie die Version, die schließlich die manuelle Prüfung um 65 % reduzierte. Jeder, der Funktionen für große Sprachmodelle anhand echter Dokumente – und nicht anhand von simplen PDFs – entwickelt, kann wochenlange, unproduktive Lernphasen überspringen.
Warum 10-K-Dokumente schwer auffindbar sind
Ein 10-K-Dokument als gewöhnliches PDF zu betrachten, unterschätzt dessen Komplexität. Ein Jahresbericht eines mittelgroßen oder großen börsennotierten Unternehmens umfasst 150 bis 400 Seiten mit Finanztabellen, Fußnoten, die auf weitere Fußnoten verweisen, langen rechtlichen Standardformularen, beschreibenden Angaben zu Risiken sowie Kommentaren der Geschäftsleitung. Das Suchziel waren die kritischen Prüfungspunkte (Critical Audit Matters, CAMs), in denen die Wirtschaftsprüfer die komplexesten oder am meisten urteilsintensiven Bereiche ihrer Arbeit erläutern.
Was ein Leser finden möchte – wie beispielsweise Begriffe im Zusammenhang mit Risiken und Prüfungsergebnissen – ist ungleichmäßig verteilt. Er befindet sich in bestimmten Abschnitten, wird in fachspezifischem Vokabular formuliert und ist mit Zahlen verbunden, die außerhalb des Kontexts wenig Bedeutung haben. Wenn man das Dokument als eine Ansammlung von Textabschnitten betrachtet, wählt das Suchsystem meist die falschen aus – genau das ist auch bei der ersten Version der Fall gewesen.
Zwei Verarbeitungsweg parallel
Der Unterschied zwischen den Versionen enthält alle Lektionen.
Version 1 folgte dem klassischen Design: Der PDF wurde in Abschnitte à 500 Token mit einer Überlappung von 50 Token aufgeteilt, mithilfe von OpenAI’s text-embedding-ada-002 verarbeitet, in ChromaDB gespeichert, für eine Abfrage die fünf wichtigsten Abschnitte abgerufen und an GPT-4 weitergeleitet, um eine Zusammenfassung zu erzeugen. Dies funktionierte bei einfachen Abfragen an sauberen Dokumenten, brach jedoch bei einem dichten 300-seitigen Dokument auf drei verschiedene Arten zusammen.
Version 2 verfügt über viele weitere Schritte: Aufnahme von PDFs, eine Ebene zur Erkennung von Abschnitten, ein nach Abschnittstyp variierendes Aufteilen in Blöcke, Metadateneintragungen für jeden Block, ein modellbasiertes Verfahren, das den Kontext berücksichtigt, Speicherung in ChromaDB mit umfangreichen Metadaten, Umformulierung von Abfragen, hybride Suchverfahren (semantisch plus Schlüsselwörter), Neuranking, Validierung und schließlich die Generierung. Jeder Schritt hat einen bestimmten Zweck, der im Folgenden erläutert wird.
Fehler Nummer eins: Feste Blöcke trennen den Kontext
Der grundlegendste Fehler von V1 bestand darin, dass 500-Token-Blöcke verwendet wurden, wodurch der Text genau an den 500. Token geteilt wurde. Ein 10-K-Bericht ist jedoch von Natur aus strukturiert. Ein CAM setzt sich aus einem Überschriftsteil, einer Beschreibung, der Antwort des Prüfers sowie oft einem Verweis auf eine finanzielle Anmerkung zusammen, und kann 600 bis 800 Token umfassen. Durch die Trennung bei 500 Token wurde ein CAM oft in zwei Teile geteilt – die Beschreibung blieb in einem Block und die Antwort im anderen – wodurch keiner der Teile für sich genommen nützlich war.
Die Lösung bestand darin, vor dem Chunking eine Abschnittserkennungsschicht einzufügen. pdfplumber analysierte die Dokumentstruktur, um Abschnittsgrenzen, Überschriften, Untertitel sowie Tabellecken zu finden, wodurch das Chunking innerhalb der Abschnitte und nicht zwischen ihnen stattfand – unter Verwendung von Größen, die natürliche Unterbrechungen berücksichtigten. Dichte Finanztabellen erhielten kleine Chunks mit etwa 200 bis 300 Tokens, um die Suchfähigkeit auf Zeilebene zu gewährleisten. Erzählerische Abschnitte wie CAMs und Risikobekanntmachungen bekamen größere Chunks mit bis zu 800 bis 900 Tokens, damit jede logische Einheit erhalten blieb. Die Überlappung lag bei 10 Prozent der Chunkgröße. Diese einzige Änderung verbesserte bereits deutlich die Relevanz der Suchergebnisse, bevor noch etwas anderes verändert wurde.
Fehler Nummer zwei: Embeddings, die die Finanzsprache übersahen
text-embedding-ada-002 ist ein leistungsstarkes Allzweckmodell, obwohl es nicht speziell auf finanziellen oder rechtlichen Texten trainiert wurde; dies zeigt sich bei dichten Prüfungsunterlagen. Eine Anfrage zu den Bewertungsbereichen bei der Ertragserkennung lieferte Abschnitte über Erträge sowie allgemeine Bewertungen. Einige stammten aus Managementdiskussionen, einige aus Fußnoten und einige aus unverwandten Risikobekundungen, und die eigene CAM zur Ertragserkennung konnte nicht zuverlässig gefunden werden.
Zwei Alternativen wurden ausprobiert. OpenAI’s neueres Text-Embedding-3-Large verbesserte die Qualität der Informationsauswahl messbar. Ein hybrider Ansatz kombinierte eine dichte Vektorsuche mit einer spärlichen BM25-Schlüsselwortsuche und fügte die Ergebnisse zusammen; er übertraf dabei jede der Methoden für sich allein. Die Logik ist einfach: Die dichte Suche findet konzeptionell verwandte Inhalte, während die spärliche Suche genaue Begriffe findet. In finanziellen Texten spielt die genaue Formulierung eine große Rolle. „Kritische Prüfungssache“ bedeutet im rechtlichen Kontext nicht dasselbe wie „bedeutendes Prüfungsproblem“, und das Vorhandensein beider Begriffe erhöht die Präzision erheblich. Für die spärliche Suche wurde die Python-Bibliothek rank_bm25 verwendet, und eine einfache Funktion zur Kombination der Rangwerte fügte die beiden Ergebnislisten zusammen, bevor eine erneute Rangfolge ermittelt wurde.
Fehler Nummer drei: Keine Validierung, zuversichtliche falsche Antworten
Das war das ruhigste und gleichzeitig gefährlichste Problem. In V1 führten fehlerhafte Abschnitte aus den Abrufdaten weiterhin dazu, dass das LLM antwortete, und GPT-4 ist sehr gut darin, bei geringem Kontext selbstsicher zu klingen. Seine Antworten waren nicht offensichtlich falsch – es handelte sich um plausible Zusammenfassungen dessen, was als Abschnitte angekommen war, selbst wenn diese aus dem falschen Teil des Dokuments stammten.
Nur ein kleiner Bewertungssatz machte das Problem sichtbar: 30 Frage-Antwort-Paare, die manuell anhand bestimmter Unterlagen überprüft wurden, wobei jeder Eintrag mit den genauen Quellabschnitten versehen war, die zurückkommen sollten. Demnach fand V1 etwa 55 Prozent der Zeit die richtigen Quellabschnitte, während in den verbleibenden 45 Prozent Floskeln aus irrelevantem Material erzeugt wurden.
Zwei Änderungen haben das Problem behoben. Die erste war eine Neubewertungsphase: Ein HuggingFace-Cross-Encoder namens ms-marco-MiniLM-L-6-v2 bewertete die zehn abgerufenen Abschnitte erneut, und nur die drei besten gelangten zum Generator. Cross-Encoder laufen zwar langsamer als Bi-Encoder, bewerten die Ergebnisse jedoch weitaus genauer, da die Anfrage und ein potenzieller Abschnitt als eine einzige Eingabe statt als zwei getrennte betrachtet werden.
Die zweite Änderung bestand in einem Validierungsmechanismus vor der Generierung. Dieser überprüfte, ob die abgerufenen Abschnitte die im Metadaten zum Zeitpunkt der Eingabe erwarteten Abschnittsidentifikatoren enthielten. Wenn beispielsweise eine Frage zu CAMs Abschnitte aus den Kompensationstabellen zurückgab, scheiterte die Validierung, und das System schrieb die Anfrage um und versuchte es bis zu zweimal, bevor es die Antwort als weniger zuverlässig einstufte. Das unterscheidet eine Demo von einem Produktivsystem: Die Demo behandelt den erfolgreichen Ablauf, während das Produktivsystem mit den 45 Prozent der Fälle umgeht, in denen dieser Ablauf nicht gilt.
Metadaten zu jedem Chunk
Eine Gestaltungsentscheidung, die in RAG-Tutorials nur selten vorkommt, sind umfangreiche Metadaten, die jedem Chunk beigefügt werden. Jeder Chunk in der ChromaDB-Sammlung enthielt folgende Felder:
section_type, der Abschnitt des 10-K-Dokuments, aus dem er stammt, wie z. B. CAM, Risikoaussagen, Finanzberichte, Fußnoten oder Managementdiskussionsection_title, der genaue Überschriftsbereich über dem Inhaltpage_range, die Seiten des Quelldokuments, die vom Chunk abgedeckt werdendocument_id, die Dokumentenidentifikation, als Unternehmenssymbol plus Geschäftsjahrhas_table, ein Boolescher Wert, der tabellarische Daten kennzeichnetfiscal_year, der Berichtszeitraum
Die Metadaten erfüllten zwei Funktionen. Erstens ermöglichten sie eine gefilterte Suche: Bei einer Frage im Zusammenhang mit der Prüfung konnte die Suche vor der Vektorsuche bereits auf den Abschnittstyp „critical_audit_matter“ eingegrenzt werden, wodurch der Suchraum erheblich eingeschränkt wurde. Zweitens stellten sie die Grundlage für die Zitierfunktion der Benutzeroberfläche dar, da jede Zusammenfassung die Seiten und Abschnitte angab, aus denen sie stammte, sodass Prüfer die Quellen sofort überprüfen konnten.
In Tools für Finanzprüfungen sind Zitierungen zwingend erforderlich. Ein Prüfer, der die Herkunft einer Zusammenfassung nicht überprüfen kann, darf sich nicht auf sie verlassen. Durch die Erstellung von Zitierungen aus den Metadaten wurde das System von einer reinen Neugierde-Quelle zu etwas, mit dem die Nutzer tatsächlich arbeiten konnten.
Das endgültige System
Der gesamte Prozess, der die Arbeitsbelastung bei der Prüfung um 65 % verringerte, besteht aus drei Schichten.
- Einlesen: pdfplumber, Abschnittserkennung, variable Teilung in Blöcke, Extraktion von Metadaten, Einbetten mit text-embedding-3-large, anschließend Speicherung in ChromaDB mit allen Metadaten.
- Abfrage: Umformulierung der Abfrage (Neuformulierung durch ein LLM zur Steigerung der Genauigkeit), gefilterte Suche mithilfe eines Vorfilters für Metadaten nach Abschnittstypen, wenn angebracht, hybride Suche nach den besten 10 Ergebnissen mittels dichter Methode und BM25, erneute Rangfolgebestimmung mittels Cross-Encoder auf die besten 3 Ergebnisse, Validierungsprüfung, Erstellung durch GPT-4, Hinzufügen von Zitaten und Anzeige in der Benutzeroberfläche.
- Bewertung: Datensatz mit 30 Elementen, Überwachung der Suchgenauigkeit und Bewertung der Antwortqualität, wobei ein LLM als Bewertungskriterium für Relevanz, Genauigkeit und Vollständigkeit herangezogen wird.
Die Streamlit-Benutzeroberfläche bot Prüfern ein Abfragefeld, die erzeugte Zusammenfassung, Quellenzitate, die auf Anfrage angezeigt wurden, sowie einen Zuverlässigkeitsindikator, der aus dem Validierungsschritt stammte.
Was anders gemacht werden sollte
- Erstellen Sie zunächst das Bewertungsdatensatz.** Er wurde aus Verzweiflung erstellt, nachdem V1 fehlschlug, und sollte von Anfang an vorhanden sein. Ohne Messung verbessert sich nichts, und „es scheint besser zu sein“ ist keine Metrik.
- Entwerfen Sie das Metadatenschema frühzeitig.** Es dauerte Zeit, es richtig umzusetzen, doch jede investierte Stunde zahlte sich mehrfach in der Qualität der Datenerfassung sowie in den durch das Schema ermöglichten UI-Funktionen aus. Metadaten verdienen in der Architektur einen ersten Platz.
- Gehen Sie davon aus, dass der PDF-Parser Dinge übersehen kann.** pdfplumber ist hervorragend, doch zusammengeführte Zellen, gedrehte Überschriften oder Fußnotenmarkierungen in Finanztabellen können ihn dennoch verwirren. Protokollieren Sie jede Abweichung bei der Extraktion und prüfen Sie dieses Protokoll regelmäßig, da stille Extraktionsfehler die schwierigsten Fehler sind, die später aufgespürt werden müssen.
Das Ergebnis
Nach der Implementierung extrahierte das System die kritischen Prüfungspunkte und erstellte Zusammenfassungen dabei mit 65 Prozent weniger manueller Überprüfungsarbeit im Vergleich zum ursprünglichen Verfahren. Als Erstprüfer fand es relevante Abschnitte und entwarf strukturierte Zusammenfassungen, wodurch die Prüfer von der Extraktion und Synthese zur Überprüfung und Beurteilung übergingen.
Genau dieser letzte Punkt ist am wichtigsten. Das Ziel war niemals, das Urteilsvermögen der Prüfer zu ersetzen, sondern die mechanischen, zeitaufwändigen Schritte wegzuführen, damit das fachliche Urteilsvermögen dort eingesetzt werden kann, wo es zählt. Gut konzipierte LLM-Systeme ersetzen keine Expertise – sie lenken sie um.
Weitere Literatur
- AegisOps: Ein autonomer SRE-Agent mit vier Speicherschichten — Wie ein LangGraph ReAct-Agent Kubernetes-Incidenten löst, unter Verwendung von pgvector für episodisches Gedächtnis, autonomiegesteuerten Ebenen, sechzehn Tools sowie einer vollständigen Audit-Trail.
- Vergleich von 16 RAG-Architekturen: Welches Muster passt zu welchem Problem — Eine Übersicht über sechzehn RAG-Muster in vier Kategorien, von standardmäßigen und hybriden Suchmethoden bis hin zu agilen, grafbasierten und federierten Designs, inklusive monatlicher Bauabläufe.