Beide Rollen (Coder + Judge) auf einem llama.cpp-Server (Port 8001). switchModel wechselt zwischen qwen3.5-coder und qwen3.5-judge via llama-cpp-single-Provider ohne Server-Neustart. start-single.sh startet den gemeinsamen Server, GPU wählbar per GPU_DEVICE-Env-Variable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.8 KiB
Plan: pi_coder_v2 — Single-Server (Option B)
Kontext
pi_coder verwendet zwei llama.cpp-Server für Coder (GPU 1) und Judge (GPU 2), die aber dasselbe GGUF-Modell ausführen. Die Rollentrennung entsteht ausschließlich durch System-Prompts. Wenn nur eine GPU verfügbar ist, kann ein einziger Server beide Rollen übernehmen — Rollenwechsel per Prompt statt per Server-Neustart.
pi_coder bleibt unverändert. Die Umsetzung erfolgt im neuen Verzeichnis ~/pi_coder_v2.
Schritt 1: Verzeichnis anlegen und Dateien kopieren
mkdir ~/pi_coder_v2
cp ~/pi_coder/pi-coder-judge-extension.ts ~/pi_coder_v2/
cp ~/pi_coder/models.json ~/pi_coder_v2/
cp ~/pi_coder/start-coder.sh ~/pi_coder_v2/
cp ~/pi_coder/start-judge.sh ~/pi_coder_v2/
cp ~/pi_coder/start-servers.sh ~/pi_coder_v2/
cp ~/pi_coder/stop-servers.sh ~/pi_coder_v2/
cp ~/pi_coder/status.sh ~/pi_coder_v2/
cp ~/pi_coder/install_servers_and_pi_coder_extension.sh ~/pi_coder_v2/
cp ~/pi_coder/README.md ~/pi_coder_v2/
cp ~/pi_coder/BEDIENUNGSANLEITUNG.md ~/pi_coder_v2/
cp ~/pi_coder/CLAUDE.md ~/pi_coder_v2/
# Plan-Datei ebenfalls kopieren
cp <dieser-plan> ~/pi_coder_v2/SINGLE_SERVER_PLAN.md
# git init
cd ~/pi_coder_v2 && git init && git add -A && git commit -m "init: kopiert aus pi_coder"
Nicht kopieren: run-tests.sh, test-utils.ts, examples/ (nicht relevant für Kernfunktion).
Schritt 2: start-single.sh anlegen
Basiert auf start-coder.sh mit folgenden Änderungen:
| Parameter | Alt (coder) | Neu (single) |
|---|---|---|
CONTAINER_NAME |
qwen36-27b-coder |
qwen36-27b-single |
HOST_PORT |
8001 | 8001 |
MODEL_ALIAS |
qwen3.5-coder |
qwen3.5-single |
--temp |
0.6 | 0.65 (Kompromiss) |
--gpus |
"device=1" |
"device=1" (oder konfigurierbar) |
Der Server registriert sich unter dem Alias qwen3.5-single.
Schritt 3: models.json anpassen
Neuen Provider llama-cpp-single hinzufügen mit beiden Modell-IDs auf Port 8001:
"llama-cpp-single": {
"baseUrl": "http://127.0.0.1:8001/v1",
"api": "openai-completions",
"apiKey": "none",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false,
"maxTokensField": "max_tokens",
"thinkingFormat": "qwen-chat-template"
},
"models": [
{
"id": "qwen3.5-coder",
"name": "Qwen3.6 27B Single-Server Coder (llama.cpp :8001)",
"reasoning": true,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
},
{
"id": "qwen3.5-judge",
"name": "Qwen3.6 27B Single-Server Judge (llama.cpp :8001)",
"reasoning": true,
"input": ["text"],
"contextWindow": 262144,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
Die bestehenden Provider llama-cpp-coder und llama-cpp-judge bleiben erhalten
(für Kompatibilität), werden aber nicht aktiv genutzt.
Schritt 4: pi-coder-judge-extension.ts — switchModel-Aufrufe
Alle Aufrufe von switchModel(pi, ctx, "llama-cpp-coder", "qwen3.5-coder")
und switchModel(pi, ctx, "llama-cpp-judge", "qwen3.5-judge") werden auf
"llama-cpp-single" umgestellt. Der Modell-ID-Parameter ("qwen3.5-coder" /
"qwen3.5-judge") bleibt unverändert — so bleiben die Registry-Wechsel erhalten,
sind aber sofort (kein Server-Neustart).
Betroffene Stellen (ca. 8):
/coderhandler/judgehandler/fixhandler/shipithandler/optimizeloop (Coder-Kickoff, Judge-Phase, Fix-Phase, ShipIt-Phase)/patchhandler/quick_checkhandler/planhandler
Schritt 5: install_servers_and_pi_coder_extension.sh anpassen
Pfade auf pi_coder_v2 anpassen (falls nötig — Skript referenziert vermutlich $REPO
als relatives Verzeichnis, was automatisch korrekt ist).
Schritt 6: waitUntilModelReady im --continue-Modus
Im --continue-Modus prüft die Extension beide Server parallel:
const [coderReady, judgeReady] = await Promise.all([
waitUntilModelReady(pi, ctx, 8001, "qwen3.5-coder"),
waitUntilModelReady(pi, ctx, 8002, "qwen3.5-judge"),
]);
Dies muss auf einen einzigen Check umgestellt werden:
const ready = await waitUntilModelReady(pi, ctx, 8001, "qwen3.5-single");
Verifikation
cd ~/pi_coder_v2 && ./start-single.sh→ Server startet auf Port 8001nvidia-smi→ nur eine GPU belegt, ~20 GB VRAM./install_servers_and_pi_coder_extension.sh→ Extension in~/.pi/agent/deployen- In pi:
/reload→ Extension neu laden /optimize <kleiner Testauftrag>→ Loop läuft durch- In der Statuszeile:
switchModelwechselt ohne spürbare Pause - Qualitätscheck: Judge-Urteil und Coder-Fix verhalten sich wie erwartet