Qwen3.8-27B-MTP-GGUF / bench /tasks_terminal.py
Davidmg0815's picture
Upload bench/tasks_terminal.py with huggingface_hub
5c7968e verified
Raw
History Blame
7.33 kB
"""Terminal-Aufgaben. Jede Aufgabe liefert einen Shell-Einzeiler, der in einer
frisch aufgebauten Sandbox laeuft; bewertet wird die tatsaechliche Ausgabe.
Kein LLM benotet hier irgendwas — entweder die Ausgabe stimmt oder nicht.
Die Sandbox wird pro Aufgabe neu erzeugt, damit ein zerstoerender Befehl
nur seine eigene Kopie trifft.
"""
# Dateien, die in jeder Sandbox liegen. Bewusst mit Stolpersteinen:
# Leerzeilen, doppelte Eintraege, gemischte Gross-/Kleinschreibung.
SANDBOX = {
"messwerte.csv": (
# Die 6 taucht absichtlich auch ausserhalb der kanal-Spalte auf
# (16.1, 231.5 hat keine, aber 16.1 und 60.4 schon). Sonst besteht
# ein blindes "grep -c 6" die Spaltenaufgabe zufaellig.
"geraet;kanal;spannung;status\n"
"pumpe;6;47.3;ok\n"
"luefter;3;16.1;warn\n"
"motor;6;231.5;ok\n"
"ventil;5;60.4;fehler\n"
"presse;3;400.2;ok\n"
"kompressor;6;18.7;warn\n"
),
"log.txt": (
"2026-08-15 10:01 INFO start\n"
"2026-08-15 10:02 WARN kanal 6 instabil\n"
"2026-08-15 10:02 INFO laeuft\n"
"\n"
"2026-08-15 10:05 ERROR kanal 5 ausgefallen\n"
"2026-08-15 10:06 WARN kanal 6 instabil\n"
"2026-08-15 10:09 INFO ende\n"
),
"namen.txt": "anna\nbernd\nanna\nclara\nbernd\nanna\ndora\n",
"config.json": '{"host":"11.0.0.12","port":8210,"modell":"qwen3.8-27b","sessions":2}\n',
}
# Zusaetzliche Dateien mit definierter Groesse fuer die "groesste Datei"-Aufgabe.
SANDBOX_SIZED = {"klein.bin": 100, "mittel.bin": 5000, "gross.bin": 90000}
TASKS = [
dict(
id="term01",
titel="Zeilen zaehlen",
prompt="Gib genau einen Shell-Einzeiler aus, der die Anzahl der Zeilen "
"in der Datei log.txt ausgibt — nur die nackte Zahl, kein Dateiname. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: out.strip() == "7",
erwartet="7",
),
dict(
id="term02",
titel="Muster mit Zeilennummer",
prompt="Gib genau einen Shell-Einzeiler aus, der aus log.txt alle Zeilen mit "
"dem Wort WARN samt ihrer Zeilennummer ausgibt. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
# Zeilen 2 und 6 enthalten WARN.
check=lambda out: ("2:" in out and "6:" in out
and out.count("WARN") == 2 and "ERROR" not in out),
erwartet="Zeilen 2 und 6 mit Praefix",
),
dict(
id="term03",
titel="Groesste Datei",
prompt="Gib genau einen Shell-Einzeiler aus, der den Namen der groessten "
"Datei im aktuellen Verzeichnis ausgibt — nur den Namen, sonst nichts. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: out.strip().split("/")[-1] == "gross.bin",
erwartet="gross.bin",
),
dict(
id="term04",
titel="Spalte aus CSV",
prompt="Die Datei messwerte.csv ist mit Semikolon getrennt und hat eine "
"Kopfzeile. Gib genau einen Shell-Einzeiler aus, der nur die Werte "
"der Spalte 'geraet' ohne die Kopfzeile ausgibt. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: [z for z in out.strip().splitlines() if z.strip()] == [
"pumpe", "luefter", "motor", "ventil", "presse", "kompressor"],
erwartet="6 Geraetenamen",
),
dict(
id="term05",
titel="Doppelte Zeilen",
prompt="Gib genau einen Shell-Einzeiler aus, der aus namen.txt jeden Namen "
"mit seiner Anzahl ausgibt, absteigend nach Anzahl sortiert. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
# anna 3x, bernd 2x, clara 1x, dora 1x — anna muss zuerst kommen.
check=lambda out: (out.strip().splitlines()[0].strip().split()[-1] == "anna"
or out.strip().splitlines()[0].strip().split()[0] == "anna")
and "3" in out.strip().splitlines()[0],
erwartet="anna mit 3 zuerst",
),
dict(
id="term06",
titel="Summe einer Spalte",
prompt="Die Datei messwerte.csv ist mit Semikolon getrennt und hat eine "
"Kopfzeile. Gib genau einen Shell-Einzeiler aus, der die Summe der "
"Spalte 'spannung' ausgibt. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
# 47.3+16.1+231.5+60.4+400.2+18.7 = 774.2
check=lambda out: any(
abs(float(t) - 774.2) < 0.05
for t in out.replace(",", ".").split()
if _istzahl(t)),
erwartet="774.2",
),
dict(
id="term07",
titel="Numerisch sortieren",
prompt="Die Datei messwerte.csv ist mit Semikolon getrennt und hat eine "
"Kopfzeile. Gib genau einen Shell-Einzeiler aus, der die Datenzeilen "
"ohne Kopfzeile absteigend nach der Spalte 'spannung' sortiert ausgibt. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: _erste_datenzeile(out).startswith("presse")
and "geraet;kanal" not in out,
erwartet="presse zuerst (400.2)",
),
dict(
id="term08",
titel="JSON-Feld lesen",
prompt="Gib genau einen Shell-Einzeiler aus, der aus config.json nur den "
"Wert des Feldes 'port' ausgibt. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: out.strip().strip('"') == "8210",
erwartet="8210",
),
dict(
id="term09",
titel="Ersetzen in Datei",
prompt="Gib genau einen Shell-Einzeiler aus, der in der Datei log.txt jedes "
"Vorkommen von WARN durch ACHTUNG ersetzt und die Datei dabei "
"tatsaechlich veraendert. Danach soll nichts weiter ausgegeben werden. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
# Geprueft wird der Dateiinhalt nach dem Lauf, nicht die Ausgabe.
check=None,
datei_check=lambda dateien: (
dateien.get("log.txt", "").count("ACHTUNG") == 2
and "WARN" not in dateien.get("log.txt", "")),
erwartet="log.txt enthaelt 2x ACHTUNG, kein WARN",
),
dict(
id="term10",
titel="Gefiltert zaehlen",
prompt="Die Datei messwerte.csv ist mit Semikolon getrennt und hat eine "
"Kopfzeile. Gib genau einen Shell-Einzeiler aus, der zaehlt, wie viele "
"Zeilen in der Spalte 'kanal' den Wert 6 haben — nur die nackte Zahl. "
"Antworte ausschliesslich mit dem Befehl, ohne Erklaerung und ohne Code-Block.",
check=lambda out: out.strip() == "3",
erwartet="3",
),
]
def _istzahl(t):
try:
float(t)
return True
except ValueError:
return False
def _erste_datenzeile(out):
for z in out.strip().splitlines():
if z.strip():
return z.strip()
return ""