7 วิธีตรวจสอบก่อนวางใจใช้โค้ดที่สร้างโดย AI

· By: SirilukP

7 Checks to Run Before Trusting AI-Generated Code

เครื่องมือช่วยเขียนโค้ดด้วย AI สามารถสร้างโค้ดจำนวนมหาศาลที่ใช้งานได้ภายในไม่กี่นาที แม้จะช่วยเพิ่มประสิทธิภาพการทำงาน แต่ในขณะเดียวกันก็แฝงความเสี่ยง โค้ดที่สร้างโดย AI ที่ไม่ดีนั้นไม่จำเป็นต้องดูแย่เสมอไป มันอาจจะคอมไพล์ผ่าน ผ่านการทดสอบ และใช้ชื่อตัวแปรที่ดูสะอาดตา ในขณะที่ยังคงตั้งสมมติฐานที่ผิดพลาดเกี่ยวกับ API, กฎการอนุญาตสิทธิ์ (authorization rule), กรณีขอบเขต (edge case) หรือการพึ่งพา (dependency)

GitHub warns ว่าโค้ดที่สร้างโดย AI อาจมีความหมายที่ไม่ถูกต้อง (semantically incorrect) และแนะนำให้ตรวจสอบและทดสอบอย่างละเอียดก่อนจะทำการ merge ดังนั้น แทนที่จะถามว่า "โค้ดที่ AI สร้างนี้ดูดีไหม?" ให้รัน 7 การตรวจสอบ เหล่านี้แทน

โค้ดที่ AI สร้างนี้ดูดีไหม?

1. ตรวจสอบ Diff ก่อนรันอะไรก็ตาม

การตรวจสอบแรกของคุณไม่ควรเป็น ChatGPT, Copilot, Claude Code หรือโมเดลอื่น แต่มันควรจะเป็น Git

เมื่อเอเจนต์เขียนโค้ดได้รับสิทธิ์เข้าถึง repository ทั้งหมด บางครั้งพวกมันอาจแก้ไขเกินกว่าที่งานกำหนด การแก้ไขบั๊กเล็กน้อยอาจกลายเป็นการทำ refactor, การอัปเดต dependency, การเปลี่ยนการตั้งค่า และการจัดรูปแบบโค้ดใหม่ทั้งหมดอย่างไม่คาดคิด

เริ่มด้วย:

git status
git diff --stat
git diff

git diff --stat จะช่วยให้คุณเห็นภาพรวมของขอบเขตการเปลี่ยนแปลงได้ทันที สมมติว่าคุณบอกเอเจนต์ว่า:

Add validation to the email signup endpoint.

คุณคาดหวังการเปลี่ยนแปลงใน 2 ไฟล์ แต่ diff กลับบอกว่า:

12 files changed, 437 insertions(+), 186 deletions(-)

หยุดตรงนั้นก่อน ก่อนจะตรวจดูว่าโค้ดทำงานได้ไหม ให้ถามว่าทำไมงานนี้ถึงต้องแก้โค้ดเป็นร้อยบรรทัด ในขณะที่ตรวจสอบ diff ให้มองหาจุดเหล่านี้เป็นพิเศษ:

  • ไฟล์ที่ไม่เกี่ยวข้องกับงาน
  • การทดสอบที่ถูกลบ, การปิดการตรวจสอบ (validation) และค่าคอนฟิกใหม่ๆ
  • การเปลี่ยนสิทธิ์การเข้าถึง (permission)
  • การเปลี่ยนแปลงในไฟล์ dependency
  • การ refactor ครั้งใหญ่ที่ซ่อนอยู่ในฟีเจอร์
  • ฟังก์ชันช่วยเหลือ (helper function) ที่ซ้ำซ้อน และการจัดการข้อผิดพลาดที่ละเลยความล้มเหลว

เป้าหมายนั้นง่ายมาก: ตรวจสอบให้แน่ใจว่า AI แก้ปัญหาตามงานที่คุณมอบหมาย ไม่ใช่งานใหญ่โตที่มันประดิษฐ์ขึ้นมาเอง

2. ให้ Compiler, Linter และ Type Checker เป็นผู้ตัดสิน

มนุษย์เป็นคอมไพเลอร์ที่แย่มาก อย่าเสียเวลาสิบนาทีในการตรวจเช็ก syntax ด้วยตา ในขณะที่เครื่องมือแบบ deterministic สามารถตรวจได้ในเวลาไม่กี่วินาที

สำหรับโปรเจกต์ Python การตรวจสอบอัตโนมัติชุดแรกของคุณอาจหน้าตาประมาณนี้:

python -m compileall .
ruff check .
mypy .

สำหรับ JavaScript หรือ TypeScript:

npm run lint
px tsc --noEmit
npm run build

การตรวจสอบประเภทข้อมูลแบบคงที่ (Static type checking) มีประโยชน์อย่างยิ่งกับโค้ดที่สร้างโดย AI เพราะโมเดลสามารถเชื่อมโยงค่าที่ดูเหมือนจะเข้ากันได้แต่จริงๆ แล้วไม่ใช่ เข้าด้วยกันอย่างมั่นใจ ตัวอย่างเช่น:

