neues modell

This commit is contained in:
Christoph Schwörer
2026-09-01 08:12:07 +02:00
parent 611fd0a80c
commit 654339464e
109 changed files with 70505 additions and 27 deletions
+103 -1
View File
@@ -1116,6 +1116,100 @@ fehlgedeutet wird.
---
### Erster lokaler Lauf und die Allowlist-Lücke (Skill 11.0.0, 31.08.2026)
Der erste Messpunkt mit einem lokal betriebenen Modell –
`Iteration 10/google/gemma-4-e4b/solo/high/03_Lauf_2026-08-31_201802_v10.1.0-b00a` – ist eine
**Fehlmessung mit hohem Erkenntniswert**. In einer vollen Stunde und 232 Turns verbrauchte
`gemma-4-e4b` 919.306 Tokens (davon 96.577 Reasoning) und tätigte dabei genau **sechs**
Tool-Aufrufe: zwei `glob`, ein `bash`, drei verweigerte. `Ergebnisse/` blieb leer.
Der Ereignisstrom zeigt das Missverhältnis unmittelbar: 182 `step_start` gegenüber 267
Textereignissen. Das Modell hat fast ausschließlich Text erzeugt, statt die Codebasis zu lesen.
**Terminierungsversagen.** Nach einem verweigerten `edit` auf den relativen Pfad
`Analysebericht.md` ging der Agent in eine Endlosschleife über und forderte über rund 180 Schritte
hinweg denselben absoluten Ausgabepfad an – der im Prompt unter *Ausgabeverzeichnis* wörtlich
steht. Der Stall-Timeout griff nicht, weil ununterbrochen Text erzeugt wurde; erst das absolute
`--max-runtime` beendete den Lauf. Das bestätigt den bereits im Smoke-Test gefundenen Befund
unter Realbedingungen.
**Die Allowlist-Lücke.** Zwei der drei Denials entfielen auf `ls src`. Die
Read-only-Shell-Allowlist des OpenCode-Adapters enthielt `rg`, lesende `git`-Kommandos und die
PowerShell-Cmdlets, aber **kein `ls`** – und damit kein POSIX-Mittel, Verzeichnisse aufzulisten,
obwohl der Werkzeugkontext genau das zusichert. Das benachteiligte OpenCode-Läufe systematisch
gegenüber den Claude-Läufen, die mit einer *Denylist* arbeiten und deshalb jedes nicht
ausdrücklich gesperrte Lesekommando erlauben. Die Asymmetrie war zuvor nicht aufgefallen, weil
die TensorX-Modelle bevorzugt `rg` und die werkzeugeigenen `read`/`glob`-Tools verwendeten.
Konsequenz: Skill 11.0.0 erweitert die Allowlist um `ls`, `cat`, `head`, `tail`, `find`, `grep`,
`wc`, `file`, `stat`, `tree` sowie `dir`, `type`, `Get-Item`, `Measure-Object`, `git log` und
`git show`. Alles Übrige bleibt `deny`; zwei Regressionstests sichern beides ab. **Die Änderung
ist MAJOR** – die Toolfreigabe ist eine unabhängige Variable. Läufe ab Iteration 11 sind mit
Iteration 10 und mit den bisherigen TensorX-Läufen nicht poolbar.
Dass ausgerechnet der schwächste bislang eingesetzte Agent diese Lücke aufdeckte, passt zum
Muster der Reihe: Stärkere Modelle wichen auf die werkzeugeigenen Tools aus und verdeckten die
Lücke, statt an ihr zu scheitern.
---
### Die Toolfreigabe als Messgröße: von der Allowlist zur Denylist (01.09.2026)
Die LM-Studio-Matrix hat in zwei Stufen offengelegt, dass die Shell-Freigabe des
OpenCode-Adapters keine Nebensache, sondern eine wirksame unabhängige Variable ist.
**Stufe 1 – die fehlenden Lesekommandos (Skill 11.0.0).** Der Gemma-solo-Lauf unter der
ursprünglichen Allowlist tätigte in einer Stunde sechs Werkzeugaufrufe, drei davon verweigert.
Nach Aufnahme von `ls`, `cat`, `find` und Verwandten stieg dieselbe Bedingung auf **106
Aufrufe bei nur einem Denial**; das Modell wechselte von reiner Textproduktion zu tatsächlicher
Codeanalyse. Die Toolfreigabe war handlungsleitend.
**Stufe 2 – die Pipeline (Skill 12.0.0).** Der erste Qwen-27B-Lauf setzte genau **zwei**
Werkzeugaufrufe ab, und **beide** wurden verweigert:
`Get-ChildItem -LiteralPath "..." | Format-Table Name`. Die Allowlist trifft Kommandos nur als
Präfix und scheitert deshalb an Pipelines – `Get-ChildItem` war erlaubt, die Weiterleitung an
`Format-Table` nicht. Was bei Gemma ein Randfall war (1 von 106), legte bei Qwen den Lauf still.
Damit war die Ursache nicht mehr zu umgehen: **Der Claude-Adapter arbeitet mit einer Denylist**
und erlaubt jedes nicht ausdrücklich gesperrte Kommando; der OpenCode-Adapter erlaubte nur
Gelistetes. Die Prüfung der OpenCode-Dokumentation ergab, dass eine Denylist technisch immer
möglich war: Regeln werden der Reihe nach ausgewertet, die **zuletzt passende gewinnt**
(Reihenfolge, nicht Spezifität; `deny` gewinnt nicht automatisch). Das empfohlene Muster ist
Catch-all `*` zuerst, spezifische Regeln danach. Die Allowlist war also nie notwendig, nur
naheliegend.
Skill 12.0.0 stellt die Shell-Rechte auf eine Denylist um, spiegelbildlich zu den
Claude-Einträgen. **Kontrolltest vom 01.09.2026**, mit je einem Kommando pro Richtung:
| Prüfung | Ergebnis |
|---|---|
| `Get-ChildItem -LiteralPath . \| Format-Table Name` | gelingt (unter der Allowlist verweigert) |
| `rm opfer.txt` | verweigert |
| `opfer.txt` nach dem Lauf | **unverändert vorhanden** |
Der harte Beleg ist die unversehrte Datei, nicht die Selbstauskunft des Modells – das zusätzlich
`Schritt1: erfolg / Schritt2: verweigert` protokollierte. Vier Regressionstests sichern die
Regel ab, darunter zwei für die eigentliche Falle: dass das Catch-all als **erster** Schlüssel
steht (stünde es hinten, wäre jede Sperre wirkungslos) und dass Lesekommandos einschließlich
Pipelines ohne eigene Regel erlaubt sind.
**Nebenbefund zur Abbruchsicherung.** Derselbe Qwen-Lauf lief 20 Minuten und wurde vom
Stall-Timeout beendet, obwohl er arbeitete: Zwischen zwei Ereignissen lagen mehr als 15 Minuten,
weil ein einzelner Schritt des 27B-Modells auf dieser Hardware so lange dauert. Der Stall-Timeout
maß damit Modellgeschwindigkeit statt Hänger. Er ist für lokale Provider seit 12.0.0 generell
abgelehnt – nicht mehr nur für die delegierenden Modi (11.1.0). Die Laufzeit wird lokal
ausschließlich über `--max-runtime` begrenzt.
**Folge für die Vergleichbarkeit.** Die Toolfreigabe ist eine unabhängige Variable; Läufe ab
12.0.0 sind mit allen früheren OpenCode- und TensorX-Läufen **nicht poolbar**. Die Iterationen
10 und 11 bleiben als Beleg für die Wirkung der Bedingung erhalten – der Sprung von 6 auf 106
Werkzeugaufrufe bei sonst identischem Aufbau ist ein eigenständiger Befund und stützt die
methodische Aussage der Arbeit: Ein Versuchsaufbau für agentische Werkzeuge lässt sich nicht
vollständig vorab spezifizieren.
---
## 6. Befunde
### 6.1 Die Anforderungsanzahl ist kein Qualitätsmaß
@@ -1336,6 +1430,14 @@ gegeneinander als Modellvergleich verwertbar; für eine saubere Trennung fehlt e
(MCP-Server): Der Skill ist darauf vorbereitet, die MCP-Konfiguration und das zugehörige
Protokollfeld fehlen aber noch.
**Erledigt – Allowlist gegen Denylist (Skill 12.0.0).** Der Claude-Adapter erlaubte
Shell-Kommandos über eine **Denylist** (jedes nicht gesperrte Kommando ist zulässig), der
OpenCode-Adapter über eine **Allowlist** (nur explizit Gelistetes). Die Werkzeugfreiheit war
zwischen beiden Adaptern nie äquivalent – für eine Arbeit, die Werkzeuge vergleicht, ein
Confounder. Die Umstellung war zunächst bis nach der LM-Studio-Matrix zurückgestellt; der erste
Qwen-Lauf machte sie vorzeitig notwendig (siehe unten). Sie ist am 01.09.2026 vollzogen und
empirisch belegt.
**Offene Aufräumarbeiten:** Drei Streudateien in `C:\DEV\` aus Lauf 13; die Erweiterung der
Nachlaufprüfung um Streudateien außerhalb des Laufverzeichnisses.
@@ -1368,7 +1470,7 @@ Stichprobe.
- Exakt gesendeter Prompt je Lauf: `_meta/combined_prompt.md`
- Subagenten-Prompts: `_meta/subagenten.md`
- Maschinelle Anforderungsauswertung: `_meta/anforderungen.md` und `.json`
- Prozessvorgabe: `.claude/skills/run-experiment/SKILL.md` (Version 10.1.0, mit Änderungshistorie)
- Prozessvorgabe: `.claude/skills/run-experiment/SKILL.md` (Version 12.0.0, mit Änderungshistorie)
- OpenCode-Adapter (TensorX und LM Studio): `.claude/skills/run-experiment/references/opencode-adapter.md`
- Messprotokolle Versuch 2: `Versuche/Versuch_02/<Iteration>/<ModellID>/custom/<Effort>/<Laufverzeichnis>/Protokoll.md`
- Agentenrollen: `Versuche/Versuch_02/02_Agents.json` (verschachtelt), `03_Agents.json` (unverschachtelt)