หนี้ทางเทคนิค หนี้ทางการรับรู้ และหนี้ทางเจตนา
(martinfowler.com)- ในสภาพแวดล้อมที่ LLM ผลิตโค้ดจำนวนมาก ไม่ได้มีแค่ปัญหาของตัวโค้ดเท่านั้นที่อ่อนแอลง แต่ความเข้าใจร่วมกันของทีมและการบันทึกเป้าหมายของระบบก็อ่อนแอลงไปพร้อมกัน ทำให้ยิ่งจำเป็นต้องจัดการมันใน 3 ชั้นคือ หนี้ทางเทคนิค·หนี้ทางการรับรู้·หนี้ทางเจตนา
- Technical debt จำกัดความสามารถในการเปลี่ยนแปลงในอนาคต, Cognitive debt ทำให้ความสามารถของทีมในการให้เหตุผลเกี่ยวกับการเปลี่ยนแปลงของระบบอ่อนลง, และ Intent debt ทำให้บันทึกของเป้าหมายและข้อจำกัดพร่าเลือน จนขัดขวางวิวัฒนาการต่อเนื่องของทั้งมนุษย์และ AI agent
- ทฤษฎี Tri-System ที่วาง AI เป็น System 3 แยก cognitive surrender ซึ่งเป็นการเชื่อถือการให้เหตุผลที่สร้างจากภายนอกโดยไม่วิจารณญาณจนข้ามการไตร่ตรอง ออกจาก cognitive offloading ที่เป็นการมอบหมายภาระการคิดอย่างมีกลยุทธ์
- ยิ่งต้นทุนการเขียนโค้ดต่ำลง สิ่งที่ยิ่งแพงขึ้นคือ verification และเกณฑ์ของความถูกต้องกับความสำเร็จก็แตกต่างกันไปตามบริบท เช่น ETA การจราจร การจัดสรรงานให้คนขับ หรือการดูแลไมโครเซอร์วิสนับร้อย ทำให้การตัดสินของมนุษย์และการออกแบบระบบตรวจสอบยิ่งสำคัญขึ้น
- แกนกลางของวิศวกรรม กำลังย้ายจากปริมาณการลงมือทำไปสู่การตรวจสอบ และต่อจากนี้มนุษย์ก็ยังจะรับบทในการยึดความหมายของระบบไว้ เช่น การสร้าง abstraction ที่มีประโยชน์ การตั้งชื่อ และการออกแบบ acceptance criteria กับ test harness
หนี้สามแบบและสุขภาพของระบบ
- ในสภาพแวดล้อมที่ LLM สร้างโค้ดจำนวนมาก ทีมมีแนวโน้มจะสูญเสียความเข้าใจว่าระบบกำลังทำอะไร และมุมมองที่เรียกสิ่งนี้ว่า Cognitive Debt กำลังได้รับความสนใจมากขึ้น
- สามชั้นของสุขภาพระบบ แบ่งหนี้ออกเป็นระดับโค้ด คน และอาร์ติแฟกต์
- Technical debt อยู่ในโค้ด สะสมเมื่อการตัดสินใจด้านการพัฒนาไปบั่นทอนความสามารถในการเปลี่ยนแปลงในอนาคต และจำกัดว่าระบบจะเปลี่ยนไปได้อย่างไร
- Cognitive debt อยู่ในคน สะสมเมื่อความเข้าใจร่วมเกี่ยวกับระบบเสื่อมลงเร็วกว่าความเร็วที่มันถูกเติมเต็มกลับคืนมา และจำกัดความสามารถของทีมในการให้เหตุผลเกี่ยวกับการเปลี่ยนแปลง
- Intent debt อยู่ในอาร์ติแฟกต์ สะสมเมื่อเป้าหมายและข้อจำกัดที่ควรชี้นำระบบไม่ได้ถูกบันทึกหรือดูแลรักษาอย่างเหมาะสม และจำกัดว่าระบบยังสะท้อนสิ่งที่ตั้งใจสร้างไว้เดิมอยู่หรือไม่ รวมถึงจำกัดว่ามนุษย์และ AI agent จะสามารถพัฒนาระบบต่อไปได้อย่างมีประสิทธิภาพหรือไม่
- มุมมองนี้ยังรวมถึง ส่วนที่ใช้วินิจฉัยและบรรเทา หนี้แต่ละประเภท และอธิบายด้วยว่าหนี้ทั้งสามมีปฏิสัมพันธ์กัน
- ทีมควรทำ กิจกรรมทั่วไป เพื่อควบคุมหนี้ทั้งสามแบบไปพร้อมกัน
ทฤษฎี Tri-System และการยอมจำนนทางการรับรู้
- งานวิจัยที่เพิ่ม LLM เข้าไปในโมเดลการคิดสองระบบของ Kahneman ขยายกรอบการคิดโดยวาง AI ไว้เป็น System 3
- System 1 คือการตัดสินใจอย่างรวดเร็วด้วยสัญชาตญาณ ส่วน System 2 คือขั้นของการคิดอย่างจงใจเพื่อแก้ปัญหา
- เพื่อประหยัดพลังงาน มนุษย์มีแนวโน้มพึ่งสัญชาตญาณเป็นค่าเริ่มต้น จึงอาจมองข้ามสิ่งที่น่าจะพบได้หากไตร่ตรองให้มากขึ้น
- ผลที่ตามมาจาก System 3 คือแนวคิด cognitive surrender ซึ่งนิยามว่าเป็นภาวะที่เชื่อถือการให้เหตุผลเทียมที่สร้างจากภายนอกโดยไม่วิพากษ์ จนข้าม System 2 ไป
- งานวิจัยแยกสิ่งนี้ออกจาก cognitive offloading
- cognitive offloading ถูกมองว่าเป็นการมอบหมายภาระการคิดอย่างมีกลยุทธ์ในกระบวนการไตร่ตรอง
- งานวิจัยนี้อธิบาย Tri-System theory of cognition อย่างละเอียด และยังตรวจสอบผ่านการทดลองหลายชุดว่าทฤษฎีนี้ทำนายพฤติกรรมได้มีประสิทธิภาพเพียงใด อย่างน้อยในสภาพแวดล้อมระดับห้องทดลอง
สัญลักษณ์ <> ในฐานะไอคอนของโค้ด
- ช่วงหลังมีภาพประกอบบางส่วนใช้สัญลักษณ์ “<>” เป็นไอคอนของโค้ด แต่เครื่องหมายนี้ดูไม่คุ้นตาเมื่อใช้เป็นรูปแบบที่ครอบองค์ประกอบของภาษาโปรแกรม
- เหตุที่ใช้ “<>” แทนที่จะเป็นสัญลักษณ์อื่นอย่าง “{ }” น่าจะเพราะมันชวนให้นึกถึง HTML หรือ XML
- หากใช้ถึงขั้นรูปแบบ “</>” ก็ยิ่งชวนให้นึกถึง HTML โดยตรงมากขึ้น แต่ HTML ก็ไม่ได้ถูกมองว่าเป็นภาษาที่โปรแกรมเมอร์ใช้เขียนโปรแกรม
เมื่อการเขียนโค้ดราคาถูกลง สิ่งที่แพงขึ้นคือการตรวจสอบ
- if coding agents make coding free, what becomes the expensive thing มองว่าเมื่อ coding agent ลดต้นทุนของการเขียนโค้ดลง สิ่งที่แพงขึ้นคือ verification
- เกณฑ์ความถูกต้อง เปลี่ยนไปตามบริบทเสมอ
- อัลกอริทึม ETA สำหรับการจราจรใน Jakarta กับอัลกอริทึม ETA สำหรับการจราจรใน Ho Chi Minh City อาจมีความหมายของคำว่า “correct” ไม่เหมือนกัน
- ในการจัดสรรงานให้คนขับ ต้องทำให้ทั้งความเป็นธรรมของรายได้ เวลารอลูกค้า และอัตราการใช้รถสอดคล้องกันพร้อมกัน จึงทำให้คำว่า “successful” ไม่มีนิยามเดียว แต่มีหลายแบบ
- ในสภาพแวดล้อมที่วิศวกรหลายร้อยคน deploy ไปยังไมโครเซอร์วิสราว 900 ตัวอย่างต่อเนื่อง คำว่า “correct” ไม่ได้มีคำนิยามเดียว แต่แตกออกเป็นนิยามนับพัน ซึ่งทั้งหมดเปลี่ยนแปลงตลอดเวลาและขึ้นอยู่กับบริบท
- การตัดสินลักษณะนี้ถูกวางไว้เป็น งานที่ agent ทำแทนไม่ได้
- agent มักทำงานได้ดีเป็นพิเศษใน workflow ที่มี การตรวจสอบที่ดีและถ้าเป็นไปได้ก็อัตโนมัติ สำหรับผลลัพธ์ของงาน
- workflow แบบนี้ส่งเสริม Test Driven Development
- ถึงอย่างนั้น ปริมาณการตรวจสอบที่ยังต้องทำก็ยังมาก จึงจำเป็นต้องทุ่มแรงมากขึ้นกับวิธีที่ช่วยให้มนุษย์เข้าใจขอบเขตการทดสอบที่กว้างขึ้นได้ง่าย
- สำหรับ การปรับระบบ legacy ให้ทันสมัย ก็มีการเสนอความเห็นต่างไว้ด้วย
- ความคาดหวังว่า agentic coding จะมาแก้ปัญหา legacy modernization ได้อย่างเด็ดขาดนั้นถูกประเมินสูงเกินไป
- แต่ในแง่ของ การทำความเข้าใจว่า legacy code กำลังทำอะไรอยู่ มีหลักฐานที่หนักแน่นว่า LLM ช่วยได้มาก
การปรับองค์กรใหม่สู่การเน้นการตรวจสอบ
- เมื่อ agent รับหน้าที่ลงมือทำ งานของมนุษย์จะย้ายไปสู่การออกแบบ verification system การนิยาม quality และการจัดการกรณีกำกวมที่ agent ยังแก้ไม่ได้
- โครงสร้างองค์กรก็ควรเปลี่ยนตามความเปลี่ยนแปลงนี้
- คำถามใน standup เช้าวันจันทร์จะเปลี่ยนจาก “deploy อะไรไปบ้าง” ไปเป็น “ตรวจสอบอะไรไปบ้าง”
- จากการติดตามปริมาณ output ไปสู่การติดตามว่าผลลัพธ์นั้น ถูกต้องหรือไม่
- ทีมวิศวกร 10 คนที่เคยสร้างฟีเจอร์ อาจถูกจัดใหม่เป็นวิศวกร 3 คน และอีก 7 คนที่รับผิดชอบ การกำหนด acceptance criteria การออกแบบ test harness และ การติดตามผลลัพธ์
- การปรับแบบนี้อาจ ทำให้รู้สึกไม่สบายใจ เพราะมันลดสถานะของการลงมือสร้าง และยกระดับสถานะของการตัดสิน
- วัฒนธรรมวิศวกรรมที่ไม่ต่อต้านความเปลี่ยนแปลงนี้มีแนวโน้มจะทำได้ดีกว่า
อนาคตของซอร์สโค้ดและภาษาที่เป็นมิตรกับ LLM
- ท่ามกลางกระแสที่ปฏิบัติต่อ LLM เหมือนโปรแกรมเมอร์ อนาคตของซอร์สโค้ด เองก็กลายเป็นคำถามขึ้นมา
- several views of the future of code รวบรวมหลายมุมมองเกี่ยวกับอนาคตของโค้ด
- บางฝ่ายกำลังทดลอง ภาษาใหม่ทั้งหมดที่ออกแบบโดยคำนึงถึง LLM
- อีกฝ่ายมองว่าภาษาเดิม โดยเฉพาะภาษาที่มี type เข้มงวดอย่าง TypeScript และ Rust อาจเหมาะกับ LLM มากกว่า
- บทความนี้มีคำอ้างอิงจำนวนมากและการวิเคราะห์ของผู้เขียนเองไม่มากนัก แต่ก็อ่านได้ในฐานะ บทความภาพรวม ของประเด็นถกเถียงทั้งหมด
มนุษย์กับหน้าที่ด้าน abstraction และการตั้งชื่อ
- แม้ในกระบวนการสร้างซอฟต์แวร์ร่วมกับ LLM มนุษย์ก็ยังจะรับหน้าที่สร้าง abstraction ที่มีประโยชน์ เพื่อให้สามารถอธิบายได้ว่าโค้ดกำลังทำอะไร
- สิ่งนี้เชื่อมโยงกับ Ubiquitous Language ใน DDD
- growing a language กล่าวถึงวิธีค่อยๆ พัฒนาภาษาร่วมกับ LLM
- การเขียนโปรแกรมไม่ได้เป็นเพียงการป้อน syntax สำหรับการโค้ดที่คอมพิวเตอร์เข้าใจและรันได้เท่านั้น แต่ยังเป็น งานในการทำให้วิธีแก้ปัญหามีรูปทรง ด้วย
- เราต้องแบ่งปัญหาออกเป็นชิ้นส่วนที่โฟกัสชัดเจน รวมข้อมูลและพฤติกรรมที่เกี่ยวข้องไว้ด้วยกัน และเลือกชื่อที่เผยให้เห็นเจตนา
- ชื่อที่ดีช่วยผ่าความซับซ้อนและเปลี่ยนโค้ดให้เป็นแบบแผนที่ทุกคนตามได้ พร้อมเชื่อมโครงสร้างของปัญหากับโครงสร้างของวิธีแก้ให้ชัดเจน
3 ความคิดเห็น
คำว่า "หนี้ด้านเจตนา" เป็นคำที่เมื่อก่อนผมเคยนิยามขึ้นมาเองแบบคร่าว ๆ พอกลับมาเห็นอีกครั้งแบบนี้ก็รู้สึกยินดีนะครับ
ดูเหมือนว่าคนเราจะคิดคล้าย ๆ กันทั้งนั้น
บทความบล็อก: https://brunch.co.kr/@limjk/2
การปรับโครงสร้างองค์กรอย่างรวดเร็วให้สอดรับกับการเปลี่ยนแปลง ก็ชวนให้รู้สึกต่อต้านขึ้นมานิด ๆ เพราะให้ความรู้สึกค่อนข้างอนุรักษ์นิยมเหมือนกันนะ
ความคิดเห็นจาก Hacker News
ถ้าคุณเป็นคนประเภทที่ต้อง เข้าใจทุกอย่างอย่างลึกซึ้ง ในสิ่งที่ตัวเอง deploy ถึงจะสบายใจ การเปลี่ยนแปลงแบบนี้ก็คงทำให้รู้สึกไม่มั่นคงพอสมควร
ตอนนี้แม้แต่ โปรเจ็กต์ modernization ที่แต่ก่อนอาจใช้เวลา 2 เดือน ก็อาจจบได้ในราวหนึ่งสัปดาห์ ถ้าโฟกัสที่การออกแบบขอบเขตและอินเทอร์เฟซให้ดี แทนที่จะพยายามขุด business logic ทั้งหมดขึ้นมาแล้วคัดลอกมันแบบเดิมทุกอย่าง
แล้วก็อย่างที่บทความบอก แค่สร้าง test harness ให้ดีเพื่อยืนยันความเท่าเทียมกันให้ได้มากที่สุด
ตอนแรกฉันเองก็ขัดแย้งในใจพอสมควร แต่พอคิดดี ๆ ก็พบว่า แม้แต่ระบบอื่นที่ฉันดูแลอยู่ทุกวัน ฉันก็ไม่ได้รู้ internal implementation หรือ business logic ของมันดีขนาดนั้นเหมือนกัน
เพราะมันเป็นโค้ดที่ฉันเขียนไว้เมื่อหลายปีก่อนและแทบไม่ได้แตะอีกเลย ดังนั้นพอจะต้องเปลี่ยนอะไร สุดท้ายฉันก็อาศัยการเชื่อ test suite หรือไล่ดูโครงสร้างโค้ดเพื่อทำความเข้าใจพฤติกรรมเฉพาะจุดอยู่ดี
แม้ในช่วงที่มีการปลดคนหรือลดต้นทุน ฉันก็เห็นมาหลายครั้งแล้วว่าคนที่มีความรู้แบบนั้นมักอยู่รอดได้นานกว่าคนที่ไม่มี
ฉันสงสัยว่าตัวเองกำลังพลาดอะไรไป
ไม่ใช่ว่า LLM จะไม่มี คุณธรรมของความขี้เกียจ เสียทีเดียว
ถ้าให้ base prompt ที่ตรงกับเจตนา คุณก็สามารถทำให้เอเจนต์ที่ใช้ Claude เปลี่ยนโค้ดให้น้อยที่สุด รันการลบความซ้ำซ้อน และแสดงพฤติกรรมที่ดูเหมือนสัญชาตญาณของ senior developer มาก ๆ ได้ค่อนข้างดี
ผมคิดว่าไม่ใช่เพราะโมเดลไม่มีความรู้นั้นเลย แต่เป็นเพราะในการตั้งค่าปกติมันไม่ได้ดันสิ่งนั้นขึ้นมาอยู่แถวหน้า
หลายคนน่าจะเคยเห็นโมเดลสไตล์ แก้ไขเกินเหตุ ที่ไปแตะทั้ง codebase แบบไม่ยั้ง และไม่สนใจเลยว่ามันจะเสี่ยงต่อการชนกับงานของคนอื่นหรือทำให้ความรู้สูญหาย
เรื่องการสร้างและตรวจเอกสาร สุดท้ายก็คล้ายกับปัญหา locking แบบดั้งเดิม และมันก็มีวิธีแก้แบบดั้งเดิมอยู่แล้ว
เอเจนต์สามารถอ่าน git และเข้าใจได้ว่าอะไรเกิดก่อน รวมถึงพอจะดูออกด้วยว่าตามธรรมเนียมแล้วควรรอการเปลี่ยนแปลงอื่นอยู่หรือไม่
ผมเองก็ถือว่าซีเนียร์พอสมควร และเคยทำงานทีมเดียวกับบางคนที่ถูกอ้างถึงในบทความนี้จริง ๆ
ผมไม่คิดว่าคนเหล่านั้นจะตั้งคำถามกับมาตรฐานวิศวกรรมของผม
แต่ใน workflow ที่ผมใช้กับ LLM แทบไม่เห็นหนี้ประเภทนั้นเลย และกลับรู้สึกว่าถ้ามองด้วยมาตรฐานเดิมแบบเมื่อก่อน คุณภาพโปรเจ็กต์ตอนนี้ดีกว่าเมื่อ 5 ปีก่อน 10 ปีก่อนเสียอีก
มันไม่ใช่เวทมนตร์อะไร แค่ต้องใช้งานเอเจนต์ที่ให้ความสำคัญกับคุณภาพแบบนั้นได้ดี
และผมก็ทำงานจริงได้มากขึ้น แทนที่จะมัวแต่เรียกความสนใจตามงานคอนเฟอเรนซ์
แต่ส่วนที่บอกว่าแม้ดูด้วย ตัวชี้วัดคุณภาพซอฟต์แวร์แบบดั้งเดิม ก็ยังดีกว่าเมื่อ 5 ปีก่อน 10 ปีก่อน ฟังดูคลุมเครือเกินไป
ฉันอยากรู้ให้ชัดกว่านี้ว่าใช้ตัวชี้วัดอะไร และโค้ดเมื่อ 10 ปีก่อน 5 ปีก่อน และตอนนี้ เทียบกันออกมาอย่างไร
ถ้าไม่มีคำอธิบายแบบนั้น ข้อความกลับยิ่งพร่าและเหมือนหลุดจากประเด็นหลัก
ถ้ามีอะไรจะเล่าเพิ่ม ฉันสนใจมาก
ถึงขั้นเขียนหนังสือชื่อ Practical LLM Coding ได้เลย
ผมว่าของที่ถูกประเมินต่ำที่สุดตรงนี้คือการวางกรอบแบบ intent debt
cognitive debt หรือ technical debt อย่างน้อยยังมีร่องรอยให้เห็นในโค้ด แต่ intent debt มองไม่เห็น
เพราะงั้นมันจะโผล่มาก็ต่อเมื่อมีการเปลี่ยนแปลงที่ดูสมเหตุสมผลในระดับ local แต่ผิดในระดับ global
เนื่องจากข้อจำกัดดั้งเดิมไม่ได้ถูกทิ้งร่องรอยไว้ใน artifact ไหนเลย
กรณีที่ยากที่สุดคือในระบบ enterprise ที่ข้อจำกัดนั้นเคยเป็นข้อกำหนดด้านกฎระเบียบ แต่เมื่อ 3 ปีก่อนมันเปลี่ยนไปเงียบ ๆ และไม่มีใครอัปเดตโค้ด
แถม test ก็ยังผ่านต่อไป ทำให้ยิ่งหลุดรอดสายตาได้ง่าย
แค่ test suite อย่างเดียวกู้เจตนาเดิมกลับมาไม่ได้
ผมไม่ได้คิดว่า Martin ผิดไปทั้งหมด แต่ตรรกะนี้ดูเป็นข้ออ้างที่พูดได้ทุกครั้งเมื่อ ชั้นของ abstraction สูงขึ้น
ถ้านิยามตามเขา การย้ายจาก Assembly ไป Python ก็เท่ากับสร้าง intent debt และ cognitive debt มหาศาลเหมือนกัน
เพราะเราเลิกคิดเองว่าจะจัดการบิตอย่างไร แล้วปล่อยให้ interpreter ทำแทน
ข้อโต้แย้งของผมคือ สิ่งที่เขาเรียกว่า technical intent สุดท้ายก็เกิดขึ้นเพราะเดิมทีเราต้องแปลเจตนาของมนุษย์ให้เป็น machine code
การคิดปัญหาอย่างลึกซึ้งนั้นไม่จำเป็นต้องเกิดจากการตั้ง abstraction แบบ domain-driven ภายในโค้ดเท่านั้น
คุณจะวาด mind map เขียน journal หรือแปะโพสต์อิทเต็มกำแพงก็คิดลึกได้
abstraction เชิงวัตถุ เองก็ไม่ใช่เวทมนตร์
ในกระบวนการนั้น ความกำกวม รายละเอียดที่ยังคิดไม่ถึง หรือแม้แต่ข้อเท็จจริงที่ว่าแนวทางทั้งชุดควรถูกคิดใหม่ มักจะเผยออกมา
การเขียนด้วยภาษาธรรมชาติก็อาจเป็นเครื่องมือคิดได้ แต่การบังคับให้ความคิดต้องสอดคล้องกับภาษารูปแบบทางการที่ไม่ยอมรับความกำกวมนั้นมีบางอย่างต่างออกไปโดยเนื้อแท้
คล้ายกับการทำคณิตศาสตร์ด้วยภาษาธรรมชาติล้วน ๆ โดยไม่มีสัญลักษณ์ทางคณิตศาสตร์ ซึ่งจะยุ่งยากและผิดพลาดได้ง่ายกว่า
เพียงแต่ทำผ่านภาษาที่มนุษย์เข้าใจง่ายกว่า
มีการแมปกันโดยตรงระหว่างเจตนากับการนำไปใช้จริง
เพราะการแมปมันนิยามไว้ชัดและมีความแน่นอน
เป้าหมายของ abstraction คือทำให้คุณเชื่อได้ว่า สิ่งที่ทำอยู่ยังถูกต้อง โดยไม่ต้องกลับไปเปิดดูชั้นข้างล่างอีก
มันเป็นไปได้เพราะผมหรือใครสักคนที่ผมไว้ใจได้เคยจ่ายต้นทุนนั้นไปแล้วครั้งหนึ่ง
แต่ LLM ต้องมีการตรวจสอบ output ทุกครั้งที่สร้างขึ้นมา และต้องจ่ายหนี้นั้นใหม่ทุกครั้ง
เพราะงั้นนี่จึงยากจะเรียกว่า abstraction
บทความเขียนได้ดีมากจริง ๆ
เมื่อวานผมเองก็เพิ่งเขียนไว้ในโน้ตส่วนตัวว่า ถ้าเราไม่ พัฒนาโค้ดต่อเนื่องแบบอินทรีย์ ก็ยากจะพูดได้ว่าเราเป็นเจ้าของมันจริง ๆ
มันเหมือนรถไร้คนขับที่เมื่อก่อนอย่างน้อยยังจำวิวระหว่างทางได้ แต่ตอนนี้เหมือนโดนวาร์ปไปอีกที่แล้วเปิดวิดีโอบันทึกให้ดูเฉย ๆ
การรีวิวแบบนี้มีประสิทธิภาพลดลง
กับเครื่องมือเล็ก ๆ ghosted code แบบนี้อาจพอรับได้ แต่กับระบบอย่างฐานข้อมูล ผมกังวลจริง ๆ
เพราะงั้นตอนนี้ผมแทบไม่ให้สิทธิ์เขียนกับเอเจนต์แล้ว และกลับไปสู่การทำ QA แบบ manual เป็นหลักเหมือนเมื่อ 2 ปีก่อน
ทั้งในแง่การใช้โทเค็นและผลลัพธ์ กลับกลายเป็นว่าวิธีนั้นมีประสิทธิภาพกว่า
แน่นอนว่านี่เป็นเพียงประสบการณ์ของผมเอง
น่าเสียดายที่ บทความวิจัยของ Wharton ที่เขาแนบมาดูเหมือนมีหลายส่วนถูกสร้างโดย AI และยังไม่ได้ผ่าน peer review ด้วย
ผมเข้าใจว่านักวิจัยสมัยนี้ใช้ AI ช่วยเขียนกันเยอะ แต่ถ้าหัวข้อของงานดันเป็น cognitive surrender ก็ยิ่งยากจะรับเนื้อหานั้นอย่างจริงจัง
not merelyตั้ง 7 ครั้งก็ไม่แน่ใจว่า LLM จะย้ำสำนวนเดิมขนาดนั้นไหม หรือจริง ๆ แล้วอาจเป็นผู้เขียนที่เริ่ม ติดนิสัยเขียนแบบ LLM ไปแล้วก็ได้
Martin ไม่ได้ผิดไปหมด แต่ผมเคยเห็นกรณีที่ AI สร้าง โค้ดขี้เกียจ และคำตอบที่ถูกต้องจริง ๆ กลับเป็นการมีโค้ดมากขึ้น
ให้ตัวอย่างคือมี Python model ที่นิยาม database schema สำหรับชุดแนวคิดทางตรรกะบางอย่าง
แล้วมีการเพิ่มแนวคิดใหม่ที่คล้ายกับชุดตรรกะเดิมมาก ซึ่ง Claude ตัดสินใจว่าน่าจะ reuse ชุด model เดิมได้เลย
ในทางทฤษฎีมันใช้งานได้ แต่ฝั่งผู้ใช้จริงกลับต้องทำทางอ้อมสารพัดเพราะการอนุมานชนิดข้อมูลตอนรันไทม์
มันเป็นกรณีที่ใช้งานได้ก็จริง แต่เลือกระดับ abstraction ผิดไปทั้งหมด
สำหรับมนุษย์เราต้องการ abstraction แต่บางครั้งการทำซ้ำตรง ๆ อาจเหมาะกว่า
ถ้าเครื่องเป็นคนเขียนและดูแลโค้ดเอง ชั้น abstraction เพิ่มเติมแบบเดิมก็อาจไม่จำเป็นเสมอไปแล้ว
สมัยก่อนเราใช้ Duff's device และ unroll loop ด้วยมือเพื่อสร้างโค้ดซ้ำเอง
ทุกวันนี้ compiler เข้าใจเจตนาและสร้าง assembly ที่ซ้ำกันให้เอง เราจึงไม่ต้องกังวลกับความซ้ำนั้น
ช่วงหลังผมต้องใช้โค้ด computational geometry ที่ไม่ธรรมดาพอสมควรอยู่หลายชิ้น ซึ่งถ้าเป็นแต่ก่อนก็ต้องไปหาไลบรารี ขออนุมัติด้าน compliance และรับต้นทุนในการแปลงโครงสร้างข้อมูลโดเมนของผมให้เข้ากับรูปแบบของไลบรารีนั้น
ต่อให้ยังถูกกว่าการเขียนเองทั้งหมด ต้นทุนพวกนั้นก็ไม่ใช่เรื่องเล็ก
ตอนนี้ LLM สามารถเขียนเฉพาะส่วนที่ผมต้องการ และใช้รูปแบบข้อมูลที่ผมเก็บอยู่ได้ตรง ๆ
ไม่ต้องดึงไลบรารีใหญ่เข้ามา และไม่ต้องแปลงโครงสร้างข้อมูลด้วย
ตามหลักทั่วไป การใช้ geometry library เพื่อหลีกเลี่ยงความซ้ำซ้อนคงเป็นทางที่ถูกกว่า แต่ในกรณีนี้ฟังก์ชันเดียวที่พึ่งพาตัวเองได้กลับทำงานได้ดีเฉย ๆ
นี่น่าจะเป็นสิ่งที่ดีที่สุดที่ผมอ่านบน Hacker News ในรอบนานมาก
รู้สึกร่วมอย่างแรง
เพราะแนวคิด cognitive debt ของ Simon Willison และมุมมองที่ว่า “หน้าที่ของคุณคือ deploy เฉพาะโค้ดที่พิสูจน์แล้วว่าใช้งานได้” ผมเลยไปทำโปรเจ็กต์ฝั่ง Intent-Driven Development
เจตนาเดิมดูเหมือนจะพร่าเลือนไปเสมอเมื่อการเปลี่ยนแปลงสะสมมากขึ้น
ผมอาจจะจัดสิ่งนี้ให้อยู่ในรูปแบบ protocol จริง ๆ แล้วเอาไปโพสต์บน Hacker News ทีหลัง
ถ้ายังไม่เคยเห็นงานเขียนของผม แนะนำให้ลองหาอ่านดู
สรุปสั้น ๆ คือแบบนี้
ภาพที่ผมใช้มองปัญหาตอนนี้ใกล้เคียงกับรูปนี้: https://excalidraw.com/#json=y1fSSx2z8-0nFs7CDnqhp,d9Di8JdGU...
ผมมองว่า คอขวดด้านการรับรู้ ใน software engineering ไม่ได้อยู่ในโค้ด แต่อยู่ ระหว่าง artifact ต่าง ๆ มากกว่า
โค้ดเป็นเพียงหนึ่งในนั้น
outcome → requirements → spec → acceptance criteria → executable proof → review
ผมกำลังทำ tooling เชิงทดลองเพื่อทำให้ส่วนที่น่าเบื่อระหว่างการเปลี่ยนผ่านเหล่านี้เป็นอัตโนมัติ และให้มนุษย์โฟกัสกับการตรวจว่าเจตนายังรอดอยู่ในแต่ละขั้นหรือไม่
มีอีกชั้นหนึ่งที่ผมอยากเติมเข้าไปคือ proxies/metrics
ในระบบที่เน้นการวิเคราะห์มาก ๆ ความสูญเสียจริงมักไม่ได้เกิดที่ spec → code แต่เกิดที่ question → proxy
พอ proxy ถูกฝังเข้าไปใน acceptance criteria, dashboard หรือ eval คนก็จะเริ่ม optimize กับมัน และค่อย ๆ ลืมไปว่ามันเป็นแค่ตัวชี้วัดตัวแทนเท่านั้น
ตอนเปิดบนมือถือ พอพยายามแพน ซูม หรือเลื่อน กลับเผลอไปขยับองค์ประกอบบนแคนวาสตลอด