- README: /version, /plan, /continue, /cancel in Kommando-Tabelle ergänzt - README: --test-cmd/--test-timeout für /optimize dokumentiert - README: Live-Aktivitätsstatus-Tabelle mit Beispielen - README: Serverparameter korrigiert: -c 262144, -n 16384, --cache-type q4_0 - README: VRAM-Tabelle auf q4_0-Basis aktualisiert (256K-Zeile ergänzt) - BEDIENUNGSANLEITUNG: neuer Abschnitt 9 "Versionsverwaltung: /version" - BEDIENUNGSANLEITUNG: Dialog-Beispiele + Manifest-Update-Logik erklärt - BEDIENUNGSANLEITUNG: Live-Status-Hinweis in /optimize-Ablauf integriert - BEDIENUNGSANLEITUNG: Versionsbeispiel in Typische Anwendungsfälle Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
314 lines
12 KiB
Markdown
314 lines
12 KiB
Markdown
# 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](https://github.com/earendil-works/pi).
|
||
|
||
---
|
||
|
||
## Ü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
|
||
|
||
/optimize = Coder→Judge→Fix-Schleife automatisch (bis PASS oder max. N Runden)
|
||
```
|
||
|
||
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 |
|
||
|--------|---------------------------------------------------|------|------------------|----------------|
|
||
| Coder | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS | 8001 | qwen36-27b-coder | qwen3.5-coder |
|
||
| Judge | Qwen3.6-27B-Uncensored-HauhauCS-Aggressive-IQ4_XS | 8002 | qwen36-27b-judge | qwen3.5-judge |
|
||
|
||
Beide Container verwenden dasselbe GGUF-Datei, aber mit unterschiedlichen
|
||
Serverparametern (Kontext, Temperatur, Parallelität).
|
||
|
||
---
|
||
|
||
## 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
|
||
```
|
||
- Mindestens eine NVIDIA-GPU (empfohlen: zwei GPUs mit je ≥ 16 GB VRAM)
|
||
- 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`
|
||
- [pi agent](https://github.com/earendil-works/pi) installiert (`~/.pi/`)
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
# 1. Repository klonen
|
||
git clone <repo-url> ~/pi_coder
|
||
cd ~/pi_coder
|
||
|
||
# 2. Extension und Modell-Config nach ~/.pi/agent/ deployen
|
||
./install.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`:
|
||
```bash
|
||
./install.sh # kopiert nach ~/.pi/agent/
|
||
# dann /reload in pi agent
|
||
```
|
||
|
||
---
|
||
|
||
## Server starten / stoppen / status
|
||
|
||
```bash
|
||
# 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. 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. |
|
||
| `--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 40` | — | Nur die 40 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 2× 24 GB. |
|
||
| `--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 der übergebenen GPUs) für Nicht-Tensor-Operationen. |
|
||
| `--tensor-split 0.5,0.5` | — | Modell-Gewichte 50/50 auf zwei GPUs aufteilen. |
|
||
| `--gpus '"device=1,2"'` | — | Docker-Argument: GPU 1 und GPU 2 dem Container übergeben. |
|
||
|
||
### 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. |
|
||
|
||
---
|
||
|
||
## Anpassung für eine einzelne GPU
|
||
|
||
Mit einer GPU läuft das Modell vollständig auf dieser GPU statt verteilt.
|
||
Anpassungen in `start-coder.sh` und `start-judge.sh`:
|
||
|
||
```bash
|
||
# Vorher (2 GPUs, device 1 und 2):
|
||
--gpus '"device=1,2"' \
|
||
--main-gpu 0 \
|
||
--tensor-split 0.5,0.5 \
|
||
|
||
# Nachher (1 GPU, z.B. device 0):
|
||
--gpus '"device=0"' \
|
||
--main-gpu 0 \
|
||
# --tensor-split ← diese Zeile komplett entfernen
|
||
```
|
||
|
||
### VRAM-Abschätzung für das 27B IQ4_XS-Modell
|
||
|
||
| Komponente | Größe (ca.) |
|
||
|---|---|
|
||
| Modell-Gewichte (IQ4_XS, 27B) | ~14,5 GB |
|
||
| KV-Cache bei 128K Kontext (q8_0) | ~14 GB |
|
||
| KV-Cache bei 64K Kontext (q8_0) | ~7 GB |
|
||
| KV-Cache bei 32K Kontext (q8_0) | ~3,5 GB |
|
||
|
||
Bei einer **24-GB-GPU** ist nur ein Server gleichzeitig sinnvoll betreibbar:
|
||
- Modell-Gewichte: ~14,5 GB
|
||
- KV-Cache bei 32K Kontext: ~3,5 GB
|
||
- Summe: ~18 GB → passt mit Puffer
|
||
|
||
**Empfehlung für eine 24-GB-GPU:**
|
||
```bash
|
||
# Coder — Kontext reduzieren
|
||
-c 32768 # statt 131072
|
||
-n 8192 # statt 16384
|
||
|
||
# Judge — Kontext reduzieren
|
||
-c 32768 # statt 131072
|
||
```
|
||
|
||
Bei einer **16-GB-GPU** ist die Modellgröße allein schon grenzwertig.
|
||
Entweder ein kleineres Modell verwenden oder die Quantisierung weiter erhöhen (IQ3_XS, Q4_K_M).
|
||
|
||
### Beide Server auf einer GPU betreiben
|
||
|
||
Technisch möglich, aber beide Server laden das Modell gleichzeitig → doppelter VRAM-Bedarf.
|
||
Auf einer 24-GB-GPU daher **nicht empfohlen**. Alternativen:
|
||
|
||
- Nur einen Server gleichzeitig starten (manuell umschalten)
|
||
- Kleinere Quantisierung wählen (IQ3_XS: ~11 GB)
|
||
- `ollama` als Alternative — lädt Modelle bei Bedarf und entlädt sie wieder
|
||
|
||
---
|
||
|
||
## 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 | ~15 GB | 2 × 24-GB-GPU — **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 |
|
||
| `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.sh` | Extension + models.json nach `~/.pi/agent/` kopieren |
|
||
|
||
---
|
||
|
||
## 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]` | beide | Vollautomatische Schleife bis PASS |
|
||
| `/optimize ... [--test-cmd "cmd"] [--test-timeout N]` | beide | Externe Test-Suite im Loop ausführen |
|
||
| `/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:
|
||
|
||
| Situation | Anzeige |
|
||
|---|---|
|
||
| Coder implementiert | `Coder implementiert…` |
|
||
| edit-Tool aktiv | `Editiere src/main.py…` |
|
||
| git commit | `Git-Commit…` |
|
||
| Judge reviewt (Runde 2/3) | `Judge reviewt (Runde 2/3)…` |
|
||
| Tests laufen | `Tests laufen…` |
|
||
| Fix-Phase | `Coder fixt Blocker…` |
|
||
|
||
So ist jederzeit erkennbar, in welcher Phase sich der automatische Loop befindet.
|