Dokumentenzusammenfassung mit LLM-Coding: Der Beginn einer methodischen Lernreise#
Einleitung: Das erste systematische Experiment#
Dieses Dokument beschreibt die Entwicklung eines Dokumenten-Zusammenfassungs-Tools als Ausgangspunkt einer Serie methodischer Experimente zum LLM-gestützten Coding. Anders als spätere, komplexere Projekte der Serie markiert dieses Tool – entwickelt vor mehr als einem Jahr – den bewussten Einstieg in systematisches LLM-Coding.
Der zeitliche Kontext ist wichtig: Seitdem haben sich alle beteiligten Technologien erheblich weiterentwickelt. LLMs bieten heute größere Kontexte, bessere Reasoning-Fähigkeiten und zuverlässigeres Prompt-Following. Bibliotheken und Frameworks haben sich verfeinert. Die hier dokumentierten Erkenntnisse sind daher im historischen Kontext zu verstehen – sie zeigen den Stand der Technik und der eigenen Kompetenz zu Beginn der Lernreise.
Im Rahmen dieser Artikelserie ist dieser Startpunkt jedoch wichtig: Er zeigt, wie mit einfachen Tools begonnen werden kann und von hier aus der Weg zu immer komplexeren Programmen beschritten wird. Die Prinzipien, die hier entwickelt wurden, blieben auch bei späteren Projekten relevant.
Anders als rein explorative Projekte entstand dieses Tool aus einem konkreten praktischen Bedarf: der schnellen Zusammenfassung von arXiv-Papers nach verschiedenen Fragestellungen, auch für große Dokumente.
Das Experiment verfolgte ein doppeltes Ziel: Einerseits sollte ein funktionales Tool entstehen, andererseits war dies der erste bewusste Versuch, LLM-gestütztes Coding systematisch zu erkunden. Drei zentrale Herausforderungen sollten verstanden werden:
- Umgang mit Kontextbeschränkungen bei der Verarbeitung großer Dokumente
- Vermeidung von Halluzinationen in generierten Zusammenfassungen
- Durchsetzung von Prompt-Following bei komplexen, mehrschichtigen Aufgaben
Das Ergebnis überraschte durch seine Einfachheit: 280 Zeilen Python-Code, entwickelt in 5-6 Stunden, mit einigen hundert täglichen Nutzungen im produktiven Betrieb.
Technische Architektur und Implementierung#
Systemüberblick#
Das Tool basiert auf einer mehrschichtigen Architektur:
UI-Layer: Gradio als Web-Framework wurde bewusst gewählt, da es für unerfahrene Nutzende klar verständlich ist und alle notwendigen Komponenten für LLM-Anwendungen mitbringt. Die Entscheidung für eine Weboberfläche ermöglichte unkomplizierte Dokumentenverarbeitung unter Wahrung des Datenschutzes.
Backend-LLM: Mistral Small 2506 mit 32K Token-Kontext, lokal betrieben. Die Wahl gegen kommerzielle APIs erfolgte bewusst aufgrund von Token-Verbrauch und Datenschutzanforderungen. Der 32K-Kontext ermöglichte bereits für viele Dokumente eine direkte Zusammenfassung ohne Chunking.
Verarbeitungs-Pipeline: Die Codebasis umfasste 10 Hauptfunktionen in einer Datei:
- LLM-Klasse als API-Wrapper
- Drei formatspezifische Extraktionsfunktionen (PDF, DOCX, ODT)
- Zentrale Zusammenfassungsfunktion mit Retry-Logik
- Gradio-UI-Konfiguration
Die Chunking-Strategie: Zweistufige Zusammenfassung#
Das Kernstück der Implementierung ist die Strategie für Dokumente, die den LLM-Kontext überschreiten:
Stufe 1 – Segmentierung und Einzelzusammenfassung:
max_chunks = 10000
chunks = [text[i:i + max_chunks] for i in range(0, len(text), max_chunks)]
summaries = []
for chunk in chunks:
partialSummary = summarize_text(llm, chunk, instructions, summary_type, prompt_only, language)
summaries.append(partialSummary)Dokumente wurden in 10.000-Zeichen-Segmente zerlegt. Diese Chunk-Größe entstand durch systematisches Experimentieren und stellte einen Kompromiss dar: Größere Chunks reduzierten die Anzahl der API-Calls, kleinere Chunks verbesserten die Qualität. Die praktische Nutzung zeigte, dass eine weitere Reduktion der Chunk-Größe die Zusammenfassungsqualität verbesserte, allerdings auf Kosten längerer Verarbeitungszeiten (teilweise mehrere Minuten).
Stufe 2 – Meta-Zusammenfassung:
summaries.insert(0, "HIER KOMMEN VERSCHIEDENE ZUSAMMENFASSUNGEN, DIE ZU EINER EINZIGEN
ZUSAMMENGEFASST WERDEN SOLLEN. BERÜCKSICHTIGE DABEI ALLE ANTEILE. DIE REIHENFOLGE IST
DABEI WICHTIG. ZUERST KOMMEN DIE VORDEREN UND WICHTIGEREN TEILE...")
final_summary = summarize_text(llm, "\n".join(summaries), instructions, summary_type, prompt_only, language)Die Einzelzusammenfassungen wurden mit einem expliziten Meta-Prompt kombiniert und zu einer finalen Zusammenfassung synthetisiert. Diese zweistufige Strategie wurde ko-kreativ mit dem LLM entwickelt, entlang der Abwägung von einfacher Implementierung und hoher Leistungsfähigkeit.
Strukturextraktion: Der Erfolg von pymupdf4llm#
Ein kritischer Erfolgsfaktor war die Verwendung von pymupdf4llm für PDF-Verarbeitung. Diese Bibliothek konvertierte PDF-Inhalte direkt in LLM-freundliches Markdown und war eine große Hilfe für die einfache Verarbeitung von PDF-Dateien im Zusammenhang mit LLMs.
Zusätzlich extrahierte das Tool explizit strukturelle Elemente:
# Für ODT-Dateien (ähnlich für andere Formate)
if style_name and 'Heading' in style_name:
extracted_text += f"[{style_name}] {teletype.extractText(element)}\n"
# Tabellen
extracted_text += "[Table]\n"
for row in table_element.getElementsByType(table.TableRow):
# ... Zellenextraktion
# Bildunterschriften
if caption_text.strip().startswith("Bildunterschrift:"):
extracted_text += f"[Image Caption] {caption_text}\n"Diese strukturierte Annotation mit Tags wie [Heading], [Table], [Image Caption] war besonders wichtig, um zentrale Inhalte identifizieren zu können und verbesserte die Qualität der Zusammenfassungen messbar.
Sechs Zusammenfassungstypen: Prompt-Engineering in der Praxis#
Das Tool implementierte sechs verschiedene Analysemodi durch spezialisierte System-Prompts. Besonders interessant war die “Thematische Zusammenfassung”, die bewusst struktur-agnostisch arbeitete:
"Erzeuge eine präzise und professionell geschriebene Zusammenfassung des Dokuments
ohne Übertreibungen, wobei der Fokus auf den Themen und nicht auf den Folien liegen
sollte. Daher braucht auch nicht jeder Absatz beschrieben werden, sondern nur die
wichtigen Themen des Dokuments. Dabei soll für jedes Thema ein kurzer Absatz
beschrieben werden..."Dieser Typ war besonders interessant und herausfordernd zu entwickeln, da er unabhängig von der Dokumentstruktur thematisch die Inhalte zu beschreiben versuchte.
Die “Kritische Reflexion” implementierte einen expliziten 4-Schritt-Prozess:
"Führe die Bearbeitung der Aufgabe in einzelnen Schritten durch:
1. Überlege, wie die Aufgabe am besten bearbeitet werden kann...
2. Wähle einen Ansatz aus, den Du selbst durchführen kannst...
3. Plane die einzelnen Schritte...
4. Führe die einzelnen Schritte aus und entwickle das Teilergebnis..."Diese Prompt-Templates wurden nicht nur während der initialen Entwicklung, sondern kontinuierlich auch außerhalb der Entwicklungsphasen erweitert und verfeinert.
Entwicklungsprozess: Iterative Ko-Kreation#
Zeitliche Struktur und Iterationen#
Die Entwicklung erfolgte über mehrere Wochen verteilt mit einer Gesamtzeit von 5-6 Stunden. Bemerkenswert war die sehr kurze Spezifikationsphase von nur 30 Minuten, gefolgt von iterativer Entwicklung. Die Architektur benötigte 4-5 Hauptiterationen, primär zur Optimierung der Chunking-Strategie.
Die Entwicklung lief noch sehr iterativ: Zunächst über eine minimale Spezifikation, dann interaktiv. Verschiedene LLMs kamen zum Einsatz, um unterschiedliche Code-Generierungsfähigkeiten zu testen. Im produktiven Betrieb lief das Tool jedoch mit Mistral Small 2506.
Vermeidung von Overengineering#
Eine zentrale methodische Herausforderung im LLM-Coding ist die Neigung von LLMs zu überkomplexen Lösungen mit vielen Abstraktionsebenen. Bei diesem Projekt gelang die Vermeidung von Overengineering durch eine spezifische Strategie: inkrementelles Hinzufügen von Features.
Die einzelnen Funktionen wurden separat hinzugefügt, anstatt eine komplexe Gesamtarchitektur vorab zu spezifizieren. Dadurch entstand auch kein Overengineering, da jede Ergänzung funktional begründet und in ihrer Komplexität minimiert wurde.
Die Rolle der Architektur-Ownership#
Eine zentrale Erkenntnis des Experiments: Die Architekturvorschläge der LLMs waren nicht gut nutzbar. Dies widerspricht der oft geäußerten Hoffnung, dass LLMs auch strategische Architekturentscheidungen übernehmen könnten.
Coding war in klaren, kleinen Schritten gut möglich, solange die Funktionalität sehr eng umrissen war. Strategische Architekturentscheidungen – wie die Wahl der Chunking-Strategie, die Strukturierung der Zusammenfassungstypen oder die Balance zwischen Einfachheit und Funktionalität – erforderten jedoch weiterhin menschliche Expertise.
Prompt-Engineering: Konkrete Techniken für Produktionsumgebungen#
Großschreibung als Signal-Verstärkung#
Eine überraschend wirksame Technik war die Verwendung von Großschreibung für kritische Anweisungen:
"HIER KOMMEN VERSCHIEDENE ZUSAMMENFASSUNGEN, DIE ZU EINER EINZIGEN ZUSAMMENGEFASST
WERDEN SOLLEN. BERÜCKSICHTIGE DABEI ALLE ANTEILE. DIE REIHENFOLGE IST DABEI WICHTIG..."Aufgrund der geringen Länge des Prompts in Bezug zum Content waren die Prompts in Großschreibung sehr hilfreich. Bei einem ungünstigen Prompt-zu-Content-Verhältnis verstärkte Großschreibung die Durchsetzungskraft der Anweisungen signifikant.
Strukturierung von System-Prompts#
Die Prompts gestalteten sich entlang etablierter Prinzipien der System-Prompt-Entwicklung:
- Kontext: Rolle und Aufgabe definieren (“Du bist ein hilfreicher Assistent, der Texte zusammenfasst”)
- Einschränkungen: Explizite Verbote (“Berücksichtige nur Angaben, die auch tatsächlich auf dem verarbeiteten Dokument beruhen”)
- Tonalität: Schreibstil vorgeben (“Der Schreibstil ist dabei akademisch und professionell”)
- Ausgabeformat: Strukturierung festlegen (“Strukturiere den Text mit Markdown”)
- Sprachspezifikation: Redundante Verstärkung (“WICHTIG: Du erzeugst alle Texte in der folgenden Sprache: … Das ist WICHTIG: Erzeuge alle Texte nur in der folgenden Sprache: …”)
Die redundante Wiederholung der Sprachanweisung erwies sich als notwendig, um konsistente mehrsprachige Ausgaben zu gewährleisten.
Grenzen und praktische Erkenntnisse#
Produktive Nutzung und Feedback#
Das Tool wurde im VPN einige hundert Mal monatlich von unterschiedlichen Nutzenden verwendet. Die Rückmeldungen waren positiv, aber nicht exzellent – eine realistische Einschätzung, die die Grenzen der Technologie reflektierte.
Typische Dokumente reichten von einigen wenigen Seiten bis zu hunderten von Seiten. Der Nachteil des Chunking-Ansatzes war, dass Analysen zwar gute Ergebnisse brachten, aber sehr viel Zeit benötigten – teilweise einige Minuten für große Dokumente.
Identifizierte Limitierungen#
Grafisch komplexe PDFs: Es gab immer wieder Dateien, insbesondere PDF-Dateien mit besonderem und eher grafisch komplexem Aufbau, die nicht gut zusammengefasst werden konnten. Die Text-Extraktion stieß hier an fundamentale Grenzen, die auch durch besseres Prompt-Engineering nicht überwindbar waren.
Chunk-Größe als kritischer Parameter: Eine Reduktion der Chunk-Größe verbesserte die Qualität etwas, erhöhte aber proportional die Verarbeitungszeit und die Anzahl der API-Calls. Dies zeigte eine fundamentale Trade-off-Beziehung in der Architektur.
Fundamentale LLM-Limitierungen: Coding war beherrschbar, wenn LLM-Technologie in Verbindung mit ergänzenden Datenstrukturen im Arbeitsspeicher eingesetzt wurde. Grenzen bestanden jedoch weiterhin in der limitierten Kontext-Größe, in Halluzinationen in den Antworten und unzureichendem Prompt-Following.
Retry-Logik für Produktionsrobustheit#
Die Implementierung einer Retry-Logik war notwendig, um mit der hohen Nutzungslast umzugehen. Das Tool wurde von vielen Personen benutzt, weshalb es auch manchmal zu Timeouts kam. Diese Robustheit war nicht in der initialen Spezifikation, sondern entwickelte sich als Reaktion auf den praktischen Einsatz.
Methodische Erkenntnisse und übertragbare Prinzipien#
Die überraschende Einfachheit funktionaler Lösungen#
Was am meisten überraschte: Dass ein so relativ kurzer Code dafür reichte, hochwertige und hilfreiche Zusammenfassungen zu generieren. Die Chunking-Strategie mit den Einzelzusammenfassungen und der Gesamtzusammenfassung funktionierte sehr gut. Angesichts des geringen Code-Umfangs funktionierte das Tool sehr gut.
Diese Einfachheit stand im Kontrast zu traditionellen Software-Entwicklungsannahmen, die für vergleichbare Funktionalität deutlich komplexere Architekturen erwarten lassen würden.
Workflow-Evolution: Der Wert der Vorab-Spezifikation#
Der Workflow konnte bei diesem Tool signifikant verbessert werden. Von Tools mit nur sehr eingeschränkter Funktionalität bis zu einem Tool, das Mehrwert für viele erzeugen konnte, obwohl es im Umfang noch sehr überschaubar war.
Eine zentrale Erkenntnis: Der Aufwand in Spezifikation und die Abstimmung und Festlegung der Gesamtarchitektur im Vorfeld war hilfreich. Die iterative Ko-Kreation mit LLMs funktionierte am besten, wenn strategische Entscheidungen vorab getroffen wurden und LLMs für taktische Implementierungsschritte eingesetzt wurden.
Übertragbare Prinzipien für LLM-Coding#
Dieses Experiment validierte mehrere Prinzipien für effektives LLM-gestütztes Coding:
Architektur-Ownership bleibt menschlich: Strategische Architekturentscheidungen konnten nicht delegiert werden. LLMs waren geeignet für eng umrissene Implementierungsaufgaben, aber nicht für architektonische Planung.
Bibliotheken mit LLM-Integration bevorzugen: Die Wahl von pymupdf4llm war ein weitreichende Vereinfachung. Bibliotheken, die bereits LLM-freundliche Ausgaben erzeugten, beschleunigten die Entwicklung.
Inkrementelles hinzufügen von Features reduziert Komplexität: Statt komplexer Vorab-Architekturen funktionierte der schrittweise Aufbau besser, wenn jede Erweiterung funktional begründet war.
Prompt-Engineering ist Systemarchitektur: Die Entwicklung robuster Prompts war nicht nachgelagert, sondern integraler Teil der Architektur. Techniken wie Großschreibung, explizite Halluzinations-Prävention und redundante Verstärkung waren systematisch einsetzbare Werkzeuge.
Einfachheit über vorzeitige Optimierung: Die funktionierende Lösung war überraschend einfach. Der Verzicht auf komplexe Optimierungen zugunsten von Klarheit und Wartbarkeit bewährte sich.
Technische Metriken und Ressourcenverbrauch#
Codebasis:
- 280 Zeilen Python-Code in einer Datei
- 10 Hauptfunktionen
- 7 Kern-Bibliotheken (Gradio, PyMuPDF, pymupdf4llm, python-docx, odfpy, requests, filelock)
- 6 Zusammenfassungstypen mit spezialisierten Prompts
Entwicklungsaufwand:
- 5-6 Stunden Gesamtzeit
- 30 Minuten initiale Spezifikation
- 4-5 Architektur-Iterationen
- Über mehrere Wochen verteilt, intermittierende Sessions
Chunking-Parameter:
- Chunk-Größe: 10.000 Zeichen
- Max. Retry-Versuche: 5
Nutzung:
- Einige hundert Zugriffe monatlich im VPN
- Dokumentgröße: wenige bis hunderte Seiten
- Verarbeitungszeit: Sekunden bis mehrere Minuten
- Nutzungsgruppe: Universitätsangehörige verschiedener Disziplinen
Fazit: Einfachheit als emergente Eigenschaft – und der Beginn einer Reise#
Dieses erste systematische Experiment demonstrierte, dass LLM-gestütztes Coding in klar definierten Kontexten hocheffizient sein konnte. Die Entwicklung eines produktiv genutzten Tools in wenigen Stunden, das einige hundert Male täglich verwendet wurde, wäre ohne LLM-Unterstützung in diesem Zeitrahmen nicht realisierbar gewesen.
Eine zentrale Erkenntnis war jedoch nicht die Geschwindigkeit, sondern die überraschende Einfachheit der funktionierenden Lösung. 280 Zeilen Code reichten für ein robustes, mehrsprachiges M