
Dieser Beitrag beschreibt die technische Umsetzung von Zero-Hallucination-Q&A in unserem AI-Reader: Antworten basieren strikt auf dem Text des geöffneten Buches, zentrale Aussagen lassen sich per Ein-Klick zur exakten Passage zurückverfolgen. Wenn Sie AI-Reading, Dokumenten-Q&A oder RAG-ähnliche Apps bauen, hoffen wir, dass drei Iterationen und die finale Architektur als Referenz dienen.
I. Entwicklung in drei Phasen
Zero-Hallucination-Q&A war von Anfang an nicht perfekt geplant, sondern entstand im Spannungsfeld von Kosten, Latenz und Genauigkeit. Im Folgenden die drei Phasen in zeitlicher Reihenfolge—als Kontext, warum die aktuelle Architektur so aussieht.
Phase 1: Gesamten Buchtext in den Context legen (einfachste Variante—und die erste, die bricht)
Vorgehen: Beim Öffnen eines Buches und einer Nutzerfrage den gesamten extrahierten Fließtext in System Prompt oder User-Nachricht packen und vom Chat-Modell beantworten lassen. Überschreitet das Buch etwa 400.000 Zeichen, erfolgt eine harte Kürzung—nur der Anfang bleibt; spätere Kapitel sind für das Modell unsichtbar.
Vorteile:
- Sehr geringer Implementierungsaufwand, kaum Vorverarbeitung;
- Bei kurzen Büchern und einfachen Dokumenten oft brauchbar—das Modell hat das Buch tatsächlich „gesehen“;
- Einfache UX: Fragen stellen, Antwort erhalten—kein „Bitte warten Sie auf die Analyse“.
Nachteile (schnell inakzeptabel):
- Langsame Antworten: Jede Frage sendet erneut eine riesige Payload; Time-to-First-Token und Gesamtlatenz wachsen mit der Buchlänge;
- Hohe Token-Kosten: Der volle Buch-Input wird bei jeder Frage erneut bezahlt;
- Lange Bücher verzerren stark: Nach 400k Zeichen existieren zweite Hälfte, Anhänge und Schlusskapitel faktisch nicht—und die UI weist selten klar darauf hin, dass gekürzt wurde;
- Keine Abrufgranularität: Das Modell muss in Hunderttausenden Zeichen „die Nadel im Heuhaufen“ finden—Details gehen leicht verloren, plausibel klingende, aber unbelegte Zusammenfassungen entstehen leichter—genau das, was Lese-Apps vermeiden müssen.
Phase 1 eignet sich für ein MVP, nicht für eine produktionsreife Lösung.
Phase 2: Leichteres LLM extrahiert Schlüsselsätze (Context komprimieren—aber zu aggressiv)
Vorgehen: Vor dem Q&A (oder beim ersten Öffnen) ein günstigeres Modell über den Fließtext: Aufteilung nach Spine-Kapitel (oder Buch in Blöcke), Extraktion von Schlüsselsätzen, Beibehaltung von Positions-Tags wie [fDatei-Start-Ende], dann Zusammenfügen der Auszüge zu kürzerem Context für späteres Q&A.
Typische Pipeline: Extract → Cache → Chat. Einmal extrahieren (offline oder on demand), „Schlüsselsatz-Bündel“ speichern, bei jeder Frage wiederverwenden—wie viele Dokumenten-Q&A-Prototypen: erst komprimieren, dann antworten.
Vorteile:
- Pro Frage deutlich weniger Text; Token-Verbrauch pro Request sinkt gegenüber Phase 1;
- Vorverarbeitung cachebar; kein Re-Extract pro Frage beim gleichen Buch;
- Positions-Tags legen die Basis für Zitate.
Nachteile (bei langen Büchern weiterhin unzureichend):
- Starker Detailverlust: „Schlüsselsätze“ werden vom Modell gewählt; Einschränkungen, Gegenbeispiele und Argumentketten gehen oft verloren—Antworten werden „richtig, aber einseitig“;
- Context bei Langwerken weiter groß: Selbst Schlüsselsatz-Bündel sind umfangreich—Latenz und Kosten werden gelindert, nicht gelöst;
- Doppelter LLM-Fehler: Extraktion kann übersehen; Q&A kann Auszüge falsch lesen—Fehler stapeln sich;
- Statischer Context: Ob die Frage ein Kapitel oder die Gesamtstruktur betrifft—das Modell erhält immer dieselbe vorab extrahierte Masse, keine dynamische Eingrenzung nach Frage.
Die Lehre: Das Problem ist nicht „ob wir komprimieren“, sondern „ob die Kompression bedarfsgesteuert ist und ob wir zum Quelltext zurückkehren können“.
Phase 3: Segment-Index + Tool-Abruf on demand + Quelltext-Rückgabe (aktuell)
Vorgehen: Angelehnt an PageIndex. Gegenüber Phase 2 drei Kernverschiebungen:
- Vorverarbeitung erzeugt einen strukturierten Index (Inhaltsverzeichnis-Zusammenfassungen + exakte Zeichen-Spannen), keine Auszüge als direkter Q&A-Context;
- Jede Frage nutzt Tool Calling zur bedarfsgesteuerten Suche, dann Abruf von Quelltext mit Positions-Tags zur Antwort;
- System Prompt + Frontend erzwingen Zitierformat und unterstützen Klick → Sprung → Hervorhebung im Reader.
Vergleich der drei Phasen:
| Dimension | Phase 1 (Volltext) | Phase 2 (Schlüsselsätze) | Phase 3 (aktuell) |
|---|---|---|---|
| Context pro Frage | Ganzes Buch (oder gekürzte erste Hälfte) | Vorab extrahierte Schlüsselsätze | Nur Quelltext-Ausschnitte zur Frage |
| Genauigkeit bei langen Büchern | Ab ~400k Zeichen stark eingebrochen | Abhängig von Extraktion; Detailverlust | Abruf per TOC/Span; kein hartes Vollbuch-Truncate |
| Antwortgeschwindigkeit | Langsam | Etwas besser; lange Bücher weiter langsam | Abruf + kurzer Context—deutlich schneller |
| Token-Kosten | Sehr hoch | Mittelhoch | Vorverarbeitung amortisiert + zahlen nach Bedarf |
| Nachvollziehbarkeit | Schwach (Zitate schwer) | Tags vorhanden, Inhalt aber gefiltert | Fußnoten → echte Quell-Spannen |
| Engineering-Aufwand | Niedrig | Mittel | Hoch |
Warum wir bei Phase 3 bleiben: Beim Lesen geht es bei Zero Hallucination nicht darum, „dem Modell möglichst viel Text zu zeigen“, sondern „vor der Antwort Belege aus dem Buch zur Frage zu holen“. Phase 1–2 kämpften mit der Context-Größe; Phase 3 teilt die Pipeline in Index (Vorverarbeitung) → Abruf (Tool) → Beleg (Quelle) → Antwort (kontrollierte Generierung)—Genauigkeit, Kosten und Nachvollziehbarkeit zusammen.
Im Folgenden die Details von Phase 3.
II. Problemstellung: Bei Buch-Q&A ist Halluzination schlimmer als im allgemeinen Chat
Gelegentliche Fehler in einem allgemeinen Chatbot verzeihen Nutzer oft. Bei Buch-Q&A ist der Preis höher:
- Nutzer fragen, was dieses Buch sagt—not was im parametrischen Gedächtnis des Modells liegt;
- Eine plausibel klingende „Ansicht aus dem Buch“ kann Notizen, Zitate und Weitergabe irreführen;
- Ohne Quellen keine Verifikation—Vertrauen ist schwer aufzubauen.
„Zero Hallucination“ wird daher zu drei durchsetzbaren Regeln:
- Buchfragen müssen zuerst das Buch befragen: Alles, was plausibel zum geöffneten Buch gehört, muss zuerst Retrieval (Tool) durchlaufen;
- Antworten müssen nachvollziehbar sein: Zentrale Aussagen tragen Positions-Tags, die die UI parsen und anspringen kann;
- Sagen, wenn nichts gefunden wird: Fehlt es im Buch, klar sagen—kein Allgemeinwissen als „Buchaussage“ verkaufen.
Der Rest folgt dem Datenfluss von Phase 3 und der Umsetzung dieser Regeln.
III. Architektur: Vorverarbeitung → Tool-Abruf → Kontrollierte Generierung → Klickbare Zitate
Kernidee: Das Modell soll nicht „aus dem Gedächtnis antworten“—sondern „Belege sammeln, dann antworten und Quellen markieren“.
IV. Vorverarbeitung: Das ganze Buch in einen durchsuchbaren Segment-Index verwandeln
Wenn jede Frage weiter Phase-1-Vollbuch-Context nutzte, sprengen lange Bücher das Token-Budget und der Abruf ist zu grob. Phase 3: Beim ersten AI-Chat zu einem Buch läuft im Hintergrund ein Segment-Zusammenfassungs-Job—Aufteilung nach TOC oder Textlänge in Segments, Zusammenfassung je Segment, Persistenz in lokaler IndexedDB.
Jedes Segment enthält Zusammenfassung plus physische Position im Fließtext:
| Feld | Bedeutung |
|---|---|
startFileIndex / endFileIndex | Spine-Datei-Index (PDF: eine Datei pro Seite) |
startOffset / endOffset | Zeichen-Start/Ende |
sequence | Lineare Lesereihenfolge |
title | TOC-Titel |
Die Aufteilung balanciert Präzision und Kosten: TOC-Knoten unter ~20 KB nur dieser Knoten; Geschwister-Knoten können zu Batches (15–20 KB) vor dem LLM-Aufruf zusammengeführt werden; unstrukturierte lange Blöcke in ~30–40k-Zeichen-Bereichen.
Der Zusammenfassungs-System-Prompt verlangt inline Positions-Tags ([fZahl-Zahl-Zahl]), damit per Tool geladener Quelltext mit Spine-Offsets übereinstimmt. Kernvorgabe:
If summary content relates to a passage, keep the trailing position tag [fNumber-Number-Number] (e.g. [f1-90-109]).
Tags are atomic—do not alter, merge, or omit any character or digit.
Nach der Vorverarbeitung hängt Q&A vom strukturierten Segment-Index ab, nicht vom Vollbuch-Context—Voraussetzung für Zero Hallucination bei langen Büchern.
V. Positions-Tag-System: „Woher“ in den Text kodieren
Zero Hallucination verlangt Inhalt aus der Quelle und maschinenlesbare, in der UI springbare Herkunft. Wir nutzen inline Tags:
[f{fileIndex}-{startChar}-{endChar}]
Beispiel: [f5-123-165] = Spine-Datei 5 (0-basiert), Zeichen 123–165.
5.1 Wie Tags in den Fließtext geschrieben werden
Die Extraktionsschicht hängt [f{fileIndex}-{start}-{end}] an Segmentenden an:
const position = `[f${fileIndex}-${absOffset}-${absOffset + segment.length}]`;
fileLines.push(segment.text.trim() + position);
Ob Vorverarbeitungs-Zusammenfassungen oder Tool-Auszüge—Positionen alignen mit Spine-Zeichen-Offsets, nicht mit vom Modell geschätzten Seitenzahlen.
5.2 Vorgaben für Modellausgabe
Der System Prompt enthält Position Citation Rules—fünf Kernpunkte:
- Standardformat: Muss
[f_fileIndex-startChar-endChar]nutzen; alle drei numerischen Teile erforderlich; - Nur aus aktuellen Quellen kopieren: Fußnoten wörtlich aus System/User-Nachrichten oder Tool-Rückgaben dieser Runde;
- Keine Erfindung: Positionen nicht berechnen, ändern oder erfinden;
- Lieber weglassen: Kein gültiger Tag im Context → normal antworten—keine Positions-Tags ausgeben;
- Inline bei Aussagen: Tags folgen dem relevanten Satz; keine Zitatlisten am Ende.
Die UI filtert gelegentliche zweiteilige ungültige Tags (z. B. [f1-293]) vor dem Rendern.

