LM-Studio-Matrix mit gemma-4-e4b: zwoelf Laeufe und vier Befunde

Skill 12.0.0 bis 12.2.0 und Adapter 2.0.0 bis 2.2.0.

Werkzeugfreigabe: Die Shell-Rechte des OpenCode-Adapters sind jetzt eine
Denylist wie beim Claude-Adapter statt einer Allowlist. Ausloeser war der
erste Qwen-Lauf, dessen einzige beide Werkzeugaufrufe an einer Pipeline
scheiterten. Kontrolltest belegt beide Richtungen: Get-ChildItem | Format-Table
laeuft durch, rm wird verweigert, die Datei bleibt bestehen.

Lokaler Betrieb: Der Preflight entlaedt alle Modelle vor jedem Lauf und laedt
den Kontext auf das Modellmaximum. Gemessen waren zuvor beide Modelle
gleichzeitig geladen - 168 MiB frei von 16,3 GB. Qwen 27B passt auf dieser
Karte nicht und wurde durch qwen3.5-9b ersetzt, in Q4_K_M wie Gemma.

Messinstrument: analyse-anforderungen.py erkennt Feldnamen in Markdown-
Fettschrift und Modulpraefixe in IDs. Der erste lokale Lauf mit Artefakten
wurde sonst mit null Anforderungen gezaehlt statt mit neun. Regressionsprobe
an vier Claude-Laeufen unveraendert.

