fix: Umlaute im Code erlaubt, Lesertexte still berichtigt
Ursache der Umschreibungen ist kein Encoding-Problem: das LLM schreibt im erzeugten Python-Code ASCII (Portfolio Nr. 2: Code-Strings 0 echte gegen 60 umschriebene Umlaute, Spezifikation 128 echte). Die Prompt-Regel wurde ignoriert, die Warnung stand in fast jedem Lauf. - Solver-Prompt: Umschreibungen in Bezeichnern, DATA-Schluesseln, Restriktionsnamen und Kommentaren erlaubt; echte Umlaute nur in Lesertexten, Regel direkt bei den report()-Argumenten. - check_text_quality meldet keine Umlaute mehr (Fachbegriffe bleiben). - umlaut_map baut je Lauf ein Woerterbuch aus Aufgabe und Spezifikation; repair_texts wendet es vor UMLAUT_STEMS an. ASCII-Formen aus dem Aufgabentext (Namen) bleiben, Restriktions-/Variablennamen unberuehrt. An vier gespeicherten Laeufen: alle Umschreibungen in Lesertexten berichtigt, 11 Ersetzungen, keine falsch. Prompt-Kennung 694c3eb3d59a. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
8697400dc2
commit
0d9b5d718f
1 changed files with 88 additions and 40 deletions
|
|
@ -156,15 +156,15 @@ def test_report_shows_multistart_stability():
|
|||
assert "nicht nachweislich das globale Optimum" in markdown
|
||||
|
||||
|
||||
def test_transliterated_umlauts_are_reported():
|
||||
# beobachtet: "Der guenstigste Ersatzplan", Tabelle "Gewaehlte Nutzungszeitraeume"
|
||||
def test_transliterated_umlauts_are_no_longer_reported():
|
||||
# Umschreibungen im Code sind erlaubt; Lesertexte werden still berichtigt statt gemeldet
|
||||
from core.model_schema import ResultTable, SolverRun, SolverStatus
|
||||
from solving.solver_stage import check_text_quality
|
||||
run = SolverRun(status=SolverStatus.OPTIMAL, headline="Der guenstigste Plan kostet 29 €.",
|
||||
tables=[ResultTable(title="Gewaehlte Zeitraeume", columns=["Kauf"], rows=[])])
|
||||
befunde = check_text_quality(run)
|
||||
assert any("guenstigste" in b for b in befunde)
|
||||
assert any("Gewaehlte" in b and "Zeitraeume" in b for b in befunde)
|
||||
assert check_text_quality(run) == []
|
||||
befunde = check_text_quality(run, summary="Es wird ein Plan gewählt.")
|
||||
assert not any("Umlaut" in b for b in befunde)
|
||||
|
||||
|
||||
def test_correct_german_is_not_flagged():
|
||||
|
|
@ -177,16 +177,14 @@ def test_correct_german_is_not_flagged():
|
|||
assert check_text_quality(run) == []
|
||||
|
||||
|
||||
def test_transliterations_are_repaired_after_being_reported():
|
||||
# Die Warnung dokumentiert den Prompt-Verstoss, der Report soll trotzdem lesbar sein
|
||||
def test_transliterations_are_repaired_silently():
|
||||
from core.model_schema import Answer, ResultTable, SolverRun, SolverStatus
|
||||
from solving.solver_stage import check_text_quality, fix_transliterations, repair_texts
|
||||
from solving.solver_stage import repair_texts
|
||||
run = SolverRun(status=SolverStatus.OPTIMAL, headline="Der guenstigste Plan kostet 29 €.",
|
||||
answers=[Answer(question_id="a", text="Die Loesung waehlt zwei Aktien.")],
|
||||
tables=[ResultTable(title="Gewaehlte Zeitraeume", columns=["Naechste Periode"],
|
||||
rows=[["gewaehlt", 3]], note="Gemaess Aufgabe.")])
|
||||
assert check_text_quality(run) # erst melden
|
||||
repair_texts(run) # dann beheben
|
||||
repair_texts(run)
|
||||
assert run.headline == "Der günstigste Plan kostet 29 €."
|
||||
assert run.answers[0].text == "Die Lösung wählt zwei Aktien."
|
||||
assert run.tables[0].title == "Gewählte Zeiträume"
|
||||
|
|
@ -205,3 +203,28 @@ def test_repair_covers_stems_seen_in_the_lot_sizing_case():
|
|||
# beobachtet in wagner_whitin_dijkstra: "110 Baelle", "Das heisst:" im Antworttext
|
||||
from solving.solver_stage import fix_transliterations
|
||||
assert fix_transliterations("Das heisst: 110 Baelle, der Ball") == "Das heißt: 110 Bälle, der Ball"
|
||||
|
||||
|
||||
def test_words_from_the_run_repair_what_the_fixed_list_misses():
|
||||
# beobachtet in "Portfolio Nr. 2": Volatilitaet, Kardinalitaet, vollstaendigen, binaere im Report
|
||||
from core.model_schema import Answer, ConstraintValue, SolverRun, SolverStatus
|
||||
from solving.solver_stage import repair_texts, umlaut_map
|
||||
aufgabe = "Datenlieferant: Mueller GmbH."
|
||||
spezifikation = ("Minimiere die Volatilität unter der Kardinalität k; nur Titel mit vollständigen Reihen, "
|
||||
"binäre Auswahl. Restriktion: Kardinalitaet") # ASCII-Bezeichner des LLM
|
||||
run = SolverRun(status=SolverStatus.OPTIMAL,
|
||||
headline="Volatilitaet 12 %, Kardinalitaet eingehalten.",
|
||||
answers=[Answer(question_id="1", text="Nur Titel mit vollstaendigen Reihen, binaere Variablen; Quelle: Mueller GmbH.")],
|
||||
constraints=[ConstraintValue(name="Kardinalitaet", lhs=20, sense="==", rhs=20)])
|
||||
repair_texts(run, umlaut_map(aufgabe, spezifikation))
|
||||
assert run.headline == "Volatilität 12 %, Kardinalität eingehalten."
|
||||
assert run.answers[0].text == "Nur Titel mit vollständigen Reihen, binäre Variablen; Quelle: Mueller GmbH."
|
||||
assert run.constraints[0].name == "Kardinalitaet" # Bezeichner bleibt: Namensabgleich hängt daran
|
||||
|
||||
|
||||
def test_ascii_form_present_in_the_task_is_not_replaced():
|
||||
# steht die ASCII-Form selbst im Text (z. B. ein Name), ist sie echt
|
||||
from solving.solver_stage import fix_transliterations, umlaut_map
|
||||
zuordnung = umlaut_map("Herr Müller und die Firma Mueller liefern.")
|
||||
assert "mueller" not in zuordnung
|
||||
assert fix_transliterations("Firma Mueller", zuordnung) == "Firma Mueller"
|
||||
|
|
|
|||
Loading…
Reference in a new issue