Der Workflow in Action – Vom vagen Wunsch bis zum fertigen Commit

Ein konkreter Walkthrough durch alle fünf Phasen des Agenten-Teams – vom ersten vagen Feature-Wunsch bis zum getesteten Commit. Inklusive der echten Handoffs, der Checkpoints und des Moments, in dem ich den Agenten korrigieren musste.

15.06.2026

15 Min. Lesezeit

Hinweis zum Inhalt

Diese Beitragsreihe beschreibt meine Erkenntnisse beim Einsatz von KI im Softwareentwicklungsprozess. Das sind persönliche Erfahrungen und Erkenntnisse, von denen ich Maßnahmen abgeleitet habe, die für meine Projekte funktionierten. Diese Serie hat nicht den Anspruch, eine umfassende Anleitung oder allgmeingültig zu sein, sondern eine Inspiration für eure eigenen Projekte.

In den letzten Posts habe ich mein Agenten-Team Stück für Stück vorgestellt: den Business Analysten und den Solution Architect – die beiden Strategen, die keine einzige Zeile produktiven Code schreiben, aber die Grundlage für alles legen, was danach kommt. Den Realisierungsplan-Agenten und den Developer-Agenten – die Macher, die aus dieser Grundlage eine fertige Implementierung machen. Und im vorherigen Post den E2E-Test-Agenten – den Prüfer, der am Ende beweist, dass das Ergebnis tatsächlich tut, was am Anfang gefordert war.

Beide Posts haben dasselbe Ziel verfolgt: erklären, warum dieser Ansatz funktioniert, welche Probleme er löst und wo seine Grenzen liegen. Die Theorie steht. Jetzt ist es Zeit, den Vorhang zu lüften.

Dieser Post zeigt, wie der Workflow in der Praxis aussieht – konkret, schrittweise, mit echten Artefakten, echten Korrekturen und dem, was am Ende dabei herauskommt.

Diagramm wird geladen …
Der gesamte Durchlauf der Suchfunktion – fünf Phasen, vier Korrekturen, acht Commits plus E2E-Test.

Der Ausgangspunkt: Ein vager Wunsch

Ich wollte eine Volltextsuche für diesen Blog. Nicht weil ich einen konkreten Plan hatte – sondern weil mich störte, dass man einen bestimmten Post nur über die Navigation oder Tags finden konnte. Die initiale Idee war ungefähr so präzise:

„Ich brauche eine Suchfunktion. Der Nutzer tippt einen Begriff ein, die passenden Posts erscheinen."

Das ist ein typischer Ausgangspunkt: verständlich, aber voller impliziter Annahmen. Was bedeutet „Suchfunktion" in einem statisch generierten Nuxt-Blog? Suche über Titel und Beschreibung oder über den gesamten Content? Live während der Eingabe oder nach Enter? Mit Debouncing? Für beide Sprachen? Auf einer eigenen Seite oder als Dropdown im Header?

Wer direkt promptet, gibt dem Agenten diese Entscheidungen. Er trifft sie – und meistens merkt man erst im fertigen Code, welche er getroffen hat.

Ich habe stattdessen den Business Analysten gerufen.

Phase 1: Der Business Analyst – aus Wunsch wird Use Case

Der Business Analyst hat genau eine Aufgabe: einen vagen Wunsch in ein präzises, strukturiertes Use-Case-Dokument zu verwandeln. Bevor er das tut, stellt er Rückfragen.

In diesem Fall vier:

  1. Soll die Suche live während der Eingabe reagieren oder erst nach einem expliziten Submit?
  2. Welche Inhalte sollen durchsucht werden – Titel und Beschreibung, oder auch der Volltext der Posts?
  3. Soll die Suche sprachübergreifend funktionieren oder separat pro Locale?
  4. Was passiert bei leerem Suchbegriff – leere Ergebnisliste oder alle Posts?

Das sind keine Fragen, die ein Coding-Agent stellt. Der baut einfach – und trifft dabei vier implizite Annahmen, die ich erst in den fertigen Komponenten entdeckt hätte.

Ich habe geantwortet: Live-Suche mit Debouncing, nur Titel und Beschreibung, getrennt pro Locale, leerer Begriff zeigt alle Posts. 90 Sekunden Aufwand meinerseits.

