Einer der frühen Builds sah gut aus. Farben, Schrift, Abstände … alles lag bis auf wenige Pixel am Mockup. Dann meldete sich ein Kollege mit seinem eigenen Account an, und die App begrüßte ihn mit einem fröhlichen
„Welcome back, Jane Doe.“
Ihn, und alle anderen auch. Die App kannte von einem Moment auf den anderen nur noch eine einzige Nutzerin, und die hieß Jane Doe. Das Ärgerlichste daran war, dass der Agent genau das getan hatte, worum wir ihn gebeten hatten. Halte dich ans Design. Und im Design stand nun mal Jane Doe.
Besser lässt sich das Problem kaum zusammenfassen. Ein Agent, der UI aus einem Mockup baut, muss es exakt nachbauen und gleichzeitig wissen, welche Teile er auf keinen Fall übernehmen darf.
Exakt nachbauen … aber nicht alles
Dass KI in Sekunden einen funktionierenden App-Screen generiert, ist keine Neuigkeit mehr. Die Ernüchterung danach auch nicht: Der Screen sieht selten so aus wie das Design, das der Kunde abgenommen hat.
Bei uns im Projekt hat dieses Problem einen konkreten Ort: unsere agentische Coding-Loop, eine Multi-Agenten-Software-Factory, die Features plant, baut und in jedem Durchlauf ihre eigene Arbeit abnimmt. Funktional lieferte sie zuverlässig – nur die Design-Treue der Flutter-Screens war ihre Schwachstelle, und das sollte sich verbessern.
Schwierig war dabei vor allem ein Zielkonflikt, der sich durchs ganze System zieht: Der Agent soll ein Design exakt umsetzen, aber eben auch merken, wann wörtliches Übernehmen genau falsch ist. Fünf Lektionen haben wir auf diesem Weg gelernt, und fast alle laufen auf genau diese Grenze hinaus.
Visuellen Aufgabe brauchen visuelle Vorgaben
Zuerst haben wir dem Agenten das Design beschrieben. Schriftlich, sorgfältig, mit Farbwerten und Abständen. Das Ergebnis hatte mit dem Mockup trotzdem wenig zu tun.
Der Grund ist banal, aber unbequem: Sprache verdichtet. Zwischen „eine Glaskarte mit weichem Schatten und großzügigem Innenabstand“ und dem tatsächlichen Frame liegen hundert Detailentscheidungen, die der Text offen lässt. Und genau diese Entscheidungen trifft der Agent dann selbst. Jedes Mal ein bisschen anders.
Inzwischen bekommt kein Agent mehr eine Nacherzählung. Builder wie Reviewer greifen in jeder Iteration über den Figma-MCP-Server direkt auf die Frames zu: Screenshot, Node-Baum, Layout-Kontext und – der wichtigste Teil – die gebundenen Design-Tokens jedes Elements. Das Design wird nicht mehr beschrieben, sondern gelesen.
Pixelvergleich ist eine Falle
Der naheliegende Test wäre ein Pixel-Diff: Build rendern, Mockup rendern, Differenz bilden. Klingt bestechend, scheitert aber aus drei Gründen:
Schriften werden nicht auf jeder Plattform gleich gerendert. Unser Prüf-Build läuft unter Linux, der Frame ist für iOS konzipiert, und schon liefert identisches Markup unterschiedliche Pixel. Echte Geräte haben außerdem Bildschirmformate, die im starren Mockup gar nicht vorkommen; ein völlig korrektes responsives Layout fällt so durch die Prüfung. Und vor allem verrät ein Pixel-Diff nur, dass etwas abweicht, aber nie was. Der Agent bekommt eine Zahl, mit der er nichts anfangen kann.
Also vergleichen wir keine Pixel mehr, sondern benannte Eigenschaften. Der Reviewer liest die Design-Tokens aus Figma und die tatsächlich aufgelösten Werte aus dem Widget-Tree und stellt sie Name für Name gegenüber.
Ein echter Fund aus einem unserer Audits:
Der Frame bindet heading/h2-bold, 32 Punkt, im Code stehen jedoch 18. Der Frame will das gedämpfte Grau #929292, im Code ist #A1A1A1 fest verdrahtet.
| Element | Figma-Token | Code-Wert | Match? |
|---|---|---|---|
| Heading | h2-bold, 32pt | 18pt | ✖ FAIL |
| Text-Farbe | #929292 | #A1A1A1 | ✖ FAIL |
Ein Fehlschlag ist damit kein Wärmebild mehr, sondern ein Satz, mit dem der nächste Agent arbeiten kann.
Der Jane-Doe-Moment
Womit wir wieder am Anfang wären. „Halte dich exakt ans Design“, und der Agent schrieb den Platzhalternamen aus dem Mockup jedem Nutzer auf den Bildschirm. Die Verwandtschaft kennt jeder, der schon mal „Hallo, Max Mustermann“ in Produktion gesehen hat.
Geholfen hat dagegen keine strengere Formulierung im Prompt, sondern eine Unterscheidung. Jeder Text im Frame ist heute eins von beidem:
Statische Copy
Überschriften, Button-Beschriftungen, Fließtext
Die muss zeichengenau stimmen, samt Interpunktion und bewusst gesetzter Zeilenumbrüche. Hier ist wörtliches Übernehmen Pflicht.
Beispieldaten (bei uns Kind=binding)
Namen, Datumsangaben, Zähler
Die müssen an eine echte Datenquelle angebunden sein, und der Reviewer prüft auch die Gegenrichtung. Taucht also ein Beispielwert aus dem Frame als Literal, Default oder Fallback im Code auf, fällt die Prüfung automatisch durch. Jane Doe darf im Code schlicht nicht mehr vorkommen.
Der Agent muss also nicht ungenauer arbeiten; er muss wissen, in welchem Modus sich ein Element befindet.
Eine feste Checkliste reicht nicht
Unser erster Reviewer hatte eine Liste: Farben, Schriften, Texte. Die hat er gewissenhaft abgearbeitet … und alles übersehen, was nicht draufstand: Abstände, Eckenradien, Effekte, Hintergründe.
Wie teuer das wird, hat uns ein manuelles Audit gezeigt. Die Loop hatte drei Onboarding-Screens als designkonform durchgewunken; beim händischen Abgleich fanden sich anschließend rund zwanzig Abweichungen, davon sechs gravierend. Ein Hintergrund-Glow war nie gebaut worden. Ein Spotify-Logo fehlte komplett. Und ein animierter Orb, im Design acht konzentrische Kreise, bestand im Code aus rotierenden Ovalen. Hübsch, ja, nur eben ein anderes Design. Nichts davon stand auf der Liste, also hat auch niemand hingeschaut.
Die feste Checkliste ist deshalb weg. Was geprüft wird, gibt jetzt das jeweilige Design vor: Der Reviewer leitet seine Prüfpunkte aus dem ab, was die Live-Abfragen über den konkreten Frame liefern: jedes Element, jede Eigenschaft, jeder gebundene Token, jeder Zustand. Ein Frame mit Verlaufshintergrund erzeugt eine Verlaufsprüfung, ein Frame mit acht Kreisen eine Geometrieprüfung. Und schon in der Planung schreibt ein eigener Design-Agent dafür ein Element-Manifest, also eine vollständige Liste dessen, was existiert und Kriterien braucht. Fehlt in der Prüfung eine Zeile aus dem Manifest, zählt das als durchgefallen.
Selbstbewertung braucht Rechenschaft
Ehrlich gesagt, die unangenehmste Lektion. Wir gaben dem Reviewer den Live-Link zu den Design-Files, und er winkte alles durch, ohne sie zu öffnen. Ein Urteil wie „entspricht dem Frame“ ist schnell geschrieben und praktisch nicht zu widerlegen.
Dasselbe Audit von oben förderte beim Nachbohren nämlich noch eine zweite Ursache zutage … und die war sogar noch etwas peinlicher: Der Review-Agent hatte zum Prüfzeitpunkt überhaupt keinen Figma-Zugang. Die exakten Frame-Werte waren in der Planung längst erfasst worden und dann zu Prosa zerlaufen, die weiter hinten niemand mehr gegen irgendetwas geprüft hat. Der Reviewer verglich die laufende App mit seiner Erinnerung an einen Frame, den er nie wieder geöffnet hatte.
Intern heißt das bei uns inzwischen „Provenance-Break“: Die Daten, die alle zwanzig Abweichungen gefangen hätten, gab es schon. Sie kamen nur nie an.
Heute darf der Reviewer nicht mehr urteilen, er muss vorrechnen. Pro Frame sind die MCP-Aufrufe Pflicht – Screenshot, Token-Definitionen, Design-Kontext –, und statt eines Fazits liefert er eine Tabelle:
| Element | Eigenschaft | Frame-Wert | Code-Wert | Match? |
|---|---|---|---|---|
| – | – | – | – | – |
Jede Zeile lässt sich einzeln nachprüfen, jede fehlende Zeile gilt als rot, und die Erinnerung zählt ausdrücklich nicht als Beleg. So eine Tabelle füllt man nicht mit Selbstbewusstsein. Nur mit Daten.
Wie das System aussieht
Und damit zu dem Teil, für den ihr vermutlich hier seid.

