2 คะแนน โดย GN⁺ 2024-12-08 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • จากการประเมินระบบ การแก้ไขร่วมกัน สำหรับเอดิเตอร์ข้อความหลักของ Moment พบว่าอัลกอริทึมตระกูล CRDT และ OT สามารถสร้างผลการรวมที่ผู้ใช้อาจมองว่าเป็นข้อมูลเสียหายได้เมื่อเกิด ความขัดแย้งโดยตรงขณะออฟไลน์
  • แม้ในกรณีง่าย ๆ ที่ Alice ลบทั้งประโยคและ Bob เปลี่ยน Color เป็น Colour ก็ยังอาจเกิด ผลลัพธ์ที่มนุษย์ไม่ได้ตั้งใจ เช่น เหลือเพียงอักขระ u ในเอกสารสุดท้าย
  • ในกรณีใช้งานของ Moment ความขัดแย้งโดยตรงที่ลองทดสอบประมาณ 20~30% ให้ผลลัพธ์ที่ยอมรับได้ยาก และมองว่ายากจะปกป้องในเชิงประสบการณ์ผลิตภัณฑ์ทั้งจากความถี่ที่เกิดและปฏิกิริยาเชิงลบ
  • Yjs, ShareJS และ Peritext ต่างชูจุดเด่นเรื่องการแก้ไขแบบออฟไลน์ การทำงานร่วมกันที่มีความหน่วงยาวนาน หรือการรวมสำเนาอิสระโดยอัตโนมัติ แต่ตัวอัลกอริทึมไม่อาจรู้เจตนาหรือลำดับของผู้ใช้ จึงต้องพึ่งพา heuristic
  • การแก้ไขร่วมกันแบบออฟไลน์ไม่ใช่ปัญหาของอัลกอริทึมล้วน ๆ แต่ใกล้เคียงกับปัญหา UI/UX มากกว่า และต้องการประสบการณ์การรวมที่มนุษย์อ่านและตัดสินใจได้ เช่น UI การรวมของ git หรือ collaborative history ของ Ink & Switch

ข้อจำกัดที่ปรากฏจากการประเมินการแก้ไขร่วมกันของ Moment

  • ต้นปี 2024 Moment เริ่มสำรวจระบบ การแก้ไขร่วมกัน สำหรับใช้กับเอดิเตอร์ข้อความหลัก
  • อัลกอริทึมหลายแบบอ้างว่าไม่เพียงรองรับการแก้ไขพร้อมกันแบบออนไลน์ แต่ยังครอบคลุม กรณีออฟไลน์ ที่ผู้ใช้แก้ไขขณะออฟไลน์ได้นานไม่จำกัดก่อนกลับมาออนไลน์แล้วให้ระบบรวมการเปลี่ยนแปลงอัตโนมัติด้วย
  • ตอนแรกหลังจากอ่านงานวิจัยและดูการนำเสนอ ก็หวังว่าชุมชนด้านการแก้ไขร่วมกันคงไปถึง “คำตอบที่ถูกต้อง” สำหรับปัญหาโดยรวมแล้ว
  • แต่ระหว่างการประเมิน อัลกอริทึมตระกูล CRDT และ OT จัดการความขัดแย้งจากการแก้ไขโดยตรงได้อย่างไม่เป็นธรรมชาติ และผู้ใช้รับรู้ผลลัพธ์นั้นว่าเป็น ข้อมูลเสียหาย
  • เนื่องจากการแก้ไขแบบออฟไลน์เพิ่มโอกาสเกิดความขัดแย้งโดยตรงอย่างมาก จึงยากที่ Moment จะสร้างประสบการณ์การแก้ไขออฟไลน์ตามต้องการได้ด้วยอัลกอริทึมเหล่านี้เพียงอย่างเดียว

กรณีง่าย ๆ ที่การลบชนกับการแก้ตัวสะกด

  • Alice และ Bob ต่างแก้ไขเอกสารเดียวกันขณะ ออฟไลน์
  • ในเอกสารมีข้อความ The Color of Pomegranates
  • Bob เปลี่ยนการสะกด Color เป็นแบบอังกฤษ Colour ส่วน Alice ลบข้อความทั้งหมด
  • เมื่อทั้งสองกลับมาออนไลน์ภายหลัง การแก้ไขทั้งสองจึงขัดแย้งกัน และระบบต้องปรับให้เข้ากันโดยไม่รู้ว่าการแก้ไขใดเกิดก่อน
  • ในกรณีนี้ Alice และ Bob จะได้เอกสารสุดท้ายที่มีเพียงอักขระ u
    • นี่ไม่ใช่ทั้งประโยคที่ใช้ได้ และไม่ใช่แม้แต่คำที่ใช้ได้
    • ผู้ใช้จะรับรู้ผลลัพธ์แบบนี้ว่า Moment ทำข้อมูลของตนเสียหาย