def get_user_id(user: dict[str, str]) -> int:
    return user["id"]

โค้ดดูเหมือนจะไม่มีพิษมีภัย แต่ dictionary ที่ประกาศไว้เก็บค่าเป็น string ในขณะที่ฟังก์ชันอ้างว่าจะคืนค่าเป็น integer ตัวเช็กประเภทข้อมูล (type checker) สามารถแจ้งเตือนเรื่องนี้ได้ทันที

3. ตรวจสอบทุก Dependency และ API ใหม่

เรื่องนี้สมควรได้รับความสนใจเป็นพิเศษ เพราะเป็นรูปแบบความล้มเหลวเฉพาะตัวของ AI บางครั้งโมเดลก็กุชื่อ package ขึ้นมาเอง และชื่อเหล่านั้นก็ดูน่าเชื่อถืออย่างมาก ตัวอย่างเช่น AI อาจแนะนำว่า:

pip install fastapi-jwt-auth-plus

อย่าทึกทักเอาเองว่ามี dependency นั้นอยู่จริงเพียงเพราะชื่อมันฟังดูสมเหตุสมผล

2025 study ได้วิเคราะห์ตัวอย่างโค้ด 576,000 ชุดที่สร้างโดย Large Language Model (LLM) และบันทึกการเกิด package hallucination ทั้งใน Python และ JavaScript โดยพบ 5.2% ในโมเดลเชิงพาณิชย์ และ 21.7% ในโมเดลโอเพนซอร์ส

สิ่งนี้สำคัญเพราะชื่อแพ็กเกจที่เกิดจากอาการหลอน (hallucinated package) สร้างโอกาสที่เรียกว่า slopsquatting คือการที่มีคนไปจดทะเบียนแพ็กเกจภายใต้ชื่อที่ AI มักจะหลอนขึ้นมาบ่อยๆ และอาจหลอกให้นักพัฒนาติดตั้งมันได้ ดังนั้นเมื่อใดก็ตามที่ AI เพิ่ม dependency ให้ตรวจสอบอย่างเป็นอิสระ

สำหรับ Python:

pip index versions package-name

สำหรับ npm:

npm view package-name

จากนั้นตรวจสอบว่าแพ็กเกจนั้นมีอยู่จริงหรือไม่ เป็นแพ็กเกจอย่างเป็นทางการใช่ไหม ใครดูแล อัปเดตล่าสุดเมื่อไหร่ โปรเจกต์จำเป็นต้องใช้จริงๆ หรือไม่ และเวอร์ชันตรงกับเอกสารหรือไม่ รวมไปถึงตรวจสอบไฟล์ lockfile และช่องโหว่ที่ทราบอยู่แล้ว

ทำแบบเดียวกันนี้กับ API ถ้า AI เขียนว่า client.responses.stream_async(...) อย่าทึกทักเอาเองว่า method นั้นมีอยู่จริงเพียงเพราะมันดูคล้ายกับส่วนอื่นๆ ของ SDK ให้เปิดเอกสารประกอบอย่างเป็นทางการล่าสุดและยืนยันโครงสร้างทั้ง class, method, parameters และ return type ให้ชัดเจน

4. ทดสอบที่พฤติกรรม ไม่ใช่การเขียนโค้ด (Implementation)

ตอนนี้ให้รันชุดการทดสอบ (test suite) ที่มีอยู่ เช่น pytest -q แต่การที่ผลการทดสอบเป็นสีเขียวทั้งหมดเป็นเพียงจุดเริ่มต้น คำถามที่สำคัญกว่าคือกรณีสำคัญใดที่ยังไม่ได้ถูกทดสอบ?

AI มักจะสร้างโค้ดสำหรับ "happy path" เพราะเป็นสิ่งที่ปรากฏเด่นชัดที่สุดในเอกสาร สำหรับทุกฟีเจอร์ที่สร้างขึ้น ให้ทดสอบอย่างน้อย 4 หมวดหมู่: ข้อมูลปกติ (Normal), ข้อมูลขอบเขต (Boundary), ข้อมูลที่ไม่ถูกต้อง (Invalid) และเงื่อนไขความล้มเหลว (Failure condition)

นอกจากนี้ ตรวจสอบให้แน่ใจว่า AI ไม่ได้ "แก้" การทดสอบที่ล้มเหลวด้วยการลบทิ้งหรือทำให้การตรวจสอบอ่อนลง สำหรับฟังก์ชันที่สำคัญ ควรพิจารณาเขียนการทดสอบ ก่อนที่จะนำ implementation ไปให้โมเดลตัวอื่นดู เพื่อให้มั่นใจว่าฟีเจอร์นั้นจะทำงานได้จริงแม้เจอสิ่งที่ไม่คาดคิด

5. โจมตีขอบเขตความปลอดภัย

ความถูกต้องในการทำงานและความปลอดภัยคือการทดสอบที่ต่างกัน เมื่อใดก็ตามที่โค้ดที่สร้างโดย AI สัมผัสกับข้อมูลที่ผู้ใช้ควบคุมได้, การยืนยันตัวตน, ฐานข้อมูล หรือ URL ภายนอก ให้เปลี่ยนความคิดมาเป็นมุมมองของผู้โจมตีทันที

