Ich habe die neu veröffentlichte generative UI-Interaktion von Claude nachgebaut!

@op7418
CHINESISCHvor 4 Monaten · 15. März 2026
265K
446
63
34
815

TL;DR

Dieser Artikel beschreibt die Nachbildung der generativen UI von Claude in Code Pilot. Er behandelt technische Hürden wie das Rendering von Sandbox-Iframes, das Parsen von Streaming-JSON sowie UX-Optimierungen für eine reibungslose und flackerfreie Darstellung.

Anthropic hat kürzlich eine neue generative UI-Interaktion in Claude eingeführt. Sie hilft dabei, Konzepte und Informationen visuell direkt im Chat-Stream darzustellen, was das Verständnis im Vergleich zu reinem Text erheblich erleichtert. !Image Ich hatte mir bereits ähnliche Lösungen angesehen, und als Claude seine veröffentlichte, hatte ich das Gefühl, meine Arbeit beschleunigen zu müssen. Gleichzeitig konnte ich ihren Ansatz als Referenz nachvollziehen. Nach zwei Tagen intensiven Promptings von Codex und Claude habe ich es tatsächlich geschafft! !https://pbs.twimg.com/amplify_video_thumb/2033112086713364480/img/EUmHCjsTK7tfnToZ.jpg Diese Funktion ermöglicht es der KI, interaktive Diagramme direkt im Chat mit Streaming-Output zu zeichnen, die während der Generierung gerendert werden. Bisher musste man, wenn man die KI bat, eine Webseite zu schreiben, auf die gesamte Code-Generierung warten, bevor gerendert werden konnte, was ewig dauerte. Jetzt ist das anders. Man kann zusehen, wie Diagramme Strich für Strich auf der Leinwand gezeichnet werden und SVG-Knoten nacheinander erscheinen. Der Generierungsprozess selbst ist atemberaubend, und direkt nach Abschluss ist er interaktiv. Erlebe es direkt in meinem Agent-Produkt, Code Pilot: https://github.com/op7418/CodePilot In diesem Beitrag werde ich seine Verwendung, den spezifischen Implementierungsprozess und einige Vorsichtsmaßnahmen vorstellen. ## Was sind einige unterhaltsame Anwendungsfälle? Datenanalyse: Endlich machen Zahlen Sinn Frage es zum Beispiel, ein Diagramm für „Tägliche Kostenschätzung des US-Iran-Konflikts“ zu zeichnen. Früher lieferte die KI einen Textblock, in dem numerische Beziehungen schwer zu erkennen waren. Jetzt generiert sie direkt ein Diagramm, sodass der Betrag für jeden Teil auf einen Blick klar ist. Text und Diagramme werden zusammen ausgegeben, wo nötig wird erklärt und wo nötig gezeichnet. !Image Kleine Werkzeuge: Baue einen interaktiven Taschenrechner oder Ähnliches Bitte es, einen Zinseszinsrechner zu erstellen. Ziehe an Schiebereglern, um den Anfangsbetrag oder die Anlagedauer zu ändern, und die Diagramme und Zahlen darunter aktualisieren sich in Echtzeit. Dies ist kein statisches Bild; es ist ein wirklich interaktives Werkzeug. Kreditberechnungen, Einheitenumrechnungen und Ähnliches sind alle möglich. !Image Architekturdiagramme: Der Favorit eines Programmierers Du kannst es bitten, beim Zeichnen der Architektur eines Projekts zu helfen oder einen Implementierungsplan zu visualisieren. Hier habe ich es zum Beispiel gebeten, den vollständigen Fluss von der API bis zur JWT-Authentifizierung zu zeichnen. Funktionsvergleiche, Flussdiagramme und hierarchische Strukturen sind alle grafisch dargestellt, was das Verständnis der Architektur viel schneller macht als das Lesen von Textbeschreibungen. !Image Analysiere Online-Daten Eine andere Möglichkeit ist, einen GitHub-Repository-Link hineinzuwerfen; es wird die Daten crawlen und eine visuelle Analyse durchführen. Zum Beispiel habe ich ihm meine eigene Projektadresse, CodePilot, zur Analyse geschickt. Sterne, Forks, Tech-Stack, Architekturdesign und Kernmodule werden alle in Diagramme gezeichnet. Du kannst das gesamte Projekt auf einen Blick sehen, was viel besser ist, als einen langen Text zu lesen. !Image Interaktive und tiefgehende Erklärungen Das Stärkste ist seine enge Integration mit dem Modell; es ist nicht nur eine einmalige Ausgabe. Du kannst mit den generierten Diagrammen interagieren und detailliertere Erklärungen anfordern. Hier habe ich es zum Beispiel gebeten, die Beziehung zwischen Monsunen und Meeresströmungen zu erklären. !Image Wenn wir mehr wissen wollen, können wir auf die Schaltfläche für den Mechanismus der Meeresströmung klicken. Es sendet automatisch einen Befehl an das aktuelle Modell, um ein Diagramm des Mechanismus der Meeresströmung zu generieren. !Image Natürlich können wir komplexere Interaktionen durchführen, wie zum Beispiel die Visualisierung gängiger Physik- und Mathematikformeln. Dies ist sehr nützlich für Studenten; jeder Parameter kann über Schieberegler und Eingaben gesteuert werden, und die Animation ändert sich sofort. !Image Unterstützung für chinesische Modelle Einmal in CodePilot implementiert, ist es nicht nur für Claude. Kimi K2.5, Minimax M2.5 und Anthropics native Modelle führen es alle gut aus. Ich finde, die von K2.5 gezeichneten Grafiken sehen sogar besser aus als die von Sonnet 3.5, und die Architekturanalyse ist sehr detailliert. Wenn du diese Funktion nutzt, empfehle ich, zuerst K2.5 auszuprobieren. Okay, das war es im Grunde mit den Modelldemonstrationen. Wenn dich die Implementierung nicht interessiert, kannst du einfach CodePilot installieren und loslegen. ## Wie wurde es implementiert? !Image Wie Claude es macht Claude.ai verwendet offiziell den tool_use-Mechanismus. Das Modell ruft ein spezielles Tool auf, um strukturierte Widget-Inhalte auszugeben, und das Frontend parst die Eingabeparameter des Tool-Aufrufs, um sie zu rendern. Diese Lösung funktioniert unter Claudes eigener Architektur gut. Aber sie funktioniert nicht für CodePilot aus drei Gründen: Erstens, SDK-Einschränkungen. CodePilot verwendet den claude_code-Voreinstellungsmodus des Claude Agent SDK, der das Registrieren benutzerdefinierter Tools nicht erlaubt. Das SDK gibt einen Text-Delta-Stream aus, daher kann es auf Tool-Ebene nicht erweitert werden. Zweitens, das Streaming-Erlebnis. Die Ergebnisse von tool_use müssen auf das Ende von input_json_delta warten, bevor gerendert wird, und es unterstützt kein inkrementelles HTML-Rendering. Mit Code-Fences kommt HTML mit dem Text-Stream an, was Rendering während der Generierung ermöglicht. Drittens, Rendering-Isolation. Claude.ai verwendet Shadow DOM für die Isolation. Wir haben uns für ein Sandbox-Iframe entschieden. Iframe-Isolation ist gründlicher – eine vollständig unabhängige JS-Ausführungsumgebung, CSP kontrolliert präzise das Laden von Ressourcen, und es gibt kein Stil-Leaking oder Script-Escape. Wie wir es gemacht haben Auslöser: Code-Fences Das Modell gibt einen speziellen Markdown-Code-Fence aus, um das Rendering auszulösen: ``show-widget {"title":"training_flow","widget_code":"<svg width=\"100%\" viewBox=\"0 0 680 400\">...</svg>"} ` Dieses Format nutzt die bestehenden Code-Fence-Modi von CodePilot (image-gen-request, batch-plan usw.), die von der Frontend-Parser-Kette nativ unterstützt werden. ![Image](https://pbs.twimg.com/media/HDcR5dyasAAtwTN?format=jpg&name=small) **Rendering: Sandbox-Iframe** Jedes Widget wird in einem Iframe mit sandbox="allow-scripts" gerendert. Das srcdoc des Iframes ist eine sorgfältig konstruierte Empfängerseite. Die CSP-Richtlinie erlaubt nur externe Skripte von 4 CDN-Domains, und connect-src 'none' verbietet alle Netzwerkanfragen. Inhaltsaktualisierungen werden über postMessage empfangen. Während der Streaming-Vorschauphase wird widget:update ohne Ausführung von Skripten gesendet. Das endgültige Rendering sendet widget:finalize, das Skripte ausführt. Ein ResizeObserver überwacht Höhenänderungen des Inhalts und meldet sie über postMessage an die übergeordnete Seite. Alle <a>-Klicks werden abgefangen und an die übergeordnete Seite weitergeleitet, um in einem neuen Fenster geöffnet zu werden. Die Themensynchronisation basiert auf der Überwachung von Klassenänderungen auf der übergeordneten Seite, um in Echtzeit zwischen Dunkel-/Hellmodi zu wechseln. ![Image](https://pbs.twimg.com/media/HDcR8ilbgAATB-8?format=jpg&name=small) **CSS-Variable-Brücke** Dies ist der Schlüssel, damit das Widget visuell mit der App verschmilzt. CodePilot verwendet CSS-Variablen im OKLCH-Farbraum. Anthropics Widget-Designrichtlinien verwenden Standardvariablennamen wie --color-background-primary. Die Brückenschicht injiziert die Werte der CodePilot-Variablen in das :root des Iframes, wenn es initialisiert wird. CSS, das vom Modell gemäß den Richtlinien geschrieben wurde, kann direkt die Farben des aktuellen Themas verwenden. Beim Wechsel in den Dunkelmodus erkennt die übergeordnete Seite die Klassenänderung, berechnet die Variablenwerte neu und überträgt sie an das Iframe. ![Image](https://pbs.twimg.com/media/HDcR_fLaYAAL88P?format=jpg&name=small) **Streaming-Rendering** Dies ist der komplexeste Teil der gesamten Implementierung. Das Modell generiert Token für Token. Zu jedem Zeitpunkt kann der empfangene Widget-Code unvollständiges JSON, unvollständiges HTML oder ein unvollständiges <script>-Tag sein. Der Verarbeitungsablauf ist wie folgt: Regex matcht `show-widget, um zwischen „ungeöffneten“ und „geschlossenen“ Zuständen zu unterscheiden. Manuelles Lokalisieren des Inhalts nach "widget_code":" und zeichenweises Entfernen von Escape-Sequenzen. JSON.parse kann nicht verwendet werden, da das JSON noch nicht fertig ist. Wenn ein ungeschlossenes <script>-Tag erkannt wird, wird vor dem <script abgeschnitten, um zu vermeiden, dass JavaScript-Code als sichtbarer Text angezeigt wird. Ein 120ms-Debounce verhindert, dass das Iframe zu häufig aktualisiert wird. Der Streaming-Inhalt entfernt alle Skripte und Ereignisbehandler; während der Vorschauphase ist keine Interaktion erforderlich. ![Image](https://pbs.twimg.com/media/HDcSDCGb0AAwY7J?format=jpg&name=small) **Die Erfahrung verfeinern: Details, die nicht auffallen sollten** Aus Code- oder Implementierungsperspektive ist es nicht so komplex; die Komplexität liegt in der Verfeinerung der Erfahrung. Es gibt zu viele Stellen, die die Erfahrung beeinflussen können, und die Benutzer sollten diese Details und den Generierungsprozess nicht bemerken. Dies erfordert eine unterschiedliche Behandlung jeder Phase: 1. Details, die nicht wie Streaming aussehen 2. Inhalte, die nicht erscheinen sollten ![Image](https://pbs.twimg.com/media/HDcSKQLaEAABilZ?format=jpg&name=small) **Textverschwinden** Das Modell gibt zuerst einen Einführungstext aus („Lass es mich visuell erklären...“) und beginnt dann mit dem Widget-Fence. Sobald der Fence erscheint, verschwindet der vorhergehende Text plötzlich und kehrt erst zurück, nachdem das Widget fertig gerendert ist. Der Grund ist, dass parseAllShowWidgets() für reinen Text ein leeres Array zurückgibt. Wenn der Fence gerade erscheint, aber nicht geschlossen ist, wird der Text vor dem Fence in diese Funktion übergeben und verworfen. Fix: Wenn der Text vor dem Fence keinen vollständigen Widget-Fence enthält, wird er direkt als <MessageResponse> gerendert, unter Umgehung der Parsing-Funktion. **Höhensprünge** In dem Moment, in dem das Widget fertig gerendert ist, wackelt der gesamte Chat-Bereich. Die anfängliche Höhe des Iframes beträgt 0px. Wenn der Inhalt zum ersten Mal seine tatsächliche Höhe meldet, könnte diese 400px+ betragen, und ein CSS-Übergang lässt diese Änderung über 300ms stattfinden, was zu einem spürbaren Sprung führt. Fix: Vorübergehendes Deaktivieren von CSS-Übergängen während der ersten Höhenmeldung, damit die Höhe sofort einrastet. Nachfolgende Höhenanpassungen verwenden sanfte Übergänge. **Finalize-Flackern** Wenn das Widget von der Streaming-Vorschau zum endgültigen Rendering wechselt, flackert der Inhalt. Das Empfänger-Iframe ersetzt das gesamte DOM mit root.innerHTML = html während der Finalisierung. Selbst wenn der neue und der alte Inhalt identisch sind (reines SVG-Widget), löst der Browser einen Frame von Neuzeichnungen aus. Fix: Während der Finalisierung wird das neue HTML zuerst in einen temporären Container geparst und die Skriptelemente werden getrennt. Vergleiche das visuelle HTML (ohne Skripte) mit dem aktuellen DOM – wenn sie identisch sind, überspringe den innerHTML-Austausch und hänge nur die Skripte zur Ausführung an. Reine SVG-Widgets erreichen eine Finalisierung ohne Neuzeichnung. **Scroll-Sprünge** Der Chat scrollt automatisch nach unten, springt dann plötzlich mehrere hundert Pixel zurück und springt wieder zurück. Wenn das Streaming endet, wird die StreamingMessage-Komponente ausgehängt und die MessageItem-Komponente eingehängt. Dies sind zwei völlig unterschiedliche React-Komponenten, und der interne WidgetRenderer wird zerstört und neu aufgebaut. Die Höhe des Iframes der neuen Instanz beginnt bei 0, was zu einem starken Abfall der Inhaltsbereichshöhe führt, der eine Scroll-Anpassung in use-stick-to-bottom auslöst. Fix: Modulweites Höhen-Caching. Immer wenn ein Widget seine Höhe meldet, wird sie unter Verwendung der ersten 200 Zeichen des widgetCode als Schlüssel in einen Cache geschrieben. Die neue WidgetRenderer-Instanz liest die Höhe während der useState-Initialisierung aus dem Cache, sodass das Iframe mit der korrekten Höhe zu rendern beginnt, wodurch der Übergang von 0→tatsächlich entfällt. **Skript-Code-Leck** Wenn ein Widget mit Chart.js geladen wird, wird ein großer Block JavaScript-Code am unteren Rand angezeigt. Die vom Modell ausgegebenen <script>-Tags kommen Zeichen für Zeichen an. Wenn das öffnende Tag ankommt, das schließende jedoch noch nicht, entfernt sanitizeForStreaming das öffnende Tag, aber der JavaScript-Code im Inneren wird zu einem bloßen Textknoten, der als sichtbarer Inhalt gerendert wird. Fix: Nach dem Extrahieren von Teilcode in StreamingMessage wird überprüft, ob das letzte <script ein passendes </script> hat. Wenn nicht, wird an der Position des <script abgeschnitten. Die Widget-Richtlinien geben vor, dass Skripte am Ende stehen, daher beeinträchtigt das Abschneiden keine visuellen Inhalte. Während des Abschneidens wird eine Schimmer-Maske angezeigt, und die Statusleiste zeigt „Füge interaktive Animationen zur Visualisierung hinzu.“ **Iframe-Ready-Race-Condition** In seltenen Fällen wird das Widget überhaupt nicht gerendert und bleibt bei 0px Höhe. WidgetRenderer registriert einen Nachrichten-Ereignis-Listener über useEffect. Das Empfängerskript des Iframes sendet jedoch widget:ready, sobald es geladen ist. Wenn das Iframe schneller lädt als der React-Effekt ausgeführt wird, wird widget:ready gesendet, bevor der Listener registriert ist, und iframeReady wird nie wahr. Fix: Hinzufügen eines onLoad-Callbacks zum Iframe-Element als Fallback. Wenn onLoad ausgelöst wird, muss das Empfängerskript die Ausführung abgeschlossen haben, was ein zuverlässiges Bereitschaftssignal liefert. **React-Komponentenbaum-Stabilität** Das Widget flackert in dem Moment, in dem der Fence geschlossen wird. Zwei Probleme überschneiden sich: Das Streaming-Teil-Widget hat keinen React-Key, und nach dem Schließen erhält es key="w-0". Die Key-Änderung verursacht ein erneutes Einhängen. Außerdem wurde die Schimmer-Überlagerung mit einem umschließenden <div> implementiert, was die Komponentenbaumstruktur änderte und ein weiteres erneutes Einhängen verursachte. Fix: Weise dem Teil-Widget einen stabilen Key zu (w-N, wobei N die erwartete Position im endgültigen Segments-Array ist), konsistent mit dem Key nach dem Schließen. Verschiebe die Schimmer-Überlagerung in den WidgetRenderer, gesteuert über eine showOverlay-Prop. Der Komponentenbaum bleibt während des gesamten Vorgangs <WidgetRenderer key="w-N">. ## **Abschließende Gedanken** Für das gesamte generative UI-System ist der schwierige Teil nicht „ein Stück HTML in einem Iframe zum Laufen zu bringen“. Das ist einfach. Die wirkliche Komplexität liegt darin, dieses Iframe während Zustandsübergängen wie Streaming, Komponentenlebenszykluswechseln und Themenänderungen visuell stabil zu halten. Jedes „Flackern“, „Springen“ oder „Verschwinden“ erfordert ein Verständnis von Reacts Reconciliation, der Rendering-Pipeline des Browsers und des Timings von postMessage`. Der endgültige Effekt ist, dass Benutzer Diagramme und Schaubilder sehen, die natürlich in die Antworten des Modells eingestreut sind, als ob sie schon immer dort sein sollten. Das war's für heute. Wenn dir das geholfen hat, gib mir bitte ein Like oder teile es mit Freunden, die es vielleicht brauchen.

Mit einem Klick speichern

Virale Artikel mit YouMind per KI tief lesen

Speichere die Quelle, stelle gezielte Fragen, fasse die Argumentation zusammen und verwandle einen viralen Artikel in wiederverwendbare Notizen in einem einzigen KI-Arbeitsbereich.

YouMind entdecken
Für Creator

Verwandle dein Markdown in einen sauberen 𝕏-Artikel

Wenn du eigene Langtexte veröffentlichst, wird die 𝕏-Formatierung von Bildern, Tabellen und Codeblöcken mühsam. YouMind macht aus einem ganzen Markdown-Entwurf einen sauberen, sofort postbaren 𝕏-Artikel.

Markdown zu 𝕏 testen

Mehr Muster zum Entschlüsseln

Aktuelle virale Artikel

Mehr virale Artikel entdecken