# pi_coder_2 — Automatisierter Coder/Judge-Workflow für pi agent Dieses Repository enthält die Konfiguration und Skripte für einen automatisierten Coding-Workflow mit einem lokalen LLaMA-Modell, das abwechselnd als Coder und Judge agiert — gesteuert über Pi Agent. Er dreht solange Optimierungsschleifen, bis das Programm Produktionsreife hat. --- ## Überblick ``` Nutzer gibt Auftrag │ ▼ /coder → coding_model (:8001, Coder-Persona) → Implementierung + git commit │ ▼ /judge → coding_model (:8001, Judge-Persona) → Review: PASS / FAIL + Blocker │ FAIL? ▼ /fix → coding_model (:8001, Coder-Persona) → Fixes + git commit │ PASS WITH CONCERNS? ▼ │ (ohne --approve-concerns: wie FAIL → weiterer Fix-Zyklus) │ PASS? ▼ /shipit → coding_model (:8001, Judge-Persona) → Finale Freigabe: SHIP / NO-SHIP (nur bei "PASS WITH CONCERNS" --approve-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 ``` Ein **einzelner** llama.cpp-Docker-Container bedient beide Rollen. Die Rollenumschaltung (Coder ↔ Judge) erfolgt über unterschiedliche System-Prompts, die der `before_agent_start`-Hook der Extension vor jeder Inference injiziert. pi agent wechselt keine Server mehr — nur die Persona im System-Prompt ändert sich. --- ## Modelle | Rolle | Modell | Port | Container | Alias | GPU | |----------------|---------------------------------------------------|------|--------------------|----------------|----------| | Coder + Judge | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS | 8001 | coding_model | coding_model | device=1 | Coder- und Judge-Rollen werden durch verschiedene System-Prompts realisiert — dasselbe Modell, derselbe Container, unterschiedliche Persona. --- ## Voraussetzungen - Docker mit NVIDIA-GPU-Support: ```bash # 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-GPU: empfohlen RTX 3090 (24 GB VRAM). Standard: GPU 1. Überschreibbar mit `GPU_DEVICE=0 ./start-single.sh`. Bei 3 GPUs: GPU 0 für Display reservieren. - 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-single.sh` - [pi agent](https://github.com/earendil-works/pi) installiert (`~/.pi/`) --- ## Installation ```bash # 1. Repository klonen git clone https://kitux.de/forgejo/dschlueter/pi_coder.git ~/pi_coder cd ~/pi_coder # 2. Extension, Modell-Config und settings.json 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-single.sh ``` Das Install-Skript sichert eine vorhandene `~/.pi/agent/settings.json` als `.bak` und kopiert dann `settings.json` aus dem Repo. Damit ist der korrekte Default-Provider (`llama-cpp-single/coding_model`) automatisch konfiguriert. Nach späteren Änderungen an `pi-coder-judge-extension.ts` oder `models.json`: ```bash ./install_servers_and_pi_coder_extension.sh # kopiert nach ~/.pi/agent/ # dann /reload in pi agent ``` --- ## Server starten / stoppen / status ```bash # Server starten (empfohlen — dauert 1–3 Minuten) ./start-single.sh # Server auf anderer GPU starten GPU_DEVICE=0 ./start-single.sh # Stoppen ./stop-servers.sh # Status prüfen ./status.sh ``` `start-single.sh` startet den Container und wartet bis HTTP-ready (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). Wenn der Server bereits läuft und du `start-single.sh` aufrufst, wird der laufende Container zuerst per `docker rm -f` gestoppt und dann neu gestartet — ein laufender Inference-Request wird dabei abgebrochen. --- ## llama.cpp-Serverparameter im Detail ### Parameter des Single-Servers (Port 8001) | 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). | | `--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. | | `--top-k 20` | — | Nur die 20 wahrscheinlichsten nächsten Tokens. | | `--min-p 0.01` | — | Tokens mit Wahrscheinlichkeit < 1 % des wahrscheinlichsten Tokens werden ausgeschlossen. | | `-ngl 999` | — | Alle Layer auf die GPU laden. | | `-fa on` | — | Flash Attention. | | `--kv-unified` | — | Einheitlicher KV-Cache über alle Schichten. | | `--cache-type-k q4_0` | — | KV-Cache Keys 4-Bit quantisiert. 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. | | `-c 262144` | 256K | Großes Kontextfenster für langen Gesprächsverlauf im Optimize-Loop. | | `-n 16384` | 16K | Maximale Ausgabelänge. | | `--temp 0.2` | — | Deterministisch — Coder-Rolle. Der Judge-System-Prompt gleicht die etwas höhere Temperatur aus. | | `--parallel 2` | — | 2 Slots, damit pi agent Folgeanfragen schnell hintereinander stellen kann. | | `--gpus '"device=1"'` | — | Standard: GPU 1. Überschreibbar: `GPU_DEVICE=0 ./start-single.sh`. | --- ## GPU-Konfiguration und VRAM ### Aktuelles Setup (1 GPU, 1 Server) Ein einzelner Container bedient beide Rollen sequenziell: ``` GPU 0 NVIDIA T600 → Display / Monitor (nicht für KI genutzt) GPU 1 RTX 3090 (24 GB) → coding_model (Port 8001, Coder + Judge) ``` Da Coder und Judge nicht gleichzeitig inferieren, gibt es keinen VRAM-Konflikt. Die Umschaltung zwischen den Rollen erfolgt ausschließlich über den System-Prompt — der Container läuft ohne Unterbrechung durch. ### VRAM-Abschätzung für das 27B IQ4_XS-Modell | 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. Keine anderen Prozesse dürfen nennenswert VRAM belegen (z. B. TTS-Dienste, Ollama). Prüfen mit: ```bash nvidia-smi --query-gpu=index,memory.used,memory.free --format=csv ``` Falls der VRAM nicht reicht: Kontext in `start-single.sh` auf `131072` oder `65536` reduzieren. ### Anpassung für andere GPU-Konfigurationen ```bash # Andere GPU verwenden: GPU_DEVICE=0 ./start-single.sh # 2 GPUs für einen Server (sehr großer Kontext): # start-single.sh anpassen: --gpus '"device=0,1"' \ --tensor-split 0.5,0.5 \ --main-gpu 0 \ -c 262144 ``` --- ## Parameter-Tuning-Guide ### Temperatur (`--temp`) | Wert | Eignung | |---|---| | `0.0–0.1` | Maximale Reproduzierbarkeit. | | `0.1–0.3` | Guter Kompromiss für Coding. **Aktuell gesetzt: 0.2.** | | `0.4–0.6` | Kreativere Lösungen. | | `0.7–1.0` | Für Coding meist zu viel Rauschen. | ### Kontextgröße (`-c`) | Kontext | KV-Cache (q4_0) | Empfehlung | |---|---|---| | 32 768 | ~1,9 GB | 1 × 16-GB-GPU | | 65 536 | ~3,7 GB | 1 × 24-GB-GPU (konservativ) | | 131 072 | ~7,5 GB | 1 × 24-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 24 GB. **Aktuell gesetzt.** | --- ## Tests ausführen ```bash ./run-tests.sh ``` Keine npm-Installation nötig — nutzt den integrierten `node:test`-Runner und `--experimental-strip-types` für TypeScript. Testet Parsing-Logik, Konfigurationskonsistenz und Extension-Guards gegen Regressionen. --- ## Dateien | Datei / Verzeichnis | Zweck | |---|---| | `pi-coder-judge-extension.ts` | pi agent Extension (Kommandos, Tools, Hooks, Rollen-Logik) | | `models.json` | Provider- und Modell-Konfiguration für pi agent | | `settings.json` | pi-agent-Settings (Default-Modell, aktivierte Modelle) — wird von Install-Skript deployt | | `run-tests.sh` | Tests ausführen | | `tests/` | Testdateien (pure-logic, config, extension-guards, scripts) | | `start-single.sh` | Single-Server starten (Port 8001, Coder + Judge) | | `stop-servers.sh` | Container stoppen | | `status.sh` | Laufstatus anzeigen | | `install_servers_and_pi_coder_extension.sh` | Extension + models.json + settings.json nach `~/.pi/agent/` deployen | | `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 | Persona | Beschreibung | |---|---|---| | `/coder ` | 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 [--rounds N] [--with-doku] [--continue] [--interactive]` | beide | Vollautomatische Schleife bis PASS (Standard: 2 Runden) | | `/optimize ... [--no-tests] [--approve-concerns] [--test-cmd "cmd"] [--test-timeout N]` | beide | Test-Erkennung überspringen / PASS WITH CONCERNS akzeptieren | | `/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 + LICENCE.md | | `/plan ` | Coder | Implementierungsplan in PLAN.md (kein Code) | | `/continue` | Coder | Unterbrochenen Prozess fortsetzen | | `/cancel` | — | Laufenden Loop nach aktuellem Schritt abbrechen | | `/new_project ` | — | Neues Projektverzeichnis + git init | Ausführliche Beschreibung aller Kommandos mit Beispielen: siehe **BEDIENUNGSANLEITUNG.md**. --- ## PASS WITH CONCERNS — Verhalten Im `/optimize`-Loop gilt `PASS WITH CONCERNS` **nicht** als bestanden — der Coder erhält einen weiteren Fix-Auftrag, genau wie bei `FAIL`. Erst sauberes `PASS` beendet die Schleife. Opt-out: `--approve-concerns` lässt `PASS WITH CONCERNS` als bestanden gelten. --- ## 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 (Runde 1) | `◉○ Runde 1/2: Judge — TASK.md + letzter Commit + Tests [00:47]` | | Judge (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 | `⏸ PASS – warte auf /continue…` | Der Timer beweist, dass die LLM tatsächlich arbeitet. Steht er still, hängt der Prozess.