pi_coder/BEDIENUNGSANLEITUNG.md

678 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bedienungsanleitung: pi_coder
pi_coder ist ein Werkzeug, das zwei lokale KI-Modelle als **Coder** und **Judge** einsetzt,
um Software automatisch zu schreiben, zu prüfen und zu verbessern — alles gesteuert über
einfache Slash-Kommandos in der pi-Agent-Oberfläche.
---
## Inhaltsverzeichnis
1. [Konzept: Coder und Judge](#1-konzept-coder-und-judge)
2. [Vorbereitung](#2-vorbereitung)
3. [Server starten und stoppen](#3-server-starten-und-stoppen)
4. [Neues Projekt anlegen](#4-neues-projekt-anlegen)
5. [Manueller Workflow: /coder → /judge → /fix → /shipit](#5-manueller-workflow)
6. [Automatischer Workflow: /optimize](#6-automatischer-workflow-optimize)
7. [Kleine Änderungen: /patch und /quick_check](#7-kleine-änderungen-patch-und-quick_check)
8. [Dokumentation generieren: /update_doku](#8-dokumentation-generieren-update_doku)
9. [TASK.md verstehen und nutzen](#9-taskmd-verstehen-und-nutzen)
10. [Typische Anwendungsfälle](#10-typische-anwendungsfälle)
11. [Fehlermeldungen und Lösungen](#11-fehlermeldungen-und-lösungen)
---
## 1. Konzept: Coder und Judge
pi_coder verwendet zwei Rollen:
**Coder** (Port 8001): Schreibt und repariert Code. Liest die Aufgabe aus `TASK.md`,
implementiert sie, führt Tests aus und erstellt Git-Commits.
**Judge** (Port 8002): Überprüft den Code mit dem Blick eines skeptischen Senior-Entwicklers.
Prüft Korrektheit, Robustheit, Randfälle, Sicherheit und Produktionsreife. Gibt ein Urteil:
- `PASS` — Code ist in Ordnung
- `PASS WITH CONCERNS` — grundsätzlich akzeptabel, aber mit Anmerkungen
- `FAIL` — enthält Blocker, die behoben werden müssen
Der Grundgedanke: Coder und Judge haben keine „Höflichkeitsschranke" zueinander —
der Judge kritisiert direkt und konkret, der Coder repariert ohne Widerspruch.
---
## 2. Vorbereitung
### Server starten
```bash
cd ~/pi_coder
./start-servers.sh
```
Ausgabe bei Erfolg:
```
[*] Starte beide Server parallel ...
[✓] Coder (:8001) bereit
[✓] Judge (:8002) bereit
```
Dauer: 13 Minuten (Modell wird in GPU-VRAM geladen).
### Status prüfen
```bash
./status.sh
```
```
=== LLaMA-Server Status ===
qwen36-27b-coder (Port 8001): Container=RUNNING HTTP=OK
qwen36-27b-judge (Port 8002): Container=RUNNING HTTP=OK
```
### pi agent öffnen
pi agent im Projektverzeichnis starten — das ist das Verzeichnis, in dem dein Code liegt,
**nicht** `~/pi_coder`:
```bash
cd ~/MeinProjekt
pi
```
---
## 3. Server starten und stoppen
### Beide starten (empfohlen)
```bash
./start-servers.sh
```
### Einzelnen Server neu starten
Z.B. wenn nur der Coder-Server abgestürzt ist:
```bash
./start-coder.sh
```
### Beide stoppen
```bash
./stop-servers.sh
```
### Alternativer Modellpfad
Falls die GGUF-Datei an einem anderen Ort liegt:
```bash
HF_HOME=/mnt/daten/huggingface ./start-servers.sh
```
---
## 4. Neues Projekt anlegen
### Kommando
```
/new_project <pfad>
```
### Beispiel
```
/new_project ~/Python_Programs/mein_tool
```
Was passiert:
- Verzeichnis `~/Python_Programs/mein_tool` wird angelegt
- `git init` wird ausgeführt
- `.gitignore` wird mit Standardeinträgen angelegt und committed
**Wichtig:** pi agent wechselt **nicht automatisch** in das neue Verzeichnis —
die Session bleibt im aktuellen Verzeichnis. Nach dem Anlegen:
```bash
cd ~/Python_Programs/mein_tool
pi
```
Dann kannst du `/coder` oder `/optimize` mit dem neuen Projekt verwenden.
---
## 5. Manueller Workflow
Der manuelle Workflow gibt dir volle Kontrolle über jeden Schritt.
### Schritt 1: /coder — Aufgabe übergeben
```
/coder <auftrag>
```
Der Coder:
1. Legt `TASK.md` im aktuellen Verzeichnis an (oder hängt an bestehende an)
2. Liest `TASK.md` und implementiert den Auftrag
3. Führt Tests oder Build-Checks aus
4. Erstellt einen Git-Commit
**Beispiel:**
```
/coder Schreibe ein Python-Kommandozeilenprogramm 'textcount'. Es soll eine Textdatei als Argument nehmen und folgendes ausgeben: Anzahl Zeichen, Wörter, Zeilen und die 5 häufigsten Wörter (ohne Stoppwörter).
```
Typische Ausgabe des Coders:
```
Implementierung abgeschlossen.
- src/textcount.py erstellt (Hauptprogramm)
- tests/test_textcount.py erstellt (Unit-Tests)
- requirements.txt angelegt (keine externen Abhängigkeiten)
- Alle 8 Tests bestanden
- Commit: feat: implement textcount CLI tool
Risiken: Stoppwortliste nur Deutsch/Englisch, keine Konfigurations-Option.
```
### Schritt 2: /judge — Code überprüfen lassen
```
/judge
```
Optionaler Fokus:
```
/judge Besonderes Augenmerk auf Fehlerbehandlung und Edge Cases
```
Der Judge:
1. Liest `TASK.md` und prüft ob alle Anforderungen umgesetzt sind
2. Analysiert `git show HEAD`
3. Führt Tests aus
4. Gibt ein strukturiertes Urteil aus
**Beispiel-Ausgabe PASS:**
```
Urteil: PASS WITH CONCERNS
Blocker: keine
Major:
- Stoppwortliste ist hardcoded; große Projekte erwarten --stopwords-file Option
Minor:
- Keine --version Flag
- Fehlermeldung bei nicht-existenter Datei gibt keinen Exit-Code 1 zurück
Fehlende Tests:
- Test für leere Datei fehlt
- Test für Datei mit nur Leerzeichen fehlt
Produktionsrisiken:
- Bei sehr großen Dateien (>1 GB) wird alles in den RAM geladen
Konkrete Fix-Aufträge:
1. exit(1) bei FileNotFoundError
2. Test für leere Eingabedatei
```
**Beispiel-Ausgabe FAIL:**
```
Urteil: FAIL
Blocker:
- textcount.py importiert 'collections.Counter' aber das ist nicht installiert
(Counter ist stdlib, aber der Import-Fehler tritt bei Python < 3.9 auf)
- ./textcount.py existiert nicht — tests/test_textcount.py schlägt komplett fehl
Major: ...
```
### Schritt 3: /fix — Kritik beheben
```
/fix
```
Optionaler Hinweis:
```
/fix Den Major-Punkt mit der Stoppwortliste kannst du weglassen, das ist kein Produktionsprojekt
```
Der Coder arbeitet die Judge-Kritik ab (Blocker zuerst, dann Major, dann Minor)
und erstellt einen neuen Commit.
### Schritt 4: /shipit — Finale Freigabe
```
/shipit
```
Der Judge gibt ein finales Urteil:
- `SHIP` — bereit für Produktion
- `NO-SHIP` — noch Probleme offen
**Beispiel:**
```
Urteil: SHIP
Letzte Blocker: keine
Restrisiken:
- Kein Streaming für sehr große Dateien (dokumentiert in README)
Empfohlene Sofortmaßnahmen: keine
```
---
## 6. Automatischer Workflow: /optimize
`/optimize` führt den gesamten Coder→Judge→Fix-Zyklus automatisch durch.
### Syntax
```
/optimize <auftrag> [--rounds N] [--with-doku]
```
- `--rounds N` — maximale Anzahl Runden (Standard: 3)
- `--with-doku` — nach SHIP automatisch `/update_doku` ausführen
### Beispiel: einfacher Auftrag
```
/optimize Schreibe ein Rust-Programm 'genpw' das sichere Passwörter generiert. Optionen: --length N (Standard 16), --count N (Standard 1), --no-symbols, --no-numbers.
```
Was im Hintergrund passiert:
```
Phase 1: Coder implementiert...
Phase 2: Runde 1/3: Judge prüft...
→ Urteil: FAIL (2 Blocker)
Phase 3: Runde 1/3: Coder fixt...
Phase 4: Runde 2/3: Judge prüft...
→ Urteil: PASS WITH CONCERNS
✓ PASS WITH CONCERNS nach Runde 2
Finale ShipIt-Prüfung...
→ SHIP
```
### Beispiel: mehr Runden
```
/optimize Implementiere einen vollständigen REST-API-Client für die GitHub API in Python mit Rate-Limiting, Retry-Logic und Caching --rounds 5
```
### Beispiel: mit automatischer Dokumentation
```
/optimize Schreibe ein Go-Tool 'logfilter' das Logdateien nach Regex-Muster filtert --with-doku
```
Nach SHIP werden automatisch ausgeführt:
1. Code-Kommentare einfügen
2. README.md schreiben
3. BEDIENUNGSANLEITUNG.md schreiben
### Loop-Erkennung
Wenn zweimal hintereinander genau dieselben Blocker auftreten, bricht `/optimize` ab:
```
⚠ Derselbe Blocker tritt erneut auf Schleife abgebrochen. Bitte manuell prüfen.
```
In diesem Fall: `/judge` manuell ausführen, Blocker lesen, mit `/fix` manuell eingreifen.
### Max. Runden ohne PASS
```
⚠ 3 Runden durchlaufen ohne PASS. Bitte manuell prüfen.
```
Dann: `/judge` und `/fix` manuell für gezielte Eingriffe.
---
## 7. Kleine Änderungen: /patch und /quick_check
Für minimale Korrekturen — kein voller Review-Zyklus, keine TASK.md-Änderungen.
### /patch — kleine Änderung umsetzen
```
/patch <beschreibung der änderung>
```
Der Coder ändert **ausschließlich** das Beschriebene, prüft ob es noch kompiliert/startet
und erstellt einen Commit.
**Beispiele:**
```
/patch Mindestpasswortlänge von 4 auf 8 Zeichen erhöhen
```
```
/patch Fehlermeldung bei ungültigem Argument von stderr auf stdout umleiten
```
```
/patch Versionsnummer in Cargo.toml von 0.1.0 auf 0.2.0 erhöhen
```
```
/patch Die Funktion parse_args() soll bei fehlendem --input-Argument eine sinnvolle Hilfsnachricht ausgeben statt zu paniken
```
### /quick_check — Änderung schnell prüfen lassen
```
/quick_check [was geprüft werden soll]
```
Der Judge schaut sich `git show HEAD` an und gibt nur `OK` oder `PROBLEM` zurück.
**Beispiele:**
```
/quick_check
```
```
/quick_check Prüfe ob die Mindestlängen-Änderung korrekt umgesetzt ist und keine Randfälle fehlen
```
**Typische Ausgaben:**
```
Urteil: OK
Die Änderung in src/main.rs Zeile 47 ist korrekt. Mindestlänge wird jetzt
sowohl bei --length als auch im Standardfall geprüft.
```
```
Urteil: PROBLEM
src/lib.rs Zeile 23: Der neue Mindestwert von 8 wird nur bei --length geprüft,
nicht beim Standardwert (16). Wenn jemand --length 6 übergibt, schlägt die
Validierung korrekt fehl, aber der Standardfall ist nicht abgedeckt.
Fix: Validierung in die Funktion generate_password() verschieben statt in parse_args().
```
### Typischer /patch + /quick_check Workflow
```
/patch Timeout bei HTTP-Requests von 30 auf 10 Sekunden setzen
```
*(Coder ändert, committet)*
```
/quick_check Prüfe ob der Timeout auch bei Retry-Versuchen korrekt gilt
```
*(Judge gibt OK oder zeigt konkretes Problem)*
---
## 8. Dokumentation generieren: /update_doku
Nach Abschluss der Entwicklung (nach `/shipit` oder `/optimize`) erstellt `/update_doku`
drei Dinge automatisch:
1. **Code-Kommentare** — erklärt das WARUM in den Quelldateien (Deutsch)
2. **README.md** — Entwicklerperspektive: Installation, Build, Verwendung
3. **BEDIENUNGSANLEITUNG.md** — Endnutzerperspektive: einfach, ohne Jargon
```
/update_doku
```
### Inkrementelles Update
`/update_doku` merkt sich via Git-Tags welche Dateien seit dem letzten Lauf geändert wurden.
Nur geänderte Quelldateien werden neu kommentiert — unveränderte bleiben unangetastet.
```
Code-Kommentare: keine Änderungen seit letztem Lauf übersprungen.
README.md: 2 Datei(en) geändert wird geprüft
BEDIENUNGSANLEITUNG.md: 2 Datei(en) geändert wird geprüft
```
### Zusammen mit /optimize
```
/optimize Implementiere Feature X --with-doku
```
Führt nach SHIP automatisch `/update_doku` aus.
---
## 9. TASK.md verstehen und nutzen
`TASK.md` ist die persistente Aufgabenbeschreibung im Projektverzeichnis. Sie wird von
allen Kommandos als Referenz gelesen.
### Erstellt von /coder und /optimize
Beim ersten `/coder`-Aufruf:
```markdown
# Aufgabe
Schreibe ein Python-Kommandozeilenprogramm 'textcount'...
## Erstellt
2026-05-19T14:30:00.000Z
## Status
- [ ] Implementierung
- [x] Review bestanden (PASS)
- [ ] Produktionsreif (SHIP)
```
### Zusatzauftrag hinzufügen
Wenn du später `/coder` mit einer neuen Aufgabe aufrufst, wird TASK.md erweitert statt überschrieben:
```
/coder Füge zusätzlich eine --csv-Option hinzu, die das Ergebnis als CSV ausgibt
```
```markdown
# Aufgabe
[...ursprüngliche Aufgabe...]
---
## Zusatzauftrag
2026-05-19T15:45:00.000Z
Füge zusätzlich eine --csv-Option hinzu...
## Status
- [ ] Implementierung
- [ ] Review bestanden (PASS)
- [ ] Produktionsreif (SHIP)
```
### Status-Checkboxen
Die Checkboxen werden automatisch abgehakt:
- `[x] Implementierung` — nach erfolgreichem `/coder` oder `Phase 1` von `/optimize`
- `[x] Review bestanden (PASS)` — nach PASS durch `/judge` oder in `/optimize`
- `[x] Produktionsreif (SHIP)` — nach SHIP durch `/shipit` oder `/update_doku`
---
## 10. Typische Anwendungsfälle
### Neues Rust-Programm von Null
```bash
# 1. Verzeichnis anlegen
/new_project ~/Rust_Programs/mein_tool
# 2. Terminal: in Verzeichnis wechseln und pi neu starten
# cd ~/Rust_Programs/mein_tool && pi
# 3. In pi: vollautomatisch implementieren + dokumentieren
/optimize Schreibe ein Rust-CLI-Tool 'csvfilter' das CSV-Dateien zeilenweise filtert. Optionen: --column NAME, --value WERT, --regex. Ausgabe auf stdout. --with-doku
```
### Bestehendes Projekt verbessern
```bash
# In pi, im Projektverzeichnis:
/coder Refaktoriere die Datenbankschicht: ersetze das raw-SQL durch sqlx mit typsicheren Queries. Alle Tests müssen danach noch laufen.
/judge
/fix
/shipit
```
### Schnelle Bugfixes
```bash
/patch Die Funktion split_csv() schlägt bei Feldern mit eingebetteten Kommas fehl (RFC 4180 nicht implementiert)
/quick_check
```
### Kommentarlosen Legacy-Code dokumentieren
```bash
# Nur Kommentare und Dokumentation, kein Code ändern:
/update_doku
```
### Schrittweise mit manuellem Review
```bash
/coder Implementiere OAuth2-Login mit GitHub
# → Code lesen, verstehen
/judge Besonderes Augenmerk auf Token-Speicherung und CSRF-Schutz
# → Judge-Bericht lesen
/fix Ignoriere den Minor-Punkt mit der Logging-Verbosität, das ist Absicht
/shipit
```
### Experiment: mehrere Runden explizit
```bash
/optimize Schreibe einen vollständigen Markdown-Parser mit AST in Python --rounds 5
```
---
## 11. Fehlermeldungen und Lösungen
### "Modell-Datei nicht gefunden"
```
[!] Modell-Datei nicht gefunden: /home/.../models/qwen3/Qwen3.6-27B-Uncensored-...gguf
```
**Ursache:** Die GGUF-Datei liegt nicht am erwarteten Ort.
**Lösung:**
```bash
# Pfad prüfen:
ls $HF_HOME/models/qwen3/
# Oder mit explizitem Pfad starten:
HF_HOME=/korrekter/pfad ./start-servers.sh
```
### Server startet nicht / HTTP nicht erreichbar
```
[!] HTTP-Server wurde nicht rechtzeitig erreichbar.
```
**Ursachen und Lösungen:**
1. Zu wenig VRAM — Container bricht beim Laden ab:
```bash
docker logs qwen36-27b-coder | tail -50
# Suche nach: "CUDA out of memory" oder "failed to allocate"
```
→ Kontext reduzieren: `-c 32768` statt `-c 131072`
2. GPU nicht verfügbar:
```bash
nvidia-smi # GPUs sichtbar?
docker run --gpus '"device=1,2"' --rm nvidia/cuda:12.0-base nvidia-smi
```
3. Port bereits belegt:
```bash
ss -tlnp | grep 800[12]
docker ps -a # alter Container noch vorhanden?
./stop-servers.sh
./start-servers.sh
```
### "Agent is already processing a prompt"
**Ursache:** Ein Kommando wurde aufgerufen während pi agent noch auf eine Antwort wartet.
**Lösung:** Warten bis die aktuelle Antwort fertig ist, dann das Kommando wiederholen.
Bei `/optimize` passiert das automatisch — der interne Mechanismus wartet auf `idle`.
### "edits[n] ... oldText must match exactly"
**Ursache:** Der interne pi-agent-Edit-Mechanismus hat beim Anwenden mehrerer Änderungen
an derselben Datei versagt.
**Was pi_coder dagegen tut:** Ein `tool_call`-Hook in der Extension sortiert
Mehrfach-Edits automatisch von hinten nach vorne (Bottom-up-Reordering), sodass
frühere Edits spätere Positionen nicht verschieben. Zusätzlich steht das `apply_patch`-Tool
bereit, das GNU `patch -p1` mit Fuzzy-Matching nutzt.
**Falls es trotzdem auftritt:** Das Modell manuell anweisen:
```
Lies die Datei neu ein und wende die Änderungen als unified diff mit apply_patch an.
```
### "Drei Runden ohne PASS" / Loop-Erkennung schlägt an
```
⚠ Derselbe Blocker tritt erneut auf Schleife abgebrochen.
```
**Ursache:** Der Coder kann einen bestimmten Blocker nicht beheben — z.B. weil die
Aufgabe einen Widerspruch enthält oder ein externes System fehlt.
**Lösung:** Manuell eingreifen:
```
/judge ← Judge-Bericht lesen
```
Dann den Blocker analysieren und entweder:
- `/fix Ignoriere Blocker X, das ist nicht Teil dieser Aufgabe`
- Den Code selbst anpassen und dann `/fix` aufrufen
- Die Aufgabe in TASK.md präzisieren
### Server läuft, aber pi wechselt nicht das Modell
**Ursache:** `models.json` wurde nach einer Änderung nicht neu deployt.
**Lösung:**
```bash
cd ~/pi_coder
./install.sh
# Dann /reload in pi agent
```
### "Neues Projekt" wechselt nicht das Verzeichnis
Das ist gewollt — pi-Sessions sind an ihr Startverzeichnis gebunden.
Nach `/new_project <pfad>` im Terminal:
```bash
cd <pfad>
pi
```