50 Punkte von GN⁺ 6 일 전 | 3 Kommentare | Auf WhatsApp teilen
  • In einer Umgebung, in der LLMs massenhaft Code erzeugen, werden nicht nur Probleme im Code selbst größer, sondern auch das gemeinsame Verständnis im Team und die Dokumentation der Systemziele schwächer. Daher wird es immer wichtiger, dies als drei Ebenen zu behandeln: technische Schuld, kognitive Schuld und Intent-Schuld
  • Technical debt begrenzt die künftige Änderbarkeit, Cognitive debt schwächt die Fähigkeit des Teams, Änderungen am System nachzuvollziehen, und Intent debt verwischt die Aufzeichnung von Zielen und Randbedingungen, was die kontinuierliche Weiterentwicklung durch Menschen und AI Agents behindert
  • Die Tri-System-Theorie, die AI als System 3 einordnet, unterscheidet cognitive surrender – also das unkritische Vertrauen in extern erzeugtes künstliches Schlussfolgern und das Überspringen bewusster Reflexion – von cognitive offloading, also dem strategischen Auslagern von Kognition
  • Je billiger das Coden wird, desto teurer wird verification; die Maßstäbe für Korrektheit und Erfolg unterscheiden sich je nach Kontext, etwa bei Verkehrs-ETAs, Fahrerdisposition oder dem Betrieb von Hunderten von Microservices, wodurch menschliches Urteilsvermögen und der Entwurf von Verifikationssystemen wichtiger werden
  • Der Schwerpunkt des Engineerings verschiebt sich von der Implementierungsmenge hin zur Verifikation, und Menschen werden weiterhin die Rolle übernehmen, die Bedeutung eines Systems festzuhalten – etwa durch nützliche Abstraktionen und Benennungen sowie durch das Definieren von acceptance criteria und den Entwurf von test harnesses

Drei Arten von Schuld und Systemgesundheit

  • In einer Umgebung, in der LLMs große Mengen Code erzeugen, verlieren Teams leicht das Verständnis dafür, was ein System eigentlich tut; zunehmend wird dies als Cognitive Debt betrachtet
  • Three layers of system health teilt Schuld in die Dimensionen Code, Menschen und Artefakte auf
    • Technical debt existiert im Code, entsteht, wenn Implementierungsentscheidungen die künftige Änderbarkeit beeinträchtigen, und beschränkt damit, wie sich ein System weiterentwickeln kann
    • Cognitive debt existiert bei Menschen, entsteht, wenn das gemeinsame Verständnis eines Systems schneller schwindet, als es aufgefüllt wird, und begrenzt die Fähigkeit eines Teams, Änderungen zu durchdenken
    • Intent debt existiert in Artefakten, entsteht, wenn Ziele und Randbedingungen, die das System leiten sollen, nicht richtig dokumentiert oder gepflegt werden, und begrenzt, ob weiterhin das ursprünglich Gewollte abgebildet wird und ob Menschen und AI Agents das System wirksam weiterentwickeln können
  • Diese Perspektive umfasst auch Abschnitte zur Diagnose und Minderung jeder Schuldart und behandelt zudem, wie die drei Formen miteinander interagieren
  • Teams sollten gemeinsame allgemeine Aktivitäten durchführen, um diese drei Schulden unter Kontrolle zu halten

Tri-System-Theorie und kognitive Kapitulation

  • Ein Paper, das LLMs dem Zwei-System-Denkmodell von Kahneman hinzufügt, erweitert das Denkmodell, indem es AI als System 3 einordnet
  • System 1 trifft schnelle Entscheidungen aus der Intuition heraus, System 2 steht für absichtliches, bewusstes Nachdenken über Probleme
    • Um Energie zu sparen, neigen Menschen grundsätzlich dazu, sich auf Intuition zu verlassen; dadurch können sie Dinge übersehen, die sie bei bewusster Reflexion entdeckt hätten
  • Als Folge von System 3 tritt cognitive surrender auf; gemeint ist ein Zustand, in dem extern erzeugtes künstliches Schlussfolgern unkritisch vertraut wird und damit System 2 umgangen wird
    • Das Paper unterscheidet dies von cognitive offloading
    • cognitive offloading wird als strategisches Delegieren von Kognition innerhalb eines bewussten Denkprozesses behandelt
  • Das Paper entfaltet die Tri-System theory of cognition ausführlich und überprüft in mehreren Experimenten, wie gut diese Theorie zumindest in einer Laborumgebung Verhalten vorhersagen kann

