Workflows

Claude Code Workflows: Subagents, Code-Review und Debugging

Charles Krzentowski9 min read

Sie haben die Grundlagen drauf. Ihre CLAUDE.md sitzt, die Hooks feuern zuverlässig, Ihre MCP-Server geben Claude direkten Zugriff auf Ihre Tools. Aber Sie arbeiten immer noch mit einem Claude gleichzeitig. Eine Conversation, eine Aufgabe, ein Thread.

Was wäre, wenn Sie fünf gleichzeitig laufen lassen könnten?

Setups mit expliziten Workflow-Mustern und Agent-Definitionen erreichen in unserer Analyse durchschnittlich 7.0/10. Der Unterschied zwischen Gelegenheitsnutzern und Power-Usern ist nicht die Konfiguration — es ist die Art, wie sie ihre Arbeit orchestrieren. Dieses Guide zeigt die Muster, die die besten Ergebnisse liefern.

Subagents: Delegieren wie ein Manager, nicht wie ein Mikromanager

Ein Subagent ist eine separate Claude Code Session, die eine bestimmte Aufgabe bearbeitet. Ihre Hauptsession bleibt fokussiert, während Subagents isolierte Teile parallel erledigen. Stellen Sie es sich vor wie Aufgaben an Teamkollegen verteilen — jeder bekommt ein klares Briefing und liefert ein bestimmtes Ergebnis.

Wann Subagents Sinn machen (und wann nicht)

Gute Subagent-Aufgaben:

  • Unabhängige Teile, die keinen geteilten Kontext brauchen
  • Mehrere Dateien, die Änderungen brauchen, aber nicht voneinander abhängen
  • Erkundungsaufgaben (einen Ansatz recherchieren), während Sie weiter bauen
  • Repetitive Arbeit über ähnliche Dateien (10 API-Routen gleich updaten)

Schlechte Subagent-Aufgaben:

  • Alles, was den vollen Kontext Ihrer laufenden Conversation erfordert
  • Änderungen, bei denen Datei A von dem abhängt, was Sie in Datei B entschieden haben
  • Schnelle Edits, die inline schneller erledigt sind

Die entscheidende Frage: Wenn Sie die Aufgabe einem Kollegen mit nur einem schriftlichen Briefing geben könnten — ohne mündlichen Kontext — ist es ein guter Subagent-Kandidat.

Wie man eine Subagent-Aufgabe richtig scoped

Vage Subagent-Aufgaben liefern vage Ergebnisse. "Verbessere die User-API" gibt Claude nichts zum Festhalten. So sieht eine gut gescoped Aufgabe aus:

## Aufgabe: Eingabevalidierung zu User-Endpoints hinzufügen

### Zu ändernde Dateien
- src/api/users/route.ts
- src/api/users/[id]/route.ts

### Zu lesende Dateien (für Kontext)
- src/lib/schemas.ts
- src/types/user.ts

### Anforderungen
- Zod-Validierung zu allen POST/PUT Request Bodies hinzufügen
- 400 mit strukturierten Fehlermeldungen für ungültige Eingaben zurückgeben
- GET oder DELETE Endpoints NICHT ändern
- Datenbankschicht NICHT ändern

### Fertig wenn
- Modifizierte Route-Dateien mit Validierung
- Neue oder aktualisierte Zod-Schemas in src/lib/schemas.ts

Beachten Sie: expliziter Datei-Scope, klare Anforderungen und eine Definition von "fertig". Der Subagent weiß genau, was er anfassen soll, was er in Ruhe lassen soll, und wann er aufhören kann.

Das Director-Muster: Parallele Subagents orchestrieren

Für größere Features können Sie Claude als Regisseur einsetzen — die Arbeit planen und dann Subagents für jedes Stück losschicken:

Sie: "Ich brauche ein Benachrichtigungssystem. Plane die Arbeit und nutze Subagents."

Claude (Director):
1. Planungsphase: Benachrichtigungsschema, API-Endpoints, UI-Komponenten
2. Subagent 1: Datenbankmigration und Prisma-Schema erstellen
3. Subagent 2: API-Endpoints implementieren (GET /notifications, POST /mark-read)
4. Subagent 3: Benachrichtigungs-Bell-Komponente und Dropdown bauen
5. Integration: Alles zusammenfügen und testen

Jeder Subagent bekommt eine abgegrenzte Aufgabe. Die Director-Session kümmert sich um Integration und stellt sicher, dass die Teile zusammenpassen. Dieses Muster funktioniert besonders gut, weil Subagents sauber starten — ohne angesammeltes Kontextgewicht aus einer langen Conversation.

