Developers สามารถรันเซสชันของ coding agent หลายตัวพร้อมกันได้โดยไม่ต้องกังวลเรื่องไฟล์สถานะ (state files) ถูกเขียนทับหรือการชนกันของไฟล์ที่ซ่อนอยู่ รูปแบบ "share-nothing" แบบ advisory จะช่วยแยกพื้นที่ทำงานของเอเจนต์แต่ละตัวออกจากกัน และแจ้งเตือนหากมีความขัดแย้งที่อาจเกิดขึ้น แนวทางนี้เปลี่ยนจากการใช้ hard locks มาเป็นเรจิสทรี (registry) ที่มีน้ำหนักเบา ซึ่งจะคอยแจ้งเตือนการทำงานที่ซ้ำซ้อนก่อนที่จะเกิดขึ้น ช่วยให้ไพป์ไลน์ทำงานต่อไปได้แม้ว่าเซสชันใดเซสชันหนึ่งจะล่มก็ตาม
ทำไมการใช้เอเจนต์แบบขนานถึงทำให้เกิดปัญหา
การรันผู้ช่วยเขียนโค้ดอัตโนมัติมากกว่าหนึ่งตัวในรีโพสิทอรีเดียวช่วยเร่งความเร็วในการสร้างโค้ด การทดสอบ หรือการรีแฟกเตอร์ (refactoring) แต่ในทางปฏิบัติ มักจะพบปัญหาสำคัญสองประการทันที
- State corruption (ข้อมูลสถานะเสียหาย) – เอเจนต์สองตัวเขียนข้อมูลลงในไฟล์สถานะเดียวกัน โดยการเขียนครั้งหลังจะเขียนทับครั้งแรก ทำให้ความคืบหน้าที่ทำไว้หายไป
- File collision (การชนกันของไฟล์) – เอเจนต์สองตัวแก้ไขไฟล์ซอร์สโค้ดเดียวกันโดยไม่รู้ตัว ความขัดแย้งจะปรากฏขึ้นในภายหลัง เมื่อการเปรียบเทียบความแตกต่าง (diff) แสดงให้เห็นว่ามีการเปลี่ยนแปลงที่สวนทางกัน
ทั้งสองปัญหานี้ทำให้เสียเวลาของนักพัฒนา และอาจนำไปสู่บั๊กที่ติดตามร่องรอยได้ยาก
กฎ "share nothing"
แนวคิดหลักนั้นเรียบง่าย: เอเจนต์แต่ละตัวจะมีพื้นที่ทำงานส่วนตัว (scratchpad) บนดิสก์ และจะเขียนข้อมูลลงในไฟล์ที่เป็นของเซสชันนั้นๆ เท่านั้น โดยอนุญาตให้มีไฟล์ที่แชร์ร่วมกันได้อย่างตั้งใจเพียงไฟล์เดียวต่อหนึ่งสาขา (branch) และจะใช้กฎ "last-writer-wins" (ผู้เขียนคนสุดท้ายเป็นผู้ชนะ) กล่าวคือ เอเจนต์ตัวใดที่เขียนข้อมูลเป็นคนสุดท้ายจะเป็นผู้กำหนดเนื้อหาขั้นสุดท้าย
Presence layer (ชั้นการตรวจสอบการมีอยู่) จะคอยติดตามทุกเซสชันที่กำลังทำงานอยู่:
- ชื่อสาขา (branch name)
- รายชื่อไฟล์ที่กำลังถูกใช้งาน
- ประทับเวลา (timestamp) ของกิจกรรมล่าสุด
เมื่อเซสชันใหม่เริ่มต้นขึ้น ระบบจะตรวจสอบเรจิสทรี หากมีเซสชันอื่นกำลังจัดการไฟล์ใดๆ ที่ซ้ำกันอยู่ นักพัฒนาจะได้รับคำเตือนก่อนที่จะเริ่มทำงานใดๆ
Advisory locks เทียบกับ Blocking locks
ไฟล์ล็อก (lock files) แบบดั้งเดิมทำงานเหมือนถนนตัน: เมื่อมีการล็อกเกิดขึ้น กระบวนการอื่นๆ จะต้องรอจนกว่าการล็อกจะถูกปลดออก หากเซสชันที่เป็นเจ้าของล็อกเกิดล่ม การล็อกนั้นอาจค้างอยู่แบบนั้นตลอดไป ทำให้ต้องเสียเวลาไล่หาไฟล์ล็อกที่ค้างอยู่ด้วยตัวเอง
โมเดลแบบ advisory นั้นนุ่มนวลกว่า โดยจะแจ้งเตือนเมื่อตรวจพบความขัดแย้งที่อาจเกิดขึ้น แต่จะไม่หยุดการทำงานของเซสชันใหม่ หากข้อมูลในเรจิสทรีเก่าเกินไป (หมายความว่ากระบวนการที่สร้างข้อมูลนั้นไม่มีอยู่แล้ว) ระบบก็จะยังคงทำเพียงแค่แจ้งเตือน เพื่อให้นักพัฒนาเป็นผู้ตัดสินใจเองว่าจะดำเนินการต่อหรือไม่
วิธีการนำรูปแบบนี้ไปใช้งาน
- Partition state by writer (แบ่งส่วนสถานะตามผู้เขียน) – ให้เอเจนต์แต่ละตัวมีไดเรกทอรีของตัวเองสำหรับไฟล์ชั่วคราวและสถานะ ส่วนไฟล์ที่แชร์ร่วมกันให้สงวนไว้สำหรับข้อมูลที่เป็นส่วนกลางจริงๆ เท่านั้น และใช้กฎ last-writer-wins เฉพาะในส่วนนี้
- Inject awareness at launch (เพิ่มการรับรู้เมื่อเริ่มทำงาน) – ก่อนที่เอเจนต์จะเริ่มทำงาน ให้ตรวจสอบ presence registry และเปรียบเทียบรายการไฟล์ที่ต้องการกับรายการที่มีอยู่ หากพบการซ้ำซ้อน ให้ยกเลิกหรือแจ้งเตือน
- Verify liveness at read time (ตรวจสอบสถานะการทำงานขณะอ่านข้อมูล) – เมื่อตรวจสอบข้อมูลในเรจิสทรี ให้เช็คว่า Process ID ที่บันทึกไว้ยังคงทำงานอยู่ใน OS หรือไม่ หากเป็นข้อมูลของกระบวนการที่สิ้นสุดไปแล้ว ให้ลบข้อมูลนั้นทิ้ง
- Prefer advisory over blocking (เลือกใช้ advisory แทนการ blocking) – ให้นักพัฒนายังคงเป็นผู้ควบคุม การแจ้งเตือนช่วยให้พวกเขาสามารถดำเนินการต่อ หยุดชั่วคราว หรือยกเลิกได้ เพื่อหลีกเลี่ยงสภาวะ deadlock
- Track waiting states (ติดตามสถานะการรอ) – เมื่อมีเอเจนต์ทำงานอยู่จำนวนมาก ความสนใจของนักพัฒนาจะกลายเป็นคอขวด ควรแสดงให้เห็นว่าเอเจนต์ตัวใดกำลังรอการป้อนข้อมูลจากมนุษย์ เพื่อที่จะได้จัดลำดับความสำคัญของงานใหม่ได้
ทั้งหมดนี้สามารถสร้างขึ้นได้ด้วยไดเรกทอรีธรรมดาที่เก็บไฟล์ JSON โดยไม่จำเป็นต้องใช้ฐานข้อมูลภายนอกหรือ message bus รูปแบบการจัดเก็บที่เรียบง่ายนี้ทำให้ระบบตรวจสอบได้ง่ายและสามารถย้ายไปใช้งานในสภาพแวดล้อมต่างๆ ได้สะดวก
ความเสี่ยงและข้อโต้แย้ง
บางทีมอาจแย้งว่าการใช้ hard lock ช่วยรับประกันความปลอดภัย เพราะจะไม่มีเอเจนต์สองตัวใดเขียนไฟล์เดียวกันได้ แต่ข้อแลกเปลี่ยนคือความยืดหยุ่นที่ลดลง เนื่องจากเซสชันที่ล่มจะทิ้งไฟล์ล็อกที่ค้างอยู่ (orphaned locks) ซึ่งจะทำให้เวิร์กโฟลว์ทั้งหมดหยุดชะงัก
สิ่งที่ควรระวัง
หากคุณกำลังใช้งานผู้ช่วยเขียนโค้ดที่ขับเคลื่อนด้วย AI หลายตัวพร้อมกัน รูปแบบ advisory แบบ "share nothing" เป็นแนวทางที่ใช้งานได้จริงเพื่อป้องกันไม่ให้เอเจนต์เหล่านั้นทำงานขัดขากันเอง การแยกสถานะออกจากกัน การแสดงเจตนาตั้งแต่เนิ่นๆ และการให้นุษย์เป็นผู้ตัดสินใจว่าจะดำเนินการต่อเมื่อใด ช่วยสร้างสมดุลระหว่างความปลอดภัยและความยืดหยุ่นที่ไพป์ไลน์การพัฒนาสมัยใหม่ต้องการ
