โค้ดถูกลงกว่าเดิม
(htmx.org)- ต้นทุนการเขียนโค้ดลดลงอย่างรวดเร็วจากการแพร่หลายของเครื่องมือเขียนโค้ดด้วย AI แต่ในความเป็นจริง ต้นทุนในการทำความเข้าใจ โค้ดที่ถูกสร้างขึ้นกลับสูงขึ้น
- LLM มีความไม่เป็นกำหนดแน่นอน ไม่เก็บรักษาซอร์สต้นฉบับไว้ และขอบเขตของผลลัพธ์ก็ขยายกว้างไปถึงซอฟต์แวร์ทั่วไปทั้งหมด จึง ไม่อาจมองว่าเทียบเท่ากับผลลัพธ์จากคอมไพเลอร์ได้
- LLM สร้างโค้ดได้เร็วกว่าความเร็วที่มนุษย์จะทำความเข้าใจได้มาก จึงแนะนำให้ใช้งานแบบ ค่อยเป็นค่อยไป (incremental) เพื่อป้องกันการเปลี่ยนแปลงขนาดใหญ่ที่ไม่มีใครเข้าใจ
- ความเสี่ยงสำคัญเมื่อโค้ดมีราคาถูกลงคือ ความซับซ้อน (complexity) ซึ่งเพิ่มขึ้นอย่างน้อยในระดับเรขาคณิตตามขนาดของระบบ ขณะที่ LLM เป็นนักเขียนโค้ดปริมาณมากที่ไม่หวั่นเกรงความซับซ้อน
- ทางออกที่เสนอคือ วิศวกรสายลดทอน (subtractive engineer) ที่เน้นลบและทำให้เรียบง่ายแทนการเพิ่มโค้ด พร้อมย้ำถึงการรักษาศิลปะแห่งการเขียนโปรแกรมคอมพิวเตอร์
ยุคที่โค้ดมีราคาถูกลง
- ในช่วง 1 ปีที่ผ่านมา AI สามารถสร้างโค้ดคุณภาพค่อนข้างดีจำนวนมากได้อย่างรวดเร็ว ทำให้ ต้นทุนการสร้างโค้ด ลดลงอย่างมาก
- ต่อข้ออ้างที่ว่า "ปัญหาไม่เคยอยู่ที่การเขียนโค้ดตั้งแต่แรก" ผู้เขียนโต้แย้งว่า การเขียนโค้ดก็เป็นส่วนหนึ่งของปัญหา และส่วนนั้นถูกลดทอนไปมากด้วยเครื่องมือเขียนโค้ดด้วย AI
- ผู้เขียนตั้งคำถามว่า สำหรับนักพัฒนาที่เคยภาคภูมิใจกับทักษะการเขียนโค้ดในอดีต การที่ ความสำคัญของการเขียนโค้ดล้วน ๆ ลดลง หมายความว่าอย่างไร
ต้นทุนของความเข้าใจที่สูงขึ้น (Understanding is Expensive(er))
- เมื่อโค้ดไม่ได้ค่อย ๆ ถูกสร้างขึ้นอย่างยากลำบากจากมือนักเขียนโปรแกรม แต่ถูกผลิตออกมาเป็นจำนวนมาก ก็เท่ากับว่า ความเข้าใจต่อโค้ดนั้นไม่ได้เกิดขึ้นเอง
- หากต้องการความเข้าใจ ก็ต้องได้มาหลังจากเขียนโค้ดเสร็จด้วยการ อ่านโค้ด
- ตามสามัญสำนึก การอ่านโค้ดที่คนอื่นเขียนมักยากกว่าการเขียนโค้ดของตัวเอง
- ผู้เขียนมองข้อโต้แย้งฝั่งสนับสนุน AI ที่ว่า "เราเองก็ไม่ได้เข้าใจผลลัพธ์จากคอมไพเลอร์อยู่แล้วไม่ใช่หรือ" ว่าเป็น ความผิดพลาดด้านการจัดหมวดหมู่ (category error)
- คอมไพเลอร์ให้ผลลัพธ์แบบกำหนดแน่นอน แต่ LLM โดยการออกแบบแล้วเป็นแบบไม่กำหนดแน่นอน
- เวิร์กโฟลว์ของคอมไพเลอร์เก็บรักษาซอร์สโค้ดต้นฉบับไว้ แต่เวิร์กโฟลว์ของ LLM โดยมากไม่ทำเช่นนั้น
- ผลลัพธ์จากคอมไพเลอร์จำกัดอยู่ในโดเมนแคบอย่างภาษาเครื่อง แต่ผลลัพธ์ของ LLM ไม่ได้ถูกจำกัดอยู่แค่ซอฟต์แวร์ที่ทำให้เป็นมาตรฐานทั่วไป
- ในกรณีส่วนใหญ่ โดยเฉพาะซอฟต์แวร์ ภารกิจสำคัญยิ่ง (mission-critical software) นักพัฒนายังจำเป็นต้องเข้าใจโค้ดฐานอยู่ดี แม้โค้ดนั้นจะถูกสร้างโดย LLM
- LLM สามารถผลิตโค้ดได้เร็วในระดับที่ไม่มีใครไล่ทัน จึงมี ความเสี่ยงที่ความเร็วในการสร้างจะนำหน้าความเร็วในการทำความเข้าใจ
- ดังนั้นจึงแนะนำให้ ใช้งานแบบค่อยเป็นค่อยไป มากกว่าการสร้างรายการเปลี่ยนแปลงขนาดใหญ่ในคราวเดียว
- อาจเหมาะกับการรีแฟกเตอร์เชิงกล แต่เมื่อใช้เพื่อใส่ความหมายใหม่ (semantics) เข้าไปในโค้ดเบส จะมีความเสี่ยงสูงมาก
กับดักศิษย์พ่อมด (The Sorcerer's Apprentice Trap)
- ผู้เขียนยกฉาก "The Sorcerer's Apprentice" จากภาพยนตร์ Disney เรื่อง Fantasia มาเป็น อุปมาที่เหมาะสมกับยุค AI
- ศิษย์ใช้เวทมนตร์กับไม้กวาดเพื่อลดภาระการทำความสะอาด แต่ไม้กวาดกลับทำความสะอาดอย่างรุนแรงขึ้นเรื่อย ๆ จนสถานการณ์ควบคุมไม่ได้
- ท้ายที่สุดพ่อมด (Sorcerer) ต้องกลับมาควบคุมสถานการณ์อีกครั้ง ตำหนิความโง่เขลาของศิษย์ และจัดการความโกลาหล
- บทเรียนจากอุปมานี้คือ เราต้องเป็นพ่อมด ไม่ใช่ศิษย์ และพ่อมดนั้นต้องเข้าใจโค้ด
ความซับซ้อนยังคงเป็นเรื่องแย่ (Complexity: Still Bad)
- มนุษย์มักทำความเข้าใจเส้นโค้งแบบเรขาคณิตและเอ็กซ์โปเนนเชียลได้ไม่ดี และมักเชื่อเรื่องอย่างดอกเบี้ยทบต้น (compound interest) ราวกับเป็นนิทาน
- ความเสี่ยงสำคัญเมื่อโค้ดมีราคาถูกลงคือ ความซับซ้อน (complexity) ซึ่งผู้เขียนอ้างว่าเพิ่มขึ้นอย่างน้อยแบบเรขาคณิต และบ่อยครั้งเป็นแบบเอ็กซ์โปเนนเชียลตามขนาดของระบบ แม้ไม่ได้ยกหลักฐานพิสูจน์
- ก่อนยุค LLM ก็มี นักเขียนโค้ดปริมาณมาก (prolific coder) อยู่แล้ว
- นักเขียนโค้ดปริมาณมากที่ไม่กลัวความซับซ้อนจะพอกโค้ดทับลงบนปัญหาเดิมต่อไปเรื่อย ๆ จนระบบพังสู่ สภาวะหยุดนิ่งที่แก้ไขไม่ได้ ซึ่งการเปลี่ยนแปลงใด ๆ ก็สร้างบั๊กพอ ๆ กับที่แก้ได้
- LLM เป็นทั้งนักเขียนโค้ดปริมาณมากและไม่มีความกลัวต่อความซับซ้อน จึง เป็นความเสี่ยง
วิศวกรสายลดทอนและการจำกัด (The Subtractive, Constraining Engineer)
- เพื่อรับมือกับความเสี่ยงของโค้ดที่สร้างโดย LLM ผู้เขียนเสนอแนวคิด วิศวกรสายลดทอนและการจำกัด (subtractive, constraining engineer)
- วิศวกรแบบนี้กล้าพูดว่า "ไม่" ตรวจทานผลลัพธ์จาก LLM อย่างละเอียด เสนอการทำให้เรียบง่าย และรักษาการควบคุมไว้อย่างเด็ดขาด
- ความภาคภูมิใจของเขาไม่ได้อยู่ที่โค้ดที่ตัวเองสร้าง แต่คือโค้ด (และเลเยอร์) ที่ ลบออกจากระบบหรือกันไม่ให้เข้ามา
- ท่าทีแบบนี้ใกล้เคียงกับ ประติมากร (sculptor) มากกว่าผู้ก่อสร้าง (builder)
- ท่าทีแบบผู้ก่อสร้าง (builder) ยังมีความสำคัญในระดับของ การออกแบบระบบ
- วิศวกรที่ดีต้องรู้วิธีประกอบคอมโพเนนต์ต่าง ๆ เข้าด้วยกันอย่างมีประสิทธิภาพเพื่อสร้างระบบ
- แต่แม้ในระดับนี้ แนวคิดแบบลดทอนที่ตัดคอมโพเนนต์และขอบเขตของระบบที่ไม่จำเป็นออก เพื่อทำให้การดีพลอยและการโต้ตอบเรียบง่ายขึ้น ก็ยังมีประโยชน์
- วิศวกรสายลดทอนเป็นคนอีกประเภทหนึ่งจากโค้ดเดอร์ส่วนใหญ่ในอดีต และสอดคล้องกับท่าทีที่ชอบพูดว่า "ไม่" กับชอบขัดเกลาระบบเดิม มากกว่าการเขียนใหม่แบบฮีโรอิก
- แนวทางนี้ยอมรับความจริงสองชั้นว่า โค้ดถูกลงแล้ว และความซับซ้อนก็ยังเป็นผู้ล่าลำดับสูงสุด (apex predator) พร้อมเสนอวิธีที่สร้างสรรค์ในการรักษาศิลปะแห่งการเขียนโปรแกรมคอมพิวเตอร์
1 ความคิดเห็น
ความคิดเห็นจาก Lobste.rs
บทความปี 1985 ของ Peter Naur เรื่อง Programming as Theory Building ดูเหมือนว่ายัง คุ้มค่าที่จะกลับไปอ่านซ้ำอีกหลายรอบ ในยุคนี้
ผมมองว่าคำพูดที่ว่า “LLM ไม่สามารถกลัวความซับซ้อนได้” ค่อนข้าง พูดเกินจริง
รูปแบบความล้มเหลวแบบนั้นมีอยู่จริง ถ้าให้คำสั่งกว้าง ๆ LLM มักจะเพิ่มชั้น สร้าง abstraction และมักเขียนโค้ดเกินความจำเป็นเมื่อเทียบกับปัญหา แต่พฤติกรรมแบบนั้นสังเกตได้ง่าย รีวิวได้ง่าย และน่าแปลกที่เปลี่ยนทิศทางได้ง่ายด้วย แค่กำหนดสไตล์ซอฟต์แวร์ที่ต้องการผ่านไฟล์ AGENTS/CLAUDE.md
แค่บอกให้เปลี่ยนให้น้อยที่สุด ถามว่าลบอะไรได้บ้าง และถามว่า abstraction นั้นคุ้มค่าจริงไหม ถามเรื่อง invariant, จุดเชื่อมต่อ, ภาระทางการรับรู้ด้วย และขอรอบที่สองเพื่อตัดความฉลาดเกินจำเป็นออก โดยทั่วไปมันก็มักจะทำตามแรงกดดันนั้น ถ้าใส่ไว้ในพรอมป์ต์ตั้งแต่แรก ก็ทำให้มันหลีกเลี่ยงได้ตั้งแต่ต้น
ความเสี่ยงไม่ได้อยู่ที่ LLM ไม่มีวันเคารพความซับซ้อนได้เลย แต่อยู่ที่มันยินดีสร้างรูปแบบโค้ดที่กระบวนการรอบข้างให้รางวัล ทีมที่ให้รางวัลกับปริมาณก็จะได้ปริมาณ ส่วนทีมที่ให้รางวัลกับความเรียบง่ายก็มักจะได้แบบนั้นเช่นกัน
โมเดลทุกวันนี้ดีกว่ามนุษย์ส่วนใหญ่แล้ว และต่อไปก็จะยิ่งดีขึ้น ถ้าโค้ดออกมาไม่ดี ก็ควรกดดันห้องแล็บ AI ด้วยฟีดแบ็ก เช่น ผมมองว่าตระกูล GPT เขียนเอกสารดี ๆ ได้แย่มาก
เพราะงั้นคำว่า “เป็นไปไม่ได้” อาจไม่ใช่คำที่ดีที่สุด แต่ผมคิดว่ามีอคติหลายอย่างที่เอนเอียงไปทางความซับซ้อนเป็นค่าเริ่มต้น
อีกอย่างยังมี อคติที่ชอบทำอะไรสักอย่าง มากกว่าจะไม่ทำ โปรแกรมเมอร์ที่ดีใช้บริบทมากกว่าผู้จัดการที่โยนคำขอมาเฉพาะหน้าเยอะมาก และยังเสนอทางเลือกได้ด้วย LLM ก็อาจทำได้ แต่ LLM ตอนนี้ยังไม่เก่งในการตั้งคำถามที่ถูกต้อง แม้จะมีโค้ดสำหรับ “ถามระหว่างวางแผน” หรือการตรวจจับการวนซ้ำก็ตาม ข้อมูลฝึกแบบนั้นก็น่าจะไม่พบได้บ่อยนัก
ในบางแง่ prompt engineering ก็ใกล้เคียงกับการแฮ็กอันน่ากลัวที่พยายามอ้อมปัญหาชุดนี้
แต่อีกด้านหนึ่ง ผมก็เคยได้คำตอบทำนองว่า “นี่เป็นโปรเจกต์แค่หนึ่งเดือน ผมไม่แนะนำครับ จะคอมมิตไว้แบบนี้แล้วเก็บเป็นเดโมดีไหม” แล้วผมต้องคอยกล่อมและทำให้ LLM มั่นใจ ทั้งที่รู้ว่าทั้งสองอย่างใช้เวลาไม่ถึงชั่วโมง แต่ถ้าพูดว่า “โอเค ลองทำอะไรใหม่ไปเลย หาแนวทางเอาเอง” มันก็ยังลองทำอยู่ดี ในความหมายนั้นก็อาจบอกได้ว่ามันไม่กลัว
แต่พูดเล่นนอกเรื่องพอแล้ว เห็นด้วยครับ ตรงกับประสบการณ์ผมเหมือนกัน
โดยทั่วไปผมไม่ค่อยเห็นด้วยกับคำพูดที่ว่า “ต้นทุนในการเข้าใจโค้ดแพงขึ้นแล้ว”
ถ้าเป็นโค้ด LLM ที่สร้างแบบไม่คิดก็อาจจริง แต่ถ้าแนะนำอย่างเหมาะสม LLM ก็สร้าง โค้ดที่อ่านง่ายและแยกชั้นชัดเจน ได้ แน่นอนว่าในกรณีนั้นการเลือกสถาปัตยกรรมส่วนใหญ่ยังเป็นหน้าที่ของมนุษย์ ซึ่งผมคิดว่าเดิมทีก็ควรเป็นแบบนั้น
ในทางกลับกัน ผมรู้สึกว่า LLM เก่งมากในการช่วยทำความเข้าใจโค้ดที่เขียนโดยคนที่เราไม่คุ้นเคย เราสามารถให้ Claude Code วิเคราะห์โค้ดบางส่วนแบบลึก ๆ สร้างเอกสาร Markdown อธิบายแต่ละส่วน และยังแนะนำลำดับว่าผมควรเริ่มรีวิวหรือเริ่มทำความเข้าใจจากตรงไหนก่อน
สิ่งนี้มีคุณค่ามากจริง ๆ
ประโยคที่ว่า “มนุษย์โดยทั่วไปไม่ค่อยเข้าใจเส้นโค้งเอ็กซ์โปเนนเชียล จึงเชื่อเทพนิยายอย่างดอกเบี้ยทบต้น” หมายความว่า ดอกเบี้ยทบต้น เป็นเทพนิยายงั้นหรือ? หรือผมเข้าใจอะไรผิดไป?