ผลลัพธ์ประหลาดจากความขัดแย้งโดยตรงไม่ได้เกิดขึ้นน้อย

  • ความขัดแย้งนี้เป็นการชนกันของการแก้ไขที่เล็กน้อยและตรงไปตรงมา แต่ก็ยังอยู่ในขอบเขตที่อัลกอริทึมการแก้ไขร่วมกันยอดนิยมอ้างว่ารองรับ
  • ผลลัพธ์ที่ได้จริงคือ เอกสารที่มนุษย์จะไม่เขียนขึ้นเอง และถูกตีความว่าเป็นการที่ผลิตภัณฑ์ Moment ทำข้อมูลเสียหาย
  • แม้รายละเอียดจะต่างกันไปตามกรณีใช้งาน แต่ในความขัดแย้งโดยตรงที่ Moment ทดลอง ประมาณ 20~30% ให้ผลลัพธ์ที่ยอมรับได้ยากในกรณีใช้งานการแก้ไขออฟไลน์
  • เมื่อพิจารณาร่วมกับความถี่ที่เกิดและฟีดแบ็กลบ จึงเห็นว่ายากที่จะอธิบายและปกป้องผลลัพธ์เช่นนี้ต่อผู้ใช้

เครื่องมือต่าง ๆ ที่ชูจุดเด่นเรื่องรองรับการแก้ไขแบบออฟไลน์

  • ตอนแรกเมื่อเห็นผลลัพธ์แบบนี้ ก็คิดว่าอาจเข้าใจความหมายที่เครื่องมือเหล่านี้ให้ไว้ผิด
  • แต่เมื่อดูคำอธิบายของแต่ละโครงการ ก็อ่านได้ว่าสถานการณ์นี้อยู่ในขอบเขตที่รองรับ
    • Yjs ระบุไว้ใน README อย่างชัดเจนว่ารองรับ offline editing
    • ShareJS อธิบายว่าสามารถทำงานร่วมกันได้กับความหน่วงทุกรูปแบบ ตั้งแต่ 0 ไปจนถึงระดับหยุดยาวหลายสัปดาห์
    • Peritext อธิบายว่าสามารถให้ผู้ใช้แก้ไขสำเนาเอกสารที่แยกจากกัน และรวมกลับโดยอัตโนมัติในลักษณะที่พยายามรักษาเจตนาของผู้ใช้ไว้ให้มากที่สุด
  • Moment ยังคงมองหาวิธีแก้ปัญหานี้อยู่ แต่เห็นว่ายากที่จะทำให้ความถี่และรูปแบบของข้อผิดพลาดที่พบจริงสอดคล้องกับคำกล่าวอ้างเหล่านี้

ข้อจำกัดพื้นฐานของอัลกอริทึมที่ไม่มีการไกล่เกลี่ย

  • เมื่อการประเมินดำเนินต่อไป ก็ได้ข้อสรุปว่าอัลกอริทึมเหล่านี้ไม่ทำงานในแบบที่ Moment ต้องการ
  • คำถามที่เหลือคือ ปัญหานี้แก้ได้ด้วยการร่วมพัฒนาหรือไม่ หรือเป็น ข้อจำกัดพื้นฐาน ของอัลกอริทึมกันแน่
  • เหตุผลที่มองว่าเป็นปัญหาพื้นฐานมี 3 ข้อ
    • อัลกอริทึมไม่อาจรู้เจตนาของ Alice และ Bob ได้ และไม่อาจส่งอีเมลไปถามว่าทั้งคู่ต้องการอะไร หรือให้ตรวจทานแบบ UI ของ GitHub Pull Request ได้
    • มันต้องรับข้อเสนอการลบทั้งหมดของ Alice และข้อเสนอการแก้ตัวสะกดของ Bob แล้วตัดสินผลลัพธ์ด้วย heuristic
    • มันทำงานในระดับอักขระ และให้การรับประกันต่อผลลัพธ์เพียงอย่างอ่อนมาก
    • หาก Alice และ Bob รู้ว่าอีกฝ่ายกำลังทำอะไร พวกเขาอาจตัดสินใจแก้ไขต่างออกไป
  • ประเด็นนี้ยังเชื่อมโยงกับปัญหาที่ว่าอัลกอริทึมแบบนี้ไม่อาจยึดตามลำดับเชิงเหตุและผลได้