Ich nutze dieses Muster für jedes Feature, das mehr als 3 Dateien betrifft. Fünf parallele Terminals, jedes mit einem Subagent für ein Stück, während die Hauptsession das große Bild behält.

Code Review: der wertvollste tägliche Workflow

Code Review ist einer der stärksten Anwendungsfälle von Claude Code — und einer der am wenigsten genutzten. Statt Ihren eigenen Code zu reviewen (den Ihr Gehirn automatisch als korrekt rationalisiert) oder auf einen Kollegen zu warten, findet Claude Probleme in Sekunden.

Die Fix-First-Methode

Die meisten Review-Tools liefern Ihnen eine Liste von Problemen. Dann müssen Sie jedes einzeln manuell beheben. Das ist umständlich.

Die Fix-First-Methode: Claude behebt mechanische Probleme direkt und fragt Sie nur bei den mehrdeutigen:

## Wie Code reviewen (in Skill oder CLAUDE.md)

1. Zuerst den VOLLSTÄNDIGEN Diff lesen — die komplette Änderung verstehen
2. Mechanische Probleme AUTO-FIXEN:
   - Fehlende Fehlerbehandlung → try/catch hinzufügen
   - Offensichtliche Typfehler → Typ korrigieren
   - Stilbrüche → beheben
3. Mehrdeutige Entscheidungen in EINER Frage bündeln:
   - "Ich habe 3 Design-Entscheidungen zum Bestätigen gefunden: [A], [B], [C]"
4. Nie Probleme anmerken, die im Diff bereits behandelt sind
5. Ausgabe: KRITISCH (muss behoben werden) und INFORMELL (überlegenswert)

Sie wollen keine Liste von 15 Kleinigkeiten, wenn 12 davon automatisch hätten behoben werden können. Die Fix-First-Methode respektiert Ihre Zeit.

Pre-Commit Review in der Praxis

Richten Sie sich einen Shell-Alias für den täglichen Gebrauch ein:

alias ccreview='claude -p "Überprüfe die gestageten Änderungen (git diff --staged). Behebe mechanische Probleme. Markiere alles Kritische."'

Oder als Skill mit mehr Funktionalität:

<!-- .claude/skills/pre-commit-review.md -->
---
name: pre-commit-review
description: Gestagete Änderungen vor dem Commit überprüfen
---

1. `git diff --staged` ausführen
2. Für jede Datei:
   - Fehlerbehandlung: async-Operationen in try/catch?
   - Sicherheit: Hartcodierte Secrets, SQL-Injection, XSS?
   - Typen: `any` das spezifisch sein sollte?
   - Tests: Haben geänderte Funktionen Test-Updates?
3. Mechanische Probleme AUTO-FIXEN
4. KRITISCH (blockiert Commit) und INFORMELL melden
5. Wenn nichts Kritisches: Commit-Message vorschlagen

Tippen Sie /pre-commit-review vor jedem Commit. Claude prüft Ihre Arbeit, fixt die kleinen Sachen und markiert die echten Probleme. Das dauert 15 Sekunden und fängt Dinge, die Sie Freitag um 18 Uhr übersehen würden.

Test-Driven Development: Spezifikation schreiben, Claude implementieren lassen

TDD mit Claude Code funktioniert anders als TDD allein. Sie beschreiben, was eine Funktion tun soll. Claude schreibt den Test. Sie prüfen, ob der Test Ihre Absicht trifft. Dann schreibt Claude den Code, der den Test besteht.

Es funktioniert, weil ein Test eine eindeutige Spezifikation ist. Wenn Sie ein Feature in Worten beschreiben, interpretiert Claude es vielleicht anders als gemeint. Wenn Sie es als Test ausdrücken, ist das erwartete Verhalten explizit — Eingaben, Ausgaben, Grenzfälle.

Die Schleife

1. Sie beschreiben, was die Funktion tun soll
2. Claude schreibt den Test
3. Sie prüfen, ob der Test Ihre Absicht trifft
4. Claude schreibt die Implementierung, die den Test besteht
5. Claude führt den Test aus und bestätigt
6. Wiederholen

Ein konkretes Beispiel: Rate Limiter bauen

Sie: "Ich brauche einen Rate Limiter. 100 Requests pro Minute pro IP.
429 zurückgeben wenn überschritten, mit Retry-After Header. Test zuerst schreiben."

Claude schreibt:

