- Moments Bewertung von kollaborativem Editieren für seinen Kern-Texteditor ergab, dass Algorithmen aus den CRDT- und OT-Familien bei direkten Offline-Konflikten Merge-Ergebnisse erzeugen können, die Nutzer als Datenbeschädigung ansehen würden
- Selbst in einem einfachen Fall, in dem Alice den ganzen Satz löscht und Bob
ColorzuColourändert, entstehen vom Menschen nicht beabsichtigte Ergebnisse, etwa dass im Enddokument nur noch der Buchstabeuübrig bleibt - In den Anwendungsfällen von Moment waren bei ungefähr 20–30 % der getesteten direkten Konflikte die Ergebnisse nicht akzeptabel, und wegen der Häufigkeit und der negativen Reaktionen hält Moment es für schwer, das als Produkterlebnis zu rechtfertigen
- Yjs, ShareJS und Peritext werben mit Offline-Bearbeitung, Zusammenarbeit mit langer Latenz oder automatischem Merge unabhängiger Kopien, aber die Algorithmen kennen weder Nutzerabsicht noch Reihenfolge und sind deshalb auf Heuristiken angewiesen
- Offline-kollaboratives Editieren ist weniger ein reines Algorithmusproblem als vielmehr ein UI/UX-Problem; nötig ist ein Merge-Erlebnis, das Menschen lesen und beurteilen können, etwa wie bei der git-Merge-UI oder Ink & Switchs collaborative history
Grenzen, die bei Moments Bewertung von kollaborativem Editieren sichtbar wurden
- Anfang 2024 begann Moment damit, ein System für kollaboratives Editieren für seinen Kern-Texteditor zu untersuchen
- Mehrere Algorithmen werben damit, nicht nur gleichzeitiges Online-Editieren zu lösen, sondern auch Offline-Szenarien, in denen Nutzer unbegrenzt lange offline bearbeiten und ihre Änderungen später beim Wiederverbinden automatisch gemergt werden
- Nach der ersten Sichtung von Papers und Vorträgen erwartete Moment, dass die Community für kollaboratives Editieren bereits zur „richtigen Antwort“ für das Gesamtproblem gekommen sei
- Im Verlauf der Bewertung lösten Algorithmen aus den CRDT- und OT-Familien direkte Bearbeitungskonflikte jedoch auf nicht intuitive Weise, und Nutzer nahmen die Ergebnisse als Datenbeschädigung wahr
- Da Offline-Bearbeitung die Wahrscheinlichkeit direkter Konflikte stark erhöht, war es mit solchen Algorithmen allein schwierig, die von Moment gewünschte Offline-Erfahrung zu schaffen
Ein einfacher Fall: Löschung und Rechtschreibkorrektur geraten in Konflikt
- Alice und Bob bearbeiten beide dasselbe Dokument im Offline-Modus
- Das Dokument enthält den Text
The Color of Pomegranates - Bob ändert die Schreibweise von
Colorzur britischen FormColour, während Alice den gesamten Text löscht - Wenn beide später wieder online gehen, geraten die beiden Bearbeitungen in Konflikt, und das System muss sie zusammenführen, ohne zu wissen, welche Änderung zuerst kam
- In diesem Fall erhalten Alice und Bob am Ende ein Dokument, das nur den Buchstaben
uenthält- Das ist weder ein gültiger Satz noch ein gültiges Wort
- Nutzer würden ein solches Ergebnis so verstehen, dass Moment ihre Daten beschädigt hat
Seltsame Ergebnisse bei direkten Konflikten sind nicht selten
- Dieser Konflikt ist ein kleiner, direkter Bearbeitungskonflikt, liegt aber dennoch innerhalb dessen, was populäre Algorithmen für kollaboratives Editieren als unterstützt gelten lassen würden
- Das tatsächliche Ergebnis war ein Dokument, das kein Mensch selbst schreiben würde, und würde so interpretiert, dass das Produkt von Moment Daten beschädigt hat
- Je nach Anwendungsfall waren ungefähr 20–30 % der von Moment getesteten direkten Konflikte in Offline-Szenarien nicht akzeptabel
- Betrachtet man die negativen Reaktionen zusammen mit der Häufigkeit, kommt Moment zu dem Schluss, dass sich solche Ergebnisse Nutzern kaum erklären oder verteidigen lassen
Wie Tools ihre Unterstützung für Offline-Bearbeitung darstellen
- Als diese Ergebnisse zuerst auftauchten, ging Moment zunächst davon aus, die Bedeutung der angebotenen Funktionen missverstanden zu haben
- Die Beschreibungen der einzelnen Projekte lassen sich jedoch so lesen, dass dieses Szenario innerhalb des unterstützten Bereichs liegt
- Yjs erklärt im README ausdrücklich,
offline editingzu unterstützen - ShareJS beschreibt, dass Zusammenarbeit bei jeder Latenz möglich sei – von null Verzögerung bis hin zu einer langen Urlaubsabwesenheit
- Peritext erklärt, dass Nutzer unabhängige Kopien eines Dokuments bearbeiten und diese automatisch so mergen können, dass die Nutzerabsicht so weit wie möglich erhalten bleibt
- Yjs erklärt im README ausdrücklich,
- Moment sucht weiterhin nach einer Lösung für dieses Problem, hält es aber für schwierig, die tatsächlich beobachtete Häufigkeit und Art der Fehler mit diesen Behauptungen in Einklang zu bringen
Grundlegende Grenzen von Algorithmen ohne Abstimmung
- Im weiteren Verlauf der Bewertung kam Moment zu dem Schluss, dass diese Algorithmen nicht das Verhalten liefern, das man sich wünscht
- Die verbleibende Frage war, ob sich das durch Beiträge beheben ließe oder ob es sich um eine grundlegende Grenze der Algorithmen handelt
- Aus drei Gründen wird es als grundlegendes Problem angesehen
- Die Algorithmen kennen die Absicht von Alice und Bob nicht und können nicht per E-Mail nachfragen oder wie in einer GitHub-Pull-Request-UI eine Prüfung einholen, was die beiden eigentlich wollten
- Sie müssen Alices Vorschlag, alles zu löschen, und Bobs Vorschlag, die Schreibweise zu ändern, per Heuristik zu einem Ergebnis zusammenführen
- Sie arbeiten auf Zeichenebene und geben nur sehr schwache Garantien für die Ausgabe
- Alice und Bob hätten möglicherweise anders entschieden, ob sie ihre Bearbeitung überhaupt durchführen, wenn sie gewusst hätten, was die andere Person tut
- Dieses Problem hängt auch damit zusammen, dass solche Algorithmen keiner kausalen Reihenfolge folgen können
Offline-Bearbeitung ist eher ein UI/UX-Problem
- Moment hatte gehofft, dass sich durch die Implementierung anspruchsvoller Algorithmen echte Offline-Bearbeitung gewissermaßen nebenbei mit unterstützen ließe, doch nach der Bewertung erscheint das nicht mehr plausibel
- Dass Nutzer die Algorithmus-Ergebnisse als Datenbeschädigung wahrnahmen, war nachvollziehbar; die seltsamen Resultate stecken im Algorithmus selbst und treten häufig genug auf, um in der Praxis relevant zu sein
- Eine andere Lesart ist, dass kollaboratives Editieren erhebliche UI/UX-Ressourcen erfordert
- Algorithmen können das Problem nicht vollständig lösen, aber sie können Teil einer Lösung sein
git-Merge-UI und Forschungsrichtungen
- Mit
gitgibt es bereits eine breit etablierte UI für das Mergen von Dokumenten - Die Forschungsfrage ist eher, wie sich diese Erfahrung zugänglicher, verständlicher und stärker automatisieren lässt
- Um 2009 gab es viele Diskussionen über die Algorithmen, die git für automatisches Mergen von Änderungen verwendet
- git übernahm den Myers O(ND) diff algorithm, einen Algorithmus, der zuvor vor allem von Biologen für BLAST-artige Sequenzanalysen genutzt wurde
- Bram Cohen empfand die diff-Ergebnisse als wenig intuitiv und entwickelte den patience diff algorithm; dieser wurde in bzr übernommen, einem inzwischen eingestellten Konkurrenzwerkzeug zu git
- Damals konzentrierte sich die Diskussion darauf, für Menschen lesbare Diffs zu erzeugen; heute geht es eher darum, ob Algorithmen dieses Ergebnis ohne menschliches Eingreifen erreichen können
- Forschung wie die collaborative history von Ink & Switch behandelt kollaboratives Editieren als UI/UX-Problem
1 Kommentare
Meinungen auf Hacker News
Ich bin der Autor von Eg-walker und ShareJS. Der Beitrag wirkt zwar, als richte er sich gegen meine Arbeit, aber tatsächlich stimme ich vollständig zu und sage auf HN seit einigen Jahren dasselbe.
Die heutigen Tools für Echtzeit-Kollaboration funktionieren gut, wenn alle gemeinsam online bearbeiten. Wenn Nutzer aber offline oder auf langlebigen Branches arbeiten, braucht es beim Mergen Konfliktmarkierungen und die Option zur manuellen Prüfung. Besonders bei Code ist das so.
Zum Glück speichern Algorithmen wie egwalker die Bearbeitungsspuren aller Nutzer auf Zeichenebene und die kausale Reihenfolge, also eine Änderungsreihenfolge wie ein Git-DAG, und haben damit viel mehr Informationen als Git. Daher sollte es möglich sein, ein CRDT zu bauen, das beim Mergen von Branches Konfliktbereiche erkennt und markiert und Nutzer sie manuell auflösen lässt.
Algorithmisch ist das interessant, aber es wirkt wie ein lösbares Problem; merkwürdigerweise scheint es im Bereich Textbearbeitung bisher kaum jemand versucht zu haben. Wenn man einen originellen und wertvollen Beitrag in diesem Feld leisten möchte: Das ist ein wichtiges fehlendes Teil im CRDT-Ökosystem, also hoffe ich, dass es jemand ausprobiert.
[1] Weiter unten in diesem Kommentar: https://news.ycombinator.com/item?id=19889174
Die nächste interessante Herausforderung entsteht, wenn es Konflikte rund um die Konfliktlösung selbst gibt.
Die Bewertung solcher Systeme ist an sich schon ein schwieriges technisches Problem, und ich denke, viele Teams werden damit zu kämpfen haben. Deshalb verdienen sie praktische Ratschläge, und ich wünschte, wir hätten das früher gewusst.
Der schwierige Teil ist, zu markieren, dass ein Konflikt gelöst wurde. Es könnte so einfach sein, dem CRDT ein Feld hinzuzufügen; dann weiß ich aber nicht, ob man das schon als algorithmische Lösung betrachten sollte.
[1] https://josephg.com/blog/crdts-go-brrr/
Wenn es um das Bearbeiten von Programmcode geht, erwartet man, dass das Merge-Ergebnis ein gültiges Programm ist; damit wird es zu einem viel tieferen Kaninchenbau. Ich habe gehört, dass es bei JetBrains ein Projekt gab, das dieses Problem mit AST-basiertem Merging lösen wollte, man nach deutlich tieferem Einstieg aber zu dem Schluss kam, dass es den Aufwand nicht wert ist.
Die einzige „Offline-Bearbeitung“, die ich bei von Menschen genutzten Dokumenten zulasse, ist das Hinzufügen von Kommentaren. Keine Bearbeitung und kein automatisches Merging.
Für „Offline-Bearbeitung“ von Quellcode, der ein Ziel von Automatisierung ist, verwendet man Git. Git tut nicht so, als löse es Merges; es zeigt nur Revisionen an. Merging ist eine Aufgabe, die von Menschen beaufsichtigt oder von spezialisierter Automatisierung nach bester Schätzung ausgeführt wird, und um den Erfolg zu prüfen, braucht es weiterhin Reviews und Tests.
Mechanische Merge-Algorithmen können je nach Konfliktart besser oder schlechter abschneiden, aber letztlich kann kein CRDT beurteilen, ob der gemergte Text das ist, was die Nutzer sagen wollten.
Das Upwelling-Paper behandelt ausführlicher den Unterschied zwischen dem, was es beim Schreiben semantische Konflikte und grammatische Konflikte nennt: https://inkandswitch.com/upwelling/
Ernsthafte Kollaboration ist am Ende wohl auch ein Problem des Dokumenten-Reviews. Im Journalismus oder in wissenschaftlichen Publikationen gilt das besonders; bei Besprechungsnotizen kann man es meist ignorieren.
Ich wollte auch auf Upwelling verlinken, konnte mich aber nicht an den Namen erinnern und habe wegen der Deadline stattdessen einen anderen Link genommen.
Eine weitere dunkle Seite von CRDT-Implementierungen ist die Infrastrukturlast. Ich habe darüber früher einmal ausführlich geschrieben[0], und ich war froh zu sehen, dass Supabase vor ein paar Jahren in seinem Beitrag zu einer CRDT-Erweiterung für Postgres[1] zu denselben Schlussfolgerungen kam wie meine empirischen Ergebnisse.
Wenn man CRDTs verwenden will, sollte man eher etwas wie Redis einsetzen oder, auch wenn der Speicherverbrauch schon beim Gedanken daran schmerzt, MyRocks[2] oder etwas auf Basis von RocksDB/LevelDB verwenden. Was auch immer man tut: Man sollte kein RDBMS, insbesondere Postgres, als Backend verwenden.
[0]: https://news.ycombinator.com/item?id=40834759
[1]: https://supabase.com/blog/postgres-crdt
[2]: http://myrocks.io
Die Beobachtungen in diesem Text sind zutreffend. CRDTs sind ein hervorragendes formales Modell für verteilte Datenstrukturen, aber die Vorstellung, dass sie alle Konflikte automatisch lösen müssten – schon dem Namen nach konfliktfreie replizierte Datentypen –, hat sich für mich immer unangenehm angefühlt.
Wie der Text zeigt, halte ich das für ein aussichtsloses Unterfangen. Was nötig ist, ist eine saubere strukturelle Darstellung, mit der Konflikte geteilt und kollaborativ gelöst werden können; man muss den Nutzern die Kontrolle zurückgeben und den Lösungsprozess unterstützen. Einer meiner Lieblingsaufsätze, „Turning Conflicts into Collaboration“ [1], behandelt diese Idee überzeugend.
Im Rahmen meiner laufenden Doktorarbeit habe ich mit „Lazy Merging: From a Potential of Universes to a Universe of Potentials“ [2] ein formales Modell für strukturelle Konfliktdarstellung auf Basis der Verbandstheorie entwickelt. Zufällig ist auch das ein CRDT, aber es versucht nicht, Konflikte automatisch zu lösen, sondern stellt sie innerhalb des kollaborativen Dokuments dar. Durch den mathematischen Ansatz konnte ich zu einem einfachen konzeptionellen Modell gelangen, das auch nach wiederholtem Mergen bestehender Konflikte starke Eigenschaften wie Vollständigkeit, Minimalität und Eindeutigkeit des Merges garantiert; außerdem ist die Berechnung des Merges sehr einfach.
[1] https://doi.org/10.1007/s10606-012-9172-4
[2] https://doi.org/10.14279/tuj.eceasst.82.1226
Konflikte sind ein komplexes Konzept, und „conflict-free“ ist als Beschreibung des Ergebnisses technisch korrekt, kann aber, wie dieser Text und der obige Kommentar zeigen, Missverständnisse erzeugen.
Kommutativität bedeutet, dass Bob Änderungen in der Reihenfolge [Bob, Alice] anwenden kann und Alice sie in der Reihenfolge [Alice, Bob], und beide trotzdem beim selben Dokument landen. Es bedeutet nicht, dass das Dokument auf einer höheren Abstraktionsebene auf sinnvolle Weise „konfliktfrei“ wäre.
Die Vorstellung, dass mehrere unterschiedliche Akteure ohne Echtzeit-Koordination gleichzeitig Autorität über ein und dasselbe Datenstück haben, ist meiner Meinung nach allgemein nicht lösbar. Das ist eine Lektion, die wir in verteilten Systemen bereits gelernt haben, und sie wird auch in diesem Text deutlich, wenn man an verteilte Dokumentbearbeitung denkt.
Dasselbe Prinzip dürfte auch für ganz andere Beispiele gelten, die einem einfallen könnten: doppelte Eingaben im Cockpit eines Flugzeugs, Kindererziehung und so weiter.
Und es ist ohnehin witzig, das „lösbar“ zu nennen, weil derzeit große Teile der Welt offenbar nahe daran sind zu akzeptieren, dass die chaotische Ausgabe von LLMs das endgültige Ergebnis von Berechnungen bestimmt.
Die in kollaborativer Textbearbeitung häufig verwendeten Algorithmen CRDT und OT haben strenge algebraische Anforderungen daran, was Editieroperationen tun und wie sie miteinander interagieren.
Selbst wenn der Server also schlau genug wäre, das „Colour“-Beispiel aus UX-Sicht sinnvoll zu behandeln, wäre es sehr schwierig, ein entsprechendes CRDT/OT für optimistische clientseitige Bearbeitung zu entwerfen.
Ohne CRDT/OT kann man das umgehen. Zum Beispiel könnte der Server Operationen in Empfangsreihenfolge verarbeiten und die gewünschte UX-Logik anwenden, während die Clients darüber eine Rebase-/Vorhersagestrategie nutzen, um optimistische Bearbeitung zu erlauben. Siehe: https://doc.replicache.dev/concepts/how-it-works
Auch die Anwendung davon auf Textbearbeitung hat Schwierigkeiten, aber die sind von den hier diskutierten CRDT/OT-Problemen getrennt.
Ich denke, das passiert, weil mathematische, kausale und entropische Konfliktbegriffe mit semantischen Konflikten vermischt werden. Ich habe früher denselben Fehler in umgekehrter Richtung gemacht und mir wurde ziemlich entschieden gesagt, dass ich nicht wüsste, wovon ich rede.
Sobald man anfängt, Bäume zu betrachten, wird es noch viel unordentlicher. yJS zum Beispiel arbeitet auf JSON-Dokumenten. Wenn die UI nur eine flache Ebene zeigt und tiefere Ebenen nicht aufgeklappt sind, sieht der Nutzer gelöschte Bearbeitungen möglicherweise überhaupt nicht.
Eine Klasse konfliktbewahrender CRDTs – soweit ich mich erinnere, am ehesten solche, bei denen ein Register mehrere Werte haben kann – wirkt am vielversprechendsten. Nutzern sollten solche Konflikte präsentiert werden; man könnte sie sogar vollständig visuell darstellen. Auch das Durchsehen der Historie zu ermöglichen, erscheint als praktische Alternative, damit Nutzer nachvollziehen können, wie etwas Merkwürdiges entstanden ist oder wie ihre eigene Änderung verschwunden ist.
Ich erinnere mich, dass Torvalds selbst ziemlich pessimistisch war, was sich mit automatischem Merging erreichen lässt. Und diese Einschätzung war richtig.
Er sagte, Git habe die Vorstellung zurückgewiesen, ein Versionsverwaltungssystem könne oder solle das „Merge-Problem lösen“, indem ein ausreichend intelligenter Algorithmus automatisch das Richtige tut.
Ich stimme zu, dass Offline-Bearbeitung ein UI/UX-Problem ist. Die tiefere Ursache ist die Gewohnheit der Computerbranche, alte Lösungen nachzuahmen, und der Glaube: „Da ein 5-Pfund-Sack im Allgemeinen leichter zu handhaben ist als ein 10-Pfund-Sack, sollte man 10 Pfund Zeug in einen einzigen 5-Pfund-Sack packen.“
Das Grundbild eines „Texteditors“ ist eine Mosaic-Textarea, MacWrite oder irgendetwas dazwischen, daher versucht man normalerweise, Merging mit möglichst minimalen Änderungen daraufzusetzen. Etwa als Menüeintrag oder mit ein paar Optionen in einem kleinen Dialog. Selbst wenn es tief in den Menüs GUI-Unterstützung fürs Mergen gibt, ist sie entweder ein diff/merge-Horror für Programmierer oder bleibt bei einer wackligen, auf Durchstreichungen basierenden Ansicht, als würde man ein Schiff im Nebel steuern.
Bei einem Texteditor mit Offline-Zusammenarbeit ist teilweises manuelles Merging jedoch der Kern des Prozesses und sollte auch im Zentrum des Editor-Designs stehen. Leider ist MacWrite ein lokales Optimum, aus dem man nur schwer herauskommt.
Wenn jemand von „Cargo-Cult-Nachahmung“ und „alten Lösungen“ spricht, lautet der nächste Satz zum Beispiel oft: „Bearbeitet Code nicht als Text, sondern als Syntaxbaum.“ Das Problem bleibt aber dasselbe. Man muss nur „Zeichen“ durch „Anweisung“ ersetzen.
Wenn Bob im
else-Zweig einerif-Anweisung eine Zeile hinzugefügt hat und Alice die gesamte Anweisung samtelse-Zweig gelöscht hat: Was soll ein intelligentes System dann tun?Insgesamt scheinen wir uns einig zu sein, dass dieser Ansatz richtig ist.
Fragen oder Feedback nehme ich gern entgegen. Ich bin zwar ein, zwei Stunden in Meetings, aber ich rede gern über solche Dinge. Schreibt mir hier oder per E-Mail, wie es euch lieber ist: alex@moment.dev
Git mischt lokale Änderungen nicht ohne ausdrückliche Zustimmung automatisch hinein. bzr hätte von so etwas vermutlich nicht einmal geträumt. Dinge wie Google Docs tun das aber bereitwillig.
Der bisherige Fortschritt ist großartig, und ich hoffe, dass auch das Early-Access-Programm gut läuft.
Ich habe differential sync (https://neil.fraser.name/writing/sync/) implementiert, weil ich die anderen Ansätze nicht verstanden habe und dies für die App grugnotes.com am einfachsten wirkte.
Die App ist ziemlich grob und nicht vollständig echtzeitfähig, aber den Merge aus dem Beispiel behandelt sie korrekt, egal wer zuerst wieder online kommt. Wenn die Löschung zuerst online ankommt, wird die
colour-Version verworfen und nicht einmal im Bearbeitungsverlauf gespeichert.Es gibt sicher weitere Probleme, und ich weiß nicht, wie es bei mehr als zwei Nutzern aussieht, aber für meinen Anwendungsfall bin ich zufrieden.