การแก้ไขแบบออฟไลน์ใกล้เคียงกับปัญหา UI/UX มากกว่า

  • Moment เคยคาดหวังว่าหากใช้อัลกอริทึมที่ซับซ้อน ก็จะรองรับการแก้ไขออฟไลน์อย่างแท้จริงได้เป็นผลพลอยได้ แต่หลังการประเมินก็ยากจะมองเช่นนั้น
  • การที่ผู้ใช้มองผลลัพธ์จากอัลกอริทึมว่าเป็นข้อมูลเสียหายนั้นสมเหตุสมผล และผลลัพธ์ประหลาดก็เป็นส่วนหนึ่งของตัวอัลกอริทึมเอง อีกทั้งเกิดบ่อยพอจะกลายเป็นปัญหาจริงได้
  • อีกมุมหนึ่งคือ การแก้ไขร่วมกันต้องลงทุนทรัพยากรด้าน UI/UX อย่างมาก
  • อัลกอริทึมไม่อาจแก้ปัญหานี้ได้ทั้งหมด แต่สามารถเป็นส่วนหนึ่งของวิธีแก้ได้

UI การรวมแบบ git และทิศทางการวิจัย

  • git คือ UI สำหรับการรวมเอกสารที่ได้รับการยอมรับอย่างแพร่หลายอยู่แล้ว
  • คำถามเชิงวิจัยจึงใกล้เคียงกับว่า จะทำให้ประสบการณ์นี้เข้าถึงง่าย เข้าใจง่าย และทำงานอัตโนมัติได้มากขึ้นเพียงใด
  • ราวปี 2009 มีการถกเถียงกันมากเกี่ยวกับอัลกอริทึมที่ git ใช้สำหรับรวมการเปลี่ยนแปลงโดยอัตโนมัติ
    • git เลือกใช้ Myers O(ND) diff algorithm ซึ่งเดิมอัลกอริทึมนี้ถูกนักชีววิทยาใช้เป็นหลักในการวิเคราะห์ลำดับแบบตระกูล BLAST
    • Bram Cohen มองว่าผลลัพธ์ของ diff ไม่เป็นธรรมชาติ จึงสร้าง patience diff algorithm ขึ้นมา และมันถูกนำไปใช้ใน bzr ซึ่งเป็นเครื่องมือคู่แข่งของ git ที่ปัจจุบันยุติไปแล้ว
  • การถกเถียงในตอนนั้นมุ่งไปที่การสร้าง diff ที่มนุษย์อ่านได้ แต่การถกเถียงในปัจจุบันใกล้เคียงกับคำถามว่าอัลกอริทึมจะบรรลุผลลัพธ์นั้นได้หรือไม่โดยไม่ต้องมีมนุษย์เข้ามาเกี่ยวข้อง
  • มีงานวิจัยที่กำลังดำเนินอยู่ซึ่งมองการแก้ไขร่วมกันเป็นปัญหา UI/UX เช่น collaborative history ของ Ink & Switch

