บทนำ — ความเข้าใจผิดของสเปกภาษาอังกฤษ
- เริ่มต้นจากการได้แรงบันดาลใจจากบทความที่ว่า “สเปกที่ละเอียดเพียงพอก็คือโค้ด” สเปกภาษาอังกฤษดูเหมือนจะแม่นยำโดยสัญชาตญาณ แต่พอจะลงมือทำจริง ความกำกวมก็ปรากฏออกมา
- “ทุกสิ่งล้วนกำกวม จนกว่าจะพยายามทำให้มันแม่นยำ” — เบอร์ทรันด์ รัสเซลล์
- การเขียนโปรแกรมก็เหมือนการเขียนหนังสือ คือเป็นกิจกรรมแบบวนซ้ำที่ค่อยๆ ลับความคิดให้คมขึ้นระหว่างลงมือทำ (เรียงความชิ้นนี้เองก็ผ่านร่างมานับไม่ถ้วน)
Vibe coding — ทำไมมันถึงเวิร์ก และทำไมมันถึงอันตราย
- เพราะ AI แปลงจากภาษาอังกฤษ→โค้ดที่รันได้เก่งขึ้นและเร็วขึ้นเรื่อยๆ เราจึงเริ่มสร้างโค้ดจากระดับ “ความรู้สึก (vibe)” แบบภาษาอังกฤษได้
- ระหว่างตอบสนองต่อผลลัพธ์ที่ AI สร้างขึ้น — “ย้ายปุ่มไปตรงนั้นหน่อย เอาให้ฟ้ากว่านี้” — กระบวนการก็จะค่อยๆ แม่นยำขึ้น
- คำว่า “vibe coding” จึงเหมาะอย่างยิ่ง: เราคงระดับความรู้สึกแบบภาษาอังกฤษไว้ ขณะเดียวกันก็ใช้ผลลัพธ์จาก AI มาลับความคิดให้คมขึ้น
- ปัญหาหลักคือ vibe ทำให้เราหลงคิดว่ามันเป็น abstraction ที่แม่นยำ พอฟีเจอร์เพิ่มขึ้นหรือสเกลใหญ่ขึ้น abstraction ก็เริ่มรั่ว (leaky abstraction) และบั๊กที่คาดไม่ถึงก็อาจพังทั้งวันของคุณได้
กรณีจริง — แอป vibe coding ของ Dan Shipper
- แอปแก้ไขข้อความที่ Dan Shipper ทำด้วย vibe coding กลายเป็นไวรัล → เซิร์ฟเวอร์ล่ม
- สาเหตุ: “การทำงานร่วมกันแบบเรียลไทม์ (live collaboration)” ดูเหมือนจะเรียบง่ายโดยสัญชาตญาณ แต่ในความเป็นจริงกลับซับซ้อนระดับฝันร้าย
- เราทุกคนเคยใช้ Google Docs และ Notion กันมาแล้ว เลยทำให้ “การทำงานร่วมกันแบบเรียลไทม์” ดูเหมือนเป็นสิ่งที่มีสเปกชัดเจนแม่นยำ ทั้งที่จริงแล้วแทบเป็นไปไม่ได้เลยที่จะรู้ล่วงหน้าว่ามันไม่ใช่แบบนั้น
- ตัวผู้เขียนเองเมื่อ 10 ปีก่อนก็เคยทำ collaborative editor แล้วเจอกับฝันร้ายของความซับซ้อนที่ไม่คาดคิด อะไรยากบ้างน่ะหรือ? จำไม่ได้แล้ว! นั่นเองก็เป็นส่วนหนึ่งของปัญหา — ความซับซ้อนนั้นน่าเบื่อ ไม่น่าอยากคิดถึง และยากจะจำรายละเอียดกับ edge case ต่างๆ
- ตัวอย่าง: ผังงานคลาสสิกของ Slack สำหรับตัดสินใจว่าจะส่ง notification หรือไม่ — ความซับซ้อนระดับนี้ซ่อนอยู่หลังคำง่ายๆ อย่าง “ส่ง notification”
Abstraction — เครื่องมือเดียวในการรับมือกับความซับซ้อน
- ข้อจำกัดพื้นฐานของสมองมนุษย์: ประมวลผลได้ครั้งละเพียง 7±2 อย่าง
- วิธีเดียว ที่จะจัดการกับมากกว่า 7 อย่างได้ คือบีบอัด (compress) หลายสิ่งให้กลายเป็นหนึ่งเดียว กระบวนการนี้ทำซ้ำแบบ recursive ได้ไม่สิ้นสุด มนุษย์จึงสามารถรับมือกับความซับซ้อนไม่มีที่สิ้นสุดได้ ขั้นของการบีบอัดนี้เองคือ abstraction
- “จุดประสงค์ของ abstraction ไม่ใช่การทำให้คลุมเครือ แต่คือการสร้างระดับความหมายใหม่ที่สามารถแม่นยำได้อย่างถึงที่สุด” — ไดคสตรา
- กรณีที่ Sophie Alpert รีแฟกเตอร์ผังงาน notification อันเลื่องชื่อของ Slack ให้เรียบง่ายลงมากด้วย abstraction ที่ชาญฉลาด
- ส่วนที่ดีที่สุดของการเขียนโปรแกรม: การสร้าง abstraction ที่ดีขึ้นเรื่อยๆ เพื่อพิชิตความซับซ้อน เหมือนที่ ReactJS หรือ TailwindCSS เคยทำได้ในแต่ละโดเมนของตัวเอง
- การที่ collaborative text editor มีความซับซ้อนโดยพื้นฐาน ไม่ได้หมายความว่าเป็นไปไม่ได้ แต่หมายความว่าเราต้องค้นหา abstraction ที่ดีกว่าเดิมต่อไป
AGI — ถึงอย่างนั้นโค้ดที่ดีก็จะไม่หายไป
- ลองนึกภาพอีก 1 ปี, 2 ปี, 5 ปี, 10 ปี, 100 ปีข้างหน้า: AI จะเก่งขึ้น / เร็วขึ้น / ถูกลงเรื่อยๆ และวันหนึ่งก็จะมาถึงจุดที่สติปัญญาของเครื่องแยกไม่ออกจากมนุษย์ (AGI)
- โลกของ AGI อาจดูเหมือนโลกของ vibe ถ้าคุณจ้างอัจฉริยะระดับ Karpathy ได้ 100 คนในราคา $1000/เดือน แล้วจะไปสนใจรายละเอียดน่ารำคาญพวกนั้นทำไม?
- “นี่มันพูดตลกชัดๆ” ความคิดแบบนี้เกิดขึ้นได้ก็เพราะเรายังคิดถึงเทคโนโลยีนี้ในเชิงนามธรรม ก่อนที่มันจะมาถึงจริง
- ถ้าเราเข้าถึงสติปัญญาระดับนั้นได้จริง จะไม่มีใครสัก 0% ใช้มันเพื่อปั๊ม slop เพิ่ม แน่นอนว่าไม่ใช่
- สาเหตุที่เราสับสนก็เพราะเราคิดผิดๆ ว่าโค้ดมีไว้เพื่อผลิตซอฟต์แวร์เท่านั้น ทั้งที่ตัวโค้ดเองก็เป็นผลลัพธ์หลักเช่นกัน ถ้าทำได้ดี มันก็เป็นบทกวีได้
- “ไม่มีใครพูดถึง ‘vibe writing’ กันไม่ใช่เหรอ?” — ในโลกของงานเขียน ไม่มีใครเชื่อว่า ChatGPT จะมาแทนนักเขียนนิยายหรือนักข่าวชั้นยอดได้ โค้ดก็เหมือนกัน แต่ความ “มหัศจรรย์” ของโค้ดที่รันได้ทำให้เกิดภาพลวงตานี้ขึ้น
- AI สร้างโค้ดที่แย่ได้ (แม้จะน้อยลงเรื่อยๆ) เราทุกคนรู้เรื่องนี้ดี การใช้ AI จึงเป็นการใช้ ทั้งที่ โค้ดมันแย่ ไม่ใช่ใช้ เพราะ โค้ดมันแย่
- คำพูดของ Simon Willison: “AI ควรช่วยให้เราสร้างโค้ดที่ดีกว่าเดิม”
- สิ่งแรกที่เราควรทำเมื่อ AGI มาถึง: ใช้มันแก้ปัญหา abstraction ที่ยากที่สุด สร้าง abstraction ที่ดีกว่าเดิมเพื่อให้เราเข้าใจและพิชิตความซับซ้อนได้ดีขึ้น
- AI ยิ่งฉลาดขึ้นแล้วความจำเป็นของโค้ดที่ดียิ่งหายไปอย่างนั้นหรือ? นั่นก็ไม่ต่างอะไรกับการบอกว่าจะใช้ ChatGPT ปั๊ม slop ให้มากขึ้น
- กรณีจริง: Opus 4.6 แก้ปัญหาค้างคาที่ Val Town มีในการสร้าง full-stack React framework (vtrr) ได้แบบ one-shot ผลลัพธ์คือเดโมแอป full-stack ไฟล์เดียว 50 บรรทัด
บทสรุป — โค้ดเพิ่งเริ่มต้นเท่านั้น
- ดูเหมือน 99% ของสังคมจะเห็นด้วยกับคำว่า “โค้ดตายแล้ว” เมื่อวานนี้เองผู้เขียนยังได้ยิน podcaster อย่าง Sam Harris พูดอย่างมั่นใจว่า “ทุกคนเห็นตรงกันแล้วว่าการเขียนโค้ดตายแล้ว ไม่มีใครจำเป็นต้องเรียนโค้ดอีกต่อไป”
- “นี่มันน่าเศร้า เหมือนพูดว่า ‘การเล่าเรื่องตายแล้ว’ หลังจากมีการประดิษฐ์แท่นพิมพ์ พวกโง่เอ๊ย โค้ดเพิ่งเริ่มต้นเท่านั้น AI จะเป็นพรอันยิ่งใหญ่ต่อการเขียนโค้ด”
- คำคมปิดท้าย:
- “อย่ามองภาระของการต้องใช้สัญลักษณ์เชิงรูปแบบเป็นภาระ แต่ให้มองว่าการได้ใช้มันคืออภิสิทธิ์ เพราะมันทำให้นักเรียนสามารถทำสิ่งที่เมื่อก่อนมีแค่อัจฉริยะเท่านั้นที่ทำได้” — ไดคสตรา
- “การใช้ภาษาแม่ได้อย่าง ‘เป็นธรรมชาติ’ ก็เป็นเพียงความสามารถในการสร้างประโยคที่ไร้สาระโดยที่ความไร้สาระนั้นไม่ชัดเจนเท่านั้น” — ไดคสตรา, “On the foolishness of natural language programming”
- “การออกแบบซอฟต์แวร์มีอยู่สองวิธี: วิธีหนึ่งคือทำให้มันง่ายเสียจนเห็นได้ชัดว่าไม่มีข้อบกพร่อง อีกวิธีคือทำให้มันซับซ้อนเสียจนมองไม่เห็นข้อบกพร่องที่ชัดเจน” — Tony Hoare
- “ปริมาณความหมายที่ถูกบีบอัดไว้ในพื้นที่เล็กๆ ผ่านสัญลักษณ์พีชคณิต คือสิ่งที่ทำให้การให้เหตุผลผ่านมันทำได้ง่ายขึ้น” — Charles Babbage
7 ความคิดเห็น
ก่อนจะไปถึงเรื่องการแก้ไขร่วมกัน แค่การทำเอดิเตอร์สำหรับใช้งานคนเดียวให้ดีจริง ๆ ก็เต็มไปด้วยความซับซ้อนที่คาดไม่ถึง ทั้งการจัดการเคอร์เซอร์, สแตก undo/redo, การป้อนข้อมูลผ่าน IME ฯลฯ อย่างที่บทความชี้ไว้ ไม่มีซอฟต์แวร์ไหนที่แสดงให้เห็นกับดักของ “สเปกที่ให้ความรู้สึกว่าเข้าใจง่ายแต่ต้องแม่นยำ” ได้ชัดเจนเท่าเอดิเตอร์อีกแล้ว สุดท้ายแล้วสิ่งที่ดูเหมือนง่าย ไม่ได้ง่ายจริง แต่เป็นการซ่อนความซับซ้อนนั้นไว้ด้วยการทำ abstraction ได้ดีต่างหาก
จริงๆ แล้วเหตุผลที่ Anthropic สร้าง C compiler เป็นเดโมก็น่าจะเป็นเพราะคอมไพเลอร์เป็นสิ่งที่มีสเปกชัดเจนและมีชุดทดสอบเตรียมไว้อย่างดีอยู่แล้วนั่นเองด้วยล่ะครับ ในขณะเดียวกันมันก็ดูเหมือนเป็นงานที่ยากมากด้วย
ผมเคยลองทำคอมไพเลอร์มาหลายตัว และตอนนี้ก็มีงานที่กำลังทำอยู่ด้วย พอมองในแง่ของ vibe coding ผมก็เคยลองทำเอดิเตอร์เหมือนกัน แต่รู้สึกว่าคอมไพเลอร์ง่ายกว่า อย่างที่คุณเขียนไว้ ผมรู้สึกว่าสเปกไม่แม่นยำน้อยกว่าและมีตัวแปรจากผู้ใช้มากกว่า อีกทั้งยังทดสอบได้ยากกว่าด้วย
แม้ว่าสเปกจะยิ่งสำคัญขึ้น แต่ผมคิดมาตั้งแต่ก่อนแล้วว่าการเขียนสเปกให้ละเอียดครบทั้งหมดและครอบคลุมทุกสถานการณ์นั้นเป็นไปไม่ได้ ผมยังคิดว่าการค่อยๆ ขัดเกลาสเปกไปพร้อมกับการทำงานเหมือนกับโค้ดยังเป็นทิศทางที่ดีกว่าในตอนนี้ แต่ก็แอบคิดเหมือนกันว่าถ้าให้เอเจนต์หลายตัวทำแบบนั้นกันเองก็น่าจะได้ อย่างไรก็ตาม สุดท้ายแล้วหากไม่มีการแทรกแซงจากมนุษย์ ก็คงยากจะก้าวพ้นสถานการณ์และความรู้ที่ได้เรียนรู้มา ดังนั้นสถานการณ์และฟังก์ชันใหม่แบบที่ไม่เคยมีมาก่อนคงจะยากอยู่ดี
มันให้ความรู้สึกเหมือนตอนที่หุ่นยนต์ดูดฝุ่นออกมาใหม่ๆ แล้วได้ยินว่าต้องทำ "การเก็บกวาดแบบง่ายๆ" คือเก็บของที่วางอยู่บนพื้นให้เรียบร้อยเพื่อหุ่นยนต์ การเขียนสเปกละเอียดให้ AI ก็เป็นงานที่หนักพอสมควร เลยรู้สึกเหมือนเรากำลังทำงานเพื่อ AI
ทั้ง IDE และ PR ตายหมดแล้ว แต่โค้ดกลับฟื้นคืนชีพขึ้นมาอย่างนั้นหรือ?
โค้ดคือข้อกำหนดที่แม่นยำที่สุดในเชิงตรรกะสำหรับระบบอย่างง่าย
แต่กับโลกความเป็นจริงที่เป็นระบบซับซ้อน นั่นแหละคือกับดัก.. สุดท้ายแล้วมีเพียงข้อมูลเท่านั้นที่ยังพอเป็นข้อกำหนดที่แม่นยำที่สุด
น่าจะต้องดูว่าสามารถแทนที่ด้วยวิธีการตรวจสอบแบบอื่นได้หรือไม่ ยิ่งใกล้ฝั่งฟรอนต์มากเท่าไร ก็อาจตรวจสอบได้ว่าทำงานได้ดีเพียงแค่ทำ E2E ผ่านพฤติกรรมของเบราว์เซอร์ แต่ยิ่งเป็นโค้ดที่ใกล้กับฝั่งแบ็กเอนด์และอินฟรามากเท่าไร ก็ยิ่งดูเหมือนว่าการรีวิวโค้ดจะเป็นสิ่งจำเป็น เพราะไม่เช่นนั้นก็จะตรวจสอบ side effect อย่างเช่นทรานแซกชันที่เปิดและปิดโดยมองไม่เห็น หรือการยิง API call ได้ยาก
ในเบราว์เซอร์มีปัญหามากมายที่แม้แต่ E2E ก็จับไม่ได้