- TypeScript 81.6%
- JavaScript 12.7%
- Shell 5.7%
Macht die Single-Server-Konfiguration reproduzierbar (defaultProvider/ defaultModel/enabledModels -> llama-cpp-single). install_servers_and_pi_coder_extension.sh deployt settings.json jetzt mit; vorher wird die bestehende Datei nach settings.json.bak gesichert, da pi sie zur Laufzeit beschreibt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|---|---|---|
| BEDIENUNGSANLEITUNG.md | ||
| install_servers_and_pi_coder_extension.sh | ||
| models.json | ||
| pi-coder-judge-extension.ts | ||
| README.md | ||
| settings.json | ||
| SINGLE_SERVER_PLAN.md | ||
| start-single.sh | ||
| status.sh | ||
| stop-servers.sh | ||
pi_coder — Automatisierter Coder/Judge-Workflow für pi agent
Dieses Repository enthält die Konfiguration und Skripte für einen automatisierten Coding-Workflow mit zwei lokalen LLaMA-Modellen: ein Coder-Modell und ein Judge-Modell, gesteuert über pi agent.
Überblick
Nutzer gibt Auftrag
│
▼
/coder → qwen3.5-coder (:8001) → Implementierung + git commit
│
▼
/judge → qwen3.5-judge (:8002) → Review: PASS / FAIL + Blocker
│
FAIL? ▼
/fix → qwen3.5-coder (:8001) → Fixes + git commit
│
PASS? ▼
/shipit → qwen3.5-judge (:8002) → Finale Freigabe: SHIP / NO-SHIP
(nur bei "PASS WITH CONCERNS" — klares PASS → direkt SHIP)
/optimize = Coder→Judge→Fix-Schleife automatisch (bis PASS oder max. N Runden)
--interactive: pausiert nach PASS für menschlichen Checkpoint + optionale Zusatzaufträge
Beide Modelle laufen als separate llama.cpp-Docker-Container und sprechen eine
OpenAI-kompatible API (/v1/chat/completions). pi agent wechselt automatisch zwischen
den Endpunkten wenn du ein /judge-, /fix- oder /coder-Kommando aufrufst.
Modelle
| Rolle | Modell | Port | Container | Alias | GPU |
|---|---|---|---|---|---|
| Coder | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS | 8001 | qwen36-27b-coder | qwen3.5-coder | device=1 |
| Judge | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS | 8002 | qwen36-27b-judge | qwen3.5-judge | device=2 |
Beide Container verwenden dasselbe GGUF-Datei, aber mit unterschiedlichen Serverparametern (Kontext, Temperatur, Parallelität).
Voraussetzungen
- Docker mit NVIDIA-GPU-Support:
# NVIDIA Container Toolkit installieren (falls nicht vorhanden) distribution=$(. /etc/os-release; echo $ID$VERSION_ID) curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list \ | sudo tee /etc/apt/sources.list.d/nvidia-docker.list sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit sudo systemctl restart docker - NVIDIA-GPUs: empfohlen 2 × RTX 3090 (je 24 GB VRAM) für Coder und Judge parallel. Bei 3 GPUs: GPU 0 für Display reservieren, GPU 1 → Coder, GPU 2 → Judge.
- GGUF-Modell vorhanden unter:
$HF_HOME/models/qwen3/Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS.gguf- Standard-Pfad:
HF_HOME=/home/dschlueter/nvme2n1p7_home/huggingface - Überschreibbar:
HF_HOME=/anderer/pfad ./start-servers.sh
- Standard-Pfad:
- pi agent installiert (
~/.pi/)
Installation
# 1. Repository klonen
git clone https://kitux.de/forgejo/dschlueter/pi_coder.git ~/pi_coder
cd ~/pi_coder
# 2. Extension und Modell-Config nach ~/.pi/agent/ deployen
./install_servers_and_pi_coder_extension.sh
# 3. pi agent neu laden (in der pi-Oberfläche)
# /reload
# 4. Server starten
./start-servers.sh
Nach späteren Änderungen an pi-coder-judge-extension.ts oder models.json:
./install_servers_and_pi_coder_extension.sh # kopiert nach ~/.pi/agent/
# dann /reload in pi agent
Server starten / stoppen / status
# Beide Server parallel starten (empfohlen — dauert 1–3 Minuten)
./start-servers.sh
# Einzeln starten (z.B. nur einen neu starten)
./start-coder.sh # Port 8001
./start-judge.sh # Port 8002
# Beide stoppen
./stop-servers.sh
# Status beider Server prüfen
./status.sh
start-servers.sh startet beide Container gleichzeitig und wartet bis beide
HTTP-ready sind (max. 5 Minuten — die neue llama.cpp-Version prüft beim Start, ob
Modell + KV-Cache in den VRAM passen, was zusätzliche Zeit kostet). Logs werden
getrennt gesammelt und nur bei Fehler ausgegeben.
Wenn Server bereits laufen und du start-servers.sh (oder ein Einzelskript)
aufrufst, werden die laufenden Container zuerst per docker rm -f gestoppt
und dann neu gestartet — ein laufender Inference-Request wird dabei abgebrochen.
llama.cpp-Serverparameter im Detail
Gemeinsame Parameter
| Parameter | Wert | Bedeutung |
|---|---|---|
--jinja |
— | Verwendet das im GGUF eingebettete Jinja-Chat-Template (Qwen-Format). Notwendig für korrekte <|im_start|>-Tokens. |
--reasoning on |
— | Aktiviert das interne Thinking-Budget des Modells (Qwen3-spezifisch). Ersetzt das frühere --chat-template-kwargs '{"enable_thinking":true}'. |
--no-context-shift |
— | Kontextfenster wird nicht verschoben wenn es voll ist — stattdessen Fehler. Verhindert stille Datenverluste. |
--repeat-penalty 1.05 |
— | Leichte Penalty für Wiederholungen. Wert > 1.0 unterdrückt Loops. |
--top-k 20 |
— | Nur die 20 wahrscheinlichsten nächsten Tokens werden berücksichtigt. |
--min-p 0.01 |
— | Tokens mit Wahrscheinlichkeit < 1 % des wahrscheinlichsten Tokens werden ausgeschlossen. |
-ngl 999 |
— | Alle Layer auf die GPU laden (999 = „alle"). Bei zu wenig VRAM reduzieren. |
-fa on |
— | Flash Attention — schnellere Attention-Berechnung, weniger VRAM für den Attention-Pass. |
--kv-unified |
— | Einheitlicher KV-Cache über alle Schichten. Effizienter bei langen Kontexten. |
--cache-type-k q4_0 |
— | KV-Cache Keys in 4-Bit quantisiert. Spart ~75 % VRAM gegenüber fp16 — nötig für 256K Kontext auf einer 24-GB-GPU. |
--cache-type-v q4_0 |
— | KV-Cache Values ebenfalls 4-Bit quantisiert. |
--cont-batching |
— | Continuous Batching: neue Anfragen werden in laufende Batches eingefügt — höherer Durchsatz bei mehreren parallelen Anfragen. |
--main-gpu 0 |
— | GPU-Index (0 = erste des Containers) für Nicht-Tensor-Operationen. |
--gpus '"device=1"' (Coder) |
— | Docker: nur GPU 1 dem Coder-Container zuweisen. |
--gpus '"device=2"' (Judge) |
— | Docker: nur GPU 2 dem Judge-Container zuweisen. |
Coder-Server (Port 8001) — optimiert für Coding-Aufgaben
| Parameter | Wert | Erklärung / Wirkung |
|---|---|---|
-c 262144 |
256K Tokens | Sehr großes Kontextfenster: gesamte Codebasis + langer Gesprächsverlauf passt rein. Sehr hoher VRAM-Bedarf. Reduziere auf 65536 wenn VRAM knapp. |
-n 16384 |
16K Tokens | Maximale Ausgabelänge pro Anfrage. Für Kommentieraufgaben (/update_doku) nötig. |
--temp 0.2 |
— | Niedrige Temperatur: deterministisch, konsistenter Code. Erhöhe auf 0.4–0.6 für kreativere Lösungsansätze. |
--top-p 0.95 |
— | Nucleus Sampling: 95 % der Wahrscheinlichkeitsmasse. Passend zu temp 0.2. |
--batch-size 1024 |
— | Prompt-Verarbeitungs-Batch. Größer = schnelleres Einlesen langer Dateien. |
--ubatch-size 512 |
— | Micro-Batch für GPU-Kernel. Muss ≤ batch-size sein. |
--parallel 2 |
— | 2 gleichzeitige Request-Slots. Nützlich wenn pi agent schnell Folgeanfragen schickt. |
Judge-Server (Port 8002) — optimiert für Reviews
| Parameter | Wert | Erklärung / Wirkung |
|---|---|---|
-c 262144 |
256K Tokens | Großes Kontextfenster: nötig bei langen /optimize-Runden, wo der Gesprächsverlauf stark anwächst. |
-n 16384 |
16K Tokens | Lange Reviews und Begründungen passen vollständig in die Ausgabe. |
--temp 0.1 |
— | Sehr niedrige Temperatur: maximale Konsistenz und Reproduzierbarkeit der Urteile. |
--top-p 0.9 |
— | Etwas enger als beim Coder — weniger Variation im Urteil gewünscht. |
--batch-size 512 |
— | Kleiner als beim Coder — Judge bekommt selten sehr lange Prompts. |
--ubatch-size 256 |
— | Entsprechend kleiner. |
--parallel 1 |
— | Judge-Aufgaben sind immer sequenziell im Workflow, daher 1 Slot ausreichend. |
GPU-Konfiguration und VRAM
Aktuelles Setup (1 GPU pro Server)
Jeder Server bekommt eine dedizierte GPU — dadurch kein VRAM-Konflikt:
GPU 0 NVIDIA T600 → Display / Monitor (nicht für KI genutzt)
GPU 1 RTX 3090 (24 GB) → qwen36-27b-coder (Port 8001)
GPU 2 RTX 3090 (24 GB) → qwen36-27b-judge (Port 8002)
Die Skripte verwenden --gpus '"device=1"' (Coder) bzw. '"device=2"' (Judge).
Innerhalb des Containers ist dies stets CUDA:0, daher --main-gpu 0 ohne --tensor-split.
VRAM-Abschätzung für das 27B IQ4_XS-Modell (eine GPU)
| Komponente | Größe (ca.) |
|---|---|
| Modell-Gewichte (IQ4_XS, 27B) | ~14 GB |
| KV-Cache bei 262 144 Tokens (q4_0) | ~8–10 GB |
| KV-Cache bei 131 072 Tokens (q4_0) | ~4–5 GB |
| KV-Cache bei 65 536 Tokens (q4_0) | ~2–3 GB |
| Summe (262k Kontext) | ~22–24 GB |
Bei einer 24-GB-GPU ist 262k Kontext knapp kalkuliert. Wichtig: keine anderen Prozesse dürfen nennenswert VRAM belegen (z. B. TTS-Dienste, Ollama). Prüfen mit:
nvidia-smi --query-gpu=index,memory.used,memory.free --format=csv
Falls der VRAM nicht reicht: Kontext in den Startskripten auf 131072 oder 65536 reduzieren.
Anpassung für andere GPU-Konfigurationen
# 2 GPUs (beide für KI, keine Display-GPU):
--gpus '"device=0"' # Coder
--gpus '"device=1"' # Judge
# 1 GPU (beide Server auf gleicher GPU — nicht empfohlen, VRAM-Konflikt):
--gpus '"device=0"' # beide Server
--tensor-split 0.5,0.5 # Modell hälftig aufteilen
-c 65536 # Kontext stark reduzieren
# 2 GPUs für einen Server (wenn sehr großer Kontext nötig):
--gpus '"device=0,1"' \
--tensor-split 0.5,0.5 \
--main-gpu 0 \
-c 262144
Bei einer 16-GB-GPU ist die Modellgröße allein schon grenzwertig. Entweder ein kleineres Modell verwenden oder die Quantisierung erhöhen (IQ3_XS, Q4_K_M).
Parameter-Tuning-Guide
Temperatur (--temp)
| Wert | Eignung |
|---|---|
0.0–0.1 |
Maximale Reproduzierbarkeit. Gut für Judge/Review. |
0.1–0.3 |
Guter Kompromiss für Coding. Empfohlen für Coder. |
0.4–0.6 |
Kreativere Lösungen, mehr Varianz. Sinnvoll für Prototyping. |
0.7–1.0 |
Kreativschreiben, Brainstorming. Für Coding meist zu viel Rauschen. |
Kontextgröße (-c)
Je größer der Kontext, desto mehr VRAM braucht der KV-Cache.
Faustregel: KV-Cache ≈ context_size × layers × head_dim × 2 × bytes_per_element.
Bei q8_0 (1 Byte/Element) und Qwen3-27B (28 Schichten, 128 Head-Dim, 32 Heads):
KV-Cache ≈ context_size × 28 × 128 × 32 × 2 × 1 Byte ≈ context_size × 0,23 MB
| Kontext | KV-Cache (q4_0) | Empfehlung |
|---|---|---|
| 32 768 | ~1,9 GB | 1 × 16-GB-GPU |
| 65 536 | ~3,7 GB | 1 × 24-GB-GPU |
| 131 072 | ~7,5 GB | 2 × 16-GB-GPU |
| 262 144 | ~8–10 GB | 1 × 24-GB-GPU (q4_0) — aktuell gesetzt |
KV-Cache-Quantisierung
--cache-type-k/v |
VRAM | Qualität |
|---|---|---|
f16 |
100 % (Basis) | Referenz |
q8_0 |
~50 % | Kaum merklich schlechter |
q4_0 |
~25 % | Merklicher Qualitätsverlust bei langen Kontexten — aber nötig für 256K Kontext auf 2× 24 GB. Aktuell gesetzt. |
Parallelität (--parallel)
Mehr parallele Slots erhöhen den Durchsatz bei gleichzeitigen Anfragen, aber jeder Slot
reserviert Speicher im KV-Cache. Im pi-coder-Workflow sind echte Parallelaufrufe selten,
daher ist --parallel 1 für den Judge ausreichend. Coder --parallel 2 bietet Puffer
wenn pi agent Folgeanfragen schnell hintereinander schickt.
Dateien
| Datei | Zweck |
|---|---|
pi-coder-judge-extension.ts |
pi agent Extension (Kommandos, Tools, Hooks) |
models.json |
Provider- und Modell-Konfiguration für pi agent |
test-utils.ts |
Unit-Tests für Hilfsfunktionen der Extension |
run-tests.sh |
Unit-Tests ausführen (TypeScript-Stripping + node) |
start-servers.sh |
Beide Server parallel starten (empfohlen) |
start-coder.sh |
Nur Coder-Container starten (Port 8001) |
start-judge.sh |
Nur Judge-Container starten (Port 8002) |
stop-servers.sh |
Beide Container stoppen |
status.sh |
Laufstatus beider Server anzeigen |
install_servers_and_pi_coder_extension.sh |
Extension + models.json nach ~/.pi/agent/ kopieren |
examples/ |
Demo-Projekte (Python, Rust, Go, C, Bash, HTML/JS) für Live-Demos |
examples/restore-all.sh |
Examples nach Demo-Lauf in Ausgangszustand zurücksetzen |
pi-Kommandos (Kurzübersicht)
| Kommando | Modell | Beschreibung |
|---|---|---|
/coder <auftrag> |
Coder | TASK.md anlegen, Implementierung starten |
/judge [fokus] |
Judge | Code-Review gegen TASK.md + letzten Commit |
/fix [hinweis] |
Coder | Judge-Kritik beheben, committen |
/shipit |
Judge | Finale Freigabeprüfung |
/optimize <auftrag> [--rounds N] [--with-doku] [--continue] [--interactive] |
beide | Vollautomatische Schleife bis PASS (Standard: 2 Runden, Runde 1: Quick-Judge) |
/optimize ... [--no-tests] [--approve-concerns] [--test-cmd "cmd"] [--test-timeout N] |
beide | Test-Erkennung überspringen / PASS WITH CONCERNS direkt shippern |
/patch <änderung> |
Coder | Gezielte Minimaländerung ohne Review |
/quick_check [was] |
Judge | Schnelle Prüfung der letzten Änderung |
/version |
— | Versionsnummer erhöhen (SemVer + Git-Tag) |
/update_doku |
Coder | Code kommentieren + README + Bedienungsanleitung |
/plan <auftrag> |
Coder | Implementierungsplan in PLAN.md (kein Code) |
/continue |
Coder | Unterbrochenen Prozess fortsetzen |
/cancel |
— | Laufenden Loop nach aktuellem Schritt abbrechen |
/new_project <pfad> |
— | Neues Projektverzeichnis + git init |
Ausführliche Beschreibung aller Kommandos mit Beispielen: siehe BEDIENUNGSANLEITUNG.md.
Live-Aktivitätsstatus
Während der Ausführung zeigt pi_coder in der Statuszeile, was gerade passiert —
inklusive eines laufenden [MM:SS]-Timers während jeder LLM-Inference-Phase:
| Situation | Anzeige |
|---|---|
| Coder implementiert | ◉ Coder implementiert: Login-Flow mit JWT [01:23] |
| edit-Tool aktiv | Editiere src/main.py… |
| git commit | Git-Commit… |
| Judge (Quick-Check, Runde 1) | ◉○ Runde 1/2: Quick-Check [00:47] |
| Judge (voller Review, Runde 2) | ●◉ Runde 2/2: Judge — TASK.md + letzter Commit + Tests [02:15] |
| Tests laufen | ●○ Runde 1/2: Tests laufen (pytest, max. 120s)… |
| Fix-Phase | ●◉ Runde 2/2: Coder fixt — fehlendes Null-Check [01:05] |
| ShipIt | ●●◉ ShipIt — finale Freigabe [00:33] |
| Interactive-Pause (--interactive) | ⏸ PASS – warte auf /continue… |
Der Timer beweist, dass die LLM tatsächlich arbeitet. Steht er still, hängt der Prozess.