VI. Tool Calling: Erst suchen, dann antworten
Ist der Chat an ein Buch gebunden (resourceId vorhanden, chatType === 'chat'), registrieren wir vor jeder Generierung zwei Tools mit Executors—Standard-OpenAI-Function-Calling-Schleife.
6.1 get_related_segment_summaries — Gezielter Segment-Abruf
Für: Konzepte, Figuren, Handlung, Kapiteldetails—klare Suchabsicht.
Ablauf:
- Modell formuliert Nutzerwortlaut in im Buch wahrscheinliche Begriffe um („Optimize Search Queries“ im System Prompt);
- Tool-Aufruf mit
question; - Alle Segment-Zusammenfassungen nach Token-Budget batchen (~30k Token pro Batch, max. 5 Batches);
- Pro Batch: separater LLM-Request wählt relevante Segment-IDs (max. 5) aus
{ id, title, summary }, JSON wie{"Thinking":"...","answer":["1","3"]}; - Für gewählte Segmente getaggten Quelltext aus dem Spine laden—not Zusammenfassungen—als Tool-Ergebnis.
Schlüsseldesign: Tool liefert Quelle, keine Zusammenfassungen. Das Modell antwortet aus echten Absätzen mit inline [f…], ohne „Zusammenfassung → erneute Zusammenfassung“-Drift.
6.2 get_full_book_segment_summaries — Gesamtbuch-Überblick
Für: „Buch zusammenfassen“, „Rezension“, „Gesamtstruktur/Themen“—globaler Blick.
Alle Segment-summary-Felder in Lesereihenfolge verketten—wichtige Kapitel nicht nur über Chunk-Relevanz verpassen.
6.3 System Prompt: Buch zuerst, Tools zuerst
Mit gebundenem Buch gilt Core Principles for Reading Assistant:
1. Book First, Tool First
- Any question possibly about the book must call tools first;
- Answers must rely mainly on retrieval—never invent “book content” without retrieval.
2. General Knowledge as Fallback Only
- Only for: casual chat / user explicitly skips the book / tools return nothing;
- If the book lacks it, say “not mentioned in this book” before general knowledge.
3. Direct Style
- Get to the point—avoid “based on the provided materials…” and similar filler.
Die Generierung führt die Tool-Schleife aus: tool_calls → ausführen → role: tool anhängen → bis zum finalen Text. Mit aktivierten Tools ist der Thinking-Kanal aus, um Protokollkonflikte zu vermeiden.
VII. Frontend-Nachverfolgung: Von der Fußnote zur Hervorhebung
Modellausgabe [f5-123-165] wird nicht roh angezeigt; die Render-Schicht macht daraus klickbare Zitate.
7.1 Fußnoten-Rendering
Tags zu Markdown-Links wie [1]([f5-123-165]) normalisieren, als nummerierte Fußnoten rendern; gleiche Position deduplizieren.
7.2 Klick-Interaktion
- Erster Klick:
[f…]parsen → fileIndex + Offsets → Spine-Text extrahieren → Vorschau (optional TOC-Titel); - Gleiche Fußnote erneut: Vorschau schließen;
- Sprung bestätigen: Lesesicht öffnen, Zeichenbereich hervorheben.
Vom kopierten Modell-Tag bis zum sichtbaren Quelltext für den Nutzer kein weiterer LLM-Schritt—deterministisch und reproduzierbar.
VIII. Grenzfälle und ehrliche Degradation
Zero Hallucination ≠ „immer eine Antwort“—sondern kein Beleg, keine Erfindung:
| Szenario | Verhalten |
|---|---|
| Segment-Zusammenfassungen noch nicht fertig | Zuerst Volltext extrahieren und zusammenfassen |
| Tool findet nichts | (No relevant segment excerpts found…) zurück; Modell soll „nicht im Buch“ sagen |
| Ungültige zweiteilige Tags vom Modell | Frontend filtert; keine kaputten Fußnoten |
| Smalltalk | System Prompt erlaubt Allgemeinwissen ohne Buch |
| Chat exportieren | Fußnoten können Reader-Deep-Links für Teilen/Archiv werden |