1 ความคิดเห็น

 
GN⁺ 2024-12-08
ความคิดเห็นใน Hacker News
  • ผมเป็นผู้เขียน Eg-walker และ ShareJS แม้บทความจะดูเหมือนมีโทนคัดค้านงานของผม แต่จริง ๆ แล้วผมเห็นด้วยเต็มที่ และก็พูดเรื่องเดียวกันนี้ใน HN มาหลายปีแล้ว
    เครื่องมือทำงานร่วมกันแบบเรียลไทม์ในปัจจุบันเหมาะมากเมื่อทุกคนออนไลน์และแก้ไขร่วมกัน แต่ถ้าผู้ใช้แก้ไขแบบออฟไลน์หรือบน branch ที่คงอยู่นาน ตอน merge จำเป็นต้องมี การแสดง conflict และตัวเลือกให้ตรวจสอบด้วยมือ โดยเฉพาะอย่างยิ่งกับโค้ด
    โชคดีที่อัลกอริทึมอย่าง egwalker เก็บร่องรอยการแก้ไขระดับตัวอักษรของผู้ใช้ทุกคน รวมถึงลำดับเชิงเหตุผล หรือก็คือลำดับการเปลี่ยนแปลงแบบ Git DAG จึงมีข้อมูลมากกว่า Git อย่างมาก ดังนั้นน่าจะสร้าง CRDT ที่ตรวจจับและแสดงช่วงที่ conflict ตอน merge branch ได้ และให้ผู้ใช้แก้ไขเองได้
    ในเชิงอัลกอริทึมเป็นปัญหาที่น่าสนใจ แต่ดูเหมือนแก้ได้พอสมควร และแปลกที่ในฝั่งการแก้ไขข้อความแทบยังไม่มีใครลองทำเลย ถ้าอยากสร้างผลงานที่แปลกใหม่และมีคุณค่าในด้านนี้ นี่คือชิ้นส่วนสำคัญที่ยังขาดใน ระบบนิเวศ CRDT จึงหวังว่าจะมีใครสักคนลองทำ
    [1] ส่วนล่างของคอมเมนต์นี้: https://news.ycombinator.com/item?id=19889174

    • ถ้าทำแบบนั้น สุดท้ายก็เท่ากับใส่ conflict เข้าไปเป็นส่วนหนึ่งของ data model วิธีนี้น่าสนใจในฐานะวิธีทำให้ได้ C ใน CRDT หรือ “conflict-free” แต่ก็สมเหตุสมผลเต็มที่ และอาจเป็นวิธีเดียวก็ได้
      ความท้าทายที่น่าสนใจถัดไปคือเมื่อเกิด conflict รอบ ๆ การ resolve conflict เอง
    • Joseph ผมไม่ได้ตั้งใจจะบอกว่างานของคุณไม่ดี เจตนาคือช่วยให้ผู้ปฏิบัติงานเข้าใจว่าคาดหวังอะไรได้บ้าง และสร้างแรงจูงใจให้กับปัญหาอย่างที่พูดไว้ตอนท้าย
      ผมคิดว่าการประเมินระบบแบบนี้เองก็เป็นปัญหาทางเทคนิคที่ยากพออยู่แล้ว หลายทีมคงลำบากกับมัน ดังนั้นพวกเขาสมควรได้คำแนะนำเชิงปฏิบัติ และผมก็รู้สึกว่าเราน่าจะรู้เรื่องนี้เร็วกว่านี้
    • ผมไม่แน่ใจว่าจะมีวิธีแก้เชิงอัลกอริทึมหรือไม่ แต่ดูเหมือนจัดการได้ที่ ชั้น UX เหนือขึ้นไป เช่น client อาจตรวจจับ conflict จากร่องรอยการแก้ไข แล้วแสดงกล่องโต้ตอบสำหรับ resolve conflict ที่สร้างผลลัพธ์การแก้ไขเป็นการแก้ไขใหม่
      ส่วนที่ยากคือการทำเครื่องหมายว่า conflict ถูกแก้แล้ว อาจง่ายแค่เพิ่ม field หนึ่งใน CRDT ก็ได้ ซึ่งผมก็ไม่แน่ใจว่าควรมองว่านั่นเป็นวิธีแก้เชิงอัลกอริทึมหรือไม่
      [1] https://josephg.com/blog/crdts-go-brrr/
    • บทความพูดถึงกรณี splice พร้อมกันที่ซ้อนทับกัน ซึ่งเป็น edge case แปลก ๆ ที่รู้จักกันดี
      ถ้าเป็นการแก้โค้ดโปรแกรม จะยิ่งลงหลุมลึกกว่านั้นมาก เพราะคาดหวังว่าผลลัพธ์จากการ merge ต้องเป็นโปรแกรมที่ถูกต้อง เคยได้ยินว่า JetBrains มีโปรเจกต์ที่พยายามแก้ปัญหานี้ด้วย การ merge แบบอิง AST แต่หลังจากขุดลึกลงไปมาก ก็สรุปว่าไม่คุ้มที่จะทำ
    • ผมมองว่าการแก้ไขแบบ “ออฟไลน์” เป็นปัญหาของมนุษย์ จึงแก้ด้วย automation ไม่ได้ คนจะหาวิธีทำลายหรือเลี่ยง automation หรือระบบได้เสมอ
      “การแก้ไขแบบออฟไลน์” ที่ยอมรับได้ในเอกสารที่คนใช้ คือการเพิ่มคอมเมนต์เท่านั้น ไม่ใช่การแก้ไข และไม่มีการ merge อัตโนมัติ
      สำหรับ “การแก้ไขแบบออฟไลน์” ของซอร์สโค้ดที่เป็นเป้าหมายของ automation เราใช้ Git ซึ่ง Git ไม่ได้แสร้งว่าจะแก้ merge ให้ แค่แสดง revision เท่านั้น การ merge เป็นงานที่มนุษย์ควบคุมดูแล หรือ automation เฉพาะทางทำการคาดเดาที่ดีที่สุด และการตรวจสอบว่าสำเร็จหรือไม่ก็ยังต้องอาศัย review และ test อยู่ดี
  • อัลกอริทึม merge เชิงกลอาจทำได้ดีหรือแย่ต่างกันไปตามชนิดของ conflict แต่ท้ายที่สุดไม่มี CRDT ใดตัดสินได้ว่าข้อความที่ merge แล้วเป็นสิ่งที่ผู้ใช้ต้องการจะสื่อหรือไม่
    บทความ Upwelling พูดถึงความแตกต่างระหว่างสิ่งที่เรียกว่า semantic conflict กับ conflict ทางไวยากรณ์ในการเขียนอย่างละเอียดกว่า: https://inkandswitch.com/upwelling/
    ผมรู้สึกว่างานร่วมกันอย่างจริงจังสุดท้ายก็เป็นปัญหาเรื่องการ review เอกสารด้วย โดยเฉพาะในงานวารสารศาสตร์หรือการตีพิมพ์ทางวิทยาศาสตร์ ส่วนในบันทึกการประชุมโดยทั่วไปอาจมองข้ามได้

    • Peter ขอบคุณสำหรับคำพูดดี ๆ หวังว่าจะเห็นว่าบทความส่วนใหญ่จบไปในทิศทางที่สร้างแรงจูงใจให้กับงานของ Ink & Switch ที่กล่าวถึงตรง ๆ ตอนท้าย
      ผมตั้งใจจะลิงก์ไปที่ Upwelling ด้วย แต่จำชื่อไม่ได้ เลยใช้ลิงก์อื่นแทนเพราะติดเดดไลน์
  • อีกด้านมืดของการ implement CRDT คือ ภาระของโครงสร้างพื้นฐาน ผมเคยเขียนเรื่องนี้ไว้อย่างละเอียดก่อนหน้านี้[0] และดีใจที่พบว่า Supabase ก็ได้ข้อสรุปเดียวกับผลเชิงประสบการณ์ของผมในบทความเรื่องส่วนขยาย CRDT สำหรับ Postgres[1] เมื่อไม่กี่ปีก่อน
    ถ้าจะใช้ CRDT ควรใช้บางอย่างอย่าง Redis หรือไม่ก็ใช้ฐานที่เป็น MyRocks[2] หรือ RocksDB/LevelDB แม้แค่คิดถึงการใช้หน่วยความจำก็ปวดใจแล้วก็ตาม ไม่ว่าจะทำอะไร อย่าใช้ RDBMS โดยเฉพาะ Postgres เป็น backend
    [0]: https://news.ycombinator.com/item?id=40834759
    [1]: https://supabase.com/blog/postgres-crdt
    [2]: http://myrocks.io

    • กำลังทำเองด้วย Yjs + Postgres อยู่ เลยดูมีประโยชน์มากจริง ๆ สักวันหนึ่งอาจช่วยให้หลบวิกฤตใหญ่ได้
  • ข้อสังเกตในบทความนี้ถูกต้อง CRDT เป็นโมเดลเชิงรูปแบบที่ยอดเยี่ยมสำหรับโครงสร้างข้อมูลแบบกระจาย แต่แนวคิดที่ว่ามันควรจะแก้ทุกความขัดแย้งโดยอัตโนมัติ หรือแนวคิดตามชื่อว่า ชนิดข้อมูลจำลองแบบไร้ความขัดแย้ง นั้นทำให้รู้สึกขัดใจมาตลอด
    อย่างที่บทความแสดงให้เห็น ผมมองว่านี่เป็นความพยายามที่ไม่มีทางสำเร็จ สิ่งที่จำเป็นคือการแทนความขัดแย้งเชิงโครงสร้างที่เหมาะสม เพื่อให้แชร์ความขัดแย้งและแก้ร่วมกันได้ โดยคืนการควบคุมให้ผู้ใช้และสนับสนุนกระบวนการแก้ไข หนึ่งในเปเปอร์ที่ผมชอบคือ “Turning Conflicts into Collaboration” [1] ซึ่งอธิบายแนวคิดนี้ได้อย่างน่าเชื่อถือ
    ในงานวิจัยปริญญาเอกที่กำลังทำอยู่ ผมได้พัฒนา “Lazy Merging: From a Potential of Universes to a Universe of Potentials” [2] ซึ่งเป็นโมเดลเชิงรูปแบบสำหรับการแทนความขัดแย้งเชิงโครงสร้างบนพื้นฐานทฤษฎีแลตทิซ บังเอิญว่าสิ่งนี้ก็เป็น CRDT เช่นกัน แต่ไม่ได้พยายามแก้ความขัดแย้งอัตโนมัติ หากแต่แสดงมันไว้ในเอกสารที่ทำงานร่วมกัน เมื่อเข้าหาด้วยคณิตศาสตร์ จึงไปถึงโมเดลแนวคิดที่เรียบง่ายซึ่งรับประกันคุณสมบัติที่แข็งแรงอย่างความครบถ้วน ความน้อยที่สุด และความเป็นเอกลักษณ์ของการผสานได้ แม้หลังจากความขัดแย้งเดิมถูกผสานซ้ำหลายครั้งแล้วก็ตาม และการคำนวณการผสานก็ง่ายมาก
    [1] https://doi.org/10.1007/s10606-012-9172-4
    [2] https://doi.org/10.14279/tuj.eceasst.82.1226

    • ตอนที่ผมเรียนรู้ CRDT ครั้งแรก ตัวย่อย่อมาจาก commutative replicated data types หรือชนิดข้อมูลจำลองแบบที่สลับลำดับกันได้ ในเปเปอร์ของ Shapiro และคณะก็ใช้แบบนั้น ถึงจะออกเสียงยากกว่า แต่ผมชอบชื่อนี้มากกว่า
      ความขัดแย้งเป็นแนวคิดที่ซับซ้อน และแม้คำว่า “conflict-free” จะถูกต้องในเชิงเทคนิคเมื่อใช้บรรยายผลลัพธ์ แต่ก็อาจก่อให้เกิดความเข้าใจผิดได้ ดังที่เห็นจากบทความนี้และข้อความข้างต้น
      คุณสมบัติการสลับลำดับได้หมายถึง Bob นำการเปลี่ยนแปลงไปใช้ในลำดับ [Bob, Alice] และ Alice นำไปใช้ในลำดับ [Alice, Bob] แล้วทั้งคู่ยังไปถึงเอกสารเดียวกัน ไม่ได้หมายความว่าเอกสาร “ไร้ความขัดแย้ง” ในแบบที่มีความหมายบนระดับนามธรรมที่สูงกว่า
  • ผมมองว่าแนวคิดที่ให้หลายฝ่ายต่างกันมีอำนาจเหนือข้อมูลชิ้นเดียวพร้อมกันโดยไม่มีการประสานงานแบบเรียลไทม์นั้น โดยทั่วไปแก้ไม่ได้ นี่เป็นบทเรียนที่เราได้เรียนรู้กันมาแล้วใน ระบบแบบกระจาย และถ้าคิดถึงการแก้ไขเอกสารแบบกระจาย บทความนี้ก็แสดงให้เห็นชัดเจน
    หลักการเดียวกันน่าจะใช้ได้กับตัวอย่างอื่น ๆ ที่ต่างกันอย่างการควบคุมคู่ในห้องนักบิน การเลี้ยงลูก และกรณีอื่นใดที่นึกออก

    • แก้ได้ แต่ต้องมี ข้อมูลบริบท ที่ซับซ้อนกว่า ซึ่งคนจำนวนมากน่าจะขี้เกียจป้อน เช่น “คำที่เพิ่งเปลี่ยนนี้มีความหมายก็ต่อเมื่อเป็นส่วนหนึ่งของทั้งประโยคนี้ และทั้งประโยคนั้นก็ไม่ได้จำเป็นต่อทั้งย่อหน้า”
      และการเรียกสิ่งนี้ว่า “แก้ได้” ก็ออกจะขำ เพราะ ณ ตอนนี้ ดูเหมือนว่าผู้คนจำนวนมากบนโลกกำลังคิดว่าเอาต์พุตอันสับสนของ LLM อาจใกล้เคียงกับสิ่งที่กำหนดผลลัพธ์สุดท้ายของการคำนวณ
    • นี่คือ ทฤษฎีบท CAP ของ Brewer สำหรับการจัดเก็บข้อมูลแบบกระจาย ในสามอย่างนี้ คุณมีได้เพียงสองอย่าง: ความสอดคล้อง ความพร้อมใช้งาน และความทนทานต่อการแบ่งพาร์ทิชัน
  • อัลกอริทึมที่ใช้กันทั่วไปในการแก้ไขข้อความร่วมกันอย่าง CRDT และ OT มี ข้อกำหนดเชิงพีชคณิต ที่เข้มงวดเกี่ยวกับว่า operation การแก้ไขทำอะไรและโต้ตอบกันอย่างไร
    ดังนั้นแม้เซิร์ฟเวอร์จะฉลาดพอที่จะจัดการตัวอย่าง “Colour” ได้สมเหตุสมผลในเชิง UX การออกแบบ CRDT/OT ที่สอดคล้องกันสำหรับการแก้ไขฝั่งไคลเอนต์แบบ optimistic ก็ยังยากมาก
    ถ้าไม่ใช้ CRDT/OT ก็สามารถอ้อมปัญหาได้ เช่น ให้เซิร์ฟเวอร์ประมวลผล operation ตามลำดับที่ได้รับและใช้ตรรกะ UX ตามต้องการ ส่วนไคลเอนต์ใช้กลยุทธ์ rebase/การคาดการณ์ทับอยู่ด้านบน เพื่ออนุญาตให้แก้ไขแบบ optimistic ดูประกอบ: https://doc.replicache.dev/concepts/how-it-works
    การนำวิธีนี้ไปใช้กับการแก้ไขข้อความก็มีความยากของมันเอง แต่เป็นคนละเรื่องกับปัญหา CRDT/OT ที่ถกกันอยู่ตรงนี้

    • คอมเมนต์นี้ถูกประเมินค่าต่ำเกินไปมาก และเห็นด้วยทั้งหมด
  • ผมคิดว่าสิ่งนี้เกิดขึ้นเพราะแนวคิดเรื่องความขัดแย้งเชิงคณิตศาสตร์ เชิงเหตุและผล และเชิงเอนโทรปี ถูกปะปนเข้ากับ ความขัดแย้งเชิงความหมาย ผมเองก็เคยทำผิดแบบเดียวกันในทิศทางตรงข้าม แล้วถูกบอกอย่างหนักแน่นว่าผมไม่รู้ว่าตัวเองกำลังพูดอะไรอยู่
    พอเริ่มพิจารณา tree เรื่องก็ยิ่งเละเทะขึ้นมาก ตัวอย่างเช่น yJS ทำงานกับเอกสาร JSON ถ้า UI แสดงเฉพาะระดับตื้น ๆ และยังไม่ได้กางระดับลึก ผู้ใช้อาจไม่เห็นการแก้ไขที่ถูกลบไปเลยก็ได้
    CRDT ประเภทที่รักษาความขัดแย้งไว้เท่าที่จำได้ กรณีที่ register สามารถมีหลายค่าได้น่าจะดูมีโอกาสมากที่สุด ผู้ใช้ควรถูกนำเสนอความขัดแย้งเหล่านั้น และอาจแสดงให้เห็นแบบภาพล้วน ๆ ได้ด้วย การให้เลื่อนดู history ได้ก็ดูเป็นทางเลือกที่ใช้งานได้จริง เพื่อให้ผู้ใช้เข้าใจว่าเรื่องประหลาดเกิดขึ้นได้อย่างไร หรือการเปลี่ยนแปลงของตัวเองหายไปได้อย่างไร

    • ชื่อที่น่าจะเท่สำหรับ CRDT ประเภทนี้คือ “Git”
    • ในแง่นั้น Loro ดูมีอนาคต กำลังจัดการปัญหานี้อย่างจริงจัง
  • เท่าที่จำได้ Torvalds เองก็ค่อนข้างมองโลกในแง่ร้ายเกี่ยวกับสิ่งที่ทำได้ด้วยการ merge อัตโนมัติ และการตัดสินนั้นก็ถูกต้อง
    เขาเคยบอกว่า Git ปฏิเสธแนวคิดที่ว่าระบบควบคุมเวอร์ชันสามารถหรือควรจะ “แก้ปัญหา merge” ด้วยวิธีที่อัลกอริทึมที่ฉลาดพอจะทำสิ่งที่ถูกต้องให้โดยอัตโนมัติ
    ผมเห็นด้วยว่าการแก้ไขแบบออฟไลน์เป็นปัญหา UI/UX สาเหตุที่ลึกกว่านั้นคือความเคยชินของวงการคอมพิวติ้งที่ทำตามวิธีแก้ปัญหาเก่า ๆ และความเชื่อว่า “โดยทั่วไปถุงขนาด 5 ปอนด์จัดการง่ายกว่าถุงขนาด 10 ปอนด์ ดังนั้นควรเอาของหนัก 10 ปอนด์ใส่ลงในถุง 5 ปอนด์ใบเดียว”
    ภาพตั้งต้นของ “text editor” คือ Mosaic textarea, MacWrite หรืออะไรสักอย่างกึ่งกลางระหว่างนั้น ดังนั้นโดยทั่วไปจึงพยายามเอา merge ไปแปะไว้บนสิ่งนั้นด้วยการเปลี่ยนแปลงให้น้อยที่สุด เช่นทำเป็นรายการเมนูหรือไม่ก็ตัวเลือกไม่กี่อย่างในกล่องโต้ตอบเล็ก ๆ ต่อให้มีการรองรับ GUI merge ซ่อนอยู่ลึกในเมนู ก็ยังอยู่ในระดับหนังสยองขวัญ diff/merge สำหรับโปรแกรมเมอร์ หรือเป็นแค่มุมมองแบบขีดฆ่าที่ชวนหวาดเสียวเหมือนขับเรือในหมอก
    แต่ใน text editor ที่มีการทำงานร่วมกันแบบออฟไลน์ การ merge แบบกึ่ง manual เป็นแกนกลางของกระบวนการ และควรเป็นแกนกลางของการออกแบบ editor ด้วย น่าเสียดายที่ MacWrite เป็น local optimum ที่หลุดออกไปได้ยาก

    • คำถามที่เหลือคือ แล้วทางเลือกคืออะไร
      ตัวอย่างเช่น คนที่พูดถึง “การลอกเลียนแบบแบบ cargo cult” กับ “วิธีแก้ปัญหาเก่า ๆ” มักจะพูดต่อว่า “อย่าแก้ไขโค้ดเป็นข้อความ แต่ให้แก้ไขเป็น syntax tree” แต่ปัญหาก็ยังเหมือนเดิม แค่เปลี่ยน “ตัวอักษร” เป็น “ประโยค” ก็พอ
      ถ้า Bob เพิ่มหนึ่งบรรทัดเข้าไปในสาขา else ของคำสั่ง if และ Alice ลบทั้งประโยคพร้อมสาขา else นั้นออกไป ระบบที่ฉลาดควรทำอย่างไร?
    • ดูเหมือนผมจะเขียนเรื่อง merge อัตโนมัติให้สับสนไปหน่อย สิ่งที่ตั้งใจจะพูดคือ ถ้ามีหลาย commit แก้ไฟล์เดียวกัน Git จะพยายาม merge เข้าด้วยกัน แต่ conflict โดยตรงต้องถูกแสดงให้เห็นเสมอ
      โดยรวมแล้วดูเหมือนว่าเราเห็นด้วยว่าแนวทางนี้ถูกต้อง
  • ยินดีรับคำถามหรือ feedback ครับ อีกสักหนึ่งหรือสองชั่วโมงผมจะติดประชุมอยู่ แต่ชอบคุยเรื่องพวกนี้ ส่งมาทางนี้หรือทางอีเมลก็ได้ตามสะดวก: alex@moment.dev

    • ถ้ายังรองรับออฟไลน์ต่อไป สุดท้ายก็น่าจะเจอกรณีที่น่าสนใจกว่านี้ เช่น “ตอนอยู่บนเครื่องบิน Wi-Fi ใช้ไม่ได้ เลยทำงานกับเอกสารนี้ แล้วไม่ชอบทิศทางที่มันไป จึงปิดแล็ปท็อปแล้วงีบ จากนั้นอีกหลายวันก็ทำงานกับเอกสารบนเดสก์ท็อป พอสุดสัปดาห์เปิดเอกสารบนแล็ปท็อป การเปลี่ยนแปลงทั้งหมดที่ทำบนเครื่องบินก็เข้ามาอยู่ในเอกสาร และทุกอย่างก็เละไปหมด ช่วยด้วย ผมไม่ได้ตั้งใจจะ merge!” อะไรทำนองนี้
      Git จะไม่ผสมการเปลี่ยนแปลงในเครื่องเข้าไปโดยอัตโนมัติโดยไม่มีการยินยอมอย่างชัดเจน bzr ก็คงไม่เคยคิดจะทำแบบนั้น แต่เครื่องมืออย่าง Google Docs กลับพร้อมจะทำ
      ความคืบหน้าจนถึงตอนนี้ยอดเยี่ยม และหวังว่าโปรแกรม early access จะไปได้สวย
    • ทำไมถึงไม่ใช้ การ merge แบบ patch/diff ไปเลย? ถ้าจะอธิบายการแก้ไขข้อความร่วมกันแบบออฟไลน์ว่าเป็นเพียงปัญหาการปรับ UX ให้เหมาะสม เรื่องนี้ก็เป็นปัญหาที่แก้ได้มาตั้งหลายสิบปีแล้ว
  • ผมได้ implement differential sync(https://neil.fraser.name/writing/sync/) เพราะอย่างอื่นไม่เข้าใจ และสำหรับแอป grugnotes.com วิธีนี้ดูง่ายที่สุด
    แอปค่อนข้างหยาบ ๆ และไม่ใช่ realtime เต็มรูปแบบ แต่ตัวอย่างการ merge จัดการได้ถูกต้องไม่ว่าใครจะกลับมาออนไลน์ก่อน ถ้าการลบออนไลน์มาก่อน เวอร์ชัน colour จะถูกทิ้ง และไม่ถูกบันทึกไว้ในประวัติการแก้ไขด้วย
    คงยังมีปัญหาอีกมาก และก็ไม่รู้ว่าจะเป็นอย่างไรในกรณีมีผู้ใช้เกินสองคน แต่สำหรับการใช้งานของผมก็พอใจแล้ว