Das Ergebnis ist ein Dokument in docs/usecases/UC-suche.md. Es sieht in seinen wesentlichen Teilen ungefähr so aus:

## Hauptablauf
1. Nutzer gibt Suchbegriff in die Suchleiste ein
2. System wartet 300ms (Debounce)
3. System filtert Posts nach Titel und Beschreibung (case-insensitive)
4. Suchergebnisse erscheinen als Dropdown unterhalb der Suchleiste
5. Nutzer wählt einen Eintrag aus → navigiert zum Post

## Alternativfluss A1: Keine Treffer
- Nach Schritt 3: Keine Ergebnisse gefunden
- System zeigt "Keine Ergebnisse" im Dropdown

## Alternativfluss A2: Leerer Suchbegriff
- Nutzer leert das Feld
- Dropdown schließt sich, alle Posts bleiben unverändert sichtbar

## Fehlerfälle
- F1: Content-Query schlägt fehl → Fehlermeldung im Dropdown, kein App-Crash

Dazu kommen ein Sequenzdiagramm und eine User Journey – beide entstehen automatisch im Use-Case-Dokument:

Diagramm wird geladen …
Sequenzdiagramm der Suchfunktion, wie es der Business Analyst im Use Case ablegt.
Diagramm wird geladen …
User Journey mit Happy Path, Alternativflüssen und Fehlerfall.

Das war Checkpoint 1.

Ich habe das Dokument gelesen. Nicht gescannt – gelesen. Zwei Stellen haben mich gestört. Erstens hatte der Agent einen Alternativfluss für „Suche im aktuellen Post" eingebaut, den ich nie erwähnt hatte. Zweitens hatte er angenommen, dass die Suchergebnisse auf einer eigenen /search-Seite erscheinen.

Beides stimmte nicht. Ich wollte einen Dropdown im Header, keine separate Seite. Der Agent hatte eine plausible, aber falsche Architektur-Annahme getroffen – und sie tief im Use Case verankert. Ich habe das in zwei Sätzen korrigiert, der Agent hat das Dokument überarbeitet.

Zwei Minuten Aufwand. Nicht die zwei Stunden, die es gekostet hätte, dasselbe im fertigen Code zu reparieren.

Phase 2: Der Solution Architect – aus Use Case wird Lösungskonzept

Das korrigierte Use-Case-Dokument geht weiter an den Solution Architect. Seine Aufgabe: die bestehende Codebase analysieren, den Soll-Zustand entwerfen und ein technisches Lösungskonzept unter docs/loesungskonzept/ ablegen.

Der Agent liest das Use-Case-Dokument. Er liest die vorhandenen Composables. Er schaut sich das Content-Schema an. Und er stellt fest, dass der useContent()-Composable bereits eine interne Filtermethode hat, die über den Titel filtert – und dass sie mit minimalem Aufwand auf die Beschreibung erweiterbar wäre, statt eine neue Suchmethode zu bauen.

Das ist genau das Duplikations-Problem aus dem ersten Post dieser Serie, das hier nicht durch Anweisung vermieden wird, sondern durch den Schritt selbst: Der Architect sucht nach existierender Logik, bevor er neue entwirft.

Das Lösungskonzept enthält einen tabellarischen Maßnahmenkatalog mit Dateipfad, Art der Änderung und Aufwandsschätzung. In diesem Fall sechs Maßnahmen:

MaßnahmeDateiArtAufwand
1composables/useContent.tsErweiterung SuchmethodeS
2components/ui/SearchBar.vueNeue KomponenteM
3components/ui/SearchDropdown.vueNeue KomponenteM
4components/AppHeader.vueIntegration SearchBarS
5i18n/locales/de.jsonÜbersetzungsschlüsselXS
6i18n/locales/en.jsonÜbersetzungsschlüsselXS

Dazu kommen ein Klassendiagramm, ein Sequenzdiagramm für den technischen Ablauf und explizite Hinweise auf vorhandene Muster, die wiederverwendet werden sollen.

Das war Checkpoint 2.

Ich habe das Konzept gelesen. Eine Sache habe ich geändert: Der Architect hatte die Debounce-Logik in den Composable gelegt. Ich wollte sie in der Komponente haben – dort lässt sie sich leichter testen und gegebenenfalls für andere Szenarien wiederverwenden, ohne den Composable mit UI-spezifischer Logik zu belasten. Eine Rückmeldung, eine Überarbeitung, das Konzept freigegeben.