IX. Design-Abwägung: Warum kein „Vektor-RAG“?
Kollegen im Dokumenten-Q&A fragen oft: Wenn Retrieval-Augmented Generation—warum nicht Embedding + Vektor-DB Top-K?
Wir machen RAG—erst suchen, dann generieren. Der Unterschied: „RAG“ impliziert in der Community oft Vektor-Ähnlichkeit; unsere Phase 3 ist Segment-Index + Tool mit Quelltext on demand—bewusst ohne Vektorschicht. Unten: architektonische Gründe, kein Abwertung von Vektor-RAG.
Abgrenzung: nicht „kein Retrieval“, sondern „kein Vektor-Retrieval“
- Breites RAG: suchen → generieren → machen wir;
- Vektor-RAG: Recall per Embedding-Ähnlichkeit → in dieser Version nicht.
Die Vorverarbeitung baut einen Segment-Zusammenfassungs-Index; das Modell wählt Segmente per Tools und erhält Quelltext. Retrieval ohne separates Embedding-Modell und Vektor-Index-Pflege.
Grund 1: Eigene LLM-Provider—kleine Integrationsfläche
Nutzer können eigene API-Keys, eigene Base-URLs oder lokales Ollama nutzen—Chat-Modell ist ihre Wahl; Kosten und Datenpfad bleiben kontrollierbar.
Typisches Vektor-RAG erweitert die Integration:
- Neben Chat-Modell meist ein Embedding-Modell (anderer Name, oft anderer Endpoint);
- Lokales Ollama braucht separates Embedding-Modell plus Dimension/API-Kompatibilität;
- Mehr Fehlerdomänen: Chat ok, aber leerer Abruf—Embedding, Index oder Dimension; schwerer zu debuggen als ein Provider end-to-end.
Hier teilen Segmentwahl und Antwort eine Provider-Konfiguration—kein „Chat auf A, Index auf B“. Für austauschbare LLM-Apps oft wichtiger als wenige Recall-Punkte.

