Files
Masterarbeit/Versuche/_matrix.ps1
T
Christoph SchwörerandClaude Opus 5 e2c3a0e8f8 TensorX-Matrix: erste vollstaendig besetzte Matrix, 918 Anforderungen
Sechs Zellen - z-ai/glm-5.3-flash und qwen/qwen3.8-flash-next je solo,
builtin und custom - alle mit dem kompletten Artefaktsatz von sieben
Dateien. 47,1 Mio. Tokens in 6,4 Stunden, hochgerechnet rund $3,25.

Das Matrixskript heisst jetzt _matrix.ps1 und nimmt -Provider und
-Effort; die LM-Studio-Ladeparameter werden nur noch lokal uebergeben.
Vor dem Start bestaetigte ein Smoke-Test den TensorX-Pfad unter den
seither geaenderten Bedingungen (Denylist, Spiegel, Freigabemuster):
Anmeldung, Modellkontrolle, wirksame Effort-Variante und Dateiuebernahme.

Befund: Die Anforderungsanzahl haette in die Irre gefuehrt. Qwens
custom-Lauf liegt mit 157 Anforderungen im Mittelfeld, ist aber
qualitativ zusammengebrochen - 61 Prozent ohne jeden Beleg, 17 Prozent
mit Primaerbeleg, 40 Prozent Hypothesen, gegenueber 0 Prozent ohne Beleg
und 79 bis 98 Prozent Primaerbelegen in den uebrigen fuenf Laeufen. Er
lieferte zugleich weniger als builtin bei 37 Prozent mehr Tokens.

Der Moduseffekt ist modellabhaengig: Bei GLM steigt der Ertrag monoton
von 126 ueber 139 auf 216 bei durchgaengig hoher Belegqualitaet, bei Qwen
ist builtin das Optimum. Die Annahme, rollenspezialisierte Agenten seien
generell ueberlegen, traegt damit nicht.

Qwens custom-Lauf meldet exit_code 1 bei finish_reason stop und ohne
Timeout, nachdem alle 24 Subagenten zurueckkamen und sieben Dateien
entstanden. Er ist als gueltig mit Vorbehalt gefuehrt, die Ursache offen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-02 16:21:31 +02:00

223 lines
10 KiB
PowerShell

# Faehrt die LM-Studio-Matrix sequenziell: zwei Modelle x drei Agentenmodi.
# Sequenziell zwingend - beide Modelle teilen sich dieselbe GPU, parallele
# Laeufe wuerden die Laufzeitmessung verzerren und den Speicher sprengen.
param(
# Optionaler Filter: nur Laeufe dieser Modelle fahren. Ohne Angabe alle.
# Erlaubt es, eine Modellzelle nachzuziehen, ohne die uebrigen zu wiederholen.
[string[]]$Modelle,
# Variante des Ausgabe-Blocks. 'standard' ist der Wortlaut, mit dem die
# Claude-Laeufe gemessen wurden. 'explizit' verbietet relative Pfade
# ausdruecklich - eigene Versuchsbedingung, eigene Iteration.
[ValidateSet('standard','explizit')][string]$Ausgabeblock = 'standard',
# 'spiegel' gibt OpenCode ein Arbeitsverzeichnis aus Verknuepfungen, in dem
# 'Ergebnisse/' auf das Laufverzeichnis zeigt. Damit wirken relative wie
# absolute Ausgabepfade, ohne dass der Prompt angepasst werden muss.
[ValidateSet('root','spiegel')][string]$Arbeitsverzeichnis = 'spiegel',
# Gateway der Laeufe. 'lmstudio' laeuft lokal und braucht Preflight und
# Ladeparameter; 'tensorx' ist remote und kennt Effort-Varianten.
[ValidateSet('lmstudio','tensorx')][string]$Provider = 'lmstudio',
# Denkaufwand. Bei TensorX als OpenCode-Variante wirksam; lokal ohne
# Wirkung (der LM-Studio-Endpunkt nimmt keinen Thinking-Level entgegen).
# 'max' bildet der Provider auf 'xhigh' ab - er kennt keine eigene Stufe.
[ValidateSet('low','medium','high','xhigh','max')][string]$Effort = 'high'
)
$ErrorActionPreference = 'Continue'
$repo = 'C:\DEV\MasterArbeit'
$skill = Join-Path $repo '.claude\skills\run-experiment'
$adapter = Join-Path $skill 'opencode-adapter.py'
$root = Join-Path $repo 'QuellCode\CentronERP'
$agents = Join-Path $repo 'Versuche\Versuch_02\03_Agents.json'
$skillVer = 'v13.0.0'
$iterV1 = if ($Provider -eq 'tensorx') { 'Iteration 16' } elseif ($Arbeitsverzeichnis -eq 'spiegel') { 'Iteration 15' } elseif ($Ausgabeblock -eq 'explizit') { 'Iteration 14' } else { 'Iteration 13' }
$iterV2 = if ($Provider -eq 'tensorx') { 'Iteration 9' } elseif ($Arbeitsverzeichnis -eq 'spiegel') { 'Iteration 8' } elseif ($Ausgabeblock -eq 'explizit') { 'Iteration 7' } else { 'Iteration 6' }
$maxRun = 28800 # 8 h je Lauf; 6 Laeufe = bis zu 48 h gesamt
$werkzeugkontext = @{
solo = @'
### Werkzeugkontext (vom Versuchsaufbau vorgegeben)
Für diesen Lauf stehen zur Verfügung: Lesen von Dateien, Suchen im Dateibestand, Auflisten von
Verzeichnissen sowie das Ausführen rein lesender Kommandozeilenbefehle im Arbeitsverzeichnis.
Nicht verfügbar sind: Subagenten, spezialisierte Agentenrollen, externe Werkzeugserver,
Webzugriff.
Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare
Werkzeuge zu ersetzen.
'@
builtin = @'
### Werkzeugkontext (vom Versuchsaufbau vorgegeben)
Für diesen Lauf stehen zur Verfügung: Lesen von Dateien, Suchen im Dateibestand, Auflisten von
Verzeichnissen, das Ausführen rein lesender Kommandozeilenbefehle im Arbeitsverzeichnis sowie
die werkzeugeigenen Subagenten.
Nicht verfügbar sind: spezialisierte Agentenrollen aus Konfigurationsdateien, externe
Werkzeugserver, Webzugriff.
Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare
Werkzeuge zu ersetzen.
'@
custom = @'
### Werkzeugkontext (vom Versuchsaufbau vorgegeben)
Für diesen Lauf stehen zur Verfügung: Lesen von Dateien, Suchen im Dateibestand, Auflisten von
Verzeichnissen, das Ausführen rein lesender Kommandozeilenbefehle im Arbeitsverzeichnis sowie
die beigestellten Agentenrollen modulinventar, faktenermittler, strs-autor, syrs-autor,
swrs-autor, belegpruefer, konsistenzpruefer und iso29148-orchestrator.
Nicht verfügbar sind: externe Werkzeugserver, Webzugriff.
Triff keine Annahmen über weitere Werkzeuge und versuche nicht, nicht verfügbare
Werkzeuge zu ersetzen.
Für die folgenden Teilaufgaben stehen vorgesehene Bearbeiter bereit. Führe diese
Teilaufgaben durch den jeweils genannten Bearbeiter aus, nicht selbst:
| Teilaufgabe | Vorgesehener Bearbeiter |
|---|---|
| Modulinventar (Schritt 0) | modulinventar |
| Faktenerhebung zu einem Modulausschnitt (Schritte 2 bis 4) | faktenermittler |
| Formulierung der StRS-Anforderungen | strs-autor |
| Formulierung der SyRS-Anforderungen | syrs-autor |
| Formulierung der SwRS-Anforderungen samt Konsolidierungsprüfung | swrs-autor |
| Prüfung ausgewiesener Belege gegen die Codebasis | belegpruefer |
| Prüfung des Gesamtbestands an den Nahtstellen der Ausschnitte | iso29148-orchestrator |
| Konsistenzcheck des fertigen Anforderungssatzes (Abschnitt Abschluss) | konsistenzpruefer |
Zuschnitt, Anzahl der Aufträge je Bearbeiter, deren Reihenfolge und die Tiefe
entscheidest du. Gebunden ist allein, wer eine Teilaufgabe ausführt. Die Bearbeiter
lesen nur; das Anlegen der Ergebnisdateien und die Übernahme ihrer Rückmeldungen
bleiben deine Aufgabe.
'@
}
# Modell x Modus. custom ist V2 und liegt deshalb unter Versuch_02.
$laeufe = if ($Provider -eq 'tensorx') {
@(
@{ modell = 'z-ai/glm-5.3-flash'; modus = 'solo' }
@{ modell = 'z-ai/glm-5.3-flash'; modus = 'builtin' }
@{ modell = 'z-ai/glm-5.3-flash'; modus = 'custom' }
@{ modell = 'qwen/qwen3.8-flash-next'; modus = 'solo' }
@{ modell = 'qwen/qwen3.8-flash-next'; modus = 'builtin' }
@{ modell = 'qwen/qwen3.8-flash-next'; modus = 'custom' }
)
} else {
@(
@{ modell = 'google/gemma-4-e4b'; modus = 'solo' }
@{ modell = 'google/gemma-4-e4b'; modus = 'builtin' }
@{ modell = 'google/gemma-4-e4b'; modus = 'custom' }
@{ modell = 'qwen/qwen3.5-9b'; modus = 'solo' }
@{ modell = 'qwen/qwen3.5-9b'; modus = 'builtin' }
@{ modell = 'qwen/qwen3.5-9b'; modus = 'custom' }
)
}
if ($Modelle) { $laeufe = $laeufe | Where-Object { $Modelle -contains $_.modell } }
$protokoll = Join-Path $repo 'Versuche\_matrix.log'
Add-Content -Path $protokoll -Value "Matrixstart $(Get-Date -Format o); Skill $skillVer; Provider: $Provider; Effort: $Effort; Ausgabeblock: $Ausgabeblock; Arbeitsverzeichnis: $Arbeitsverzeichnis; Modelle: $(($laeufe.modell | Select-Object -Unique) -join ', ')"
foreach ($l in $laeufe) {
$modell = $l.modell
$modus = $l.modus
if ($modus -eq 'custom') {
$promptDir = Join-Path $repo 'Versuche\Versuch_02'
$promptDatei = Join-Path $promptDir '02_Prompt.md'
$nn = '02'; $iter = $iterV2
} else {
$promptDir = Join-Path $repo 'Versuche\Versuch_01'
$promptDatei = Join-Path $promptDir '03_Prompt.md'
$nn = '03'; $iter = $iterV1
}
$zelle = Join-Path (Join-Path (Join-Path $iter $modell) $modus) $Effort
do {
$id4 = '{0:x4}' -f (Get-Random -Maximum 65536)
$lauf = Join-Path (Join-Path $promptDir $zelle) "${nn}_Lauf_$(Get-Date -Format 'yyyy-MM-dd_HHmmss')_${skillVer}-$id4"
} while (Test-Path $lauf)
New-Item -ItemType Directory -Force "$lauf\Ergebnisse" | Out-Null
New-Item -ItemType Directory -Force "$lauf\_meta" | Out-Null
Set-Content -Path "$lauf\_meta\before.txt" `
-Value (git -C $repo status --porcelain -- 'QuellCode/CentronERP' | Out-String)
if ($Ausgabeblock -eq 'explizit') {
$block2 = @"
### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben)
Schreibe ALLE zu erzeugenden Ergebnisdateien in dieses Verzeichnis:
$lauf\Ergebnisse
Verwende bei jedem Schreibvorgang den vollständigen absoluten Pfad, beginnend mit
``$lauf\Ergebnisse\``. Ein relativer Pfad wie ``Ergebnisse\StRS.md`` wird vom
Arbeitsverzeichnis aus aufgelöst und deshalb abgewiesen.
Beispiel für die Datei StRS.md:
``$lauf\Ergebnisse\StRS.md``
Lege im Arbeitsverzeichnis (der analysierten Codebasis) kein Verzeichnis ``Ergebnisse``
an und verändere dort keine Dateien.
"@
} else {
$block2 = @"
### Ausgabeverzeichnis (überschreibt anderslautende Pfadangaben oben)
Schreibe ALLE zu erzeugenden Ergebnisdateien in das Verzeichnis
``$lauf\Ergebnisse\``.
Verändere keine Dateien im Arbeitsverzeichnis (der analysierten Codebasis).
"@
}
Set-Content -Path "$lauf\_meta\combined_prompt.md" -Encoding utf8 `
-Value ((Get-Content $promptDatei -Raw) + "`n`n" + $werkzeugkontext[$modus] + "`n" + $block2)
Add-Content -Path $protokoll -Value "START $(Get-Date -Format o) $modell $modus -> $lauf"
Set-Content -Path "$lauf\_meta\startzeit.txt" -Value (Get-Date -Format o)
$argumente = @(
$adapter,
'--prompt', "$lauf\_meta\combined_prompt.md",
'--root', $root,
'--output', "$lauf\Ergebnisse",
'--result-dir', $lauf,
'--provider', $Provider,
'--model', $modell,
'--effort', $Effort,
'--mode', $modus,
'--min-context', '32768',
'--arbeitsverzeichnis', $Arbeitsverzeichnis,
# Feste Kontextgroesse statt Modellmaximum: Gemma kann 131.072, Qwen 3.5-9B
# 262.144. Bei vollem Qwen-Kontext bleiben nur 294 MiB VRAM frei und der
# Durchsatz faellt von 27 auf 10,8 tok/s. Gleicher Wert fuer beide Modelle
# haelt zudem das Kontextfenster als Versuchsbedingung konstant.
'--lmstudio-context', '131072',
'--lmstudio-parallel', '4',
'--lmstudio-gpu', 'max',
'--lmstudio-autoload',
'--stall-timeout', '0',
'--max-runtime', "$maxRun",
'--title', "run-experiment $modell $modus $Effort"
)
if ($modus -eq 'custom') { $argumente += @('--agents', $agents) }
if ($Provider -eq 'lmstudio') {
# Nur der lokale Betrieb kennt Preflight und Ladeparameter. Feste
# Kontextgroesse statt Modellmaximum: Gemma kann 131.072, Qwen 3.5-9B
# 262.144; bei vollem Qwen-Kontext bleiben nur 294 MiB VRAM frei und der
# Durchsatz faellt von 27 auf 10,8 tok/s. Gleicher Wert fuer beide Modelle
# haelt das Kontextfenster als Versuchsbedingung konstant.
$argumente += @(
'--min-context', '32768',
'--lmstudio-context', '131072',
'--lmstudio-parallel', '4',
'--lmstudio-gpu', 'max',
'--lmstudio-autoload'
)
}
& python @argumente 2> "$lauf\Stderr.log"
$code = $LASTEXITCODE
Set-Content -Path "$lauf\_meta\endzeit.txt" -Value (Get-Date -Format o)
Set-Content -Path "$lauf\_meta\after.txt" `
-Value (git -C $repo status --porcelain -- 'QuellCode/CentronERP' | Out-String)
& python (Join-Path $skill 'analyse-anforderungen.py') $lauf 2>&1 | Out-Null
$dateien = (Get-ChildItem "$lauf\Ergebnisse" -Recurse -File -EA SilentlyContinue | Measure-Object).Count
Add-Content -Path $protokoll -Value "ENDE $(Get-Date -Format o) exit=$code dateien=$dateien"
}
Add-Content -Path $protokoll -Value "Matrixende $(Get-Date -Format o)"