Wichtig: Ich habe an dieser Stelle kein einziges Mal Code gelesen. Das Konzept lag auf einem Abstraktionsniveau, das ich vollständig beurteilen konnte – Struktur, Abhängigkeiten, Wiederverwendung – ohne dafür in useContent.ts schauen zu müssen.

Phase 3: Der Realisierungsplan-Agent – aus Konzept wird Schlachtplan

Das freigegebene Lösungskonzept geht weiter an den Realisierungsplan-Agenten. Er nimmt die sechs Maßnahmen und zerlegt sie in acht konkrete Implementierungsschritte unter docs/plan/plan-suche.md.

Jeder Schritt hat eine feste Struktur. Ein Ausschnitt aus dem fertigen Plan:

## Schritt 2: SearchBar.vue erstellen

**Datei:** `components/ui/SearchBar.vue`

### Aufgaben
- [ ] Neue Komponente mit Input-Feld anlegen
- [ ] Debounce-Logik mit 300ms Verzögerung in der Komponente implementieren
- [ ] `modelValue`-Prop für v-model-Kompatibilität
- [ ] Placeholder-Text über i18n-Schlüssel `search.placeholder` befüllen
- [ ] Fokus-Styles gemäß bestehendem Design-System

### Validierung
`npm run typecheck` → muss grün sein

### Manuelle Verifikation
| Aktion | Erwartetes Ergebnis |
|---|---|
| Dev-Server starten | Keine Build-Fehler |
| SearchBar in Isolation rendern | Input-Feld mit korrektem Placeholder sichtbar |

### Risikoeinschätzung
Keines – neue Komponente ohne bestehende Abhängigkeiten

Die entscheidende Eigenschaft dieses Plans: Nach jedem abgeschlossenen Schritt befindet sich die Anwendung in einem lauffähigen Zustand. Das ist keine Absicht, die ich mir wünsche – es ist eine explizite Anforderung an den Agenten, die er beim Erstellen des Plans einhalten muss. Kein Schritt bricht den Build. Kein Schritt hinterlässt halbfertige Abhängigkeiten.

Das war Checkpoint 3.

Ich habe den Plan gelesen. Zehn Minuten. In Schritt 5 hatte der Agent eine Abhängigkeit falsch eingeordnet: Er setzte voraus, dass SearchBar.vue bereits im Header eingebunden war – aber das war erst in Schritt 6 vorgesehen. Die Reihenfolge war vertauscht, der Build hätte zwischen Schritt 5 und 6 kaputt gelegen.

Ich habe das mitgeteilt, der Agent hat die Schritte getauscht. Dann habe ich den Plan freigegeben.

Phase 4: Der Developer-Agent – aus Plan wird Code

Der Developer-Agent bekommt nicht das Lösungskonzept. Er bekommt nicht den Plan als Ganzes. Er bekommt einen Schritt.

Schritt 1: useContent.ts erweitern.

Der Agent liest die Datei, erweitert die Suchmethode, führt npm run typecheck aus, meldet: grün. Fertig.

Ich schaue mir die Änderungen an. Eine Datei, zwei Methoden, ein neuer optionaler Parameter. Alles wie geplant. Kein zusätzlicher State, keine neue Abhängigkeit, keine Eigeninitiative außerhalb der Aufgabe.

Dann Schritt 2. Dann Schritt 3.

Nach Schritt 4 habe ich kurz eingegriffen: Der Agent hatte das Dropdown mit position: absolute in Inline-Styles umgesetzt, obwohl im Plan explizit das Tailwind-Pattern relative/absolute stand. Kein funktionaler Fehler – aber genau die Art von kleiner Interpretation, die sich über acht Schritte zu einer Inkonsistenz summiert, die man später nicht mehr nachvollziehen kann. Ich habe es korrigiert, der Agent hat den Schritt erneut ausgeführt.

Schritt 5, 6, 7, 8. Nach jedem Schritt: Änderungen anschauen, Build grün, weiter.

Das Ergebnis: Eine funktionierende Suchleiste im Header, live mit Debouncing, mit korrektem Dropdown, ohne separate Seite, ohne Duplikation der bestehenden Composable-Logik. Acht saubere, fokussierte Commits im Log.