import { describe, it, expect, vi, beforeEach } from 'vitest';
import { createRateLimiter } from './rate-limiter';

describe('Rate Limiter', () => {
  beforeEach(() => {
    vi.useFakeTimers();
  });

  it('should allow requests under the limit', () => {
    const limiter = createRateLimiter({ maxRequests: 100, windowMs: 60000 });
    const result = limiter.check('192.168.1.1');
    expect(result.allowed).toBe(true);
    expect(result.remaining).toBe(99);
  });

  it('should block requests over the limit', () => {
    const limiter = createRateLimiter({ maxRequests: 2, windowMs: 60000 });
    limiter.check('192.168.1.1');
    limiter.check('192.168.1.1');
    const result = limiter.check('192.168.1.1');
    expect(result.allowed).toBe(false);
    expect(result.retryAfter).toBeGreaterThan(0);
  });

  it('should reset after the window expires', () => {
    const limiter = createRateLimiter({ maxRequests: 1, windowMs: 60000 });
    limiter.check('192.168.1.1');
    vi.advanceTimersByTime(61000);
    const result = limiter.check('192.168.1.1');
    expect(result.allowed).toBe(true);
  });

  it('should track IPs independently', () => {
    const limiter = createRateLimiter({ maxRequests: 1, windowMs: 60000 });
    limiter.check('192.168.1.1');
    const result = limiter.check('192.168.1.2');
    expect(result.allowed).toBe(true);
  });
});

Sie lesen den Test. Vier Fälle: unter dem Limit, über dem Limit, Window-Reset, IP-Isolation. Sieht richtig aus. Sie geben grünes Licht, und Claude schreibt die Implementierung, die alle vier Tests besteht. Der Test diente als Vertrag, auf den Sie sich beide geeinigt haben, bevor eine Zeile Produktionscode geschrieben wurde.

Debugging: der systematische Ansatz, der wirklich funktioniert

Debugging mit Claude ist mächtig, aber es kann sich im Kreis drehen, wenn Sie es zulassen. Claude hält mehr Kontext und prüft mehr Hypothesen als Sie — aber es braucht Struktur, um nicht ins Schleudern zu kommen.

Der 7-Schritte-Debugging-Workflow

Schreiben Sie das in Ihre CLAUDE.md oder einen Debugging-Skill:

Beim Debuggen:
1. REPRODUZIEREN — den fehlschlagenden Fall ausführen, exakten Fehler erfassen
2. HYPOTHESEN — 3 mögliche Ursachen auflisten, nach Wahrscheinlichkeit sortiert
3. UNTERSUCHEN — die wahrscheinlichste Ursache zuerst prüfen
4. LOGGEN — Logging an jeder async-Grenze hinzufügen, wenn unklar wo die Ausführung stoppt
5. IDENTIFIZIEREN — die exakte Zeile oder Funktion lokalisieren
6. BEHEBEN — den minimalen Fix anwenden
7. VERIFIZIEREN — den ursprünglichen fehlschlagenden Fall ausführen und bestätigen

Die entscheidende Regel: Schritt 7 nie überspringen. Unsere Daten zeigen, dass 40% der Debugging-Sessions, die schiefgehen, dies tun, weil ein Fix behauptet aber nie verifiziert wurde. "Sollte jetzt funktionieren" ist kein Beweis. Ausführen.

Die Drei-Versuche-Regel

Dieses Muster trennt produktives Debugging von Zeitverschwendung:

Wenn Claude nach drei Versuchen die Ursache nicht gefunden hat, stoppen Sie. Lassen Sie es nicht weiter raten — immer wildere Hypothesen machen das Problem schwieriger zu diagnostizieren. Wählen Sie stattdessen einen von drei Wegen:

Option A: Neue Hypothese. Komplett zurücktreten. Das Problem von Grund auf neu betrachten. Manchmal scheiterte der dritte Versuch, weil der erste die Denkrichtung vergiftet hat.

Option B: Menschliche Überprüfung. Claude zeigt Ihnen alles, was es bisher gefunden hat, und Sie fügen Kontext hinzu. Vielleicht wissen Sie etwas über die Produktionsumgebung oder ein kürzliches Deployment, das Claude nicht kennt.

Option C: Instrumentieren und warten. Umfassendes Logging hinzufügen und das Problem reproduzieren. Die Logs verraten, wo die Ausführung stoppt, statt zu raten.

Im Zweifel: Zuerst Logging hinzufügen

