fix: Vergleichstabellen nicht als Summenabweichung melden; Verstehen-Prompt in Prompt-Kennung
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
0d9b5d718f
commit
7aac3ff3ec
4 changed files with 40 additions and 2 deletions
|
|
@ -26,9 +26,10 @@ RESULTS_DIR = BENCHMARK_DIR / "results"
|
||||||
# Nach dem ersten fatalen API-Fehler (Kontingent/Guthaben/Key) keine weiteren Läufe starten
|
# Nach dem ersten fatalen API-Fehler (Kontingent/Guthaben/Key) keine weiteren Läufe starten
|
||||||
quota_exhausted = threading.Event()
|
quota_exhausted = threading.Event()
|
||||||
|
|
||||||
# Dateien, die das LLM-Verhalten steuern: die drei System-Prompts und die Feldbeschreibungen
|
# Dateien, die das LLM-Verhalten steuern: die vier System-Prompts und die Feldbeschreibungen
|
||||||
# (Field(description=...) geht als JSON-Schema mit und wirkt wie eine Prompt-Anweisung).
|
# (Field(description=...) geht als JSON-Schema mit und wirkt wie eine Prompt-Anweisung).
|
||||||
PROMPT_FILES = ("modeling/Routing-und-Extraktions-Prompt.txt", "checks/Pruef-Prompt.txt", "solving/Solver-Prompt.txt",
|
PROMPT_FILES = ("understanding/Verstehen-Prompt.txt", "modeling/Routing-und-Extraktions-Prompt.txt", "checks/Pruef-Prompt.txt",
|
||||||
|
"solving/Solver-Prompt.txt",
|
||||||
"core/model_schema.py")
|
"core/model_schema.py")
|
||||||
|
|
||||||
# Umgebungsvariablen, die das Verhalten ändern – ohne sie ließe sich ein A/B-Lauf nicht zuordnen
|
# Umgebungsvariablen, die das Verhalten ändern – ohne sie ließe sich ein A/B-Lauf nicht zuordnen
|
||||||
|
|
|
||||||
|
|
@ -271,6 +271,17 @@ def _is_sum_row(row, value=None, others=None) -> bool:
|
||||||
return _close(value, sum(others))
|
return _close(value, sum(others))
|
||||||
|
|
||||||
|
|
||||||
|
def _is_comparison(values, no_sum_row: bool, total: float, objective_value) -> bool:
|
||||||
|
"""Vergleichstabelle: jede Zeile ist ein eigener Zielwert (Konfiguration, Szenario), keine Zerlegung.
|
||||||
|
|
||||||
|
Erkennbar daran, dass die Summe nicht passt, aber genau eine Zeile den gemeldeten Zielwert trägt.
|
||||||
|
Beobachtet: "Vergleich der Konfigurationen" (Portfolio Nr. 2) galt sonst als "Summe weicht ab".
|
||||||
|
"""
|
||||||
|
if objective_value is None or not no_sum_row or len(values) < 2 or _close(total, objective_value):
|
||||||
|
return False
|
||||||
|
return sum(_close(v, objective_value) for v in values) == 1
|
||||||
|
|
||||||
|
|
||||||
def _close(a: float, b: float) -> bool:
|
def _close(a: float, b: float) -> bool:
|
||||||
return abs(a - b) <= 1e-3 * max(abs(a), abs(b)) + 1e-6
|
return abs(a - b) <= 1e-3 * max(abs(a), abs(b)) + 1e-6
|
||||||
|
|
||||||
|
|
@ -303,6 +314,8 @@ def parse_result_tables(raw_tables: list, objective_value) -> tuple:
|
||||||
warnings.append(f"Tabelle '{table.title}': Spalte '{table.objective_column}' enthält nicht nur Zahlen – Summe nicht prüfbar.")
|
warnings.append(f"Tabelle '{table.title}': Spalte '{table.objective_column}' enthält nicht nur Zahlen – Summe nicht prüfbar.")
|
||||||
continue
|
continue
|
||||||
total = sum(values)
|
total = sum(values)
|
||||||
|
if _is_comparison(values, len(values) == len(cells), total, objective_value):
|
||||||
|
continue
|
||||||
if objective_value is not None and not _close(total, objective_value):
|
if objective_value is not None and not _close(total, objective_value):
|
||||||
warnings.append(
|
warnings.append(
|
||||||
f"Tabelle '{table.title}': Summe der Spalte '{table.objective_column}' ({total:.6g}) "
|
f"Tabelle '{table.title}': Summe der Spalte '{table.objective_column}' ({total:.6g}) "
|
||||||
|
|
|
||||||
|
|
@ -309,6 +309,7 @@ def test_benchmark_records_the_prompt_state():
|
||||||
assert len(stand["prompts"]) == 12 and stand["commit"]
|
assert len(stand["prompts"]) == 12 and stand["commit"]
|
||||||
assert "modeling/Routing-und-Extraktions-Prompt.txt" in PROMPT_FILES
|
assert "modeling/Routing-und-Extraktions-Prompt.txt" in PROMPT_FILES
|
||||||
assert "core/model_schema.py" in PROMPT_FILES # Feldbeschreibungen wirken wie Prompt-Anweisungen
|
assert "core/model_schema.py" in PROMPT_FILES # Feldbeschreibungen wirken wie Prompt-Anweisungen
|
||||||
|
assert "understanding/Verstehen-Prompt.txt" in PROMPT_FILES
|
||||||
|
|
||||||
|
|
||||||
def test_deviating_settings_are_recorded(monkeypatch):
|
def test_deviating_settings_are_recorded(monkeypatch):
|
||||||
|
|
|
||||||
|
|
@ -228,3 +228,26 @@ def test_ascii_form_present_in_the_task_is_not_replaced():
|
||||||
zuordnung = umlaut_map("Herr Müller und die Firma Mueller liefern.")
|
zuordnung = umlaut_map("Herr Müller und die Firma Mueller liefern.")
|
||||||
assert "mueller" not in zuordnung
|
assert "mueller" not in zuordnung
|
||||||
assert fix_transliterations("Firma Mueller", zuordnung) == "Firma Mueller"
|
assert fix_transliterations("Firma Mueller", zuordnung) == "Firma Mueller"
|
||||||
|
|
||||||
|
|
||||||
|
# beobachtet in Portfolio Nr. 2: eine Zeile je Konfiguration, die gewählte trägt den Zielwert
|
||||||
|
COMPARISON = {
|
||||||
|
"title": "Vergleich der Konfigurationen",
|
||||||
|
"columns": ["Konfiguration", "lambda1", "lambda2", "Zielfunktionswert"],
|
||||||
|
"rows": [["Reine Varianzminimierung", "1.0", "0.0", 0.18217355],
|
||||||
|
["Reine Korrelationsminimierung", "0.0", "1.0", -187.29514112],
|
||||||
|
["Ausgewogene Skalarisierung", "0.5", "0.5", -93.56364364]],
|
||||||
|
"objective_column": "Zielfunktionswert",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_comparison_table_is_not_a_sum_mismatch():
|
||||||
|
tables, warnings = parse_result_tables([COMPARISON], objective_value=0.18217353985482126)
|
||||||
|
assert warnings == [] and len(tables) == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_decomposition_with_one_term_equal_to_objective_is_still_checked():
|
||||||
|
# eine Summenzeile macht daraus eine Zerlegung – deren Fehler bleibt sichtbar
|
||||||
|
table = dict(DECOMPOSITION, rows=[["Rendite", 0.097557], ["Kosten", -0.05], ["Zielwert", 0.2]])
|
||||||
|
_, warnings = parse_result_tables([table], objective_value=0.097557)
|
||||||
|
assert any("weicht vom Zielwert" in w for w in warnings)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue