Dieselbe TensorX-Matrix ein zweites Mal bei hoechstem Effort. Zwoelf gueltige Laeufe, 2.116 Anforderungen, 127,6 Mio. Tokens, hochgerechnet $10,53 aus der Preisliste vom 02.09.2026. Befund: In den nicht-delegierenden Zellen bewegt sich der Ertrag zwischen minus 18 und plus 44 Prozent ohne erkennbare Richtung - in der Groessenordnung der Streuung. Der eine deutliche Ausschlag ist GLM in custom mit plus 122 Prozent, erreicht mit 78 statt 30 Subagenten. Der hoehere Denkaufwand schlaegt sich in mehr Zerlegung nieder, und die traegt den Ertrag, nicht der Denkaufwand als solcher. Qwens custom-Zelle hat sich qualitativ erholt: bei high 61 Prozent ohne Beleg und 40 Prozent Hypothesen, bei max 3 Prozent ohne Beleg und 96 Prozent Primaerbeleg. Der Einbruch war ein Laufmerkmal, kein Modellmerkmal - ein weiterer Beleg, dass n gleich 1 je Zelle nicht traegt. Skill 13.2.0: analyse-anforderungen.py toleriert jetzt vier Markdown-Fassungen der Feldvorgabe. Jedes der vier eingesetzten Modelle formatierte sie anders, und jede Fassung wurde zunaechst mit null Anforderungen gezaehlt, obwohl Belege und Pruefideen vollstaendig vorlagen. Das ist ein Befund ueber den Versuchsaufbau: Die Formatvorgabe ist fuer Menschen eindeutig, fuer maschinelle Auswertung nicht. Regressionsprobe an sieben Laeufen unveraendert. _matrix.ps1 nimmt zusaetzlich -Effort und -Modi fuer einzelne Zellen. Ein Lauf fiel durch Standby des Rechners aus und wurde wiederholt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
227 lines
11 KiB
PowerShell
227 lines
11 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,
|
|
# Optionaler Filter auf Agentenmodi - erlaubt es, eine einzelne Zelle
|
|
# nachzuziehen, ohne die uebrigen zu wiederholen.
|
|
[ValidateSet('solo','builtin','custom')][string[]]$Modi,
|
|
# 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 } }
|
|
if ($Modi) { $laeufe = $laeufe | Where-Object { $Modi -contains $_.modus } }
|
|
|
|
$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)"
|