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>
182 lines
7.9 KiB
PowerShell
182 lines
7.9 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'
|
|
)
|
|
$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 = 'v12.1.0'
|
|
$iterV1 = if ($Ausgabeblock -eq 'explizit') { 'Iteration 14' } else { 'Iteration 13' }
|
|
$iterV2 = if ($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 = @(
|
|
@{ 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\_lmstudio_matrix.log'
|
|
Add-Content -Path $protokoll -Value "Matrixstart $(Get-Date -Format o); Skill $skillVer; Ausgabeblock: $Ausgabeblock; 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) 'high'
|
|
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', 'lmstudio',
|
|
'--model', $modell,
|
|
'--effort', 'high',
|
|
'--mode', $modus,
|
|
'--min-context', '32768',
|
|
'--lmstudio-context', 'max',
|
|
'--lmstudio-parallel', '4',
|
|
'--lmstudio-gpu', 'max',
|
|
'--lmstudio-autoload',
|
|
'--stall-timeout', '0',
|
|
'--max-runtime', "$maxRun",
|
|
'--title', "run-experiment $modell $modus high"
|
|
)
|
|
if ($modus -eq 'custom') { $argumente += @('--agents', $agents) }
|
|
|
|
& 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)"
|