Funktioniert sie auch wirklich? Der Build ist grün – aber grün heißt nur „kompiliert", nicht „tut, was im Use Case stand". Diese letzte Frage beantwortet der fünfte Agent.

Phase 5: Der E2E-Test-Agent – aus Code wird verifiziertes Feature

Der E2E-Test-Agent, den ich im vorherigen Post vorgestellt habe, bekommt jetzt zwei Dinge: das ursprüngliche Use-Case-Dokument aus docs/usecases/UC-suche.md und die laufende Anwendung. Nicht den Plan, nicht den Code, nicht die Implementierungsdetails – nur die Anforderung in ihrer freigegebenen Form und einen Browser.

Er übersetzt die Struktur des Use Cases direkt in Playwright-Testfälle: den Hauptablauf in das zentrale Szenario, die beiden Alternativflüsse (keine Treffer, leerer Begriff) in je einen eigenen Test, den Fehlerfall F1 in einen Test, der den fehlschlagenden Content-Query erzwingt. Dann startet er den Dev-Server, steuert den Browser und führt die Suite aus.

test('Hauptablauf: Treffer erscheinen im Dropdown', async ({ page }) => {
  await page.goto('/')
  await page.getByRole('searchbox').fill('Agenten')
  const dropdown = page.getByTestId('search-dropdown')
  await expect(dropdown).toBeVisible()
  await expect(dropdown.getByRole('link')).not.toHaveCount(0)
})

test('A2: Leerer Begriff schließt das Dropdown', async ({ page }) => {
  await page.goto('/')
  const box = page.getByRole('searchbox')
  await box.fill('Agenten')
  await box.fill('')
  await expect(page.getByTestId('search-dropdown')).toBeHidden()
})

Das war Checkpoint 5. Und hier liegt der Punkt, an dem ich am genauesten hinsehe – nicht auf das grüne Häkchen, sondern auf den Test-Code selbst.

Genau das hat sich gelohnt. Der erste Wurf für den Fehlerfall F1 sah so aus:

// zu schwach – läuft grün, prüft aber nichts Belastbares
test('F1: Fehler beim Content-Query', async ({ page }) => {
  await page.goto('/')
  await page.getByRole('searchbox').fill('xyz')
  await expect(page.getByTestId('search-dropdown')).toBeVisible()
})

Der Test erzwang den Fehler gar nicht – er tippte nur einen Begriff und prüfte, dass irgendein Dropdown sichtbar ist. Grün, aber wertlos: Genau die Schein-Sicherheit, vor der ich im Post über HITL gewarnt habe. Ich habe den Agenten angewiesen, den Content-Query per Route-Mock tatsächlich fehlschlagen zu lassen und auf die definierte Fehlermeldung zu prüfen, nicht auf bloße Sichtbarkeit. Drei Minuten, eine Überarbeitung – danach prüfte der Test wirklich das im Use Case beschriebene Fehlerverhalten.

Vier Testfälle, alle grün, alle aussagekräftig. Sie wandern ins Repository und laufen ab jetzt bei jeder künftigen Änderung mit. Aus dem einmaligen „funktioniert" ist ein dauerhaftes „funktioniert immer noch" geworden.

Was dieser Durchlauf wirklich zeigt

Ich habe an vier von fünf Checkpoints tatsächlich eingegriffen. Das klingt nach viel Korrekturaufwand.

Tatsächlich war es das Gegenteil. Jeder Eingriff hat zwischen zwei und zehn Minuten gedauert. Ich habe eine Fehlannahme korrigiert (Phase 1), eine Architekturentscheidung angepasst (Phase 2), eine Abhängigkeitsreihenfolge geglättet (Phase 3) und eine zu schwache Test-Assertion nachgeschärft (Phase 5); Phase 4 lief bis auf eine winzige Stil-Korrektur durch. Die ersten drei Eingriffe erforderten keinen einzigen Blick in den finalen Code – sie fanden auf Ebenen statt, die ich ohne Code-Dive beurteilen konnte: Anforderung, Konzept, Plan. Der vierte fand auf Test-Ebene statt, aber auch dort las ich nicht die Implementierung, sondern nur, was der Test behauptet – und blieb damit genauso eine Sache von Minuten.

