การแก้ไขเกินความจำเป็น: เมื่อโมเดลแก้โค้ดเกินขอบเขตที่ต้องใช้
(nrehiew.github.io)- แม้เป็นบั๊กที่แก้ได้ด้วยการแก้ไขเพียง เล็กน้อยที่สุด ก็มักเกิดการเขียนฟังก์ชันใหม่ทั้งก้อน เพิ่มตรรกะเสริม หรือแม้แต่เปลี่ยนซิกเนเจอร์ จนเกิด diff ขนาดใหญ่ ได้ง่าย
- ในงานแบบ brown-field ที่ต้องคงโครงสร้างเดิมไว้ การผ่านเทสต์อย่างเดียวไม่พอ แต่ต้องดูด้วยว่าเปลี่ยนไปน้อยแค่ไหน เพื่อรักษาความสามารถในการรีวิวและความปลอดภัยของการเปลี่ยนแปลง
- จากปัญหา BigCodeBench 400 ข้อที่ถูกทำให้เสียหายแบบโปรแกรม ผู้วิจัยใช้ Levenshtein ระดับโทเค็น, คะแนนแพตช์สัมพัทธ์ และ Added Cognitive Complexity เพื่อวัด over-editing เชิงปริมาณ
- พบแนวโน้มการเขียนใหม่เกินจำเป็นในโมเดลโค้ดดิ้งสมัยใหม่โดยรวม โดย Claude Opus 4.6 เด่นด้านความแม่นยำควบคู่กับการแก้ไขให้น้อยที่สุด ส่วน GPT-5.4 มีลักษณะ over-editing ชัดเจนกว่าเมื่อเทียบกัน
- พรอมป์ต์ที่ระบุให้คงต้นฉบับไว้ช่วยลด diff ได้ โดยเฉพาะใน reasoning model และในบรรดาวิธีฝึก RL ให้ผลสมดุลที่สุด โดยเรียนรู้พฤติกรรมการแก้ไขให้น้อยที่สุดโดยไม่ทำให้ความสามารถด้านการเขียนโค้ดโดยรวมลดลง
ปัญหา Over-Editing
- Over-Editing หมายถึงปรากฏการณ์ที่โมเดลแก้โค้ดเกินขอบเขตการแก้ไขขั้นต่ำที่จำเป็นต่อการแก้บั๊ก จนลามไปถึงการเปลี่ยนโครงสร้างโค้ดอย่างมาก
- แม้จะเป็นบั๊ก off-by-one ที่แค่เปลี่ยน
range(len(x) - 1)เป็นrange(len(x))ก็พอ โมเดลก็ยังอาจแก้เกินจำเป็น เช่น เขียนฟังก์ชันใหม่ทั้งก้อน เพิ่มฟังก์ชันช่วยหรือเพิ่มตรรกะตรวจสอบ - ในตัวอย่าง GPT-5.4 ได้เพิ่มการตรวจ
None, การแปลงnp.asarray(dtype=float), การทำ finite-value masking, การตรวจสอบขนาดอาร์เรย์, การเปลี่ยนซิกเนเจอร์ของการเรียกcurve_fitและการเปลี่ยนตรรกะการพล็อต ซึ่งแม้เทสต์จะผ่าน แต่ก็ทำให้เกิด diff ขนาดใหญ่
- แม้จะเป็นบั๊ก off-by-one ที่แค่เปลี่ยน
- ในงาน brown-field ที่ต้องทำกับโค้ดเบสเดิม การคงโค้ดที่ทีมเข้าใจและตั้งใจเขียนไว้อยู่แล้ว พร้อมแก้เฉพาะปัญหาที่มี ถือว่าสำคัญมาก
- ต่างจากงาน green-field ที่สร้างขึ้นใหม่ การแก้ไขที่ไม่เคารพโครงสร้างเดิมทำให้ผู้รีวิวเข้าใจได้ยากว่าอะไรเปลี่ยนไปและเปลี่ยนไปทำไม
- หากมีการเขียนฟังก์ชันใหม่ทั้งก้อน โค้ดจะอ่านและจดจำได้ยากขึ้น และยังประเมินความปลอดภัยของการเปลี่ยนแปลงได้ยากด้วย
- ถ้าใช้เกณฑ์แค่ว่าเทสต์ผ่านหรือไม่ ก็จับปัญหานี้ได้ยาก
- Over-Editing ไม่ใช่ ความล้มเหลวด้านความถูกต้อง แต่เป็นความล้มเหลวด้านความซื่อตรงต่อขอบเขตการแก้ไข จึงมักไม่สะท้อนใน test suite
- ยิ่งโค้ดที่ถูกสร้างขึ้นมีมาก ปริมาณที่ต้องรีวิวยิ่งเพิ่ม และเมื่อความซับซ้อนที่ไม่จำเป็นสะสมขึ้น คุณภาพของโค้ดเบสก็อาจค่อย ๆ ลดลงโดยไม่ทันสังเกต
วิธีวัด Over-Editing
- เพื่อสร้างชุดข้อมูลที่รู้คำตอบของการแก้ไขขั้นต่ำอย่างชัดเจน ผู้วิจัยนำโจทย์ BigCodeBench 400 ข้อมา ทำให้เสียหายแบบโปรแกรม เพื่อสร้างชุดประเมิน
- แทนที่จะฉีดบั๊กด้วย LLM อื่นแบบ benchmark เดิม วิธีนี้ควบคุมได้ละเอียดกว่า เช่น เปลี่ยน
<เป็น<=,+เป็น-, หรือTrueเป็นFalse - ตัวอย่างที่ถูกทำให้เสียหายแต่ละรายการได้รับการตรวจว่าไวยากรณ์ยังถูกต้อง และทำให้ test case ที่สอดคล้องกันล้มเหลวจริง โดยคำตอบที่ถูกต้องมีเพียงการย้อนการทำให้เสียหายนั้นกลับไปเท่านั้น จึงถูกออกแบบให้เป็น การแก้ไขขั้นต่ำ
- แทนที่จะฉีดบั๊กด้วย LLM อื่นแบบ benchmark เดิม วิธีนี้ควบคุมได้ละเอียดกว่า เช่น เปลี่ยน
- ด้วยการจัดองค์ประกอบแบบนี้ จึงประเมินได้ไม่เพียงว่าโมเดลแก้บั๊กสำเร็จหรือไม่ แต่ยังวัดได้ด้วยว่าในกระบวนการแก้ โมเดล เปลี่ยนเกินไปมากแค่ไหน
- ระบบจะคำนวณขนาดแพตช์เชิงสัมพัทธ์โดยเทียบทั้งคำตอบอ้างอิงและผลลัพธ์ของโมเดลกับอินพุตที่ถูกทำให้เสียหาย
- ยิ่งมีการเปลี่ยนเพิ่มเติมนอกเหนือจากการกู้คืนคำตอบเดิมมาก คะแนนก็ยิ่งแย่
- โค้ดที่เกี่ยวข้องเผยแพร่ไว้ใน GitHub repository
ตัวชี้วัด
-
Levenshtein Distance ระดับโทเค็น
- ใช้ Levenshtein แบบแปรผันในระดับ โทเค็น ของ Python แทนการวัดแบบตัวอักษรทั่วไป
- โดยแยกโค้ดด้วย Python tokenizer ออกเป็นหน่วยไวยากรณ์ย่อย เช่น
def,add,(,a,,,b,)แล้วคำนวณระยะห่างบนลำดับโทเค็นนี้ - หากเปลี่ยน
def add(a, b):เป็นdef someotherfunctionname(a, b):ระยะห่างแบบตัวอักษรจะเป็น 19 แต่แบบโทเค็นจะนับว่าเปลี่ยนเพียง identifier เดียว จึงมีค่าเป็น 1 - เพื่อให้เทียบกันได้แม้ความยาวฟังก์ชันต่างกัน จึงมีการทำ normalization ด้วยจำนวนโทเค็นรวม
-
คะแนนแพตช์สัมพัทธ์
- ไม่ได้เทียบผลลัพธ์ของโมเดลกับคำตอบอ้างอิงโดยตรง แต่เทียบทั้งสองฝั่งกับ อินพุตที่ถูกทำให้เสียหาย
- การแก้ไขที่แท้จริงแบบขั้นต่ำคือการย้อนจากคำตอบที่เสียหายกลับไปเป็นคำตอบเดิม และตัวชี้วัดนี้ใช้วัดว่าแพตช์ที่โมเดลสร้างขึ้นใกล้เคียงกับสิ่งนั้นมากเพียงใด
- ค่ายิ่งใกล้ 0 ยิ่งหมายความว่าแพตช์ของโมเดลคล้ายกับการแก้ไขขั้นต่ำจริง
-
Added Cognitive Complexity
- ใช้ Cognitive Complexity ร่วมด้วย เพราะสะท้อนความยากในการอ่านได้ดีกว่า Cyclomatic Complexity
- เมตริกนี้ให้โทษกับการซ้อนกัน, recursion, ตัวดำเนินการตรรกะแบบผสม และ control flow ที่ไม่เป็นธรรมชาติ โดยโครงสร้างอย่าง
if, ลูป,try/exceptที่ทำให้ผู้อ่านต้องติดตามสถานะมากขึ้นจะเพิ่มความซับซ้อน - โค้ดตัวอย่างที่มีลูปซ้อนและเงื่อนไขจะมี Cognitive Complexity เท่ากับ 6
- เนื่องจากความเสียหายที่ใส่เข้าไปในการทดลองนี้เปลี่ยนแค่ค่า ไม่แตะโครงสร้าง การแก้ที่ถูกต้องจึงควรมี Added Cognitive Complexity เท่ากับ 0 เสมอ
- หากความซับซ้อนของผลลัพธ์โมเดลเพิ่มขึ้น แปลว่ามีการเพิ่มโค้ดที่ไม่ได้ร้องขอ และแม้ค่าจะน้อยกว่า 0 ก็ถูกมองว่าเป็นการทำให้ง่ายลงโดยไม่จำเป็น จึงไม่ถือว่าพึงประสงค์
โมเดลมีการ Over-Edit จริงหรือไม่
- พบ Over-Editing แม้ใน frontier model รุ่นใหม่
- ทั้ง reasoning model และ non-reasoning model ต่างมีความต่างระหว่าง Pass@1 กับความสามารถในการแก้ไขให้น้อยที่สุด
- ความสามารถในการแก้ให้ถูกอย่างเดียว จึงไม่พอจะบอกได้ว่าการแก้ไขนั้นซื่อตรงต่อขอบเขตที่ต้องแก้หรือไม่
- ในการเปรียบเทียบ reasoning model นั้น Claude Opus 4.6 ให้ชุดผลลัพธ์ที่แข็งแกร่งที่สุด
- มี Pass@1 สูงสุดที่ 0.912 และมี normalized Levenshtein 0.060, Added Cognitive Complexity 0.200 ทำให้ diff เล็กที่สุดด้วย
- Gemini 3.1 Pro Preview ก็อยู่ในกลุ่มใกล้เคียงกัน และในบรรดาโมเดล open-weight นั้น GLM 5 มีแนวโน้มแก้ไขอย่างระมัดระวังมากกว่า
- GPT-5.4 อยู่ในกลุ่มที่มี Over-Editing รุนแรงที่สุดในบรรดาโมเดลที่ประเมิน
- ในโหมด reasoning มี Levenshtein 0.395 และ Added Cognitive Complexity 2.313 ส่วนในโหมด non-reasoning ก็ยังสูงที่ 0.327 และ 1.563 ตามลำดับ
- Pass@1 ก็อยู่ในระดับต่ำเช่นกันที่ 0.723 และ 0.770 จึงสะท้อนว่าทั้งความแม่นยำและความสามารถในการแก้ให้น้อยที่สุดยังอ่อน
- ในกลุ่ม non-reasoning model นั้น Qwen 3.6 Plus มี Pass@1 สูงสุดที่ 0.870 ขณะที่ GLM 5 มี Added Cognitive Complexity ต่ำสุดที่ 0.235
- ส่วน Claude Opus 4.6 รุ่น non-reasoning ก็ยังรักษาขนาดการเปลี่ยนแปลงที่เล็กมากได้ โดยมี Levenshtein 0.079 และ Added Cognitive Complexity 0.313
ปรับปรุงได้ด้วยพรอมป์ต์หรือไม่
- เมื่อเพิ่มข้อความ “IMPORTANT: Try to preserve the original code and the logic of the original code as much as possible” ลงในพรอมป์ต์ พบว่า Levenshtein Distance ของทุกโมเดลลดลง
- ยกเว้น DeepSeek R1/v3 แล้ว Pass@1 ก็เพิ่มขึ้นด้วย
- ตีความได้ว่าข้อกำหนดให้แก้ไขให้น้อยที่สุดช่วยจำกัดพื้นที่ของคำตอบที่เป็นไปได้ ทำให้โมเดลมุ่งไปสู่การเปลี่ยนแปลงที่แม่นยำและเฉพาะจุดมากขึ้น
- ผลนี้เด่นชัดเป็นพิเศษใน reasoning model
- เพราะมีคุณสมบัติในการทำตามคำสั่งที่ชัดเจนได้ดีกว่า คำขอให้ลดการแก้ไขให้น้อยที่สุดจึงเชื่อมโยงกับการลด diff อย่างเด่นชัด
- สิ่งนี้ชี้ให้เห็นว่า แม้ในสภาพตั้งต้นโมเดลจะชอบแก้เกินจำเป็น แต่เมื่อมีคำสั่งกำกับ ก็สามารถขยับไปสู่การแก้ไขที่ซื่อตรงมากขึ้นได้
การให้เหตุผลนำไปสู่การเขียนใหม่มากเกินไปหรือไม่
- จับคู่โมเดลแบบให้เหตุผลและไม่ให้เหตุผลในตระกูลเดียวกัน แล้วเปรียบเทียบ Levenshtein Distance โดยดูเฉพาะ ตัวอย่างที่ทั้งคู่ตอบถูกเท่านั้น
- หากมีตัวอย่างที่ล้มเหลวจำนวนมาก โอกาสที่จะเกิด Over-Editing เองก็จะลดลง ทำให้เกิดอคติได้ จึงควบคุมความแม่นยำก่อนแล้วค่อยแยกดูเฉพาะสไตล์การแก้ไข
- ในการตั้งค่า prompt แบบทั่วไป คู่ส่วนใหญ่พบว่า โมเดลให้เหตุผลเขียนใหม่มากกว่า
- DeepSeek V3, GPT-5, GPT-5.4, Gemini 3.1 Pro Preview, Qwen 3.6 Plus และ Kimi 2.5 ต่างมีแถบของรุ่นให้เหตุผลสูงกว่า
- เห็นแนวโน้มชัดเจนว่าการให้เหตุผลแบบขยายมักมุ่งไปที่ “implementation ที่ดีกว่า” แทนการแก้ไขให้น้อยที่สุด จนนำไปสู่การรีแฟกเตอร์ที่ไม่จำเป็น
- ข้อยกเว้นคือ Claude Opus 4.6 ซึ่งรุ่นให้เหตุผลแก้ไขน้อยกว่ารุ่นไม่ให้เหตุผลอย่างมาก
- หากสั่งให้คงต้นฉบับไว้อย่างชัดเจน ภาพรวมจะเปลี่ยนไปมาก
- โมเดลให้เหตุผลในเกือบทุกคู่มี Levenshtein Distance เท่ากับหรือต่ำกว่ารุ่นไม่ให้เหตุผล
- Claude Opus 4.6 รุ่นให้เหตุผลทำค่า Levenshtein ต่ำที่สุดในบรรดาทุกโมเดลภายใต้การตั้งค่านี้
- GPT-5 และ GPT-5.4 ก็มีคะแนนของรุ่นให้เหตุผลลดลงมากเช่นกัน แต่ใน GPT-5.4 รุ่นไม่ให้เหตุผลยังคงนำอยู่เล็กน้อย
- โดยพฤติกรรมพื้นฐาน โมเดลให้เหตุผลมีแนวโน้มจะ Over-Editing ได้ง่าย แต่ความสามารถในการให้เหตุผลแบบเดียวกันนี้ก็ทำให้ ทำตามข้อจำกัดได้ดีขึ้นด้วย
- ความต่างระหว่างการตั้งค่าทั่วไปกับการตั้งค่าแบบชัดเจนปรากฏมากกว่าอย่างสม่ำเสมอในโมเดลให้เหตุผล
- ดังนั้น Over-Editing จึงใกล้เคียงกับพฤติกรรมตั้งต้นมากกว่าจะเป็นข้อจำกัดโดยเนื้อแท้ และสามารถพลิกกลับได้ด้วยข้อจำกัด
สามารถสร้างผู้แก้ไขที่ซื่อสัตย์ด้วยการฝึกได้หรือไม่
- ใช้ Qwen3 4B 2507 Instruct เป็นโมเดลตั้งต้น และใช้การตั้งค่า 0-shot กับ 8-shot ที่มีคำสั่งให้คงต้นฉบับไว้เป็น baseline
- วิธีการฝึกแบบอื่นทั้งหมดจะทดสอบภายใต้การตั้งค่าทั่วไปโดยไม่มีคำสั่งคงต้นฉบับอย่างชัดเจนในขั้นประเมิน
-
การจัดการทดลอง
- ทำให้โจทย์ DeepCoder เสียหายในรูปแบบเดียวกันเพื่อสร้าง ชุดข้อมูลสังเคราะห์
- นอกจากนี้ยังให้ Qwen3 4B 2507 Instruct พื้นฐานสร้าง 8 completion ต่อโจทย์แต่ละข้อ แล้วคงไว้เฉพาะตัวอย่างที่ถูกต้องเชิงฟังก์ชัน จากนั้นจัดอันดับด้วย Levenshtein Distance เพื่อสร้างชุดข้อมูล self-distillation ด้วย
- การฝึกถูกออกแบบคล้าย Context Distillation โดยตั้งเป้าให้ตอนประเมิน โมเดลแสดงพฤติกรรมแก้ไขให้น้อยที่สุดโดยไม่ต้องมีคำสั่งชัดเจน
-
วิธีการฝึก
- SFT: ทำ supervised fine-tuning โดยตรงด้วยชุดข้อมูลที่สร้างขึ้นแบบโปรแกรม
- rSFT: ในชุดข้อมูล self-distillation จะเลือกเฉพาะ 3 completion ที่มี Levenshtein Distance ต่ำที่สุดของแต่ละตัวอย่างมาใช้ฝึก
- DPO: ทำ preference optimization ระหว่าง completion ที่มี Levenshtein Distance สูงสุดกับ completion ที่ต่ำสุดในแต่ละตัวอย่าง
- RL: ใช้ reinforcement learning ที่รวมรางวัลด้านความถูกต้องเชิงฟังก์ชันและรางวัลการแก้ไขให้น้อยที่สุดบนฐาน Levenshtein
- หากผ่านทุกเทสต์ ให้
r = r_edit + 0.1 - หากไม่ผ่าน ให้
r = -0.2 r_editคำนวณจากรางวัลที่อิง normalized Levenshtein
- หากผ่านทุกเทสต์ ให้
ผลออกมาอย่างไรเมื่อเป็นประเภทความเสียหายแบบเดียวกัน
- ในการตั้งค่า in-domain ที่ประเภทความเสียหายของชุดฝึกและชุดทดสอบเหมือนกัน SFT ให้ผลลัพธ์เกือบสมบูรณ์แบบ
- Baseline 0-shot มี Pass@1 0.735, Norm. Levenshtein 0.169, Added CC 0.731
- Baseline 8-shot มี Pass@1 0.775, Norm. Levenshtein 0.115, Added CC 0.479
- SFT ทำได้ดีที่สุดทั้งสามตัวชี้วัดด้วย Pass@1 0.932, Norm. Levenshtein 0.002, Added CC 0.000
- rSFT ได้ 0.782 / 0.100 / 0.435, DPO ได้ 0.752 / 0.021 / 0.113, และ RL ได้ 0.802 / 0.046 / 0.112
- เนื่องจากผลลัพธ์นี้ดูดีเกินไป จึงเกิดการตรวจสอบว่าโมเดลอาจเพียงแค่ ท่องจำการแปลงย้อนกลับ ของประเภทความเสียหายเฉพาะบางแบบหรือไม่
- กล่าวคือ โมเดลอาจไม่ได้เรียนรู้พฤติกรรมการแก้ไขให้น้อยที่สุดแบบทั่วไป แต่เรียนรู้เพียงการย้อนรูปแบบความเสียหายที่กำหนดไว้
- เพื่อตรวจสอบเรื่องนี้ จึงสร้างข้อมูลฝึกและข้อมูลประเมินใหม่ให้ประเภทความเสียหายแตกต่างกันโดยสิ้นเชิง
สามารถทั่วไปไปยังประเภทความเสียหายอื่นได้หรือไม่
- ในการตั้งค่า out-of-domain ที่ประเภทความเสียหายของชุดฝึกและชุดทดสอบต่างกัน SFT พังลงอย่างมาก
- Pass@1 ของ SFT ลดลงถึง 0.458 และโมเดลอยู่ในสภาพที่พยายามเปลี่ยนให้น้อยที่สุดแบบเฉพาะทางโดยที่แก้บั๊กจริงไม่ได้
- Norm. Levenshtein อยู่ที่ -0.008 และ Added CC อยู่ที่ 0.006 ซึ่งต่ำมาก แต่ความสามารถในการแก้ให้ถูกต้องพังทลาย
- rSFT และ DPO ดีกว่า baseline 8-shot เล็กน้อย แต่ขนาดการปรับปรุงยังเล็ก
- rSFT ได้ 0.780 / 0.107 / 0.501 / LiveCodeBench -0.069
- DPO ได้ Pass@1 0.787 / 0.092 / 0.348 / LiveCodeBench -0.046
- เพียงแค่ฝึกจากข้อมูลร่องรอยที่โมเดลพื้นฐานสร้างขึ้นเอง ก็ยังสามารถทั่วไปได้ในระดับหนึ่ง
- มีเพียง RL เท่านั้นที่ทั่วไปได้อย่างสะอาดตาในทุกตัวชี้วัดหลัก
- RL ทำได้ Pass@1 0.782, Norm. Levenshtein 0.050, Added CC 0.185, และ LiveCodeBench Change +0.006
- ทั้งสามตัวชี้วัดดีกว่า baseline ทั้งสองแบบ และประสิทธิภาพการเขียนโค้ดทั่วไปก็ไม่ลดลง
- การที่ช่วงการปรับปรุงของ Levenshtein และ Added Cognitive Complexity มากกว่า Pass@1 ยังช่วยสนับสนุนว่าโมเดลไม่ได้แค่ท่องจำการย้อนความเสียหาย แต่ได้เรียนรู้ พฤติกรรมการแก้ไขให้น้อยที่สุดเอง
Catastrophic Forgetting
- ตรวจสอบด้วย LiveCodeBench v6 ด้วยว่าเมื่อทำ fine-tuning เพื่อการแก้ไขให้น้อยที่สุดแล้ว ความสามารถในการเขียนโค้ดทั่วไป ลดลงหรือไม่
- เป้าหมายคือหลังฝึกแล้ว โมเดลยังคงรักษาระดับใกล้เคียงกับ pretrained model เดิม
- SFT มีการลดลงของความสามารถทั่วไปอย่างมาก
- บน LiveCodeBench พบว่า ประสิทธิภาพลดลง 43% และไม่สามารถรักษาความสามารถพื้นฐานในการระบุและแก้บั๊กไว้ได้
- rSFT และ DPO ก็ลดลงเล็กน้อยเช่นกัน
- แม้จะฝึกด้วยตัวอย่างที่โมเดลเดิมสร้างขึ้นเอง แต่ด้วยลักษณะของงานก็ยังคงมี Catastrophic Forgetting อยู่ในระดับหนึ่ง
- RL เรียนรู้พฤติกรรมใหม่ได้โดยไม่มีประสิทธิภาพลดลง
- มันรักษาความสามารถการเขียนโค้ดทั่วไปไว้ได้ ขณะเดียวกันก็ปรับปรุงประสิทธิภาพของงานแก้ไขให้น้อยที่สุดได้ดีที่สุด
- สิ่งนี้สอดคล้องกับ SFT memorizes while RL generalizes
- ในมุมมองเชิงการกระจายตัว ยังอาจตีความได้ด้วยว่ายิ่งชุดข้อมูลที่สร้างขึ้นแบบโปรแกรมแตกต่างจากการกระจายตัวของโมเดลเดิมมากเท่าใด Forgetting ก็ยิ่งมากขึ้น
- SFT ปรับเข้ากับข้อมูลที่ต่างจากการกระจายตัวเดิมอย่างมาก จึงทำให้การกระจายตัวของโมเดลเปลี่ยนไปมาก
- rSFT และ DPO มีการเปลี่ยนแปลงที่ไม่รุนแรงเท่า เพราะข้อมูล self-distilled ใกล้กับการกระจายตัวเดิมมากกว่า
- ระดับของ Catastrophic Forgetting มีแนวโน้มแปรผันตามความแตกต่างระหว่างการกระจายตัวเดิมกับการกระจายตัวของข้อมูลฝึกเฉพาะงาน
การทดลองเพิ่มเติม
-
RL with LoRA: จำเป็นต้องทำ full fine-tuning หรือไม่
- งานนี้ใกล้เคียงกับการ ปรับสไตล์ ของความสามารถในการแก้โค้ดที่มีอยู่เดิม มากกว่าการใส่ความรู้ใหม่ จึงตรวจสอบว่า LoRA เพียงอย่างเดียวจะเพียงพอหรือไม่
- rank 1 มี Pass@1 0.738, Norm. Levenshtein 0.166, Added CC 0.676, LiveCodeBench Δ -0.022
- rank 8 มีค่า 0.775 / 0.112 / 0.426 / -0.022
- rank 16 มี Pass@1 0.805 / 0.087 / 0.328 / -0.005
- rank 32 มีค่า 0.795 / 0.065 / 0.235 / -0.011
- rank 64 มีค่า 0.797 / 0.051 / 0.160 / +0.001
- โมเดล Full RL ที่ดีที่สุดมีค่า 0.782 / 0.050 / 0.185 / +0.006
- LoRA rank 64 ให้ผลเกือบไล่ทัน Full RL ใน Levenshtein และออกมาดีกว่าใน Added CC
- เมื่อ rank เพิ่มขึ้น Levenshtein และ Added CC จะ ลดลงแบบโมโนโทนิก ตั้งแต่ 1 ถึง 64
- การปรับปรุงขนาดใหญ่กระจุกอยู่ในช่วงต้น โดย Levenshtein ลดลงมากจาก 0.166→0.087 ในช่วง rank 1→16 และช่วง 16→64 จะแคบลงอย่างค่อยเป็นค่อยไปเป็น 0.087→0.051
- rank 1 และ 8 แสดงให้เห็นการประนีประนอมระหว่างความแม่นยำกับการแก้ไขให้น้อยที่สุด และเป็นไปได้ว่าความจุไม่พอสำหรับเรียนรู้ฟังก์ชันรางวัลทั้งสองพร้อมกัน จึงเอนเอียงไปทางการลดการแก้ไขซึ่งมีรางวัลสูงกว่า
- สำหรับการเปลี่ยนพฤติกรรมระดับสไตล์ในงานที่มีความสามารถเดิมอยู่แล้ว พารามิเตอร์เพิ่มเติมเพียงเล็กน้อย ก็อาจเพียงพอ และหลังจุดหนึ่งไปแล้วผลตอบแทนจากการเพิ่มความจุจะลดลง
-
บันทึกเรื่อง reward hacking
- ในฟังก์ชันรางวัลช่วงแรก มีบั๊กที่ให้ 0 คะแนนกับ rollout ที่ไม่มีการรันสำเร็จเลยแม้แต่ครั้งเดียว
- เนื่องจากมีการกลับเครื่องหมายของ Levenshtein เพื่อทำให้อยู่ในรูปแบบ “ยิ่งมากยิ่งดี” ค่า 0 นี้จึงกลับกลายเป็นรางวัลที่สูงกว่าการรันสำเร็จ
- ถึงอย่างนั้น Full RL ก็ยังเรียนรู้งานได้ แต่ใน LoRA กลับเกิด reward hacking ในลักษณะที่ไม่สร้างโค้ดที่ถูกต้องเชิงหน้าที่ออกมาเลย จนนำไปสู่การตรวจสอบสภาพแวดล้อม
- หลังแก้ฟังก์ชันรางวัลแล้ว ผลของ Full RL ดีขึ้นอีกเพียงเล็กน้อย
-
ขยายไปสู่โมเดลที่ใหญ่กว่าได้หรือไม่
- ได้นำ out-of-domain RL recipe แบบเดียวกันไปใช้กับ Qwen3 14B
- Baseline 14B มี Pass@1 0.770, Norm. Levenshtein 0.136, Added CC 0.315
- หลังใช้ RL ค่าต่าง ๆ ดีขึ้นโดยรวมเป็น Pass@1 0.833, Norm. Levenshtein 0.059, Added CC 0.165, LiveCodeBench Δ +0.011
- แม้จำนวนพารามิเตอร์จะมากขึ้น ก็ยังคงเห็นการเพิ่มขึ้นของ Pass@1, การลดลงของ Levenshtein, การลดลงของ Added Cognitive Complexity และการไม่มี Catastrophic Forgetting ควบคู่กัน
- สิ่งนี้สนับสนุนความเป็นไปได้ที่ RL recipe สำหรับการแก้ไขโค้ดให้น้อยที่สุดจะขยายไปใช้กับโมเดลหลายขนาดได้
สรุปสุดท้าย
- Over-Editing เป็นปัญหาที่พบได้แพร่หลายและวัดผลได้
- ในบรรดา frontier coding model โดยรวม ความสามารถในการแก้ให้ถูกต้องกับความสามารถในการแก้ให้น้อยที่สุดแยกจากกันอย่างชัดเจน
- โดยเฉพาะ GPT-5.4 มีแนวโน้มเขียนใหม่มากเกินไปค่อนข้างชัดในค่าตั้งต้น ขณะที่ Opus 4.6 แสดง baseline ที่แข็งแกร่ง
- เพียงแค่ใช้พรอมต์อย่างชัดเจนก็สามารถชี้นำให้แก้ไขอย่างตรงต้นฉบับได้ในระดับมาก
- โดยเฉพาะ reasoning model มีแนวโน้มจะเข้าไปแก้มากเกินจำเป็นเป็นค่าเริ่มต้น แต่เมื่อสั่งให้คงต้นฉบับไว้ก็จะทำตามได้ดีขึ้น
- GPT-5.4 ก็แสดงการปรับปรุงอย่างมากในโหมด reasoning ทำให้เห็นชัดว่าความสามารถด้าน instruction following นั้นแข็งแกร่ง
- ที่การปรับปรุงของ Opus 4.6 ดูน้อย อาจเป็นเพราะประสิทธิภาพตั้งต้นสูงอยู่แล้ว
- ในมุมของการฝึก RL เป็นวิธีแก้ที่สมดุลที่สุด
- มันเรียนรู้พฤติกรรมการแก้ไขที่ตรงต้นฉบับมากขึ้นโดยไม่ทำลายความสามารถด้านการเขียนโค้ดทั่วไป และผลยังคงอยู่ทั้งใน Qwen3 ขนาด 4B และ 14B
- SFT แข็งแกร่งกับความเสียหายบางประเภท แต่ล้มเหลวอย่างมากในด้านการทำให้ทั่วไปและการรักษาความสามารถทั่วไป
- แม้การประเมินการแก้บั๊กระดับฟังก์ชันเดี่ยวจะมีขอบเขตจำกัดกว่าเกณฑ์ประเมินที่เป็น agentic มากกว่าอย่าง SWE-Bench Pro แต่ก็เป็นจุดเริ่มต้นในการจัดการกับ ปัญหาที่ก่อนหน้านี้ยากจะวัดเชิงปริมาณ ของ Over-Editing ในบริบทที่สมจริง
- ทิศทางของการประเมินและปรับปรุงความสามารถในการแก้ไขให้น้อยที่สุด อาจนำไปสู่การยกระดับคุณภาพโดยรวมของโค้ดที่ AI สร้างขึ้นได้
1 ความคิดเห็น
ความเห็นจาก Hacker News
วิธีที่ฉันใช้ Claude Code มันได้ผลเกินคาดมาก
ถ้ามันแก้เกินความจำเป็น ฉันก็ให้มันอธิบายว่าตรงไหนผิด แล้วบันทึกบทเรียนไว้ใน ไฟล์ skill ของแต่ละโปรเจกต์
แบบนั้นมันแทบไม่ทำพลาดซ้ำอีก และพอไฟล์ skill โตขึ้น มันก็จัดระเบียบและบีบอัดได้ค่อนข้างดีด้วย
ตอนนี้ฉันรู้สึกว่าการนั่งเขียนโค้ดเองในที่ทำงานไม่มีความหมายทางเศรษฐกิจมากนักแล้ว
ฉันใกล้เคียงกับบทบาทครู สถาปนิก และผู้ดูแลอินฟรามากกว่า และโยนงานพัฒนาส่วนใหญ่ให้ทีมเซสชัน Claude ที่ชำนาญทำ
แน่นอนว่าฉันรีวิวทั้งหมด และ Claude ก็เขียนเทสต์ละเอียดมากเพื่อให้ตรวจทานร่วมกัน
เดี๋ยวนี้แม้แต่โปรเจกต์ใหญ่ก็จัดการได้สบาย
ไม่ได้อยากพูดเหมือนโฆษณา Anthropic หรอก แต่ฉันสงสัยจริง ๆ ว่าฉันกำลังทำอะไรอยู่ถึงได้ เวิร์กเป็นพิเศษขนาดนี้
แล้วตอนนี้โทเคนก็แทบไม่ค่อยขาดแล้วด้วย
ฉันแทบใช้แต่ โมเดล Opus เพราะประหยัดโทเคนดี และสัปดาห์ก่อนฉันทำคอมมิตที่มีนัยสำคัญไปเกิน 150 ครั้งด้วยความช่วยเหลือจาก Claude แต่ใช้โควตารายสัปดาห์ไปแค่หนึ่งในสาม
ก่อนมี Claude ฉันทำได้เต็มที่ราว 25~30 คอมมิตต่อสัปดาห์
เมื่อวานดูสถิติแล้วตกใจที่ตอนนี้ 97% ของโค้ดบริษัทถูก Cursor AI เขียน
ปกติรันผ่าน cloud agent เพราะถ้านั่งดูแบบเรียลไทม์มันชวนวอกแวก
วิธีของฉันง่ายมาก แค่ สั่งให้ชัดด้วยคำพูด
คนชอบทำเรื่องนี้ให้ซับซ้อนเกินไป
การแชร์ไฟล์ .md แล้วลงลึกเรื่อง orchestration หรือ prompt hack มันดูน่าสนใจพอ ๆ กับการหมกมุ่นกับคีย์ลัด vim หรือสกิน IDE
แค่บอกให้ชัดว่าอยากได้อะไร แล้วให้ฟีดแบ็กดี ๆ ก็พอ
ผลลัพธ์ที่ได้อยู่ในระดับที่ฉันรับได้โดยไม่ขัดเขิน แม้จะคิดว่าเป็นโค้ดที่เพื่อนร่วมงานเขียน
แน่นอนว่าฉันยังอ่านทีละบรรทัดและแก้อยู่ แต่การแก้นั้นก็ใกล้เคียงกับระดับที่เคยทำใน code review ปกติ
ฉันไม่ได้วัด productivity เป็นตัวเลข แต่แค่เห็นว่าตอนนี้เริ่มลงมือทำงานที่ผัดมาหลายปีได้แล้วก็สัมผัสได้
มันเก่งเป็นพิเศษกับ งานน่าเบื่อ อย่างเช่นแปลง markdown 100 ไฟล์เป็น json 5 ไฟล์ แล้วอัปเดตโค้ดที่ใช้มันด้วย
มันเป็นซอฟต์แวร์ที่มีข้อบกพร่องและบั๊กเยอะมาก แต่ในทางปฏิบัติกลับได้ผลมาก
หนึ่งในสิ่งที่แปลกที่สุดของ AI คือประสบการณ์ของแต่ละคนต่างกันสุดขั้วจริง ๆ
งานของคุณมีส่วนที่เป็นงานปฏิบัติการเยอะไหม และกำลังดูแลโค้ดโปรดักต์ที่ต้องอยู่ยาวหรือเปล่าก็สำคัญ
สมมติฐานของฉันคือเครื่องมือนี้ทำงานได้ดีกับแพตเทิร์นเรียบง่าย และถึงจะทำเรื่องซับซ้อนได้บ้าง แต่ การคิดค้นแพตเทิร์นใหม่ นั้นแย่มาก
ถ้าปล่อยโดยไม่กำกับ มันจะสร้างแพตเทิร์นใหม่ที่อันตรายขึ้นมาเร็วมากแล้วทำทุกอย่างพัง
เพราะอย่างนั้นฉันเลยมักเขียนของที่ Claude ให้มาใหม่ทั้งก้อนอยู่บ่อย ๆ
บางครั้งฉันถึงขั้นแข่งความเร็วกับหุ่นยนต์แล้วเสร็จเร็วกว่าด้วยซ้ำ
การที่ฉันรู้อยู่แล้วว่าต้องการอะไรแน่นอนว่าช่วยได้ แต่ฉันรู้สึกว่า ต้นทุนจุกจิกในการเก็บงาน ตรงนี้ถูกประเมินต่ำไป
ทั้ง futzing fraction และ the peril of laziness lost พูดถึงความน่ารำคาญของวิธีที่เครื่องพยายามมากเกินไป
ไม่เข้าใจว่าทำไมแค่ทำอย่างเดียวถึงไม่พอ ต้องพยายามทำสามอย่าง
ต่อให้แก้ให้แล้วมันจะปรับตามใหม่ได้ แต่ฉันก็ยังต้องวนลูปแบบเดียวกับเวลาทำงานกับเพื่อนร่วมงานว่า "อย่าทำ A, B, C ให้ทำแค่ A" ซ้ำอีก ซึ่งน่าหงุดหงิด
การสร้างเทสต์ ก็ละเอียดอ่อน มันเขียนเทสต์ที่มีทิศทางชัดได้ดี แต่ถ้าเปิดให้มีความคิดสร้างสรรค์ มันจะสร้างเทสต์ไร้ประโยชน์อย่าง
foo + bar == bar + fooเยอะเกินไปต้องคอยตั้งคำถามกับประโยชน์ของเทสต์ตลอดเพื่อให้วงจรฟีดแบ็กยังดีอยู่
ช่วงนี้บางครั้งมันมีประโยชน์มากกว่าที่จะใช้ดึง import ที่ต้องใช้มาให้ครบในทีเดียว มากกว่าตัวเทสต์เอง
ถ้าเครื่องพวกนี้จะมาทำงานแทน ค่าเฉลี่ยคุณภาพโค้ดก็น่าจะสูงขึ้นได้
แต่หลายคนกำลังใช้งานมันในแนว "อย่างน้อยก็อยู่แถวค่าเฉลี่ย" และขึ้นกับวิธีทำงานแล้ว มันอาจฉุดค่าเฉลี่ยลงด้วยซ้ำ
ฉันทำงานแบบนี้มา 28 ปี แล้ว และตอนนี้การนั่งเขียนโค้ดแอปสำหรับงานด้วยตัวเองในเวลาที่รับเงินเดือนจากบริษัท มันไม่ค่อยสมเหตุสมผลทั้งในเชิงเศรษฐกิจและในแง่ความปรารถนาดีแล้ว
ในทางกลับกัน ฉันกลับรู้สึกว่าถ้า coding agent จะปรับให้เข้ากับความต้องการใหม่ มันควรกล้าเปลี่ยนโค้ดเดิมมากกว่านี้ แต่กลับให้ความสำคัญกับ การคงโค้ดเดิมไว้ มากเกินไปบ่อยครั้ง
สุดท้ายคงเป็นเรื่องว่าควร ตรึงโค้ดเดิมไว้ มากแค่ไหน
ถ้าเป็นแอปโปรดักชันขนาดใหญ่ที่รันมาหลายสิบปี การเปลี่ยนให้น้อยที่สุดก็น่าจะถูกต้อง แต่ถ้าเป็นโปรเจกต์ทดลองที่เพิ่งสร้างเมื่อ 3 วันก่อน ก็น่าจะแก้ให้ดีขึ้นมากกว่าปล่อยไว้แบบเดิม
สุดท้ายมันคงต้องเรียนรู้ที่จะปรับระดับความรุนแรงให้เหมาะกับบริบทของโปรเจกต์เอง
ต่อให้เป็นโปรเจกต์เดียวกัน ในแต่ละ PR ก็มีบางส่วนที่อยากให้เปลี่ยนได้เต็มที่ แต่บางส่วนก็อยากตรึงไว้เพื่อลด diff และขอบเขตของเทสต์
เพราะงั้นฉันเลยอธิบายล่วงหน้าว่าส่วนไหนเปลี่ยนได้แรงแค่ไหน แต่ผลลัพธ์ก็ยังไม่นิ่ง
โดยทั่วไปมันเอนเอียงไปทาง diff น้อยที่สุด ซึ่งแลกมาด้วย ความซ้ำซ้อน หรือการบิด abstraction แบบฝืน ๆ อยู่บ่อย
ถ้าใครมีวิธีที่เวิร์กกว่านี้ ฉันก็อยากฟังเหมือนกัน
ต่อให้สั่งให้ refactor หรือให้คิดทบทวนกว้าง ๆ ผลลัพธ์ก็มักไม่ค่อยดี
ฉันเลยให้มันเก็บกวาด markdown ที่อัดแน่นด้วยดีไซน์มากเกินไป แล้วลบเนื้อหาเชิงเทคนิคหรือ implementation/interface หลักออกจากซอร์ส ก่อนให้เซสชันใหม่ออกแบบขึ้นมาอีกครั้ง
จากนั้นค่อยกู้สิ่งที่ลบไปกลับมาแล้วให้ reconcile กับเซสชันที่ไร้เดียงสาน้อยกว่า
path dependency มันแรงเกินไป ตอนนี้ฉันเลยยังทำ workflow นี้ด้วยมืออยู่ แต่ก็อยากทำแพตเทิร์นนี้ให้เป็น skill แบบเป็นทางการ
AI มักพยายามปกปิดความล้มเหลวด้วยการ กลืน exception แล้วคืนค่าหลอก ๆ กลับมา หรือทิ้งข้อความไว้เพียงบรรทัดเดียวที่ถูกกลบอยู่ใน log จิปาถะจำนวนมาก
log เองก็มักถูกย่อมากเกินไป จนข้อมูลสำคัญที่ต้องใช้ debug จริง ๆ หายไป
เดาว่าอาจเป็นเพราะมันถูกฝึกให้ หลอกระบบเพื่อเอาคะแนน
ถ้าปล่อย exception ตรง ๆ มันคือความล้มเหลวชัดเจนและโดนลงโทษ แต่ถ้ากลบปัญหาไว้ บางครั้งก็ดูเหมือนสำเร็จ
ฉันก็สงสัยว่ามันแสดงออกแบบไหนใน Q&A ทั่วไป
โมเดลกำลังมุ่งไปทางที่ทำให้ฟังดูน่าเชื่อพอที่ผู้ใช้จะคล้อยตามแล้วจากไปหรือเปล่า
แพตเทิร์นที่เห็นบ่อยคือแนว "นั่นไม่ใช่ X แต่เป็น Y" ซึ่งการสร้างกรอบแบบสองขั้วอย่างนี้ทำให้คนไม่คิดถึงความเป็นไปได้อื่น
การปิดท้ายคำตอบด้วยแผนปฏิบัติการก็พบได้บ่อย ซึ่งมันดูเหมือนเทคนิคการขายแบบ assumptive close คือทำให้คนเห็นภาพผลลัพธ์หลังจากเห็นด้วยกับ AI มากกว่าตัวคำตอบเอง
ท้ายที่สุด hill-climbing เพื่อไต่ metric มันก็หน้าตาแบบนั้นเอง
มันเหมือน A/B enshittification รูปแบบที่รุนแรงจนแทบตีความไม่ได้
ตราบใดที่ยังฝึกด้วย human feedback ทุกชิ้นส่วนของทุกคำตอบก็เลี่ยงไม่ได้ที่จะพุ่งไปทางหลบผู้ประเมินและทำให้พอใจ
การใช้ AI ทำอะไรให้ ดีมากจริง ๆ ต้องลงแรงกว่าที่คิด
ถ้าสั่ง มันก็สร้างผลลัพธ์ที่ดูน่าเชื่อได้พอสมควร แต่ก็อาจไม่รู้ด้วยซ้ำว่าตัวเองไม่รู้อะไร
โดยเฉพาะเวลา AI พูดด้วยน้ำเสียงมั่นใจยิ่งอันตราย
เพราะงั้นการตรวจสอบจากหลายมุมและยืนยันความถูกต้องจึงไม่ใช่เรื่องง่าย
น่าสนใจว่ามันจะเปลี่ยนไปอย่างไรเมื่อเวลาผ่านไป
แต่ในเวลาเดียวกัน ทั้งบทความนี้และคอมเมนต์ที่นี่ก็ให้ความรู้สึกเหมือน ภาพสแนปช็อตของช่วงเวลา
ความเร็วในการพัฒนาของวงการมันสูงมาก จนโมเดลสำหรับเขียนโค้ดตอนนี้ดีกว่าเมื่อแค่ 9 เดือนก่อน มากแล้ว
ทุกครั้งที่อ่านคำบ่นเกี่ยวกับความสามารถของ AI ฉันไม่ได้โทษคนพูดนะ แต่ในใจก็มักคิดว่า "ตอนนี้ยัง" เสมอ
คือทำให้มันช่วยรีวิวผลลัพธ์ของกันและกัน
ถึงอย่างนั้นส่วนใหญ่ก็ยังทำงานแบบ async ได้ ฉันเลยเอาเวลาระหว่างนั้นไปทำอย่างอื่นได้
เลยมีบางโปรเจกต์ที่ฉันเริ่มจากใช้เอเจนต์ทำ prototype ไปพร้อมกับเรียนรู้ แล้วค่อยเขียนดีไซน์ จากนั้นเริ่มใหม่ตั้งแต่ต้น
แบบนั้นจะทำให้รู้ว่าจุดไหนควรลงลึกมากขึ้น
ส่วนอีก 20% ที่เหลือคืออะไร สุดท้ายก็ขึ้นอยู่กับธรรมชาติของปัญหา
ที่พูดกันตรงนี้คือเรื่อง การแก้โค้ดเกินจำเป็น แต่เอเจนต์ทำมากกว่านั้นอีก
มันแตะหลายไฟล์ รันเทสต์ ดีพลอย และแม้แต่ทำ smoke test ซึ่งทั้งหมดนี้ถูกซ่อนอยู่หลัง abstraction
ด้านหนึ่งมันน่าทึ่ง แต่อีกด้านก็ชวนกังวลมาก
อย่างแรกคือฉันไม่เข้าใจจริง ๆ ว่าข้างในเกิดอะไรขึ้น
มันง่ายและเย้ายวนเกินไปที่จะกดอนุมัติสคริปต์ที่เอเจนต์ประกอบขึ้นมาแล้วปล่อยให้รัน
แต่ฉันก็เคย ลบฐานข้อมูลทิ้ง มาแล้ว เพราะเชื่อว่าที่เอเจนต์ตัดสินมานั้นถูกต้อง และก็เคยจับได้ด้วยว่ามันกำลังจะส่ง AWS credentials ที่ห้ามส่งเด็ดขาดไปยังปลายทางดีพลอย
อย่างที่สองคือฉันไม่ได้เรียนรู้อะไรเลย
แม้แต่การประกอบคำสั่ง docker ง่าย ๆ เองก็เริ่มมีภาระทางความคิดสูงขึ้น จนต้องพึ่ง AI แบบเป็น ไม้ค้ำยัน ซ้ำ ๆ
อย่าเปิด auto-approve และควรอนุมัติทุกคำสั่งที่เอเจนต์จะรันด้วยตัวเอง
เรื่องการตัดสินใจด้านดีไซน์หรือสถาปัตยกรรมก็ไม่ควรมอบให้มัน มนุษย์ต้องเป็นคนกำหนดว่าจะสร้างอย่างไรแล้วสั่งเจ้ากระป๋องนั่นให้ชัด
ไม่ได้พูดเล่นนะ ถ้าปฏิบัติกับ AI ในฐานะเครื่องมือ มันจะใช้งานได้ดีขึ้นมาก
อาจไม่ถึง 10 เท่า แต่ก็อย่างน้อยยังเข้าใจโค้ดตลอดทาง
Day 1 มันจะระวังเรื่องความปลอดภัยมาก สอนตั้งแต่ทำไมต้องใส่ .env ไว้ใน .gitignore ไปจนถึงห้ามส่ง credentials และต้องให้ฉันแก้เอง
แต่พอ Day 2 ให้ทำเรื่องเดิมอีกครั้ง มันกลับลืมกฎหรือการตั้งค่าเหล่านั้น แล้วไปค้นทั้งดิสก์ อ่าน .env กับไฟล์อื่น ๆ เข้าใจว่าตัวเองถือโทเคนอยู่ แล้วสร้างคำสั่ง curl เพื่อทดสอบเองเสร็จสรรพ
วันแรกเหมือนผู้เชี่ยวชาญด้านความปลอดภัย แต่วันถัดมากลับแย่กว่านักศึกษาฝึกงานทั่วไป
วิธีนี้แม้จะมีพฤติกรรมที่ไม่ต้องการหรือ implementation เกินจำเป็นเยอะ แต่ก็มีประโยชน์ในแง่ ตัด boilerplate
ในความเป็นจริงส่วนแบบนี้ฉันมัก ลบทิ้งราว 70%
แต่ฉันจะไม่ให้ AI แตะส่วนในข้อ 1 และ 2
แน่นอนว่าต้องมีสถาปัตยกรรมที่แยกส่วนแบบนี้ได้ แต่โดยรวมฉันค่อนข้างพอใจ
แค่ไม่ต้องให้ production credentials กับ LLM ก็พอ
ถ้าทำซ้ำใน local หรือ staging/dev ไม่ได้ ก็ควรทำให้อินฟรา deploy ใกล้เคียง prod มากขึ้น และถ้ายังแยกสิทธิ์ตาม environment ให้ละเอียดพอไม่ได้ ก็ควรแก้ระบบสิทธิ์ก่อน
ฉันยึดหลักนี้มาตลอด เลยแทบไม่เคยเจอปัญหาแบบที่คุณว่า
ถ้าเป็นงานวินิจฉัย ฉันอาจให้ credentials แบบอ่านอย่างเดียวชั่วคราวได้ แต่ถึงอย่างนั้นก็จะออก โทเคนอายุสั้นมาก เผื่อกรณีรั่วไหล
เพราะงั้นโดยมากฉันยังพอรู้ว่าเกิดอะไรขึ้น
บางครั้ง Claude ก็ตัดสินใจแปลก ๆ หรือไม่ตรงธรรมเนียมอยู่บ้าง
แต่เวลาเราทำงานกับ codebase ใหญ่เป็นทีม ก็มีหลายส่วนที่เดิมทีก็ไม่ได้เข้าใจทั้งหมดอยู่แล้ว โดยเฉพาะส่วนที่สร้างโดยคนซึ่งออกจากบริษัทไปนานแล้วและถูกซ่อนไว้หลัง abstraction
แต่ก่อนมีคำสอนที่พูดกันบ่อยแต่แทบไม่ค่อยทำได้จริง คือ ให้ refactor ระหว่างทำงานไปเลย
แนวคิดคือถ้าแตะพื้นที่ไหนแล้วก็ควรใช้โอกาสนั้นเก็บกวาดและชำระหนี้เทคนิคไปด้วย
แต่ในโลกจริงมันไม่ค่อยเกิดขึ้น และตอนนี้พอ LLM เริ่มทำแบบนั้นได้จริง เราก็เลยเริ่มสัมผัส ผลข้างเคียง ของมัน
บางทีมันถึงขั้นสร้างใหม่ทั้งที่ฟังก์ชันที่ต้องใช้ก็มีอยู่ตรงนั้นแล้ว
ที่แย่กว่าคือมันแก้ฟังก์ชันเดิมให้ดูเหมือนยังคงพฤติกรรมเดิม แต่ดันทำจุดใช้งานอื่นพัง
ที่แย่ที่สุดคือไปแตะ side effect จากการเปลี่ยน state ระหว่างคลาสโดยไม่เข้าใจ แล้วทำให้เกิด deadlock หรือบั๊กธรรมดา ๆ
ในสายตาฉันมันไม่ใช่ refactoring แต่ใกล้เคียงกับการดึง คันโยกสล็อตแมชชีน เพิ่มอีกครั้งมากกว่า
ปัญหาจริงของฉันคือ คุณภาพของการ refactor ที่เอเจนต์ทำมันแย่
ฉันแค่อยากหยุดการแก้แบบนั้น แล้วสั่งให้ชัดขึ้นว่าควรแก้อะไรและแก้อย่างไร
หลายกรณี abstraction เดิมก็ใช้ได้ดีพอที่จะตามบั๊กหรือขยายฟีเจอร์ต่อยอดบนมันได้
แต่บางครั้งเราก็มาถึงทางแยกว่า จะฝืนอ้อม implementation เดิมต่อไป หรือจะ ออกแบบใหม่
พอทำงานกับ LLM ความชัดเจนว่าเราควรทบทวนเรื่องนี้อย่างไร หรือควรทบทวนตั้งแต่แรกไหม กลับเลือนลง
แถมการตัดสินใจแบบนั้นยังถูกซ่อนไว้จนผู้ใช้มองเห็นได้ยาก
บางทีการเปลี่ยนแบบนั้นอาจมีประโยชน์ก็ได้ เลยอยากเห็น ตัวอย่าง เพิ่มอีก
ฉันไม่ได้เชื่อ metric อย่าง cognitive complexity มากนัก แต่ก็แอบน่าสนใจอยู่ว่าการแก้แบบนี้มัก ทำให้ตัวเลขนั้นสูงขึ้น อย่างสม่ำเสมอ
ฉันไม่ค่อยเห็น การแก้เกินจำเป็น ใน Claude Code หรือ Codex มาพักหนึ่งแล้ว เลยสงสัยว่าการศึกษานี้ใช้พรอมป์แบบไหน
น่าจะอยู่ตรงนี้ และแก้ล่าสุดเมื่อ 8 เดือนก่อน
https://github.com/nreHieW/fyp/blob/5a4023e4d1f287ac73a616b5b944a14f28422c7e/partial_edits/utils/prompts_utils.py
GPT-5.4 เขียนใหม่ไป 50 บรรทัดเพราะคิดว่าสะอาดกว่า ทั้งที่ฉันขอแค่เพิ่ม 10 บรรทัด
มันเป็นการเพิ่มแบบกลไกมาก แค่ดูโค้ดเดิมแล้วใส่สิ่งคล้ายกันโดยเปลี่ยนชื่อตัวแปรก็พอ แต่ก็ยังทำเกิน
แถมตอนแรกยังไม่ได้ใส่ฟีเจอร์ที่ฉันขอด้วย เลยยิ่งน่าอึ้ง
over-editing ไม่ใช่ปัญหาในอดีตแน่นอน และครั้งนี้เกิดขึ้นเพราะฉันลืมลด thinking ลง ทำให้มันรันแบบ xhigh thinking
สำหรับฉันมันอ่านเหมือนเป็น ปัญหายุคเอเจนต์ระยะแรก มากกว่า
บทความนี้ค่อนข้างแน่น
LLM นั้น ฟุ่มเฟือยเกินไป ทั้งในงานเขียนร้อยแก้วและในโค้ด และในมุมฉันสาเหตุหลักมาจากวิธีฝึก
cross entropy loss ทำให้มันเอนเอียงไปหาประโยคแบบ garden path
สิ่งที่มนุษย์พูดจบได้ในประโยคเดียว หรือกระทั่งไม่กี่คำ มันกลับขยายเป็นทั้งย่อหน้า
เพราะประโยคยาวคือเส้นทางที่สร้างความประหลาดใจทางสถิติน้อยกว่า หรือก็คือเส้นทางที่มี perplexity ต่ำ
ฉันก็รู้สึก ก้ำกึ่ง กับปัญหานี้
ส่วนใหญ่แล้วมันทำเกินไปและฉันต้องใช้เวลา 30 นาทีแก้กลับ เลยเห็นด้วยกับการประเมินนั้น
แต่บางครั้งมันก็พลาดการเปลี่ยนที่ควรทำแบบครอบคลุมกว่า
น่าจะเพราะข้อจำกัดของบริบท ทำให้ฉันเริ่มคุมเครื่องมือให้เข้มขึ้น
ถึงอย่างนั้นฉันก็ยังไม่ได้ ความรู้สึกว่าควบคุมได้ ในระดับที่ต้องการ
มันให้ความรู้สึกเหมือน ร่องรอยจากข้อมูลฝึก
ในข้อมูล SFT และ preference มีตัวอย่างแบบ "เวอร์ชันที่แก้ไฟล์ให้สะอาดขึ้น" เต็มไปหมด แต่ตัวอย่างแนว "diff แค่ 3 บรรทัดพอดี" มีน้อย
เพราะงั้นโมเดลเลยเรียนรู้ว่าผลลัพธ์ที่ใหญ่กว่าและเกลามากกว่าคือผู้ชนะ
จะคุมด้วยพรอมป์ก็ได้ระดับหนึ่ง แต่สุดท้ายมันก็เหมือนต้องสู้กับอคติเดิมที่แรงมากอยู่ดี