Die Grundmaschine stand schon, bevor wir uns die Design-Treue vorgenommen haben: Auf eine Planungsphase, in der ein Rat aus Spezialisten-Agenten das Feature aus verschiedenen Blickwinkeln zerlegt, folgt die Build-Phase. Dort tritt pro Arbeitspaket ein Paar an: ein Implementor, der baut, und ein Architekt, der abnimmt und dafür drei Prüfer losschickt: einen für Korrektheit, einen für Code-Hygiene, einen für Design-Treue. Findet einer davon einen Blocker, geht das Paket als Rework zurück, und die Runde beginnt von vorn.
Neu ist der Designpfad durch beide Phasen. In der Planung sitzt der Figma-Agent mit am Tisch, der als Einziger die Live-Frames liest und das Element-Manifest samt Abdeckungstabelle pflegt; fehlende Designs landen als Frage beim Menschen, statt still improvisiert zu werden. In der Build-Phase haben Implementor und Design-Prüfer den Figma-Zugriff, den die Lektionen oben beschreiben, node-genau und in jeder Iteration: Jeder Frame wandert als Bookmark aus File-Key und Node-ID von der Planung bis in die Abnahme.
Die interessanteste Entscheidung steckt aber ganz am Ende. Der Wert einer solchen Loop liegt nicht in einer einzelnen Antwort, sondern im gesamten Weg vom ersten Entwurf bis zum abgenommenen Screen. Und irgendwann muss dieser Weg zu Ende sein.
Wann also darf eine selbstkorrigierende Maschine aufhören, sich zu korrigieren? Hört sie zu früh auf, liefert sie die 20 Abweichungen von oben. Hört sie nie auf, poliert sie Kommentare, bis das Budget alle ist. Unsere Antwort ist bewusst asymmetrisch: Korrektheits- und Designbefunde treiben Rework ohne Rundenlimit; ein Paket ist erst fertig, wenn die Tests grün sind und die Fidelity-Tabelle keine rote Zeile mehr enthält. Stil- und Aufräumthemen bekommen dagegen genau eine Zusatzrunde; danach werden sie festgehalten statt blockiert. Die Loop beißt sich am Design fest, aber nicht an Geschmacksfragen.
Und die Screenshots? Gibt es weiterhin, aber nur noch als Plausibilitätscheck für Komposition und Ebenen. Ein auffälliger Screenshot löst eine genauere Prüfung aus; bestehen oder durchfallen lässt er nichts.
Fazit
Die Pointe der Jane-Doe-Geschichte ist nicht, dass der Agent dumm war. Er war gehorsam.
Und da ist sie wieder, die Grenze vom Anfang: Ein design-treuer Agent braucht keine strengeren Anweisungen, sondern schärfere Unterscheidungen. Zwischen dem, was er kopieren muss, dem, was er anbinden muss, und dem, was er belegen muss.
Und dann heißt am Ende auch wieder jeder so, wie er heißt.


Schreibe einen Kommentar