Grund 2: Embeddings binden an den Index—Provider-Wechsel ist teuer
Bei Vektor-RAG sind Vektoren kein universelles Zwischenformat—sie sind Koordinaten unter einem Embedding-Modell. Index mit A, Abfrage mit B: Ähnlichkeit meist nicht vergleichbar—oft vollständiges Re-Embedding, Dimensionen (768 / 1024 / 1536 …) binden das Speicher-Schema.
Phase 3 persistiert strukturierte Zusammenfassungen + Zeichen-Spannen, keine Vektoren; Chat-Modell wechseln ohne Index-Rebuild; Belegkette (Quellpositionen) bleibt—passt zu „jederzeit andere LLMs testen“.
Grund 3: Strukturiertes Routing reicht oft für TOC-lastige Langdokumente
E-Books und PDFs haben meist Kapitelstruktur; die Vorverarbeitung liefert Segmenttitel + Zusammenfassungen. Für „was sagt Kapitel X“ oder „wie definiert das Buch Y“: Segmente aus dem Katalog wählen, dann Quelle ziehen—in der Praxis stabil; Tool liefert Quelle mit [f…], Zero Hallucination bleibt an Zeichen-Spannen verankert.
Vektoren helfen bei semantischer Unschärfe, Mehrsprachigkeit, langen wörtlichen Treffern; für TOC + Vorverarbeitung + starke Nachverfolgbarkeit lohnt sich die Investition in Tool + Quellrückgabe + Zitierregeln oft mehr.
Ausblick: Hybrider Recall, kein Neuanfang
Möglich ist später Vektor-Grobrecall (Embedding nur für Top-N-Kapitel-Kandidaten), Ende bleibt Segment wählen → Quelle → klickbare Spur—Zero-Hallucination-Regeln unverändert. Falls eingeführt: Embedding optional, explizite Re-Index-Hinweise bei Modellwechsel—kein silent wrong retrieval.
Bis dahin: jede OpenAI-kompatible Chat-API funktioniert; Chat-Modell wechseln ohne lokalen Index-Rebuild.
X. Zusammenfassung
| Schritt | Methode | Rolle |
|---|---|---|
| Vorverarbeitung | Aufteilung nach TOC/Länge + Segment-Cache | Lange Bücher durchsuchbar & lokalisierbar |
| Positions-Tags | [fDatei-Start-Ende] in der Quelle | Maschinenlesbare Herkunft |
| Tool-Abruf | Segmente / Vollbuch-Zusammenfassungen pro Frage, Quelle zurück | Beleg vor Antwort erzwingen |
| System Prompt | Buch zuerst, keine gefälschten Tags, fehlendes benennen | Generierung einschränken |
| Frontend | Fußnote → Vorschau → Sprung & Hervorhebung | Nutzer prüft Belege |
| Kein Vektor-Retrieval | Ein Provider; Chat-Modell tauschen ohne Re-Index | Geringere Integrations- & Migrationskosten |
„Zero Hallucination“ heißt nicht, dass das Modell nie irrt—sondern dass Engineering die Ausgabe an eine Belegkette bindet: kein Abruf → nicht als Buchinhalt ausgeben; mit Abruf → verifizierbare Quellpositionen.
Wenn Sie AI-Reading oder Dokumenten-Q&A bauen, hoffen wir, der Weg Volltext → Schlüsselsätze → Tool-first on demand plus inline Positions-Tags + Quellrückgabe sei eine nützliche Referenz.
Das sind Erfahrungen aus dem Foxycape AI-Reader—nur zur Orientierung. Den Reader finden Sie auf der Download-Seite.
