diff --git a/BEDIENUNGSANLEITUNG.md b/BEDIENUNGSANLEITUNG.md index 8463f57..6b2d7a2 100644 --- a/BEDIENUNGSANLEITUNG.md +++ b/BEDIENUNGSANLEITUNG.md @@ -91,12 +91,12 @@ Beide Befehle müssen ohne Fehler durchlaufen. Die Tests brauchen keinen API-Sch Eine kleine Beispielaufgabe liegt bei. Lösen, Report und Programm speichern: ```bash -mkdir -p output -.venv/bin/python TextToModel.py benchmark/cases/lp_klein/task.txt \ - --report output/lp_klein.html --code output/lp_klein.py > output/lp_klein.json +.venv/bin/python TextToModel.py benchmark/cases/lp_klein/task.txt --ausgabe output/lp_klein echo $? # 0 = Ergebnis zuverlässig (direkt danach abfragen) ``` +`--ausgabe output/lp_klein` schreibt `output/lp_klein.json` (Ergebnis), `.html` (Report) und `.py` (Solver-Programm) und legt den Ordner bei Bedarf an. + Während des Laufs zeigt das Terminal den Fortschritt (Verstehen, Extraktion, Prüfung, Solver …) und am Ende Kosten und Laufzeit je Stufe. Die Aufgabe kostet etwa zwei Cent und dauert ein bis drei Minuten. Danach: @@ -140,19 +140,19 @@ Die Aufgabe kann als `.txt` oder `.md` vorliegen; Markdown-Tabellen und Formeln .venv/bin/python TextToModel.py aufgabe.md -o output/aufgabe.json --report output/aufgabe.html # Aufgabe über die Standardeingabe -echo "Ein Betrieb …" | .venv/bin/python TextToModel.py --report output/aufgabe.md > output/aufgabe.json +echo "Ein Betrieb …" | .venv/bin/python TextToModel.py --report output/aufgabe.md -o output/aufgabe.json # ohne Aufgabendatei und ohne umgeleitete Eingabe (oder bei leerer Eingabe): eingebaute Beispielaufgabe (Schichtplanung) -.venv/bin/python TextToModel.py --report output/beispiel.html > output/beispiel.json +.venv/bin/python TextToModel.py --report output/beispiel.html -o output/beispiel.json # nur modellieren und prüfen, keinen Solver-Code erzeugen (billiger, schneller) -.venv/bin/python TextToModel.py aufgabe.md --no-solve --report output/modell.html > output/modell.json +.venv/bin/python TextToModel.py aufgabe.md --no-solve --report output/modell.html -o output/modell.json # anderes Modell -.venv/bin/python TextToModel.py aufgabe.md --model deepseek/deepseek-v4-pro-0813 > output/aufgabe.json +.venv/bin/python TextToModel.py aufgabe.md --model deepseek/deepseek-v4-pro-0813 -o output/aufgabe.json # mit beigelegten Daten (siehe Abschnitt 8) -.venv/bin/python TextToModel.py aufgabe.md --daten kurse.csv --report output/aufgabe.html > output/aufgabe.json +.venv/bin/python TextToModel.py aufgabe.md --daten kurse.csv --report output/aufgabe.html -o output/aufgabe.json ``` Hinweise: @@ -181,9 +181,9 @@ LLM-Nutzung: 5 Aufrufe, 36874 Input- (davon 12000 aus dem Cache, 33 %)/53898 Out Die Zeilen je Stufe zeigen, wo Zeit und Geld hingehen. Erscheint `ERGEBNIS UNZUVERLÄSSIG – …`, steht der Grund direkt dahinter. -### Ergebnis-JSON (Standardausgabe) +### Ergebnis-JSON (`-o`/`--ausgabe`, sonst Standardausgabe) -Das vollständige Ergebnis aller Stufen. Die wichtigsten Felder: +Das vollständige Ergebnis aller Stufen – in der Datei aus `-o` bzw. `--ausgabe`, sonst auf der umgeleiteten Standardausgabe. Läuft das Programm ohne beides direkt im Terminal, erscheint statt des JSON nur eine Kurzfassung (Status, Zielwert, Antworten, Zuverlässigkeit). Die wichtigsten Felder: | Feld | Bedeutung | |---|---| @@ -225,7 +225,7 @@ print(d['reliable'], r['status'], r['objective_value']); [print(a['question_id'] Damit lässt sich das Programm in Skripten einsetzen: ```bash -.venv/bin/python TextToModel.py aufgabe.md > output/aufgabe.json +.venv/bin/python TextToModel.py aufgabe.md -o output/aufgabe.json case $? in 0) echo "zuverlässig" ;; 2) echo "unzuverlässig – bitte Report prüfen" ;; @@ -279,7 +279,8 @@ Der Report folgt dem Weg von der Aufgabe zur Lösung. Ganz oben stehen die **Lau | Zulässigkeitsprüfung | Die gemeldete Lösung verletzt Restriktionen, Schranken oder Ganzzahligkeit. | `--von solver` versuchen. | | Datenherkunft | Das Programm hat Eingabedaten erzeugt, ohne sie auszuweisen. | Daten beilegen (`--daten`) oder fehlende Werte in den Text schreiben. | | Szenario ohne Ergebnis | Eine verglichene Konfiguration hat keinen Wert, ist aber nicht als unlösbar belegt (z. B. Zeitlimit). | `--von solver`. | -| Solver-Fehler | Das erzeugte Programm ist auch nach allen Reparaturversuchen gescheitert (Absturz, Zeitlimit, kein Ergebnis). Die Fehlermeldung steht im Abschnitt „Ergebnis“. | `--von solver`; bei Zeitlimit `SOLVER_TIMEOUT` erhöhen. | +| Solver-Fehler | Das erzeugte Programm ist auch nach allen Reparaturversuchen gescheitert (Absturz, Zeitlimit, kein Ergebnis) – oder das LLM hat gar keinen Solver-Code geliefert („LLM-Aufruf … gescheitert“). Die Fehlermeldung steht im Abschnitt „Ergebnis“. | `--von solver`; bei Zeitlimit `--solver-timeout` erhöhen. | +| LLM-Fehler | Das LLM ist schon vor dem Modell nach allen Wiederholungen gescheitert (Überlastung, abgeschnittene Antworten). Es gibt kein Modell; der Report heißt „Lauf abgebrochen“, die Kosten sind trotzdem erfasst. | Später erneut starten. | | Unlösbar, Gegenprobe uneindeutig | Der Solver meldet „unlösbar“, eine unabhängige zweite Modellierung konnte das weder bestätigen noch widerlegen. | Aufgabe auf widersprüchliche Bedingungen prüfen. | ### Besondere Ergebnisse @@ -297,7 +298,7 @@ Für größere Datenmengen (Kurse, Bedarfe, Entfernungen) legt man Dateien bei: ```bash .venv/bin/python TextToModel.py aufgabe.md --daten kurse.csv entfernungen.xlsx \ - --report output/aufgabe.html --code output/aufgabe.py > output/aufgabe.json + --report output/aufgabe.html --code output/aufgabe.py -o output/aufgabe.json ``` - Unterstützt werden **CSV** (Trennzeichen Komma, Semikolon oder Tabulator werden erkannt, deutsche Dezimalkommas ebenfalls) und **Excel** (`.xlsx`, `.xls`). @@ -324,7 +325,7 @@ Stehen Daten nur in einer Abbildung – ein Graph mit bewerteten Pfeilen, eine T ```bash # Dokument mit docling nach Markdown wandeln (Bilder eingebettet), dann lösen docling aufgabe.pdf --to md --image-export-mode embedded --output output/ -.venv/bin/python TextToModel.py output/aufgabe.md --report output/aufgabe.html > output/aufgabe.json +.venv/bin/python TextToModel.py output/aufgabe.md --report output/aufgabe.html -o output/aufgabe.json ``` Was dabei passiert: @@ -352,11 +353,11 @@ Alle Eingabewerte des Programms stehen im Wörterbuch `DATA` (im JSON unter `sol ```bash # unverändert neu rechnen -.venv/bin/python TextToModel.py --resolve output/aufgabe.json > output/nachgerechnet.json +.venv/bin/python TextToModel.py --resolve output/aufgabe.json -o output/nachgerechnet.json # mit geänderten Werten .venv/bin/python TextToModel.py --resolve output/aufgabe.json --data output/neue_werte.json \ - --report output/variante.html > output/variante.json + --report output/variante.html -o output/variante.json ``` `neue_werte.json` enthält nur die Einträge, die sich ändern – mit denselben Schlüsseln wie in `solver_run.data`: @@ -378,10 +379,10 @@ Ist das Modell gut, aber das Programm gescheitert, muss nicht alles neu bezahlt ```bash # Modell und Prüfbericht behalten, nur Solver-Code neu erzeugen (etwa 2 statt 5–7 Aufrufe) -.venv/bin/python TextToModel.py --von solver output/aufgabe.json --report output/neu.html > output/neu.json +.venv/bin/python TextToModel.py --von solver output/aufgabe.json --report output/neu.html -o output/neu.json # Modell behalten, neu prüfen und korrigieren, dann lösen -.venv/bin/python TextToModel.py --von pruefung output/aufgabe.json > output/neu.json +.venv/bin/python TextToModel.py --von pruefung output/aufgabe.json -o output/neu.json ``` - Der Aufgabentext kommt aus dem gespeicherten Ergebnis; keine Aufgabendatei angeben. @@ -474,7 +475,7 @@ Wo das Geld hingeht: rund zwei Drittel der Kosten sind **erzeugter Output**, dav Beispiel für einen einzelnen Lauf mit geänderten Einstellungen: ```bash -MAX_REVISIONS=1 LLM_REASONING_EFFORT=low .venv/bin/python TextToModel.py aufgabe.md > output/aufgabe.json +MAX_REVISIONS=1 LLM_REASONING_EFFORT=low .venv/bin/python TextToModel.py aufgabe.md -o output/aufgabe.json ``` --- diff --git a/README.md b/README.md index 8b6a001..474f0f3 100644 --- a/README.md +++ b/README.md @@ -90,13 +90,13 @@ echo "Ein Betrieb ..." | .venv/bin/python TextToModel.py --report output/modell. .venv/bin/python output/solve.py # Variante rechnen: geänderte Eingabedaten, gleiches Programm, KEIN LLM-Aufruf -.venv/bin/python TextToModel.py --resolve output/ergebnis.json --data neue_daten.json > output/variante.json +.venv/bin/python TextToModel.py --resolve output/ergebnis.json --data neue_daten.json -o output/variante.json # Aufgabe mit beigelegten Daten (CSV/Excel); das Profil geht in die Prompts, die Datei ins Programm .venv/bin/python TextToModel.py aufgabe.md --daten kurse.csv --report output/modell.html # nur die Solver-Stufe wiederholen: Modell und Prüfbericht bleiben, spart die Aufrufe davor -.venv/bin/python TextToModel.py --von solver output/ergebnis.json > output/neu.json +.venv/bin/python TextToModel.py --von solver output/ergebnis.json -o output/neu.json ``` Exit-Codes: `0` Ergebnis zuverlässig, `1` Eingabefehler (Datei, Abbildung, gespeichertes Ergebnis), `2` Ergebnis vorhanden, aber unzuverlässig, `64` falscher Aufruf, `3` abgelehnt – der Text ist keine Optimierungsaufgabe (es wird weder modelliert noch gerechnet; Report und JSON nennen den Grund). Der Ordner `output/` ist in `.gitignore` eingetragen. Ohne Eingabe wird eine eingebaute Beispielaufgabe verwendet. Fortschritt und Kosten erscheinen auf stderr; das Ergebnis-JSON geht mit `-o`/`--ausgabe` in eine Datei, sonst auf eine umgeleitete Standardausgabe – im Terminal erscheint stattdessen eine Kurzfassung. Umgebungsvariablen wie `SOLVER_TIMEOUT` haben gleichnamige Optionen (`--solver-timeout`), die Vorrang haben. @@ -110,17 +110,17 @@ Exit-Codes: `0` Ergebnis zuverlässig, `1` Eingabefehler (Datei, Abbildung, gesp | `--von STUFE ERGEBNIS.JSON` | gespeichertes Ergebnis fortsetzen statt alles zu wiederholen: `solver` (nur Solver-Code neu) oder `pruefung` (ab Prüfung/Korrektur) | – | | `--max-revisions` / `MAX_REVISIONS` | Korrekturrunden | 2 | | `--no-solve` | keinen Solver-Code erzeugen | aus | -| `UNDERSTAND_RETRIES` | Nachfassen, wenn die Verstehensstufe Zahlen oder Teilfragen übersehen hat | 1 | -| `SOLVER_RETRIES` | Reparaturversuche für fehlerhaften Solver-Code oder nicht ausgewiesene Eingabedaten | 2 | -| `INFEASIBLE_RECHECK` | Gegenprobe mit unabhängiger Modellierung bei „unlösbar“ (0 schaltet ab) | 1 | -| `LLM_MAX_TOKENS` | Obergrenze je Antwort (OpenRouter) | 32000 | +| `--understand-retries` / `UNDERSTAND_RETRIES` | Nachfassen, wenn die Verstehensstufe Zahlen oder Teilfragen übersehen hat | 1 | +| `--solver-retries` / `SOLVER_RETRIES` | Reparaturversuche für fehlerhaften Solver-Code oder nicht ausgewiesene Eingabedaten | 2 | +| `--infeasible-recheck` / `INFEASIBLE_RECHECK` | Gegenprobe mit unabhängiger Modellierung bei „unlösbar“ (0 schaltet ab) | 1 | +| `--max-tokens` / `LLM_MAX_TOKENS` | Obergrenze je Antwort (OpenRouter) | 32000 | | `--max-restarts` / `MAX_RESTARTS` | komplette Neustarts, wenn das Modell nach allen Korrekturrunden fehlerhaft ist | 1 | | `OPENROUTER_MIN_THROUGHPUT` | bevorzugte Mindestgeschwindigkeit des OpenRouter-Anbieters (Tokens/s); Präferenz, kein harter Filter | 75 | | `OPENROUTER_SWITCH_BELOW` | liefert ein Aufruf (ab 1000 Tokens) weniger Tokens/s, wird der Anbieter für den Rest des Laufs gemieden; `0` schaltet das ab | wie `OPENROUTER_MIN_THROUGHPUT` (75) | -| `LLM_TIMEOUT` | Timeout je LLM-Aufruf (s) | 420 | -| `LLM_REASONING_EFFORT` | Denkaufwand des Modells über OpenRouter: `low`, `medium` oder `high` | Modellvorgabe | -| `SOLVER_TIMEOUT` | Zeitlimit je Programmlauf in Sekunden; zugleich das Zeitbudget, das der Solver-Prompt dem Programm nennt | `60` | -| `SOLVER_SANDBOX` | Isolierung des erzeugten Codes: `auto` (bubblewrap, wenn vorhanden), `bwrap` (Pflicht), `aus` | `auto` | +| `--llm-timeout` / `LLM_TIMEOUT` | Timeout je LLM-Aufruf (s) | 420 | +| `--reasoning` / `LLM_REASONING_EFFORT` | Denkaufwand des Modells über OpenRouter: `low`, `medium` oder `high` | Modellvorgabe | +| `--solver-timeout` / `SOLVER_TIMEOUT` | Zeitlimit je Programmlauf in Sekunden; zugleich das Zeitbudget, das der Solver-Prompt dem Programm nennt | `60` | +| `--sandbox` / `SOLVER_SANDBOX` | Isolierung des erzeugten Codes: `auto` (bubblewrap, wenn vorhanden), `bwrap` (Pflicht), `aus` | `auto` | | `LLM_MODEL_UNDERSTANDING`, `LLM_MODEL_EXTRACTION`, `LLM_MODEL_REVIEW`, `LLM_MODEL_REVISION`, `LLM_MODEL_SOLVER` | Modell einzelner Pipeline-Stufen, z. B. ein schnelles für den Solver-Code; verschiedene Anbieter sind erlaubt | Modell aus `--model` | ### Solver-Programme