feat(eval): generische CID-Korruptions-Warnung ohne Messverhaltens-Aenderung (#306)#337
Merged
Conversation
…nderung (#306) PR #298 fixt exakt zwei Codepoints eines defekten Fonts im Jockisch-PDF (U+0231/U+022C). Jedes andere PDF mit anderem CID-Glyph-Mapping erzeugt dasselbe Fehlerbild (quellentreue Notes faelschlich als Halluzination) und blieb bisher unentdeckt. Neu: generative/eval_text_quality.py::detect_cid_suspect() prueft den per PyMuPDF extrahierten Volltext auf ein verdaechtiges Nicht-ASCII- Haeufigkeitsprofil (ein einzelner Codepoint ausserhalb ASCII/Latin-1/ Latin-Extended-A, abzueglich einer Whitelist gaengiger typografischer Satzzeichen, >= 0,5% aller Zeichen). Verdrahtet additiv in eval_quality_v4.py: neues Feld result["pdf_text_suspect_cid"] + Flag "cid_font_suspect" in result["quality_flags"], stderr-Warnung beim Oeffnen der PDF. Kein Rueckmapping, keine Label-/Raten-Aenderung -> kein EVAL_VERSION-Bump. test_audit_double_call.py-Snapshot um das neue additive Feld ergaenzt. docs/evaluation.md um Abschnitt zur neuen Warnung erweitert.
…reek/Cyrillic-FP) (#306) Adversarialer Fund: ein statistik-lastiger Absatz mit griechischer Koeffizienten-Notation (α, β, χ²) triggerte die CID-Verdachts-Warnung faelschlich (CidSuspectResult(U+03B1, ratio 1,93%) bei 0,5%-Schwelle). CID-Korruptionsglyphen landen empirisch in Latin Extended-B (U+0231/U+022C, #278), nicht in etablierten Nicht-Latein-Schriftbloecken -- Statistik-, Linguistik-, Klassik- und Slawistik-Fachtexte nutzen Griechisch/Kyrillisch dagegen legitim und gehaeuft. generative/eval_text_quality.py: Greek and Coptic (U+0370-U+03FF) und Kyrillisch (U+0400-U+04FF) neben der bestehenden Satzzeichen-Whitelist von der Verdachtszaehlung ausgenommen (_ESTABLISHED_SCRIPT_RANGES). Neue Tests: griechischer und kyrillischer Absatz -> kein Flag (RED vor dem Fix reproduziert: beide Faelle schlugen mit realer CidSuspectResult fehl); Regressionstest bestaetigt, dass das Jockisch-Muster (Latin Extended-B) weiterhin triggert. docs/evaluation.md: #306-Abschnitt um Schriftblock-Ausnahme, bekannte Grenze (exotische Schriften ausserhalb Griechisch/Kyrillisch/Latein koennten weiterhin flaggen) und Alt-Cache-Hinweis (Warnung feuert fuer bereits gecachte Evals erst bei Re-Eval/--fresh-run) ergaenzt.
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 #306.
Problem
PR #298 fixt exakt zwei Codepoints eines defekten eingebetteten Fonts im
Jockisch (2010)-PDF (U+0231 → Leerzeichen, 5173×; U+022C → Trennstrich,
240×; per PyMuPDF am Original nachgemessen, siehe
eval_common._normalize).Jedes andere PDF mit einem anderen CID-Glyph-Mapping erzeugt dasselbe
Fehlerbild — quellentreue Notes werden fälschlich als Halluzination
markiert — und bleibt unrepariert, bis jemand manuell eine neue
Replace-Zeile einbaut. Die adversariale Kontrolle zu #298 bestätigte am
selben PDF weitere seltene (≤8×) Rest-Artefakte (ĺ, Έ, ȟ) als Vorboten
dieser Fehlerklasse.
Fix: Erkennung + Warnung, kein Rückmapping
Neues Modul
generative/eval_text_quality.py::detect_cid_suspect():prüft den per PyMuPDF extrahierten Volltext auf ein verdächtiges
Nicht-ASCII-Häufigkeitsprofil. Erwartbarer "gesunder" Codepoint-Bereich für
deutschen/englischen Fachtext: ASCII + Latin-1 Supplement (Umlaute, ß) +
Latin Extended-A, abzüglich einer Whitelist gängiger typografischer
Satzzeichen (Gedankenstriche, "smarte" Anführungszeichen, Ellipse —
PyMuPDF-Extraktionsartefakte, keine CID-Signale). Dominiert ein einzelner
Codepoint außerhalb davon mit ≥ 0,5 % aller Zeichen, gilt das als
CID-Verdacht — exakt das Muster, das U+0231 im Jockisch-PDF zeigte (ein
Glyph ersetzt praktisch jedes Leerzeichen).
Verdrahtung in
eval_quality_v4.py(additiv, in_pdf_artifacts()/_aggregate()):result["pdf_text_suspect_cid"]({codepoint, count, ratio, total_chars}oderNone)"cid_font_suspect"inresult["quality_flags"](dasselbeMechanismus-Muster wie die bereits existierenden Flags
possible_retrieval_miss,parse_errors_presentetc.)Prozess, nicht pro Note — dank bestehendem PDF-Artefakt-Cache)
Kein generisches Rückmapping (das bleibt bewusst Handarbeit pro PDF wie
in #298 — ein falsches automatisches Mapping würde stillschweigend
Text verändern), keine Label-Änderung, keine Raten-Änderung.
Kalibrierungs-Belege (synthetisch, siehe
test_cid_suspect_detection.py)count=280,total_chars=3040, ratio=9,21 % → Flag gesetztWarum kein
EVAL_VERSION-Bump nötig istJede geänderte Zeile wurde daraufhin geprüft, ob sie Chunk-Texte, Embeddings,
Evidence-Corpus, Judge-Prompt, Labels oder Raten beeinflusst:
detect_cid_suspect()liest nur den bereits vorhandenenfull_textlesend,verändert ihn nicht — Chunking/Retrieval/Evidence-Verifikation laufen exakt
wie vorher auf demselben Text.
_aggregate()bekommt den neuencid_suspect-Parameter nur additiv: erfügt einen Eintrag zu
quality_flagshinzu und setzt ein neues Feldpdf_text_suspect_cid— alle anderen Result-Keys (Raten, Label-Counts,claim_scores,hallucination_rate,coverage_rate, ...) bleibenunverändert. Dediziert getestet:
TestAggregateCidSuspectAdditive::test_cid_suspect_does_not_change_any_other_result_fieldvergleicht ein
_aggregate()-Ergebnis mit und ohne CID-Verdacht beiidentischem Input und belegt: die einzige Differenz sind die zwei
neuen additiven Keys.
EVAL_CACHE_NAMESPACE) bleibt anEVAL_VERSIONgebunden, die unverändert bleibt — kein Grund zurInvalidierung, da bit-identisches Messverhalten bei identischem Input.
Bei identischem Input sind gemessene Halluzinationsraten/Labels vor und
nach diesem PR bit-identisch.
TDD: RED → GREEN
RED (vor der Verdrahtung, 5 Fehlschläge — die reine Heuristik-Funktion war
zu diesem Zeitpunkt schon implementiert/kalibriert, die Verdrahtung in
_pdf_artifacts/_aggregatenoch nicht):GREEN (nach Verdrahtung in
_PdfArtifacts/_pdf_artifacts()/_aggregate()/eval_note()):11 passed in 2.01s.Suite-Zahlen (voller Lauf, sauber, keine Parallel-Prozesse)
uv run ruff check .→ All checks passed.uv run ruff format --check .→ 303 files already formatted.(Ein erster Suite-Lauf zeigte 1 Fehlschlag in
test_audit_double_call.py::TestEvalNoteResultUnchanged::test_full_result_matches_pre_fix_snapshot— Zeitpunkt-Artefakt: die Testsammlung dieses Laufs hatte den alten Stand der
Datei erfasst, bevor ich den Snapshot um das neue additive Feld ergänzt
hatte. Der zweite, saubere Lauf mit finalem Code-Stand bestätigt 0
Fehlschläge.)
Geänderte Dateien
generative/eval_text_quality.py(neu) — Heuristik +CidSuspectResultgenerative/eval_quality_v4.py— Verdrahtung (additiv)generative/tests/test_cid_suspect_detection.py(neu) — Heuristik- +Verdrahtungs-Tests
generative/tests/test_audit_double_call.py— Snapshot um additives Feldergänzt
docs/evaluation.md— Abschnitt zur neuen Warnung + Tabellen-/Absatz-Updatein Kapitel 5
Abgrenzung
#27 (Textqualitäts-Gate + OCR-Fallback) adressiert die Pipeline-/
Chunker-Seite. Dieser PR betrifft ausschließlich die Eval-Messseite
(
eval_quality_v4.py, direkter PyMuPDF-Zugriff). Nicht angefasst:eval_dashboard_server.py,orchestrator.py,agents/extractor.py,tools/pdf_enrich.py,pipeline/pdf_chunker.py(parallele Arbeit).Nachbesserung: Griechisch/Kyrillisch-False-Positive (Commit
dad3827)Adversariale Kontrolle bestätigte die Bump-Freiheit über 6 Vektoren, fand
aber einen realen False-Positive: ein statistik-lastiger Absatz mit
griechischer Koeffizienten-Notation (α, β, χ²) triggerte die Warnung
fälschlich (empirisch
CidSuspectResult(U+03B1, ratio 1,93 %)bei0,5 %-Schwelle). Ursache: Griechisch/Kyrillisch sind etablierte
Schriftblöcke, die in Statistik-/Linguistik-/Klassik-/Slawistik-Fachtexten
legitim und gehäuft vorkommen — CID-Korruptionsglyphen landen dagegen
empirisch in Latin Extended-B (U+0231/U+022C, #278), nicht dort.
Fix:
_ESTABLISHED_SCRIPT_RANGESineval_text_quality.pynimmt Greek andCoptic (U+0370–U+03FF) und Kyrillisch (U+0400–U+04FF) von der
Verdachtszählung aus. Neue Tests (
test_greek_statistics_paragraph_does_not_trigger,test_cyrillic_paragraph_does_not_trigger) reproduzieren den False-Positiveals RED (vor dem Fix:
AssertionError, echteCidSuspectResultfür α bzw.т), GREEN danach; Regressionstest
test_jockisch_pattern_still_triggers_despite_script_exclusionbelegt, dass das eigentliche Jockisch-Muster (Latin Extended-B) weiterhin
erkannt wird.
docs/evaluation.mdergänzt: bekannte Grenze (exotische Schriften außerhalbGriechisch/Kyrillisch/Latein könnten weiterhin fälschlich flaggen — reine
Diagnostik, kein Messeinfluss) und Alt-Cache-Hinweis (da kein
EVAL_VERSION-Bump erfolgt, feuert die Warnung für bereits unter 4.3gecachte Evals erst bei Re-Eval/
--fresh-run, bestehende Baselines bleibenunmarkiert).
Suite nach Nachbesserung:
6195 passed, 3 skipped, 8 deselected(EXIT_CODE 0,303,94 s).
ruff check/ruff format --checkweiterhin grün.Nicht gemergt — zur Review.