12 min readAI
Comprehension Debt: โค้ดผ่าน Test เขียว แต่ไม่มีใครในทีมอธิบายระบบได้
Codebase สะอาด tests ผ่าน dashboard สวย แต่พอถามว่าทำไมระบบเป็นแบบนี้ ทั้งห้องเงียบ บันทึกจากเดฟ·PM หลังอ่าน Addy Osmani และ Margaret-Anne Storey ว่าหนี้ความเข้าใจสะสมอย่างไร และทำไมการไม่เข้าใจจึงยังพอรับได้ ถ้าเรารู้ว่าตัวเองไม่มีอะไร

คำถามที่น่ากลัวที่สุดในห้องประชุมของทีม software อาจไม่ใช่ "ระบบล่มเพราะอะไร" ครับ แต่คือ "ทำไมตรงนี้ถึงเขียนแบบนี้"
ลองนึกภาพฟีเจอร์ที่ส่งไปเมื่อเดือนก่อน โค้ดอ่านง่าย ตั้งชื่อดี test เขียวทุกตัว ไม่มี incident ทุกอย่างดูเป็นงานที่ดี จนวันหนึ่ง PM ขอแก้ business rule ข้อเล็ก ๆ แล้วทุกคนในห้องมองหน้ากัน ไม่มีใครกล้าประเมินว่าใช้เวลากี่วัน เพราะไม่มีใครรู้จริง ๆ ว่าถ้าแตะตรงนั้นแล้วอะไรจะขยับตาม
ผมเป็นทั้ง developer, PM และ PO ที่ Mulberrysoft ดูแลทีม junior และใช้ Claude, Codex กับ agent อื่น ๆ แทบทุกวัน สองโพสต์ก่อนหน้า ผมเขียนเรื่องการให้ agent ทำงานแทนโดยไม่ให้มันคิดแทน และเรื่องวันที่คำตอบของ agent กลายเป็นความเห็นของเรา ทั้งสองเรื่องพูดถึงช่วงเวลาที่เรากดรับงาน โพสต์นี้อยากดูว่าเกิดอะไรขึ้นหลังจากนั้น เมื่อการกดรับแบบนั้นเกิดซ้ำเป็นร้อยครั้งในระบบเดียว
จุดยืนของผมอาจฟังดูแปลกนิดหน่อยสำหรับโพสต์เรื่องนี้ การไม่เข้าใจโค้ดทุกบรรทัดยังไม่ใช่ปัญหา ปัญหาคือการไม่รู้ว่าตอนนี้ทีมไม่เข้าใจอะไรบ้าง
หนี้ที่ไม่ขึ้นบน dashboard
Addy Osmani นิยาม comprehension debt ไว้ว่าเป็นช่องว่างที่กว้างขึ้นเรื่อย ๆ ระหว่างปริมาณโค้ดที่มีอยู่ในระบบ กับปริมาณที่มนุษย์สักคนเข้าใจจริง ๆ
ส่วนที่ผมว่าคมที่สุดคือการเทียบกับ technical debt ครับ หนี้เทคนิคยังส่งเสียงเตือน งานช้าลง แก้ทีหนึ่งพังอีกที่ ทุกคนบ่นกันได้ แต่ comprehension debt ตามคำของ Addy คือสิ่งที่ "breeds false confidence" เพราะ codebase ดูสะอาดและ test ก็เขียว
ในมุม PM ข้อนี้ทำให้ผมนั่งนิ่งไปพักหนึ่ง Addy ชี้ว่า velocity, DORA metrics, จำนวน PR และ test coverage อาจดูดีหมด ในขณะที่หนี้ก้อนนี้โตอยู่ข้างใต้ ถ้าผมดูแค่ตัวเลขเหล่านี้ ทีมที่กำลังสะสมหนี้เร็วที่สุด อาจเป็นทีมที่ผมกำลังชมว่าทำงานดีที่สุดก็ได้
หนี้ที่อยู่ในหัวคน ไม่ได้อยู่ในโค้ด
ก่อนหน้า Addy นั้น Margaret-Anne Storey เขียนเรื่อง cognitive debt ไว้ และเป็นบทความที่เปลี่ยนวิธีคิดของผมมากกว่าที่คาดครับ
Storey ชี้ว่าเวลาพูดถึง technical debt เรามักมองว่ามันเป็นคุณสมบัติของโค้ด แต่ cognitive debt อยู่ในหัวของนักพัฒนา แล้วโยงกลับไปหาแนวคิดของ Peter Naur ที่มองว่าโปรแกรมคือทฤษฎีชุดหนึ่งที่คนทำถืออยู่ ไม่ใช่แค่ตัวหนังสือในไฟล์ ถ้าทฤษฎีนั้นหายไป โค้ดจะยังรันได้ตามปกติ แต่เราเสียความสามารถในการบอกว่าระบบทำอะไร ทำไมถึงสร้างแบบนี้ และควรเปลี่ยนมันอย่างไร
ตัวอย่างที่ทั้ง Storey และ Addy ยกมาคือทีมนักศึกษาในวิชาด้าน entrepreneurship ที่ชนกำแพงราวสัปดาห์ที่ 7 หรือ 8 ตอนแรกพวกเขาคิดว่าเป็นเพราะ technical debt แต่พอลงไปดูจริง ปัญหาคือไม่มีใครในทีมอธิบายได้ว่าการตัดสินใจเรื่อง design เหล่านั้นเกิดขึ้นเพราะอะไร และแต่ละส่วนควรทำงานร่วมกันอย่างไร
คำที่ Storey ใช้และผมจำได้แม่นคือ "a silent loss of shared theory" มันไม่ทำให้ build พังครับ มันแค่ค่อย ๆ หายไปจากห้อง
ผมเองก็เคยอยู่ในห้องแบบนั้นในขนาดย่อม ๆ คือมีคนถามถึงโมดูลที่ผมให้ agent ทำเมื่อไม่นานมานี้ ผมเปิดปากจะตอบแล้วพบว่าสิ่งที่จำได้คือสรุปใน PR ไม่ใช่เหตุผลที่อยู่ข้างหลังมัน
ตัวเลขชุดนี้ต้องอ่านอย่างระวัง
Addy อ้างงานของ Anthropic ที่ชื่อ How AI assistance impacts the formation of coding skills ผมลองตามไปอ่านหน้าสรุปของงานนี้ครับ
เป็น randomized controlled trial กับ software engineer 52 คน ส่วนใหญ่เป็น junior ให้เขียนฟีเจอร์ด้วย Python library ที่ชื่อ Trio แล้วทำ quiz ต่อ กลุ่มที่ใช้ AI ได้คะแนนเฉลี่ย 50% ส่วนกลุ่มที่เขียนเองได้ 67% และช่องว่างกว้างที่สุดอยู่ที่คำถามเรื่อง debugging ขณะที่กลุ่ม AI เสร็จเร็วกว่าราวสองนาที ซึ่งยังไม่มีนัยสำคัญทางสถิติ
เรื่อง debugging นี่ทำให้ผมสะดุดครับ เพราะมันคือทักษะที่เราใช้ตรวจว่า agent ผิดตรงไหน ถ้าทักษะนี้หายไปก่อน เครื่องมือตรวจของเราก็จะอ่อนลงในวันที่ต้องใช้มันมากที่สุด
งานนี้ยังพบด้วยว่าวิธีใช้ AI มีผล กลุ่มที่ใช้แบบถามเพื่อเข้าใจแนวคิด หรือให้สร้างโค้ดแล้วตามไปทำความเข้าใจ มีคะแนนเฉลี่ยตั้งแต่ 65% ขึ้นไป ส่วนกลุ่มที่ปล่อยให้ AI ทำแทนหรือให้ AI ไล่แก้บั๊กซ้ำ ๆ ได้ต่ำกว่า 40%
แต่ต้องอ่านอย่างซื่อตรงครับ ตัวอย่างมีน้อย แต่ละรูปแบบการใช้งานมีคนเพียงไม่กี่คน Anthropic ระบุเองว่าการวิเคราะห์ส่วนนี้ไม่ได้สรุปความเป็นเหตุเป็นผล และ quiz วัดความเข้าใจเฉพาะช่วงสั้น ๆ หลังทำงานเสร็จ ที่สำคัญคือมันวัดคนที่กำลังเรียน library ใหม่ ไม่ได้วัดทีมที่ดูแลระบบจริงเป็นปี ผมจึงไม่ขอลากเลขนี้ไปอธิบายทีมตัวเอง และผมอ่านแค่หน้าสรุป ไม่ได้ลงไปอ่าน paper ฉบับเต็ม ใครอยากเช็กกดลิงก์ไปได้เลยครับ
ด่านเดิมของเรากันไม่อยู่
ถ้าถามว่าทำไมหนี้ก้อนนี้เพิ่งมาโตตอนนี้ ผมคิดว่าเป็นเพราะด่านเดิมของเราถูกสร้างมาสำหรับความเร็วอีกแบบหนึ่งครับ
Code review Addy บอกว่าการรีวิวแบบเดิมเป็นคอขวดที่มีประโยชน์ เพราะมันช้าพอให้ความรู้กระจายในทีม แต่ตอนนี้ junior สร้างโค้ดได้เร็วกว่าที่ senior จะอ่านทันแล้ว ด่านคุณภาพเลยกลายเป็นปัญหาเรื่อง throughput และเมื่อคิวยาว สิ่งแรกที่หายไปก็คือการอ่านเพื่อเข้าใจ
Test Addy พูดตรงมากว่า test เขียนครอบคลุมพฤติกรรมที่เราไม่เคยคิดจะระบุไม่ได้ และถ้า agent แก้ test ไปพร้อมกับโค้ด สีเขียวก็ตอบไม่ได้ว่าพฤติกรรมที่เปลี่ยนไปนั้นถูกต้องหรือเปล่า ผมเขียนเรื่องติ๊กเขียวไม่ได้แปลว่าตรวจครบไว้แล้วในมุมของงานชิ้นเดียว แต่ในมุมนี้มันหนักกว่าครับ เพราะ test ชุดใหญ่ที่ไม่มีใครเข้าใจ จะทำให้เราเชื่อระบบมากขึ้นโดยที่รู้จักมันน้อยลง
Spec ข้อนี้ผมฟังแล้วเจ็บในฐานะ PM ครับ ผมเคยคิดว่าถ้า spec ดีพอ ก็รีวิวแค่ spec ได้ แต่ Addy ชี้ว่าคนสองคนที่ทำตาม spec เดียวกันจะได้ระบบที่พฤติกรรมต่างกันหลายจุด และถ้าอยากเขียน spec ให้ละเอียดจนครบ มันก็แทบจะเป็นตัวโปรแกรมเอง Spec ยังจำเป็นอยู่ แต่มันไม่ได้แทนความเข้าใจระบบที่รันจริง
สร้างความเข้าใจใหม่ตอนต้องใช้ ก็โอเค ถ้ารู้ว่าตัวเองไม่มีอะไร
ส่วนนี้เป็นความเห็นของผมเองครับ ไม่ได้มาจากบทความของ Addy หรือ Storey
ผมไม่คิดว่าเป้าหมายคือให้มีคนเข้าใจโค้ดทุกบรรทัดตลอดเวลา ทีมขนาดเล็กทำไม่ได้มาตั้งแต่ยุคก่อน agent แล้ว มีโมดูลเก่าที่คนเขียนลาออกไปนาน มี library ที่เราไม่เคยเปิดอ่าน แล้วเราก็อยู่กันมาได้ เพราะพอถึงวันต้องแก้ เราก็นั่งอ่าน ไล่ log เขียน test เพื่อจับพฤติกรรม แล้วสร้างความเข้าใจขึ้นมาใหม่
ยิ่งมี agent การสร้างความเข้าใจตามต้องการแบบนี้ก็ยิ่งถูกลง ผมให้มันไล่ flow ทำแผนผังการเรียก หรือช่วยตั้งสมมติฐานได้ในไม่กี่นาที บางส่วนของระบบผมยอมปล่อยไว้แบบนี้จริง ๆ ครับ และคิดว่าเป็นการใช้เวลาที่คุ้มกว่าการพยายามจำทุกอย่าง
เงื่อนไขของผมคือ ต้องรู้ยอดหนี้ มันต่างกันมากระหว่างคำว่า "ส่วน export เราไม่มีใครเข้าใจลึก ถ้าจะแก้ต้องกันเวลาไว้อ่านก่อนสองวัน" กับ "ส่วน export น่าจะง่าย เดี๋ยวให้ agent แก้" ประโยคแรกคือหนี้ที่รู้ตัว คุยในการวางแผนได้ เผื่อเวลาได้ และเลือกได้ว่าจะยังไม่จ่าย ส่วนประโยคหลังคือหนี้ที่จะไปโผล่ตอนตีสองของคืนที่ระบบล่ม
แต่ผมก็มีข้อระวังอีกสามข้อ ซึ่งทำให้การสร้างใหม่ไม่ได้ฟรีอย่างที่ดูครับ
ข้อแรก "อะไร" สร้างใหม่ได้ แต่ "ทำไม" อาจไม่ได้ อ่านโค้ดแล้วรู้ว่ามัน retry สามครั้ง แต่ไม่มีทางรู้ว่าเลขสามมาจาก incident กับ vendor รายหนึ่งถ้าไม่มีใครจดไว้ ทางเลือกที่ถูกปฏิเสธไปแล้วก็ไม่ทิ้งร่องรอยในโค้ดเลย agent อ่านโค้ดให้เราได้ แต่อ่านเหตุผลที่ไม่เคยถูกบันทึกไม่ได้ มันอาจเล่าเหตุผลที่ฟังขึ้นมาให้แทน ซึ่งแย่กว่าบอกว่าไม่รู้เสียอีก
ข้อที่สอง คำอธิบายจาก agent ยังไม่ใช่ความเข้าใจ มันคือคำอธิบายหนึ่งฉบับที่ต้องเอาไปเทียบกับของจริง ถ้าผมอ่านแล้วพยักหน้า ผมก็แค่ได้ความมั่นใจจากน้ำเสียงเดิมกลับมาอีกรอบ เรื่องเดียวกับที่เขียนไว้ในโพสต์ Cognitive Surrender ผมจึงถือว่าเข้าใจแล้วก็ต่อเมื่อทายได้ว่าเปลี่ยนตรงนี้แล้วจะเกิดอะไร และลองแล้วเป็นตามนั้น
ข้อที่สาม การสร้างใหม่ต้องมีวัตถุดิบและคนที่อ่านเป็น ถ้าวันนั้นทีมเหลือแต่คนที่ไม่เคยไล่ระบบเอง ต่อให้มี agent ก็ไม่มีใครตัดสินได้ว่าคำอธิบายไหนถูก ส่วนนี้จึงโยงกลับไปหาทีม junior ของผมโดยตรง
สัญญาณว่าหนี้เริ่มสูงเกินที่คิด
ส่วนนี้ผมเรียบเรียงจากสัญญาณเตือนที่ Storey ระบุไว้ ผสมกับสิ่งที่ผมเห็นจากมุม PM ครับ
สัญญาณแรกคือ ไม่มีใครกล้าแตะ Storey พูดถึงอาการลังเลที่จะแก้โค้ดเพราะกลัวผลข้างเคียง ในงานของผมมันมักมาในรูป "ขอให้ agent ลองดูก่อน" แทนที่จะเป็น "ตรงนี้กระทบ A กับ B นะ"
สัญญาณที่สองคือ ความรู้อยู่กับคนหนึ่งหรือสองคน ต้องรอคนเดิมตอบทุกครั้ง ถ้าเขาลาพักร้อนแล้วงานส่วนนั้นหยุด แปลว่าเรามีหนี้อยู่แล้ว และบางทีก็ต้องถามต่อด้วยว่าคนคนนั้นเข้าใจจริง หรือแค่เป็นคนเดียวที่เคยสั่ง agent ในส่วนนั้น
สัญญาณที่สามคือ ประมาณเวลาแล้วพลาดแบบแปลก ๆ ส่วนนี้ผมเห็นจากโต๊ะ PM งานที่ควรเล็กกลับบานปลาย งานที่ควรใหญ่กลับเสร็จเร็ว ส่วนต่างที่เดาไม่ถูกแบบนี้คือสัญญาณว่าแผนที่ในหัวเราไม่ตรงกับระบบแล้ว
สัญญาณที่สี่คือ คำตอบของ "ทำไม" ขึ้นต้นด้วยการเปิดแชต ถ้าทุกคำถามเกี่ยวกับระบบต้องเริ่มจากการถาม agent ใหม่ ระบบก็เริ่มเป็นกล่องดำสำหรับทีมแล้ว แม้ว่าเราจะเป็นคนสร้างมันเองก็ตาม
ที่ผมจะลองทำกับทีม
ผมยังไม่มีสูตรสำเร็จครับ นี่คือสิ่งที่จะลอง บางข้อได้จาก Addy กับ Storey บางข้อคิดขึ้นเองจากงานที่ทำอยู่
ทำแผนที่ความเข้าใจ ข้อนี้เป็นไอเดียของผมเอง ตั้งใจให้เป็นตารางหน้าเดียวครับ แต่ละส่วนหลักของระบบระบุว่าใครอธิบายได้ และอยู่ระดับไหน ระหว่าง "อธิบายได้เลย" "ต้องอ่านก่อนแต่รู้ว่าอ่านตรงไหน" และ "ไม่มีใครรู้" ผมไม่ต้องการให้ทุกช่องเขียว แค่ต้องการให้ช่องแดงถูกเขียนไว้ และถูกหยิบมาดูตอนวางแผนงาน
แบ่งระดับตามความเสี่ยง Storey เสนอให้มีคนอย่างน้อยหนึ่งคนเข้าใจการเปลี่ยนแปลงจาก AI อย่างครบถ้วนก่อนส่งงาน ผมเห็นด้วยสำหรับงานที่แตะเงิน สิทธิ์ และข้อมูลลูกค้า ส่วนสคริปต์ภายในที่พังแล้วเสียหายน้อย ผมยอมให้เป็นหนี้ได้ ตราบใดที่ตารางด้านบนบอกไว้
จดเหตุผล ไม่ใช่แค่สิ่งที่เปลี่ยน Storey แนะนำเรื่องนี้เช่นกัน และมันตอบข้อระวังแรกตรง ๆ ผมอยากให้ PR ที่สำคัญมีไม่กี่บรรทัดว่าทำไมถึงเลือกทางนี้ ไม่เลือกทางไหน และมีข้อจำกัดอะไรซ่อนอยู่ agent ช่วยร่างได้ แต่คนที่ตัดสินใจจริงต้องเป็นคนยืนยัน เพราะ agent ไม่รู้เหตุผลที่อยู่นอกหน้าต่างแชต
คุย intent ก่อนเขียนโค้ด ข้อนี้ Addy ย้ำไว้ และเป็นส่วนที่ PM อย่างผมมีส่วนช่วยได้มากที่สุด ถ้าทีมตกลงกันได้ก่อนว่างานนี้แก้ปัญหาอะไรและเส้นแบ่งอยู่ตรงไหน โค้ดที่ agent เขียนออกมาก็จะมีทฤษฎีให้เทียบ
อธิบายระบบโดยไม่เปิดหน้าจอ Storey แนะนำให้มี checkpoint อย่าง code review, retrospective และการแชร์ความรู้เป็นประจำ ผมจะลองเพิ่มรอบสั้น ๆ ทุกสองสัปดาห์ สุ่มส่วนหนึ่งของระบบ แล้วให้คนในทีมวาดบนกระดานว่ามันทำงานอย่างไร จุดที่วาดไม่ออกจะถูกบันทึกในแผนที่ ไม่ใช่เอามาตำหนิกัน
ซ้อมสร้างความเข้าใจใหม่ ถ้าเราจะฝากความหวังไว้กับการสร้างใหม่ตอนต้องใช้ ก็ควรรู้ว่าทำได้จริงแค่ไหน ผมจะให้น้องในทีมเลือกส่วนที่ติดแดง ลองไล่ให้เข้าใจโดยใช้ agent ช่วย แล้วจดว่าใช้เวลาเท่าไร ติดตรงไหน และอะไรที่หาจากโค้ดไม่ได้เลย ตัวเลขนี้จะกลายเป็นยอดหนี้ที่ผมเอาไปใช้ประเมินงานได้จริงมากกว่าการเดา
ท้ายที่สุด
ผมยังให้ agent เขียนโค้ดต่อไปครับ และคงมากขึ้นอีก Storey เขียนว่า "velocity without understanding is not sustainable" ซึ่งผมเห็นด้วย แต่ไม่ได้อ่านว่าต้องช้าลงทุกงาน ผมอ่านว่าความเร็วต้องมาพร้อมบัญชีที่ซื่อตรงว่าเรารู้อะไรและไม่รู้อะไร
Addy ปิดบทความไว้ว่า "The comprehension work is the job." ในฐานะคนที่ทำทั้งโค้ดและวางแผนงาน ผมขอต่อท้ายอีกนิดว่า ส่วนหนึ่งของงานนั้นคือการรู้ว่าวันนี้เรายังไม่ได้ทำความเข้าใจส่วนไหน
หนี้ไม่ได้เลวร้ายเสมอไปครับ ธุรกิจจำนวนมากกู้เงินเพื่อเดินหน้าได้เร็วขึ้น แต่คงไม่มีใครบริหารธุรกิจที่ไม่รู้ว่าตัวเองติดหนี้ใครอยู่เท่าไรได้นาน
ดังนั้นคำถามที่ผมจะหยิบไปถามในการวางแผนรอบหน้า ไม่ใช่ "ทุกคนเข้าใจระบบนี้ไหม" เพราะคำตอบแบบซื่อตรงคงเป็นไม่ ผมจะถามว่า ถ้าพรุ่งนี้ต้องแก้ส่วนนี้ เรารู้ไหมว่าต้องเริ่มอ่านจากตรงไหน และต้องใช้เวลาเท่าไร
ถ้าตอบได้ นั่นคือหนี้ที่บริหารได้ครับ ถ้าตอบไม่ได้ นั่นคือส่วนที่ควรลงมือก่อนจะสั่ง agent ทำงานชิ้นถัดไป