Die produktivsten Debugging-Sessions beginnen damit, Beobachtbarkeit herzustellen, bevor irgendetwas gefixt wird:

// Vorher: Stille Fehler — keine Ahnung wo es bricht
async function processOrder(orderId: string) {
  const order = await db.orders.findUnique({ where: { id: orderId } });
  const payment = await chargePayment(order.amount);
  await db.orders.update({ where: { id: orderId }, data: { status: 'paid' } });
}

// Nachher: Jeder Schritt ist sichtbar
async function processOrder(orderId: string) {
  console.log('[processOrder] start', { orderId });

  const order = await db.orders.findUnique({ where: { id: orderId } });
  console.log('[processOrder] order geladen', { found: !!order, amount: order?.amount });

  if (!order) {
    console.error('[processOrder] order nicht gefunden', { orderId });
    throw new Error(`Order ${orderId} not found`);
  }

  const payment = await chargePayment(order.amount);
  console.log('[processOrder] payment ergebnis', { paymentId: payment.id, status: payment.status });

  await db.orders.update({ where: { id: orderId }, data: { status: 'paid' } });
  console.log('[processOrder] fertig', { orderId });
}

Wenn etwas hängt oder fehlschlägt, verrät die letzte Log-Zeile genau, wo die Ausführung gestoppt hat. Diese Technik spart mehr Debugging-Zeit als jede clevere Analyse.

Prompting-Muster für bessere Ergebnisse

Wie Sie Anweisungen formulieren, macht mehr Unterschied als man denkt. Hier sind die Muster, die konsistent besseren Code produzieren.

Definieren Sie, was "fertig" heißt

Schlecht: "Verbessere die Authentifizierung."

Gut: "Rate-Limiting zum Login-Endpoint hinzufügen. 5 Versuche pro Email pro 15 Minuten. 429 mit Retry-After Header zurückgeben. Tests für Limit und Reset schreiben. Registrierungs-Endpoint nicht anfassen."

Der zweite Prompt hat keine Zweideutigkeit. Claude kann ihn ausführen, ohne eine einzige Rückfrage.

Einschränkungen explizit benennen

- Dateien in src/legacy/ NICHT ändern — dieser Code ist eingefroren
- Der Build muss mit Node 18 bestehen (keine Node 20+ APIs)
- Bundle-Größe unter 200KB halten — mit `npm run analyze` prüfen

Bei 3+ Dateien: Erst den Plan einfordern

Plane, wie du eine Caching-Schicht für API-Antworten implementieren würdest. Zeig mir:
1. Welche Dateien du erstellen oder ändern würdest
2. Die Cache-Invalidierungsstrategie
3. Wie es sich in die bestehende Middleware integriert

Schreib noch keinen Code. Nur den Plan.

Den Plan reviewen, anpassen, dann Claude ausführen lassen. Das fängt strukturelle Fehler ab, bevor sie sich über mehrere Dateien ausbreiten. Einen Plan ändern kostet nichts. Einen halb umgesetzten falschen Ansatz rückgängig zu machen kostet Stunden.

Wie alles zusammenspielt

Ihr Setup gibt Claude Projektwissen. Ihre Automatisierung setzt Standards durch. Ihre Integrationen geben Claude Zugriff auf Ihre Infrastruktur. Workflows bestimmen, wie Claude im Alltag operiert.

Starten Sie mit Pre-Commit Review — das ist der einfachste Gewinn und der, den Sie jeden einzelnen Tag nutzen. Dann probieren Sie beim nächsten Feature, das 4+ Dateien betrifft, Subagents aus. Bewerten Sie Ihr Setup um zu sehen, wo Ihre Workflow-Orchestrierung steht.

Häufig gestellte Fragen

Wie viele Subagents können gleichzeitig laufen?

Das hängt von Ihrer Maschine (RAM, CPU) und API-Rate-Limits ab. Auf einem typischen Entwicklerrechner funktionieren 3-5 gleichzeitige Subagents gut. Jeder ist eine separate Session, die Tokens verbraucht — behalten Sie also Ihren Verbrauch im Auge, wenn Sie nach API-Preisen zahlen.

Sollte ich für alles Subagents verwenden?

Nein. Sie erzeugen Overhead — Kontextwechsel, Session-Erstellung und das Risiko, dass ein Subagent Kontext der Hauptsession vermisst. Eine gute Faustregel: Wenn Sie die Aufgabe einem Kollegen mit nur einem schriftlichen Briefing geben könnten (kein mündlicher Kontext nötig), ist sie ein guter Subagent-Kandidat. Wenn Sie 10 Minuten Erklärung bräuchten, bleibt sie in der Hauptsession.