Die Schreibweise <> als Code-Icon

  • Einige neuere Illustrationen verwenden das Symbol „<>“ als Code-Icon, doch diese Schreibweise wirkt ungewohnt, wenn es darum geht, Elemente von Programmiersprachen zu umschließen
  • Dass statt anderer Symbole wie „{ }“ ausgerechnet „<>“ verwendet wird, liegt offenbar daran, dass es an HTML oder XML erinnert
  • Wenn sogar die Form „</>“ verwendet wird, ruft das HTML noch direkter ins Gedächtnis; HTML wird jedoch nicht als Sprache verstanden, in der Programmierer Programme schreiben

Wenn Coden billiger wird, wird Verifikation teurer

  • if coding agents make coding free, what becomes the expensive thing argumentiert, dass mit sinkenden Coding-Kosten durch Coding Agents verification der teure Faktor wird
  • Die Kriterien für Korrektheit unterscheiden sich fortlaufend je nach Kontext
    • Ein ETA-Algorithmus für den Verkehr in Jakarta und einer für den Verkehr in Ho-Chi-Minh-Stadt können Unterschiedliches unter „correct“ verstehen
    • Bei der Fahrerdisposition müssen Fairness der Einnahmen, Wartezeit der Kundschaft und Fahrzeugauslastung zugleich erfüllt werden, sodass es nicht nur eine, sondern mehrere Definitionen von „successful“ gibt
    • In einer Umgebung, in der Hunderte Engineers kontinuierlich auf rund 900 Microservices deployen, zerfällt „correct“ nicht in eine, sondern in Tausende Definitionen, die sich alle fortlaufend ändern und kontextabhängig sind
  • Solche Urteile gelten als Aufgaben, die Agents nicht übernehmen können
  • Besonders gut funktionieren Agents in Arbeitsabläufen, in denen es für die Arbeitsergebnisse gute und möglichst automatisierte Verifikation gibt
    • Solche Abläufe fördern Test Driven Development
    • Da weiterhin viel Verifikation nötig bleibt, braucht es mehr Aufwand für Wege, die Menschen helfen, breitere Testumfänge leicht zu verstehen
  • Hinsichtlich Legacy-Modernisierung werden auch einige Gegenpositionen genannt
    • Die Erwartung, dass agentic coding die Legacy-Modernisierung endgültig lösen werde, ist überschätzt
    • Allerdings gibt es starke Belege dafür, dass LLMs beim Verstehen dessen, was Legacy-Code tut, sehr hilfreich sind

Reorganisation hin zu verifikationszentrierten Organisationen

  • Wenn Agents die Ausführung übernehmen, verlagert sich die menschliche Arbeit in Richtung Entwurf von verification systems, Definition von quality und die Bearbeitung unklarer Fälle, die Agents nicht lösen können
  • Auch Organisationsstrukturen müssen sich an diesen Wandel anpassen
    • Die Leitfrage im Stand-up am Montagmorgen lautet dann weniger „Was haben wir deployed?“ als „Was haben wir verifiziert?
    • Statt die Menge des Outputs zu verfolgen, verfolgt man, ob die Ergebnisse korrekt waren
  • Ein Team aus 10 Engineers, das bislang Features gebaut hat, könnte zu 3 Engineers sowie 7 Personen umgebaut werden, die acceptance criteria definieren, test harnesses entwerfen und outcomes überwachen
  • Diese Umstellung kann sich unangenehm anfühlen, weil sie den Status des Bauens senkt und den des Urteilens erhöht
  • Eine Engineering-Kultur, die sich diesem Wandel nicht widersetzt, wird ihn wahrscheinlich besser bewältigen

Die Zukunft des Source Codes und LLM-freundliche Sprachen

  • In dem Trend, LLMs wie Programmierer zu behandeln, rückt auch die Zukunft des Source Codes selbst als Frage in den Vordergrund
  • several views of the future of code sammelt verschiedene Perspektiven auf die Zukunft von Code
    • Einige experimentieren mit vollständig neuen Sprachen, die mit Blick auf LLMs entworfen wurden
    • Andere meinen, dass bestehende Sprachen, insbesondere streng typisierte Sprachen wie TypeScript und Rust, besser zu LLMs passen könnten
  • Der Artikel enthält viele Zitate und wenig eigene Analyse, ist aber als Überblick über die Diskussion lesenswert

