เมื่อเดือนที่แล้ว ผู้ช่วย AI ได้สร้างสคริปต์ Python สำหรับโปรเจกต์ที่ใช้งานจริง (production) ผลลัพธ์ที่ได้ทำงานได้โดยไม่มีข้อผิดพลาด ข้อมูลดูถูกต้องแม่นยำ แต่จากการตรวจสอบด้วยตนเองกลับพบรูปแบบการคิวรีแบบ N+1 (N+1 query pattern) ซ่อนอยู่ในการเรียกใช้งานฐานข้อมูล สำหรับชุดข้อมูลขนาดเล็ก โค้ดนี้ทำงานได้ดี แต่หากขยายขนาดขึ้นเป็นข้อมูลหลายพันรายการ แอปพลิเคชันจะต้องส่งคำสั่งคิวรีหนึ่งครั้งสำหรับออบเจกต์หลัก จากนั้นจึงตามด้วยคำสั่งคิวรีอีกหลายพันครั้งสำหรับข้อมูลที่เกี่ยวข้อง ผลลัพธ์ที่ได้คือวิกฤตด้านประสิทธิภาพที่รุนแรง (catastrophic performance cliff) ซึ่ง unit test ใดๆ ก็ไม่สามารถตรวจพบได้
นี่คือความเป็นจริงของการพัฒนาซอฟต์แวร์ในปัจจุบัน เครื่องมือ AI สามารถจัดการทั้งการเขียนโค้ด การดีบั๊ก และการให้คำแนะนำด้านสถาปัตยกรรมด้วยความเร็วที่มนุษย์ไม่สามารถเทียบได้ ความรวดเร็วนั้นเป็นเรื่องจริง แต่มันได้เปลี่ยนลักษณะงานของคุณไปอย่างสิ้นเชิง คุณไม่ได้ถูกจ้างมาเพื่อพิมพ์ไวยากรณ์ (syntax) เป็นหลักอีกต่อไป แต่คุณถูกจ้างมาเพื่อตรวจสอบ (audit) วางโครงสร้าง (architect) และดักจับกับดักที่มองไม่เห็นเหล่านี้
อันตรายที่เงียบเชียบของสิ่งที่ "ดูสมเหตุสมผลแต่ผิดพลาด"
โค้ดที่สร้างโดย AI มักจะดูเหมือนถูกต้องเพราะมันสามารถคอมไพล์ รัน และคืนค่าตามที่คาดหวัง ตรรกะดูเหมือนจะเชื่อมโยงกันได้อย่างสมบูรณ์ในเบื้องต้น แต่ลึกลงไปข้างใต้ มันอาจจะพังอย่างเงียบเชียบ
ลองดูตัวอย่างเรื่อง regular expressions AI อาจจะส่งรูปแบบที่จับคู่ที่อยู่อีเมลหรือตัวระบุ (identifiers) ในภาษาอังกฤษได้อย่างสมบูรณ์แบบ แต่หากคุณนำ expression เดียวกันนั้นไปใช้กับตัวอักษร umlaut ของเยอรมัน, อักษรอาหรับ หรือกรณีขอบเขต (edge cases) ของ Unicode normalization มันจะล้มเหลวโดยไม่แจ้งเตือน โค้ดไม่ได้ผิดในลักษณะที่ทำให้เกิด exception แต่มันเพียงแค่คัดข้อมูลในโลกความเป็นจริงที่ถูกต้องออกไป
การคิวรีฐานข้อมูลก็มีความเสี่ยงที่คล้ายกัน AI สามารถเขียนคำสั่ง PostgreSQL ที่คืนค่าแถวข้อมูลที่ถูกต้องระหว่างการทดสอบ แต่ยังคงทำให้ตารางของคุณบวมด้วย dead tuples, ข้ามการใช้ index หรือบังคับให้เกิด sequential scans ที่ทำลายประสิทธิภาพของงานในระบบ production สิ่งที่ทำงานได้ดีในชุดข้อมูลสาธิต (demo dataset) กับสิ่งที่ทำงานได้ดีภายใต้ภาระงานจริง (real load) นั้นเป็นคนละเรื่องกัน เครื่องจักรไม่รู้สึกถึงความหน่วง (latency) และมันไม่ได้เป็นคนจ่ายค่าบริการคลาวด์
จากการเขียนสู่การตรวจสอบ
การเปลี่ยนแปลงที่สำคัญคือการเปลี่ยนจาก "ฉันจะเขียนสิ่งนี้ได้อย่างไร?" เป็น "ฉันจะตรวจสอบสิ่งนี้ได้อย่างไร?" เมื่อ AI จัดการร่างแรกให้คุณ ภาระทางความคิด (cognitive load) ของคุณควรจะย้ายไปสู่ขั้นตอนการตรวจสอบ คุณจำเป็นต้องอ่านโค้ดในแบบที่ผู้ตรวจสอบความปลอดภัย (security auditor) อ่าน ไม่ใช่แบบที่ผู้เขียนที่เหนื่อยล้าอ่านผ่านๆ งานของตัวเอง
สิ่งนี้ต้องการวินัยในอีกรูปแบบหนึ่ง อคติจากการเชื่อมั่นในระบบอัตโนมัติ (Automation bias) นั้นมีอยู่จริง เมื่อเครื่องมือสร้างผลลัพธ์ที่ลื่นไหลและมีไวยากรณ์ที่สมบูรณ์แบบ สมองของมนุษย์จะผ่อนคลายลง คุณจะทึกทักเอาเองว่ามันถูกต้องเพราะการนำเสนอนั้นดูดี การต่อต้านสัญชาตญาณนั้นคือทักษะหลักในตอนนี้ คุณต้องสมมติว่าทุกคำแนะนำเป็นเพียงสมมติฐาน จนกว่าจะได้รับการพิสูจน์ว่าเป็นจริง
การทำงานร่วมกับเครื่องจักร
การได้รับผลลัพธ์ที่มีประโยชน์จากผู้ช่วยเขียนโค้ด AI ไม่ใช่เรื่องของการพิมพ์ให้เร็วขึ้น แต่เป็นเรื่องของการลดช่องว่างระหว่างข้อมูลที่ใช้ฝึกฝนเครื่องจักรกับความเป็นจริงเฉพาะด้านของคุณ คุณสามารถลดช่องว่างนั้นได้ด้วยแนวทางปฏิบัติที่เป็นรูปธรรมบางประการ
มีความแม่นยำใน prompt ของคุณ ความกำกวมไม่ได้สร้างบทกวีในบริบทนี้ แต่มันสร้างบั๊ก Prompt อย่างเช่น "optimize this function" จะนำไปสู่คำแนะนำแบบกว้างๆ แทนที่จะเป็นแบบนั้น ให้เขียนว่า "refactor ลูป Python นี้ให้ใช้การอัปเดตฐานข้อมูลแบบ bulk ครั้งเดียว แทนการใช้การ save แบบวนซ้ำ" ความเฉพาะเจาะจงจะช่วยจำกัดขอบเขตของความเป็นไปได้ให้แคบลง
ให้บริบทที่แท้จริง AI จะไม่รู้ว่าคุณกำลังรัน Django 4.2 บน PostgreSQL 15 ภายใน Kubernetes cluster ที่มีการตั้งค่า request timeout ไว้เคร่งครัดที่ 30 วินาที เว้นแต่คุณจะบอกมัน จงป้อนข้อมูลเวอร์ชันของ dependency, ไลบรารีภายใน และข้อจำกัดที่คุณยอมรับไม่ได้ลงไป บริบทไม่ใช่สิ่งตกแต่ง แต่มันคือแนวทางป้องกัน (guardrails)
อ้างอิงคำตอบด้วยเอกสารของคุณเอง Retrieval-Augmented Generation หรือ RAG ไม่ใช่แค่คำศัพท์สวยหรูสำหรับแชทบอท จงชี้ให้ผู้ช่วยของคุณดูข้อกำหนด API (API specifications) จริงของคุณ, บันทึกการตัดสินใจด้านสถาปัตยกรรม (architecture decision records) และธรรมเนียมปฏิบัติของโค้ด (codebase conventions) เมื่อโมเดลดึงข้อเท็จจริงจากเอกสารของคุณแทนที่จะเดาจากข้อมูลที่ใช้ฝึกฝน ช่องว่างระหว่างคำแนะนำทั่วไปกับโค้ดที่ใช้งานได้จริงจะลดลงอย่างมหาศาล
แบ่งงานที่ซับซ้อนออกเป็นงานย่อยๆ ที่แยกจากกันชัดเจน รูปแบบการทำงานแบบ Agent (Agent patterns) จะทำงานได้ดีที่สุดเมื่อแต่ละขั้นตอนมีขอบเขตที่แคบ อย่าขอให้ refactor microservice ทั้งหมดในครั้งเดียว แต่ให้เริ่มจากการขอ data schema ก่อน ตรวจสอบความถูกต้อง จากนั้นจึงขอสคริปต์การย้ายข้อมูล (migration script) ตรวจสอบความถูกต้อง แล้วจึงขยับไปที่ service layer