Befunde: Der Standard-Ausgabeblock, mit dem Claude sieben Artefakte erzeugt,
liefert bei gemma-4-e4b null von sechs Laeufen ein Ergebnis - das Modell loest
den Pfad relativ zum Arbeitsverzeichnis auf. Ein Lauf startete alle sieben
vorgesehenen Rollen und lieferte neun formkonforme Anforderungen. Ein anderer
erzeugte sieben richtig benannte Dateien ohne eine einzige formkonforme
Anforderung. Und eine Shell-Umleitung schrieb an der Denylist vorbei in den
eingefrorenen Snapshot - gefunden vom Vorher/Nachher-Vergleich, nicht von der
Regel.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christoph Schwörer
2026-09-01 11:02:04 +02:00
co-authored by Claude Opus 5
parent 654339464e
commit 28e927013b
218 changed files with 20745 additions and 17 deletions
+7 -5
View File
@@ -2,7 +2,7 @@
name: run-experiment
description: Führt einen Versuchs-Prompt aus einer Prompt-Datei als messbaren Headless-Lauf mit Claude Code, Codex CLI oder OpenCode (TensorX oder lokales LM Studio) aus und schreibt ein Messprotokoll mit Start-/Endzeit, Modell, Tokenverbrauch und weiteren Metriken. Verwenden bei "/run-experiment <Pfad-zur-Prompt-Datei>" oder wenn der User einen Versuch/ein Experiment ausführen und tracken will.
argument-hint: <Pfad zur Prompt-Datei> <Root-Verzeichnis>
version: 12.0.0
version: 12.2.0
---
# RunExperiment – Versuchslauf mit Messprotokoll
@@ -127,12 +127,12 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
3. **Werkzeugadapter bestimmen und CLI-Pfad auflösen.** Die Modell-ID entscheidet eindeutig:
`claude-*` verwendet Claude Code, OpenAI-IDs wie `gpt-*` oder `o*` verwenden Codex CLI,
`z-ai/*`, `qwen/qwen3.8-flash-next` und `moonshotai/*` verwenden OpenCode mit
`--provider tensorx`, `google/gemma-4-e4b` und `qwen/qwen3.8-27b` verwenden OpenCode mit
`--provider tensorx`, `google/gemma-4-e4b` und `qwen/qwen3.5-9b` verwenden OpenCode mit
`--provider lmstudio` gegen den lokalen LM-Studio-Server.
Keine Modell-ID an eine CLI übergeben, die sie nicht unterstützt.
**Achtung Präfixkollision:** `qwen/qwen3.8-flash-next` läuft remote über TensorX,
`qwen/qwen3.8-27b` lokal über LM Studio. Das Präfix `qwen/` allein entscheidet **nicht** –
`qwen/qwen3.5-9b` lokal über LM Studio. Das Präfix `qwen/` allein entscheidet **nicht** –
maßgeblich ist die vollständige Modell-ID.
Unter Windows liegt `claude` in der Regel **nicht im PATH**. Erst
@@ -186,7 +186,7 @@ per stdin übergebenen Text angehängt (siehe Schritt „Prompt zusammenstellen"
| Lokale Modell-ID (LM Studio) | Einordnung |
|---|---|
| `google/gemma-4-e4b` | Gemma 4 E4B, 7,5B Parameter, lokal über LM Studio |
| `qwen/qwen3.8-27b` | Qwen 3.8 27B, lokal über LM Studio |
| `qwen/qwen3.5-9b` | Qwen 3.5 9B, lokal über LM Studio (Q4_K_M wie Gemma) |
Lokale IDs nur anbieten, wenn `lms ls` das Modell als heruntergeladen ausweist. Fehlt es,
den User auf `lms get <ID>` hinweisen und den Download **nicht** ungefragt starten – es
@@ -1119,7 +1119,7 @@ streamt die Rohereignisse, erzwingt Berechtigungen und normalisiert das Ergebnis
| `--provider` | Modell-IDs | Betrieb | Vorlage |
|---|---|---|---|
| `tensorx` (Standard) | `z-ai/*`, `qwen/qwen3.8-flash-next`, `moonshotai/*` | Remote `https://api.tensorx.ai/v1` | `opencode-tensorx.json` |
| `lmstudio` | `google/gemma-4-e4b`, `qwen/qwen3.8-27b` | lokal `http://localhost:1234/v1` | `opencode-lmstudio.json` |
| `lmstudio` | `google/gemma-4-e4b`, `qwen/qwen3.5-9b` | lokal `http://localhost:1234/v1` | `opencode-lmstudio.json` |
Vor jedem Lauf die vollständige Referenz
[`references/opencode-adapter.md`](references/opencode-adapter.md) lesen und deren Aufruf,
@@ -1354,6 +1354,8 @@ der Historie unten – im selben Arbeitsschritt.
| Version | Änderung | Grund | Verwendet in |
|---|---|---|---|
| **12.2.0** | **`analyse-anforderungen.py` erkennt Feldnamen in Markdown-Fettschrift und Modulpraefixe in IDs.** `**ID:** M003-StRS-01` wird wie `ID: StRS-01` gelesen; die Ebene wird aus der ID auch dann bestimmt, wenn ein Praefix vorangeht. Zwei neue Hilfsskripte: `lauf-uebersicht.py` verdichtet die `RawResult.json` einer Matrix zu einer Tabelle und zeigt mit `--details` die tatsaechlichen Schreibziele; `protokoll-geruest.py` erzeugt aus den Rohdaten eines Laufs das Protokollgeruest und fuellt nur belegbare Felder - Deutung und Gueltigkeit bleiben Handarbeit. | Der erste lokale Lauf mit Artefakten (`Iteration 7/.../v12.1.0-001c`) erzeugte vier regelkonform gefuellte Dateien, wurde vom Parser aber mit **0 Anforderungen** gezaehlt: Das Modell formatierte die Feldnamen als Markdown. Nach der Korrektur sind es **9**. Die Praefixregel behob zugleich eine falsche Auffaelligkeitsmeldung ('StRS-Block in StRS.md' als Fremdablage). Regressionsprobe an vier Claude-Laeufen: 42/82/60/73 Anforderungen vor und nach der Aenderung identisch - die Korrektur findet nur zusaetzlich, was zuvor uebersehen wurde. `lauf-uebersicht.py` entstand, weil `written_files` bei fehlgeleiteten Schreibversuchen schlicht leer bleibt und die Ursache so unsichtbar ist. MINOR: Korrektur am Messinstrument, keine Aenderung der Versuchsbedingung; rueckwirkend auf alle Laeufe anwendbar. | rueckwirkend; ab sofort |
| **12.1.0** | **Speicherhygiene und Kontextgroesse fuer lokale Laeufe; Modellwechsel `qwen/qwen3.8-27b` -> `qwen/qwen3.5-9b`.** Der Preflight entlaedt vor jedem Lauf **alle** Modelle (`lms unload --all`) und bricht ab, wenn neben dem angeforderten ein weiteres geladen ist. Neue Optionen `--lmstudio-context` (Standard `max`: laedt das Modellmaximum statt der Mindestgroesse), `--lmstudio-parallel` (Standard 4) und `--lmstudio-gpu` (Standard `max`). `local_runtime` fuehrt zusaetzlich `parallel_slots`, `gpu_offload` und `alleiniges_modell`. Adapter-Version 2.2.0. | Messungen vom 01.09.2026 auf einer RTX 5080 Laptop GPU (16.303 MiB): Gemma und Qwen 27B waren **gleichzeitig geladen** - 15.836 MiB belegt, 168 MiB frei, Durchsatz 0,028 Mio. Tokens/h. Nach `unload --all` laeuft Gemma mit 48,3 tok/s. Das Modellmaximum kostet fast nichts: 131.072 statt 32.768 Kontext bedeutet 6.854 statt 5.162 MiB und 46,8 statt 48,3 tok/s - vierfaches Fenster fuer 1,5 tok/s. `--parallel 4` ist gegenueber 1 messtechnisch neutral (47,7 vs. 48,3 tok/s). **Der Modellwechsel ist hardwarebedingt:** `qwen3.8-27b` belegt mit 17,74 GB Gewichten mehr, als die Karte hat; ein Generierungstest brach nach 10 Minuten ohne Ergebnis ab. Die 27B-Klasse ist auch mit kleinerer Quantisierung nicht messbar, weil der KV-Cache bei brauchbarem Kontext mehrere GB zusaetzlich fordert. `qwen3.5-9b` ist die groesste Qwen-Variante, die mit vollem Fenster hineinpasst, und laeuft wie Gemma in **Q4_K_M** - damit unterscheiden sich die beiden lokalen Modelle nur in der Groesse, nicht zusaetzlich in der Quantisierung. MINOR fuer die Ladeparameter; der Modellwechsel eroeffnet ohnehin eine neue Iteration, weil `qwen3.8-27b` keinen gueltigen Messpunkt geliefert hat. | ab der LM-Studio-Matrix in Iteration 13 (V1) bzw. 6 (V2) |
| **12.0.0** | **Die Shell-Rechte des OpenCode-Adapters werden eine Denylist statt einer Allowlist** – spiegelbildlich zu den Claude-Eintraegen: alles erlaubt ausser den ausdruecklich gesperrten schreibenden und bauenden Kommandos (`rm`, `mv`, `sed -i`, schreibende `git`-Kommandos inkl. `fetch`/`pull`/`remote`, `dotnet`, `msbuild`, `npm install`, `Remove-Item`, `Set-Content`, `Out-File` u. a.). Das Catch-all `"*": "allow"` steht zuerst, weil OpenCode die **zuletzt passende** Regel gewinnen laesst. Zusaetzlich lehnt der Adapter `--stall-timeout > 0` jetzt fuer **jeden** lokalen Provider ab, nicht nur fuer die delegierenden Modi. Adapter-Version 2.0.0, vier neue Regressionstests. | Der Claude-Adapter erlaubt ueber eine Denylist jedes nicht gesperrte Kommando, der OpenCode-Adapter nur explizit Gelistetes. Die Werkzeugfreiheit war zwischen beiden **nie aequivalent** – ein Confounder fuer jeden Werkzeugvergleich. Ausloeser war der erste Qwen-Lauf (`v11.1.0-45b1`): Dessen **einzige beide** Werkzeugaufrufe, `Get-ChildItem ... | Format-Table ...`, wurden verweigert, weil die Allowlist nur Praefixe trifft und an Pipelines scheitert. Bei Gemma war das ein Randfall (1 von 106 Aufrufen), bei Qwen legte es den Lauf still. Der zweite Ausloeser: Qwen 27B benoetigte fuer einen einzelnen Schritt mehr als 15 Minuten, sodass der Stall-Timeout auch in `solo` Modellgeschwindigkeit als Haenger wertete. **Kontrolltest am 01.09.2026 bestaetigte beide Richtungen:** `Get-ChildItem ... | Format-Table Name` lief durch, `rm opfer.txt` wurde verweigert, und die Datei blieb auf der Platte. MAJOR: Die Toolfreigabe ist eine unabhaengige Variable; Laeufe ab dieser Version sind mit allen frueheren OpenCode- und TensorX-Laeufen nicht poolbar. | ab dem naechsten OpenCode-Lauf; Iterationen 10 und 11 bleiben unter der Allowlist |
| **11.1.0** | **Der Adapter lehnt `--stall-timeout > 0` in den Modi `builtin` und `custom` ab.** Die Laufzeit wird dort ausschliesslich ueber `--max-runtime` begrenzt. Adapter-Version 1.3.0; Referenz und Aufrufbeschreibung entsprechend ergaenzt. | Der erste `builtin`-Lauf mit LM Studio (`v11.0.0-9ad0`) wurde nach 15:48 min abgebrochen, obwohl das Limit bei 60 min lag. Ursache war nicht das Modell: OpenCode sendet **keine Ereignisse, solange ein Subagent arbeitet**. Nach 8 Ereignissen in den ersten 39 Sekunden schwieg der Strom, waehrend der gestartete `explore`-Subagent lief; der Stall-Timeout deutete das als Haenger. Jeder Lauf mit Subagenten waere so zuverlaessig zu frueh gestorben. Die Kombination wird abgelehnt statt stillschweigend korrigiert, damit die Entscheidung bewusst faellt. MINOR: Es existierte noch **kein** gueltiger OpenCode-Lauf in `builtin` oder `custom`, dessen Bedingung sich dadurch aendern koennte; die `solo`-Laeufe waren nie betroffen, weil bei ihnen der Stall-Timeout nie griff. **Zu pruefen:** ob die als Fehler protokollierten TensorX-V2-Laeufe (Modus `custom`, `--stall-timeout 600`) dieselbe Ursache haben. | ab dem naechsten OpenCode-Lauf in `builtin` oder `custom` |
| **11.0.0** | **Read-only-Shell-Allowlist des OpenCode-Adapters erweitert.** Neben `rg` und den lesenden `git`-Kommandos sind jetzt die verbreiteten POSIX-Werkzeuge `ls`, `cat`, `head`, `tail`, `find`, `grep`, `wc`, `file`, `stat`, `tree` sowie `dir`, `type`, `Get-Item` und `Measure-Object` freigegeben; `git log` und `git show` kommen hinzu. Alles Übrige bleibt `deny`. Zwei Regressionstests sichern die Liste ab: Sie muss die lesenden Kommandos enthalten und darf kein schreibendes enthalten. Adapter-Version 1.2.0. | Der erste LM-Studio-Lauf (`v10.1.0-b00a`, Gemma/solo) erzeugte zwei Permission-Denials auf `ls src` – das Kommando fehlte auf der Allowlist. Der Agent hatte damit kein POSIX-Mittel, Verzeichnisse aufzulisten, obwohl genau das laut Werkzeugkontext zur Bedingung gehört. Die Lücke benachteiligte OpenCode-Läufe gegenüber den Claude-Läufen, die mit einer Denylist arbeiten und deshalb jedes nicht ausdrücklich gesperrte Lesekommando erlauben. **MAJOR: Die Toolfreigabe ist eine unabhängige Variable.** Läufe ab dieser Version sind mit den bisherigen OpenCode- und TensorX-Läufen nicht poolbar; der nächste Lauf eröffnet eine neue Iteration. | ab dem nächsten OpenCode-Lauf; Iteration 10 bleibt unter der alten Allowlist |