Was tun, wenn Claudes Fix nicht funktioniert?

Stellen Sie zuerst sicher, dass Claude den Fix tatsächlich verifiziert hat, indem es den fehlschlagenden Test ausgeführt hat. Wenn der Fix wirklich nicht funktioniert, lassen Sie Claude nicht denselben Ansatz erneut versuchen. Sagen Sie: "Dieser Ansatz hat nicht funktioniert — schlage eine andere Ursache vor." Nach drei gescheiterten Versuchen eskalieren: neue Hypothese, menschliche Überprüfung, oder instrumentieren und Daten sammeln.

Kann Claude Code Pair-Programming?

Ja, und es funktioniert am besten mit einer klaren Aufteilung: Sie treffen Architekturentscheidungen, Claude kümmert sich um die Implementierung. Beschreiben Sie auf hoher Ebene, was Sie wollen, lassen Sie Claude den Code vorschlagen, reviewen, iterieren. Das Anti-Pattern ist, Claude Architekturentscheidungen ohne Ihren Input treffen zu lassen — die akkumulieren sich, und wenn Sie eine falsche Abzweigung bemerken, hat Claude bereits drei Schichten darauf gebaut.

Wie gehe ich mit großen Refactorings um?

Aufteilen in Phasen, ein Subagent pro Phase. Phase 1: "Alle Vorkommen von OldService in NewService umbenennen." Phase 2: "Alle Aufrufer auf die neue API-Signatur aktualisieren." Phase 3: "Veraltete Methoden entfernen und Tests aktualisieren." Jede Phase ist abgegrenzt und testbar. Die Hauptsession verfolgt den Fortschritt und kümmert sich um die Integration zwischen den Phasen.

FAQ

Wie viele Subagents können gleichzeitig laufen?
Das hängt von Ihrer Maschine (RAM, CPU) und API-Rate-Limits ab. Auf einem typischen Entwicklerrechner funktionieren 3-5 gleichzeitige Subagents gut. Jeder ist eine separate Session, die Tokens verbraucht — behalten Sie also Ihren Verbrauch im Auge, wenn Sie nach API-Preisen zahlen.
Sollte ich für alles Subagents verwenden?
Nein. Sie erzeugen Overhead — Kontextwechsel, Session-Erstellung und das Risiko, dass ein Subagent Kontext der Hauptsession vermisst. Eine gute Faustregel: Wenn Sie die Aufgabe einem Kollegen mit nur einem schriftlichen Briefing geben könnten (kein mündlicher Kontext nötig), ist sie ein guter Subagent-Kandidat. Wenn Sie 10 Minuten Erklärung bräuchten, bleibt sie in der Hauptsession.
Was tun, wenn Claudes Fix nicht funktioniert?
Stellen Sie zuerst sicher, dass Claude den Fix tatsächlich verifiziert hat, indem es den fehlschlagenden Test ausgeführt hat. Wenn der Fix wirklich nicht funktioniert, lassen Sie Claude nicht denselben Ansatz erneut versuchen. Sagen Sie: "Dieser Ansatz hat nicht funktioniert — schlage eine andere Ursache vor." Nach drei gescheiterten Versuchen eskalieren: neue Hypothese, menschliche Überprüfung, oder instrumentieren und Daten sammeln.
Kann Claude Code Pair-Programming?
Ja, und es funktioniert am besten mit einer klaren Aufteilung: Sie treffen Architekturentscheidungen, Claude kümmert sich um die Implementierung. Beschreiben Sie auf hoher Ebene, was Sie wollen, lassen Sie Claude den Code vorschlagen, reviewen, iterieren. Das Anti-Pattern ist, Claude Architekturentscheidungen ohne Ihren Input treffen zu lassen — die akkumulieren sich, und wenn Sie eine falsche Abzweigung bemerken, hat Claude bereits drei Schichten darauf gebaut.
Wie gehe ich mit großen Refactorings um?
Aufteilen in Phasen, ein Subagent pro Phase. Phase 1: "Alle Vorkommen von OldService in NewService umbenennen." Phase 2: "Alle Aufrufer auf die neue API-Signatur aktualisieren." Phase 3: "Veraltete Methoden entfernen und Tests aktualisieren." Jede Phase ist abgegrenzt und testbar. Die Hauptsession verfolgt den Fortschritt und kümmert sich um die Integration zwischen den Phasen.