แผนที่คุณข้ามไปคือปัญหาที่คุณต้องแก้ในภายหลัง
ทุกแนวทางในวิศวกรรมซอฟต์แวร์บอกให้คุณเคลื่อนไหวเร็ว ปล่อยเร็ว ทำซ้ำในโปรดักชัน สำหรับเว็บไซต์ที่สร้างด้วย AI นั้นกลับตรงกันข้าม ตัวสร้างในที่นี้ปฏิเสธที่จะสตรีมโค้ดตรงจากพรอมพต์ของคุณเลย — มันจะหยุด เขียนแผน แล้วรอให้คุณดูก่อน — และการปฏิเสธนี้แหละคือการตัดสินใจเดียวที่ทุกอย่างในไปป์ไลน์นี้ถูกสร้างขึ้นมารองรับ ช้าลงในตอนแรก แต่ประหยัดกว่าในทุกขั้นตอนหลังจากนั้น ผมเลือกแลกแบบนี้ทุกครั้ง และคิดว่าคนส่วนใหญ่ที่โต้แย้งในทางตรงข้ามคงยังไม่เคยเห็นจริง ๆ ว่าการเดาผิดต้องแลกด้วยอะไรในขั้นตอนถัดไป
นี่คือรูปแบบความล้มเหลวที่แผนมีไว้เพื่อป้องกัน คุณพิมพ์ว่า "เว็บไซต์จองคิวสำหรับสตูดิโอของฉัน" แล้วกดไป ระบบต้องเดาว่า "การจอง" หมายถึงอะไร — วิดเจ็ตปฏิทิน, การฝังจากบุคคลที่สาม, หรือระบบจองจริงที่ตรวจสอบความขัดแย้งของเวลา — และต้องเดาก่อนที่จะเขียนอะไรเลย เพราะไม่มีลำดับอื่นให้ทำ ถ้าเดาผิดในขั้นตอนแผน การแก้ไขก็แค่หนึ่งประโยค ห้าวินาที จบ แต่ถ้าเดาผิดในโค้ดที่สร้างเสร็จแล้ว คุณจะไม่ได้แก้แค่ประโยคเดียวอีกต่อไป แต่ต้องรื้อไฟล์สิบไฟล์ที่พึ่งพาข้อสมมติฐานผิด ๆ นั้นไปแล้ว ผมเคยเห็นทั้งสองแบบเกิดขึ้น การแก้ไขในขั้นตอนแผนคือการสนทนาแค่ครั้งเดียว ส่วนการหักเหหลังสร้างเสร็จในความคลุมเครือแบบเดียวกันคือการทิ้งของเก่าแล้วสร้างใหม่
แผนไม่ได้เป็นแค่รายการสิ่งที่ต้องทำ และนี่คือส่วนที่คนมักมองข้าม มันคือสัญญา และระบบก็ยึดตามสัญญานั้นจริง ๆ: ตัวตรวจสอบความสอดคล้อง (conformance-check verifier) หนึ่งในเอเจนต์ที่ต้องอนุมัติก่อนบิลด์จะถูกปล่อยออกไป จะเปรียบเทียบเว็บไซต์ที่สร้างเสร็จกับแผนที่คุณอนุมัติไว้ ทุกหน้าที่วางแผนไว้ถูกสร้างครบหรือไม่ รายการฟีเจอร์ตรงกับสิ่งที่ปล่อยออกไปหรือไม่ คำว่า "เสร็จ" ในที่นี้ไม่ใช่ความรู้สึก แต่วัดเทียบกับคำมั่นสัญญาที่เขียนไว้ ตรวจสอบได้ทีละบรรทัด นี่คือการรับประกันที่แข็งแกร่งกว่า "โค้ดรันได้" และคุณจะได้สิ่งนี้ก็เพราะมีเอกสารให้เทียบเท่านั้น เอาแผนออกไป ก็เท่ากับเอาไม้บรรทัดที่ใช้วัดออกไปด้วย
จุดที่คุ้มค่าที่สุดจริง ๆ
อิทธิพลของคุณในฐานะคนขับเคลื่อนการสร้างจะมีน้ำหนักมากที่สุดในช่วงต้น ไม่ว่าคุณจะใช้มันหรือไม่ก็ตาม ถ้าคุณใส่ใจเรื่องโครงสร้างข้อมูล โครงหน้าเว็บ ฟีเจอร์ไหนควรอยู่ใน v1 หรือ v2 — ความละเอียดยิบแบบนั้นมีค่ามากกว่าสิบเท่าตอนตรวจแผน เทียบกับหลังจากรอบสร้างแรกผ่านไปแล้ว การใช้เวลาสี่นาทีเพิ่มเติมอ่านแผนอีกรอบ ดีกว่าต้องวนกลับไปแก้บิลด์ที่พลาดไปแล้ว
ตัวอย่างที่ชัดที่สุดคือประเภทผลิตภัณฑ์ — เว็บไซต์สแตติกธรรมดา, แอปที่ติดตั้งได้, บิลด์แบบเฟรมเวิร์ก, แอปที่มีเซิร์ฟเวอร์รองรับพร้อมข้อมูลถาวรจริง ดูเผิน ๆ เหมือนเป็นแค่ดรอปดาวน์ แต่ไม่ใช่เลย มันคือการตัดสินใจเชิงโครงสร้างที่สำคัญที่สุดในกระบวนการทั้งหมด เพราะมันกำหนดสิ่งต่าง ๆ อีกนับสิบอย่างอย่างเงียบ ๆ ที่ไม่เกี่ยวอะไรกับหน้าตาของเว็บไซต์เลย
| ประเภทผลิตภัณฑ์ | ดูตัวอย่าง | เผยแพร่ | บัญชีผู้ใช้ / ฐานข้อมูล |
|---|---|---|---|
| เว็บไซต์สแตติกธรรมดา | ทันที เพราะเป็นแค่ไฟล์สแตติก | คัดลอกไฟล์ที่ส่งออกได้อย่างราบรื่น | เป็นไปไม่ได้ — การขอให้มีระบบล็อกอินคือการขอสิ่งที่ประเภทนี้ทำไม่ได้โดยโครงสร้าง |
| บิลด์แบบเฟรมเวิร์ก | คอมไพล์ก่อน ถ้าบิลด์พังจะแสดงเป็น "ไม่มีตัวอย่าง" ไม่ใช่ "หน้าเว็บพัง" | เส้นทางคัดลอกไฟล์สแตติกแบบเดียวกัน หลังจากคอมไพล์แล้ว | เป็นไปไม่ได้ |
| แอปที่มีเซิร์ฟเวอร์รองรับ | — | ต้องมีที่ให้รันโปรเซสจริง ซึ่งจะล้มเหลวในรูปแบบที่ต่างออกไป — โปรเซสล่ม ไม่ใช่ไฟล์หายไป | ประเภทเดียวที่มีบัญชีผู้ใช้และฐานข้อมูลอยู่จริง |
และคุณไม่สามารถอัปเกรดประเภทเว็บไซต์ในภายหลังได้แบบสบายๆ การเปลี่ยนจากเว็บไซต์ธรรมดาไปเป็นแอปที่ทำงานบนเซิร์ฟเวอร์ไม่ใช่แค่การสลับปุ่มตั้งค่า — มันเกือบเท่ากับการสร้างใหม่ครั้งที่สอง เพราะครึ่งหนึ่งของสมมติฐานในแผนเดิม (วิธีโหลดหน้าเว็บ ข้อมูลอยู่ที่ไหน "เผยแพร่" หมายถึงอะไร) ถูกกำหนดไว้ตามประเภทเดิม ดังนั้นควรพูดตั้งแต่ตอนวางแผน แม้จะไม่แน่ใจเต็มที่: "มีความเป็นไปได้ว่าฉันอาจต้องมีระบบบัญชีผู้ใช้" การวางแผนสำหรับแอปที่ทำงานบนเซิร์ฟเวอร์แต่ใช้แค่ส่วนที่เป็นสแตติกนั้นไม่มีค่าใช้จ่ายเพิ่ม แต่การมารู้ทีหลังว่าต้องการมันจริงๆ ต้องแลกด้วยการสร้างใหม่ทั้งหมด
จุดที่นักวิจารณ์พูดถูก
ไม่มีสิ่งใดในนี้ที่ไม่มีต้นทุน และเราจะไม่แสร้งทำเป็นว่าไม่มี พื้นที่ทำงานแยกส่วนต่อการรันหมายความว่าไฟล์ความรู้ของคุณจะถูกคัดลอกใหม่ทุกครั้ง ไม่มีอะไรย้อนกลับไปที่เครื่องของคุณ — ดีสำหรับคุณถ้าแล็ปท็อปพังกลางคันขณะสร้างงาน แต่แย่สำหรับเวลาตอบสนอง เพราะการเตรียมพื้นที่ทำงานและ สำหรับการสร้างงานแบบเฟรมเวิร์ก การติดตั้ง dependency จริงภายในขอบเขตคอนเทนเนอร์นั้นใช้เวลาจริง ขอบเขตคอนเทนเนอร์นี้มีอยู่เพราะการสร้างงานแบบเฟรมเวิร์กต้องรัน `npm install` และสคริปต์ build ที่ไม่ทราบที่มา — โค้ดที่คุณไม่ได้เขียนเอง ทำงานด้วยสิทธิ์ระดับ build-time — และการทำแบบนั้นบนโฮสต์ที่ใช้ร่วมกันโดยไม่มีการแยกส่วนนั้นเสี่ยงต่อการโจมตีแบบ dependency-confusion เพียงครั้งเดียวก็อาจกระทบข้อมูลของผู้ใช้รายอื่นได้ ทางเลือกที่เร็วแต่ไม่ปลอดภัยนั้นมีให้เลือก แต่มันไม่คุ้มค่าที่จะแลก
เรื่องเดียวกันกับการตรวจสอบ (verification) งานที่เสร็จสมบูรณ์ไม่ได้ออกจากไปป์ไลน์เมื่อการสร้างหยุดลง แต่จะออกเมื่อชุดตัวตรวจสอบอิสระหยุดพบสิ่งที่ควรบล็อกไว้:
- การรีวิวโค้ด
- ความปลอดภัย
- ลิงก์และ SEO
- การเข้าถึง (Accessibility)
- ความสอดคล้อง (Conformance)
- การรันจริงในเบราว์เซอร์
นั่นไม่ใช่การตรวจแค่รอบเดียว แต่เป็น flag-fix-recheck วนซ้ำจนกว่าจะไม่มีใครเหลืออะไรจะพูด เพราะการตรวจแบบ linter ครั้งเดียวอาจพลาดข้อผิดพลาดที่เกิดจากการแก้ไขของมันเอง การแก้ลิงก์เสียแล้วดันไปทำลายลำดับชั้นของหัวข้อในหน้าเดียวกันโดยไม่ตั้งใจ คือตัวอย่างที่การตรวจครั้งเดียวมองข้ามแต่การตรวจซ้ำจับได้ ต้นทุนที่แท้จริงของการวนซ้ำนี้คือบางครั้งงานจะใช้เวลานานขึ้นอีกนาทีในช่วงท้ายโดยไม่มีเหตุผลที่มองเห็นได้ชัด ผู้คนสังเกตเห็นนาทีนั้น แต่ไม่สังเกตเห็นตัวแทน (agent) ทั้งหกที่เพิ่งถกเถียงกันจบเรื่องเว็บไซต์ของพวกเขา นั่นเป็นข้อร้องเรียนที่สมเหตุสมผลเกี่ยวกับประสบการณ์การใช้งาน — เพียงแต่ฉันไม่คิดว่ามันเป็นเหตุผลที่ดีที่จะปล่อยงานออกไปโดยไม่ให้การถกเถียงนั้นเกิดขึ้นเลย