Und das ist der Punkt, den ich im Post über HITL theoretisch beschrieben hatte, jetzt aber in der Praxis sehen konnte: Es geht nicht darum, Fehler zu finden. Es geht darum, Richtung zu halten. Die Agenten machten technisch keine groben Fehler. Sie trafen implizite Entscheidungen – kleine, plausible, aber falsche. Und der Moment, in dem ich diese Entscheidungen gesehen habe, war immer dann, wenn sie noch nichts kosteten.

Wo der Overhead wirklich liegt

Ja, dieser Workflow hat länger gedauert als ein direkter Prompt – mit Nachjustieren gut eine Stunde statt vielleicht 20 Minuten. Diese Zeit zahle ich bewusst, weil sie genau das produziert, was ein direkter Prompt nicht liefert: Sicherheit und Qualität. Jede der vier Korrekturen, die ich auf Anforderungs-, Konzept-, Plan- und Test-Ebene gemacht habe, wäre im fertigen Code – oder schlimmer, erst in Produktion – zu Stunden Refactoring, einem kaputten Build oder schleichender Duplikation geworden.

Für kleine, isolierte Änderungen ist dieser Workflow Overkill. Für alles, was mehrere Schichten betrifft und in eine gewachsene Codebase integriert werden muss, zahlt der Overhead sich aus – nicht sofort, aber konsistent.

Fazit

Dieser Walkthrough war kein Showcase. Er war ein ehrlicher Blick auf einen Prozess, der genau das tut, was er tun soll – und dabei trotzdem menschliche Eingriffe braucht. An vier Stellen. Mit insgesamt rund 30 Minuten Review-Aufwand, eingebettet in ein Feature, das von der ersten Anforderung bis zum getesteten Commit gut eine Stunde gedauert hat.

Was ich am Ende habe: keine Überraschungen, kein Backtracking, kein „das hätte ich vorher wissen müssen". Die Korrekturen, die nötig waren, haben mich Minuten gekostet – nicht Stunden. Die Artefakte aus jeder Phase lagen bereits im Projekt und bildeten nachvollziehbar ab, warum jede Entscheidung so getroffen wurde.

Und genau das macht für mich den Reiz dieses Mittelwegs aus. Wenn ich die drei Ansätze nebeneinanderlege, wird das Bild deutlich:

  • Vibe Coding ist schnell. Ein Prompt, ein paar Minuten, ein lauffähiges Ergebnis. Aber ohne Konzept, ohne Architekturplan, ohne nachvollziehbare Entscheidungswege. In einer gewachsenen Codebase produziert dieser Ansatz Probleme, die man später teuer bezahlt – das habe ich in Post 11 ausführlich beschrieben.
  • Traditionelle Softwareentwicklung mit realen Product Ownern, Business Analysten, Solution Architekten, Plannings, Groomings und anschließender Implementierung produziert auf der anderen Seite sehr verlässliche Ergebnisse – aber zieht sich für ein einzelnes Feature über Tage oder Wochen. Das ist für viele Projekte richtig und nötig. Für ein kleineres Vorhaben oder eine Einzelperson ist es schlicht nicht leistbar.
  • Agentisch + Human-in-the-Loop liegt dazwischen. Der gesamte Prozess – Anforderungsanalyse, Konzept, Plan, Implementierung und Verifikation – passt in gut eine Stunde, weil die Agenten die Fleißarbeit übernehmen. Der Mensch entscheidet dort, wo es zählt: an den Übergängen zwischen Anforderung, Architektur, Plan, Code und Test. Die strukturelle Disziplin der klassischen Entwicklung bleibt erhalten, nur in einer Form, die für ein einzelnes Feature angemessen skaliert.

Aus meiner Sicht ist dieser Mittelweg vertretbar – mehr noch: Er ist genau der Punkt, an dem KI-gestützte Entwicklung anfängt, im Engineering-Sinne ernsthaft nutzbar zu werden. Nicht so schnell wie ein einzelner Prompt, aber zuverlässiger. Nicht so gründlich wie ein klassisches Projektsetup, aber für die meisten Aufgaben gründlich genug.

Bisher habe ich gezeigt, was die fünf Agenten tun und wie sie in der Praxis zusammenarbeiten. Im nächsten Post wird es praktisch: wie man sich ein solches Agenten-Team überhaupt anlegt – mit fertigen Templates als Abkürzung oder von Grund auf selbst gescaffoldet.