So baust du einen autonomen Coding-Agenten mit OpenClaw: PR-Reviews, Tests, Bug-Fixes
Warum ein dedizierter Coding-Agent?
Wenn man anfängt, mit KI-Agenten zu arbeiten, ist die erste Versuchung: den Teamlead-Agenten alles machen zu lassen. Sam schreibt den Blog, reviewt Code, antwortet auf E-Mails, und managed nebenbei noch den CI/CD-Pipeline.
Das funktioniert — bis der Kontext explodiert. Ein Agent, der gleichzeitig über Marketing-Strategie und Race Conditions in TypeScript nachdenkt, macht beides mittelmäßig.
Die Lösung: Spezialisierung. Peter ist unser Coding-Agent. Er macht nichts anderes als Code-Arbeit. Kein Blog, keine E-Mails, keine Kalender. Nur:
Das klingt nach einem engen Scope — und das ist genau der Punkt. Ein enger Scope bedeutet tiefes Kontextwissen und konsistente Qualität.
---
Das Skill-Setup: coding-agent
Peter läuft mit dem `coding-agent`-Skill, der in OpenClaw mitgeliefert wird. Dieser Skill gibt dem Agenten Zugriff auf:
Installation und Aktivierung:
```bash
# Skill ist bereits in OpenClaw enthalten
ls ~/.npm-global/lib/node_modules/openclaw/skills/coding-agent/
# Im Workspace des Coding-Agenten aktivieren:
# In Peters SOUL.md / AGENTS.md:
# "Skill: coding-agent ist aktiv. Nutze ihn für alle Code-Operationen."
# Alternativ: In der OpenClaw-Konfiguration explizit angeben
openclaw config set skills.enabled "coding-agent"
```
Das `coding-agent`-Skill unterscheidet sich von anderen Skills dadurch, dass es aktiv Code ausführen kann — nicht nur lesen. Das macht es mächtig, aber auch sicherheitsrelevant. Dazu später mehr.
---
Peters SOUL.md: Präzision über alles
Peters SOUL.md ist die kürzeste unserer 6 Agenten — aber die konkreteste. Jede Zeile ist operational:
```markdown
# SOUL.md — Peter (Coding Agent)
Identität
Du bist Peter, Coding-Spezialist bei Humanizing Technologies.
Deine einzige Aufgabe: Code-Qualität. Kein Marketing, keine E-Mails, kein CEO-Support.
Du bist kein Co-Pilot — du bist ein unabhängiger Reviewer mit eigenem Urteil.
Kommunikation
Kurz und technisch. Kein "Ich würde vorschlagen..." — nur "Problem: X. Lösung: Y."
Befunde als Liste, priorisiert nach Schwere: CRITICAL → HIGH → MEDIUM → LOW.
Code-Beispiele immer in Codeblöcken, mit Sprach-Tag.
Dev-Regeln (absolut, keine Ausnahmen)
Was du TUN kannst
Was du NICHT tun darfst (absolut)
```
Die letzte Sektion — "Was du NICHT tun darfst" — ist entscheidend. Ohne diese Grenzen könnte Peter versehentlich direkt auf main pushen. Das ist kein hypothetisches Szenario.
---
GitHub-Integration: PR-Reviews automatisch triggern
Das interessanteste Use-Case: Peter reviewed Pull Requests, sobald sie erstellt werden — ohne manuellen Trigger.
Ansatz 1: Cron-basiertes Polling (einfach)
Peters Cron-Job prüft alle 15 Minuten, ob neue PRs auf GitHub offen sind:
```
Zeitplan: */15 * * * *
Prompt:
Prüfe neue Pull Requests im Repository humanizing/humanizing-agents-monorepo
die in den letzten 15 Minuten erstellt wurden und noch kein Review von Peter haben.
Für jeden solchen PR:
1. Hole den diff mit git fetch origin pull/<PR-ID>/head:pr-<PR-ID>
2. Analysiere den Code auf:
- Security-Probleme (SQL Injection, XSS, unsichere Dependencies)
- Fehlende Fehlerbehandlung
- TypeScript-Typ-Fehler oder any-Verwendung
- Fehlende oder unzureichende Tests
- Verletzungen unserer Dev-Regeln (npm statt bun, console.log, etc.)
3. Poste das Review als GitHub-Kommentar mit Priorisierung (CRITICAL/HIGH/MEDIUM/LOW)
4. Wenn CRITICAL-Probleme: Request Changes. Sonst: Comment.
5. Schreibe das Review-Ergebnis in status/pr-<PR-ID>.md
Wenn keine neuen PRs: HEARTBEAT_OK
```
Ansatz 2: Webhook-basiert (reaktiv, präziser)
Für schnellere Reaktion nutzen wir GitHub Webhooks. Ein Webhook feuert bei PR-Events und schickt eine Nachricht an Peters Discord-Kanal:
```bash
# GitHub Repository → Settings → Webhooks → Add webhook
# Payload URL: https://dein-webhook-relay.example.com/github
# Content type: application/json
# Events: Pull requests
```
Der Webhook-Relay (ein einfacher Express-Server) transformiert das GitHub-Event in eine Discord-Nachricht:
```javascript
// webhook-relay/index.js
app.post('/github', (req, res) => {
const event = req.headers['x-github-event'];
const payload = req.body;
if (event === 'pull_request' && payload.action === 'opened') {
const pr = payload.pull_request;
// Discord-Nachricht an Peters Kanal
sendDiscord({
channel: 'dev-code-review',
content: `@Peter Neuer PR: "${pr.title}" von ${pr.user.login}
PR #${pr.number}: ${pr.html_url}
Branch: ${pr.head.ref} → ${pr.base.ref}
Bitte reviewen.`
});
}
res.status(200).send('ok');
});
```
Peter sieht die Discord-Nachricht, liest den PR, und reviewt.
Sicherheitshinweis: Der Webhook-Relay braucht eine öffentliche URL — oder einen internen Relay über Tailscale. Bei uns läuft er auf einem dedizierten Hetzner-Nano-Server (2€/Monat) hinter nginx.
---
Test-Generierung: Der Use-Case, der am meisten Zeit spart
Der nützlichste Workflow für uns ist nicht das PR-Review — es ist die automatische Test-Generierung.
In unserem Monorepo fehlen häufig Tests für neue Utility-Funktionen. Peters Job: wenn ein PR neue Dateien ohne entsprechende Test-Dateien enthält, schreibt er die Tests.
```
Prompt (als Erweiterung des PR-Review-Prompts):
Falls der PR neue TypeScript-Dateien enthält, die noch keine Test-Datei haben
(Konvention: *.test.ts neben der Quelldatei):
1. Analysiere die exportierten Funktionen/Klassen
2. Schreibe Bun-Tests für die wichtigsten Pfade:
- Happy path (normale Eingabe, erwartete Ausgabe)
- Edge cases (leere Eingabe, null/undefined, Grenzwerte)
- Fehler-Szenarien (ungültige Eingabe, fehlende Dependencies)
3. Erstelle die Test-Datei direkt im Verzeichnis der Quelldatei
4. Führe die Tests aus: bun test <pfad>
5. Falls Tests fehlschlagen: Fehler analysieren und Tests korrigieren
6. Poste die Test-Datei als Vorschlag im PR-Kommentar
```
Das Ergebnis: PR-Ersteller bekommen nicht nur Feedback zum Code, sondern auch einen Testvorschlag. In der Praxis werden ~70% dieser Tests unverändert übernommen.
Zeitersparnis pro PR: ~45 Minuten Entwicklerzeit (Tests schreiben + iterieren).
---
Bug-Diagnose: Log-Analyse auf Abruf
Ein weiterer Peter-Workflow: Bug-Reports aus Logs.
Wenn ein Staging-Server-Fehler auftritt, schickt Dimitrios eine Nachricht an Peters Discord-Kanal:
```
Dimitrios: "@Peter Fehler auf staging seit 14:30: [paste Stacktrace]"
```
Peter:
```
1. Stacktrace analysieren: Welche Datei, welche Zeile?
2. git blame der betroffenen Zeile: Wer hat das zuletzt geändert?
3. git log -20 --oneline: Welche PRs wurden heute gemerged?
4. Korrelation: Welcher PR könnte den Bug verursacht haben?
5. Hypothese formulieren: "Wahrscheinliche Ursache: PR #182 (merged 14:12)
hat die Fehlerbehandlung in getUserById entfernt."
6. Fix-Vorschlag als Code-Snippet
7. ClickUp-Task erstellen: "Bug TC-XX: [Beschreibung], Ursache PR #182"
```
Das dauert in der Praxis 3-8 Minuten statt 20-40 Minuten manuell.
---
Sicherheit: Was Peter wirklich tun kann
Das ist der kritischste Aspekt eines Coding-Agenten. Peter hat Shell-Zugriff und kann Code ausführen — das ist by design. Aber ohne Grenzen ist das gefährlich.
Container-Isolation als harte Grenze
Peter läuft in einem Docker-Container. Sein Volume mountet nur das Projekt-Verzeichnis:
```yaml
# docker-compose.yml
services:
peter:
image: openclaw/openclaw:latest
volumes:
- ./workspaces/peter:/workspace:rw
- /home/sam/projects/humanizing-agents-monorepo:/project:rw
# Kein Zugriff auf andere Projekte, kein Zugriff auf /etc, /home, etc.
environment:
- GITHUB_TOKEN=${GITHUB_TOKEN_PETER}
# Peter hat seinen eigenen, eingeschränkten GitHub-Token (nur read + PR-Comment)
```
Peters GitHub-Token hat nur diese Berechtigungen:
Er kann nicht pushen, nicht mergen, nicht Branches löschen. Selbst wenn jemand Peters Prompt manipuliert — der Token hat die Berechtigungen nicht.
Das "Kein Push"-Prinzip
In Peters SOUL.md steht "git push — niemals direkt pushen". Aber Instruktionen können umgangen werden.
Unsere technische Sicherung: Git-Hooks im Projekt-Repository:
```bash
# .git/hooks/pre-push
#!/bin/bash
# Prüft ob der pushende Nutzer Peter ist
if [ "$GIT_AUTHOR_NAME" = "Peter-CodingAgent" ]; then
echo "BLOCKED: Coding agent is not allowed to push directly"
exit 1
fi
exit 0
```
Zwei Schutzebenen: Instruktion (SOUL.md) + technische Sperre (Git Hook). Beide müssen gleichzeitig versagen, damit ein direkter Push passiert.
---
Peters Tages-Workflow in der Praxis
Zur Illustration: was Peter in einem typischen Tag bei uns tut.
09:00 Uhr — erster Cron-Check:
Drei offene PRs seit gestern Abend. Peter reviewed alle drei. PR #201: kein CRITICAL, zwei HIGH (fehlende Input-Validierung). PR #202: CRITICAL (SQL-String-Konkatenation ohne Escaping). PR #203: Tests fehlen — Peter schreibt sie.
11:00 Uhr — Slack-Ticket von Dimitrios:
"Peter, staging wirft 500er seit dem Deploy." Peter analysiert die Logs, identifiziert den Commit, postet Fix-Vorschlag innerhalb von 5 Minuten.
14:00 Uhr — Dependency-Cron:
Peter führt `bun outdated` aus, vergleicht mit Changelogs, identifiziert einen Breaking Change in der nächsten Major-Version von einer Core-Library. Erstellt ClickUp-Task mit Migrationshinweis.
17:00 Uhr — letzter PR des Tages:
Ein Junior-Entwickler hat drei `any`-Typen in TypeScript verwendet. Peter kommentiert mit erklärtem Typ-Fix-Vorschlag.
Gesamte menschliche Code-Review-Zeit des Teams an diesem Tag: ~30 Minuten (nur für finale Entscheidungen). Peters Beitrag: ~3 Stunden äquivalente Review-Arbeit.
---
Was nicht funktioniert (und warum)
Ehrlichkeit: Ein Coding-Agent ist kein Entwickler-Ersatz.
Peter ist schlecht bei:
Peter ist gut bei:
Die Regel: Je strukturierter die Aufgabe, desto besser Peter. Je mehr Kontext und Urteilsvermögen nötig, desto mehr muss ein Mensch ran.
---
Das vollständige Setup
Die vollständige Konfiguration für Peter — Docker-Compose, SOUL.md, GitHub-Token-Setup mit minimalen Berechtigungen, die exakten Cron-Job-Prompts und die Git-Hook-Sicherung — ist im OpenClaw Setup Playbook dokumentiert.
Das Playbook zeigt nicht nur das Setup, sondern auch die Iteration: Wie wir Peters Prompts über Wochen verfeinert haben, welche Review-Kommentare zu vage waren und wie wir das verbessert haben.
18 Kapitel, basierend auf echten Produktionserfahrungen.
Komplett auf Deutsch verfügbar. 🇩🇪