Abstraktionen und Benennungen bleiben menschliche Aufgaben

  • Auch beim Entwickeln von Software mit LLMs werden Menschen weiterhin die Rolle übernehmen, nützliche Abstraktionen zu schaffen, mit denen sich beschreiben lässt, was Code eigentlich tut
  • Das steht in Verbindung mit der Ubiquitous Language aus DDD
  • growing a language behandelt, wie sich gemeinsam mit LLMs eine Sprache weiterentwickeln lässt
  • Programmieren ist nicht nur das Eingeben einer Coding-Syntax, die Computer verstehen und ausführen können, sondern auch die Formgebung einer Lösung
    • Dazu gehört, Probleme in fokussierte Teile zu zerlegen, zusammengehörige Daten und Verhalten zu bündeln und Namen zu wählen, die die Absicht sichtbar machen
    • Gute Namen schneiden durch Komplexität, verwandeln Code in ein Schema, dem alle folgen können, und verbinden Problemstruktur und Lösungsstruktur klar miteinander

3 Kommentare

 
jeikei 3 일 전

Den Begriff „Intentional Debt“ hatte ich früher einmal auf meine eigene Weise definiert, daher freut es mich, ihn hier wiederzusehen. Offenbar denken Menschen doch alle ziemlich ähnlich.
Blogbeitrag: https://brunch.co.kr/@limjk/2

 
shakespeares 6 일 전

