fix(extractor): Fensterexpansions-Rescue bei leerem Erst+Retry (#308)#335
Merged
Conversation
Root-Cause (#280/#297): der Planner weist Konzepten Chunks zu, die die Belegstelle nicht ausreichend enthalten; das 400-Wort-Fenster (concept_text_window) traf sie dann auch nach dem #280-Retry nicht -- der #297-Retry lief auf demselben Fenster und verdoppelte nur die Token-Kosten des Fehlversuchs, ohne die Ursache zu beheben. Fix: bleibt ein Konzept nach Erst-Call UND #280-Retry (extractor. run_per_concept) weiterhin leer, folgt auf Orchestrator-Ebene genau EIN Rescue-Versuch mit deutlich groesserem Fenster (400 -> 1200 Woerter, _RESCUE_WINDOW_WORDS). Neuer Parameter retry_empty=False an run_per_concept unterdrueckt dabei den internen #280-Retry, damit der Rescue max. 1 statt bis zu 2 Zusatz-Calls kostet. Erfolg -> Draft zaehlt normal, kein dropped-Event; Fehlschlag -> weiterhin dropped/ empty_extraction. Kein Rescue-Call, wenn das expandierte Fenster identisch zum urspruenglichen waere (z.B. sehr kurze Dokumente). Log-Signaturen: [extractor-window-rescue] / [extractor-window-rescue-failed].
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #308.
Problem
PR #297 hat für den stummen
<!--END-->-Drop einen Retry auf demselben Textfenster eingebaut (Symptom-Milderung). Die in #280 benannte Wurzel blieb: der Planner weist Konzepten Chunks zu, die die Belegstelle nicht enthalten. Bleibt ein Konzept nach Erst-Call UND #280-Retry (beide auf dem 400-Wort-Fenster vonconcept_text_window) leer, fiel es endgültig alsdropped/empty_extractionweg — der #297-Retry verdoppelte in diesem Fall nur die Token-Kosten des Fehlversuchs, ohne die Chance auf Rettung zu erhöhen.Vorher-Messung
Coverage-Serie 2 (2026-07-16): 2
[extractor-empty]-Fälle, #297-Retry rettete 1 von 2 (Sandmeier „Psychometrische Validierung" gerettet → Inbox; Kok Lauf 5 „Informierte Einwilligung" trotz Retry Totalverlust, tracedrop_reason: empty_extraction). Ältere Belege: Schlebbe 2026-07-12 „Forschungstrends zu Information Needs" (1/3 verloren), Schüller 2026-07-14 „Kompetenzniveaus am Beispiel Datenanalyse" (<!--END-->-only), alte A/B-Logscell4_Porstmit 21[extractor-empty]-Zeilen. Testlauf-Serie 2026-07-14: Sonnet 4.6 traf Kernkonzepte in 3 von 6 Läufen (u.a. „Amotivation", [high]-priorisiert).Design-Entscheidung
Fensterexpansion statt Neu-Ranking der Chunk-Zuordnung (die im Auftrag genannte Alternative): schlichter, ändert nichts am Planner/Chunking-Vertrag, und die Belegstelle ist ja durch
concept_text_windowbereits korrekt lokalisiert (Titel-Match, Score +100) — das Problem ist die Fenstergröße um den Treffer, nicht die Zuordnung selbst.orchestrator._RESCUE_WINDOW_WORDS = 1200(3xwindow_words=400).extractor.run_per_conceptnach Erst-Call+[MITTEL] Stiller Konzeptverlust via <!--END--> ohne Retry — traf Kernkonzepte in 3 von 6 Läufen #280-Retry beiNone, folgt auf Orchestrator-Ebene (run_extractors_per_concept) genau EIN Rescue-Versuch mit dem expandierten Fenster.retry_empty: bool = Trueanrun_per_concept: der Rescue-Call setztretry_empty=False, damit der interne [MITTEL] Stiller Konzeptverlust via <!--END--> ohne Retry — traf Kernkonzepte in 3 von 6 Läufen #280-Retry (auf demselben, bereits expandierten Fenster) nicht nochmal feuert — Kostendeckelung auf max. 1 Zusatz-Call pro Konzept (statt bis zu 2).dropped-Event, Draft zählt normal zudrafts/concept_map. Endgültiger Verlust → weiterhindropped/empty_extraction.[extractor-window-rescue](Erfolg) /[extractor-window-rescue-failed].run_extractors_per_concept(drafts, concept_map, dropped, failures) unverändert — nurdrafts/droppederweitern sich natürlich um die geretteten Fälle.RED-Nachweis (vor Implementierung)
generative/tests/test_extractor_window_rescue.py, 6 Tests, 3 schlugen vor der Implementierung fehl:Nach Implementierung: alle 6 grün (plus 34 bestehende Extractor-/Stage-Outcome-/Citation-Tests weiterhin grün, keine Regression).
Suite-Ergebnis
uv run pytest generative lib/decision_engine/tests shared/tests -q: 6162 passed, 3 skipped, 8 deselected, keine Fehler.uv run ruff check .: All checks passed.uv run ruff format --check .: 302 files already formatted.Geänderte Dateien
generative/agents/extractor.py— Parameterretry_empty: bool = Trueanrun_per_concept.generative/orchestrator.py— Fenster-Rescue inrun_extractors_per_concept(nur die Extractor-Dispatch-Region).generative/tests/test_extractor_window_rescue.py(neu) — 6 Tests (Orchestrator-Rescue-Erfolg/-Fehlschlag/-Skip-bei-identischem-Fenster/-nur-für-None-nicht-Exceptions, Extractor-retry_empty-Kontrakt).Offene Punkte
expanded_ctext == old_ctext-Skip vergleicht auf Textgleichheit; bei sehr großen Dokumenten mit vielen gleich hoch bewerteten Fenstern ist ein (harmloser) dritter Call mit im Ergebnis nahezu identischem, aber nicht bytegleichem Fenster nicht ausgeschlossen — kein Korrektheitsproblem, nur ein theoretisch möglicher Extra-Call.generative/config.py,pdf_enrich.py,docs/evaluation.md,agents/base.py,eval_quality_v4.py(Sperrzonen).