ค้นหาพื้นที่ที่เกี่ยวข้องกับ SQL queries, authentication, file paths, หรือ API keys แล้วตั้งคำถามว่าผู้ใช้สามารถควบคุมค่าเหล่านี้ได้ไหม หรือสามารถเข้าถึงทรัพยากรของคนอื่นได้หรือไม่ จากนั้นให้ใช้เครื่องมือตรวจสอบความปลอดภัยแบบคงที่ (static security tooling) ตามความเหมาะสม

ทางเลือกหนึ่งคือ Semgrep หรือถ้าเป็นโปรเจกต์ Python สามารถใช้ Bandit เพื่อวิเคราะห์หาปัญหาด้านความปลอดภัยทั่วไป ส่วน Repository บน GitHub สามารถใช้ CodeQL ช่วยสแกนโค้ดได้

อีกหนึ่งการตรวจสอบที่สำคัญคือการค้นหาความลับ (secrets) เช่น API keys หรือรหัสผ่านฐานข้อมูล เอเจนต์ AI ไม่ควรเปลี่ยนการเรียกใช้ environment variable ให้กลายเป็นค่า hard-coded เพียงเพราะมันเห็นข้อมูลนั้นในบริบทของมัน

6. ติดตามเส้นทางความล้มเหลว (Failure Path)

โค้ด AI มักดูดีในสภาวะปกติ จงจงใจตรวจสอบว่าจะเกิดอะไรขึ้นเมื่อทุกอย่างไม่เป็นไปตามแผน มองหารูปแบบการจัดการข้อผิดพลาดที่กว้างเกินไป เช่น except Exception: pass ซึ่งจะทำให้การดีบักยากขึ้นอย่างมาก

ตรวจสอบเรื่องการลองใหม่ (Retries) ว่า AI เขียนให้ลองใหม่ตลอดกาลหรือไม่, การกำหนดการหมดเวลา (Timeouts), การย้อนกลับข้อมูล (Transactions) เมื่อเกิดความล้มเหลว, การ await งานในโค้ดแบบ Async ที่ถูกต้อง ไปจนถึงการล้างข้อมูล (Cleanup) หลังเกิดข้อผิดพลาด

การทดสอบที่มีประโยชน์คือการจงใจทำให้ dependency ภายนอกพัง เช่น ปิดฐานข้อมูล หรือส่งคืน HTTP 500 แล้วสังเกตว่าแอปพลิเคชันล้มเหลวในแบบที่คาดเดาได้ ปลอดภัย และมองเห็นได้หรือไม่

7. ถามว่าโค้ดนั้นควรจะมีอยู่ตั้งแต่แรกหรือไม่

การตรวจสอบขั้นสุดท้ายคือสิ่งที่นักพัฒนามักข้ามไป เอเจนต์เขียนโค้ด AI สามารถสร้างสิ่งที่เกินความจำเป็นได้ เช่น wrapper หรือชั้น abstraction ที่ซับซ้อนเกินไป

ก่อนจะ merge ให้ถามว่าฟีเจอร์นี้ได้นำความซับซ้อนใหม่เข้ามาโดยไม่จำเป็นหรือไม่ ฟังก์ชันที่มีอยู่แล้วสามารถทำสิ่งนี้ได้ไหม หรือ AI ได้สร้างสิ่งที่ซ้ำซ้อนกับที่มีอยู่แล้วหรือเปล่า จงปรับแต่งเพื่อให้เกิดความซับซ้อนใหม่น้อยที่สุดเท่าที่จำเป็น

นำฟังก์ชันสำคัญที่สุดที่ถูกสร้างขึ้นมา แล้วลองอธิบายมันโดยไม่มี AI ถ้าคุณไม่สามารถอธิบาย input, output, การเปลี่ยนสถานะ และเหตุผลในการเลือกวิธีนี้ได้ แสดงว่าคุณยังไม่พร้อมที่จะนำโค้ดนั้นไปใช้จริงในโปรดักชัน

บทสรุป

เครื่องมือเขียนโค้ดด้วย AI ช่วยลดต้นทุนในการผลิตโค้ดลงอย่างมาก แต่มันไม่ได้ลดต้นทุนในการพิสูจน์ว่าโค้ดนั้นถูกต้อง กระบวนการทำงานกับ AI ที่ดีที่สุดจึงไม่ใช่การสร้างแล้วเชื่อทันที (generate and trust) แต่มันคือ สร้างและตรวจสอบ (generate and verify) เพื่อให้มั่นใจว่าผลงานที่ได้มีคุณภาพและปลอดภัยอย่างแท้จริง

Source: KDnuggets
ดูแลงานแปลและเรียบเรียงโดย SirilukP

ความคิดเห็น (0)

เข้าสู่ระบบเพื่อร่วมแสดงความเห็น

สมัครสมาชิก

มาเป็นคนแรกที่แสดงความเห็นกันเลยโบร