Statt modell-spezifischer Namen (qwen3.5-single, qwen36-27b-single) wird überall der semantisch neutrale Bezeichner coding_model verwendet. Dadurch kann das Modell bei Bedarf ausgetauscht werden, ohne Konfiguration, Skripte oder Tests anpassen zu müssen. Geändert: models.json, settings.json, start-single.sh, stop-servers.sh, status.sh, pi-coder-judge-extension.ts, tests/, README.md, BEDIENUNGSANLEITUNG.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
314 lines
12 KiB
Markdown
314 lines
12 KiB
Markdown
# 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 <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) |
|
||
| `/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 <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**.
|
||
|
||
---
|
||
|
||
## 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.
|