Auch die schnelle Umstrukturierung einer Organisation, um mit Veränderungen Schritt zu halten, wirkt auf mich etwas konservativ und stößt bei mir auf leichte Ablehnung.

 
GN⁺ 6 일 전
Hacker-News-Kommentare
  • Wenn man der Typ ist, der alles, was er deployt, tief verstehen muss, um ruhig schlafen zu können, dann fühlt sich so ein Wandel ziemlich beunruhigend an.
    Ein Modernisierungsprojekt, das früher 2 Monate gedauert hätte, kann heute in etwa einer Woche abgeschlossen sein, wenn man nicht versucht, die gesamte Business-Logik bis ins Detail zu durchdringen und 1:1 zu reproduzieren, sondern sich darauf konzentriert, Grenzen und Schnittstellen sauber zu entwerfen.
    Und wie im Artikel gesagt, baut man einfach ein gutes Test-Harness, um die Gleichwertigkeit so weit wie möglich zu verifizieren.
    Ich war anfangs auch ziemlich hin- und hergerissen, aber wenn ich ehrlich darüber nachdenke, kannte ich die interne Implementierung oder Business-Logik anderer Systeme, die ich täglich gewartet habe, auch nicht wirklich so gut.
    Oft war es Code, den ich vor Jahren geschrieben und seitdem kaum angefasst hatte, und wenn ich etwas ändern musste, habe ich am Ende entweder der Testsuite vertraut oder bin der Struktur des Codes gefolgt, um ein bestimmtes Verhalten zu verstehen.

    • Tiefes Domain-Wissen über Branche und Unternehmen macht Menschen im Team und in der Firma extrem wertvoll.
      Ich habe mehrfach gesehen, dass Leute mit viel solchem Wissen Entlassungs- oder Sparrunden länger überstehen als andere.
    • Um ein gutes Test-Harness zu bauen, muss man die Business-Logik am Ende nicht doch ziemlich tief verstehen?
      Ich frage mich, was ich hier übersehe.
  • LLMs fehlt es nicht unbedingt an einer Tugend der Faulheit.
    Wenn man ihnen nur einen passenden Base Prompt für die gewünschte Intention gibt, konnte ich Claude-basierte Agenten ziemlich gut dazu bringen, Code-Änderungen zu minimieren, einen Deduplizierungs-Durchlauf zu machen und Verhaltensweisen zu zeigen, die fast wie die Instinkte eines sehr Senior-Entwicklers wirken.
    Ich glaube nicht, dass dem Modell dieses Wissen grundsätzlich fehlt; es ist nur in der Standardkonfiguration nicht im Vordergrund.
    Wahrscheinlich hat jeder schon Modelle gesehen, die im Stil einer Überbearbeitung die gesamte Codebase anfassen und sich überhaupt nicht um fremde Änderungen oder das Risiko von Wissensverlust scheren.
    Auch die Sache mit Dokumentenerstellung und Verifikation ähnelt letztlich dem klassischen Locking-Problem, und dafür gibt es traditionelle Lösungen.
    Ein Agent kann Git lesen und gut genug nachvollziehen, was zuerst passiert ist und ob man konventionsgemäß auf andere Änderungen warten sollte.
    Ich bin selbst ziemlich senior und habe mit einigen der Leute aus diesem Artikel tatsächlich im selben Team gearbeitet.
    Ich glaube nicht, dass sie meine Engineering-Standards infrage stellen würden.
    Trotzdem sehe ich in meinem LLM-Workflow kaum solche Arten von Schulden, und selbst nach denselben Maßstäben wie früher fühlt sich die Projektqualität für mich besser an als vor 5 oder 10 Jahren.
    Das ist keine Magie; man muss nur Agenten gut betreiben, die diese Qualitätsprioritäten teilen.
    Und ich bekomme damit in der Praxis mehr echte Arbeit erledigt, statt nur auf Konferenzen Aufmerksamkeit zu erzeugen.

    • Ich stimme der Stoßrichtung hier zu.
      Nur der Teil, dass es selbst nach traditionellen Software-Qualitätsmetriken besser sei als vor 5 oder 10 Jahren, klingt mir zu vage.
      Ich würde gern konkreter wissen, welche Metriken du verwendest und wie sich Code von vor 10 Jahren, vor 5 Jahren und heute jeweils vergleicht.
      Ohne diese Erklärung wirkt die Botschaft eher verwässert und etwas neben der eigentlichen Aussage.
      Wenn du mehr dazu teilen kannst, wäre ich ziemlich interessiert.
    • Mich würde interessieren, welche Anweisungen du Claude gibst, um minimale Änderungen oder eine ähnliche Richtung zu fördern.
    • Du solltest ruhig auch mal auf Konferenzen gehen.
      Ein Buch mit dem Titel Practical LLM Coding würde sich auch gut machen.
  • Ich finde, das am meisten unterschätzte hier ist das Framing von Intent Debt.
    Kognitive oder technische Schuld hinterlassen wenigstens Spuren im Code, aber Intent Debt ist unsichtbar.
    Sie wird erst sichtbar, wenn eine Änderung lokal plausibel wirkt, global aber falsch ist.
    Der ursprüngliche Zwang bleibt nämlich in keinem Artefakt erhalten.
    Die schwierigsten Fälle sind Enterprise-Systeme, in denen dieser Zwang eine regulatorische Anforderung war, sich vor 3 Jahren still verändert hat und niemand den Code aktualisiert hat.
    Die Tests laufen weiter grün, deshalb übersieht man es noch leichter.
    Mit einer Testsuite allein kann man Intention nicht wiederherstellen.

  • Ich denke nicht, dass Martin komplett falschliegt, aber dieses Argument scheint man immer bringen zu können, sobald die Abstraktionsebene steigt.
    Nach seiner Definition würde schon der Übergang von Assembly zu Python massiv Intent Debt und Cognitive Debt erzeugen.
    Man denkt schließlich nicht mehr selbst darüber nach, wie Bits manipuliert werden, sondern überlässt das dem Interpreter.
    Mein Gegenargument ist, dass das, was er technische Intention nennt, letztlich daraus entstanden ist, dass menschliche Intention überhaupt erst in Maschinensprache übersetzt werden musste.
    Tief über ein Problem nachzudenken setzt nicht zwingend voraus, dass man im Code domaingetriebene Abstraktionen aufbaut.
    Man kann auch mit Mindmaps, Journaling oder Post-its an der Wand tief nachdenken.
    Objektorientierte Abstraktion ist nicht magisch.

    • Der Prozess, Intention in eine formale Sprache zu überführen, ist selbst ein Denkwerkzeug.
      Dabei treten oft Mehrdeutigkeiten, übersehene Details oder sogar die Notwendigkeit zutage, den gesamten Ansatz noch einmal zu überdenken.
      Natürlich kann auch natürliche Sprache ein Denkwerkzeug sein, aber es gibt etwas grundlegend anderes daran, Gedanken an eine formale Sprache anzupassen, die keine Mehrdeutigkeit zulässt.
      Das ist ähnlich wie Mathematik nur in natürlicher Sprache ohne mathematische Notation zu betreiben: umständlicher und fehleranfälliger.
    • Über deterministischen Code nachzudenken heißt letztlich auch, über die Bitmanipulation in der Hardware nachzudenken.
      Nur geschieht das in einer Sprache, die für Menschen leichter verständlich ist.
      Es gibt eine direkte Abbildung zwischen Intention und Implementierung.
    • Diese Schuld ist im Grunde schon einmal bezahlt worden.
      Das Mapping ist gut definiert und deterministisch.
      Genau dazu dient Abstraktion: Man soll darauf vertrauen können, dass das, was man gerade getan hat, weiterhin korrekt ist, ohne wieder darunter schauen zu müssen.
      Das funktioniert, weil ich oder jemand, dem ich vertraue, diese Kosten einmal bezahlt hat.
      Bei LLMs muss man die Ausgabe aber bei jeder Generierung erneut verifizieren und die Schuld jedes Mal wieder begleichen.
      Deshalb fällt es mir schwer, das als Abstraktion zu sehen.
    • Ein Interpreter ist deterministisch, ein LLM aber nicht.
    • AI ist keine Abstraktionsebene.
  • The most creative act is this continual weaving of names that reveal the structure of the solution that maps clearly to the problem we are trying to solve.
    Für mich berührt das auch die konfuzianische Idee der Richtigstellung der Namen.
    In den Gesprächen 13.3 heißt es sinngemäß: Wenn die Namen nicht richtig sind, stimmen die Worte nicht mit der Wirklichkeit überein, und wenn die Worte nicht mit der Wirklichkeit übereinstimmen, können die Dinge nicht gelingen.
    Am Ende geht es also darum, dass Benennung die Struktur der Lösung präzise auf das Problem abbildet.

  • Wirklich sehr gut geschrieben.
    Ich habe gestern erst in meine privaten Notizen geschrieben, dass man schwer behaupten kann, etwas wirklich zu besitzen, wenn man den Code nicht organisch weiterentwickelt.
    Es fühlt sich an wie bei selbstfahrenden Autos: Früher erinnerte man sich wenigstens an die Landschaft auf dem Weg, heute wird man einfach an einen anderen Ort teleportiert und bekommt nur noch die Aufnahme gezeigt.
    Diese Art von Review ist weniger wirksam.
    Für kleine Tools mag solcher ghosted code in Ordnung sein, aber bei Systemen wie Datenbanken macht mir das wirklich Sorgen.
    Deshalb gebe ich Agenten inzwischen fast keine Schreibrechte mehr und bin wieder zu stärker manueller QA zurückgekehrt, wie vor 2 Jahren.
    Bei Token-Verbrauch und Ergebnissen war das für mich sogar effizienter.
    Natürlich ist das nur meine persönliche Erfahrung.

  • Leider wirkt ein großer Teil des von ihm verlinkten Wharton-Papers so, als sei er mit AI erzeugt worden, und es ist noch nicht peer-reviewed.
    Ich weiß, dass Forschende heute beim Schreiben oft AI-Hilfe nutzen, aber wenn das Paper ausgerechnet von cognitive surrender handelt, fällt es mir schwer, den Inhalt wirklich ernst zu nehmen.

    • Er verwendet tatsächlich ganze 7 Mal not merely.
      Ich bin mir nicht einmal sicher, ob ein LLM denselben Ausdruck so oft wiederholen würde; vielleicht hat sich der Autor einfach einen LLM-artigen Schreibstil angewöhnt.
    • Zum Glück habe ich das Paper nicht direkt gelesen und nur eine LLM-Zusammenfassung darüber laufen lassen.
    • I realize that most researchers use AI to assist with writing
      Das ist wirklich widerlich.

  • Martin liegt nicht komplett falsch, aber ich habe selbst erlebt, wie AI faulen Code erzeugt hat, und die richtige Lösung war damals eher mehr Code statt weniger.
    Konkret gab es Python-Modelle, die ein Datenbankschema für eine Menge logischer Konzepte definierten.
    Dann wurde ein neues Konzept ergänzt, das den bestehenden Konzeptmengen sehr ähnlich war, und Claude entschied, man könne einfach die bestehende Modellgruppe wiederverwenden.
    Theoretisch funktionierte das, aber auf Konsumentenseite brauchte man wegen Runtime-Typinferenz allerlei Umgehungslösungen.
    Es lief zwar, war aber ein Fall von komplett falsch gewählter Abstraktionsebene.

    • Ich bin mir nicht sicher, ob mehr Code wirklich schlecht ist.
      Aus menschlicher Sicht wollen wir Abstraktion, aber manchmal ist Wiederholung schlicht passender.
      Wenn Maschinen Code schreiben und warten, sind zusätzliche Abstraktionsebenen von früher vielleicht nicht mehr immer nötig.
      Früher hat man Duff's Device benutzt und Schleifen manuell unrolled, also absichtlich duplizierten Code erzeugt.
      Heute versteht der Compiler die Intention und erzeugt den redundanten Assembler selbst, und wir kümmern uns nicht weiter darum.
      Ich brauchte vor Kurzem ein paar ziemlich nichttriviale Stücke Computational-Geometry-Code mit LLM-Unterstützung. Früher hätte ich dafür eine Bibliothek suchen, eine Compliance-Freigabe einholen und die Datenstrukturen meiner Domain in das Format dieser Bibliothek umbiegen müssen.
      Das wäre wohl immer noch günstiger gewesen als eine Eigenimplementierung, aber keineswegs trivial.
      Jetzt kann mir ein LLM genau die Teile schreiben, die ich brauche, und dabei direkt mein bestehendes Datenformat verwenden.
      Ich muss keine große Bibliothek einführen und brauche auch keine Datenstruktur-Transformationen.
      Aus orthodoxer Sicht wäre es vermutlich richtiger, eine Geometry Library zu verwenden, um Duplikation zu vermeiden, aber hier funktioniert eine in sich geschlossene Funktion einfach gut.
  • Das war ehrlich gesagt eines der besten Dinge, die ich seit Langem auf Hacker News gelesen habe.
    Ich fühle das sehr.
    Wegen Simon Willisons Begriff cognitive debt und der Haltung „Dein Job ist es, nur Code zu deployen, von dem du bewiesen hast, dass er funktioniert“, arbeite ich inzwischen an Projekten in Richtung Intent-Driven Development.
    Frühere Intention scheint mit jeder angesammelten Änderung immer weiter zu verblassen.
    Vielleicht kann ich das irgendwann als echtes Protokoll ausarbeiten und später auf Hacker News posten.

    • Ich frage mich, ob wir vielleicht an derselben Sache bauen.
      Falls du meine Texte dazu noch nicht gesehen hast, schau sie dir gern einmal an.
      Kurzfassung:
      1. stacked-commits automation: Die Abschnitte context/why/verify können nicht übersprungen werden
      2. product specs: einschließlich vollständigem ERD (https://excalidraw.com/#json=WT-oRUdyKBhAsDZJ3NwAR,WAbVgfO39...)
      3. SCIP-Indizes verknüpfen Spec und Code sowie Commits und AC, sodass man später beliebige gewünschte Artefakte weiter anhängen kann
  • Meine aktuelle Visualisierung des Problems sieht eher so aus: https://excalidraw.com/#json=y1fSSx2z8-0nFs7CDnqhp,d9Di8JdGU...
    Ich glaube, der kognitive Flaschenhals im Software Engineering liegt weniger im Code selbst als zwischen den Artefakten.
    Code ist nur eines davon.
    outcome → requirements → spec → acceptance criteria → executable proof → review
    Ich baue experimentelles Tooling, das die langweiligen Teile dieser Übergänge automatisiert und den Menschen die Prüfung überlässt, ob die Intention in jeder Phase erhalten geblieben ist.

    • Ich mag dieses Framing von zwischen den Artefakten.
      Eine zusätzliche Schicht, die ich noch ergänzen würde, sind proxies/metrics.
      In stark analysegetriebenen Systemen entsteht der eigentliche Verlust oft nicht bei spec → code, sondern bei question → proxy.
      Sobald der Proxy in Acceptance Criteria, Dashboards oder Evaluations verankert ist, optimieren Menschen darauf, und dass es nur ein Stellvertretermaß war, gerät immer mehr in Vergessenheit.
    • Die Datenvisualisierung ist cool, aber schade, dass sie im bearbeitbaren Zustand ist.
      Auf dem Handy versuche ich zu pannen, zu zoomen oder zu scrollen und verschiebe dabei ständig Elemente auf der Leinwand.