การแยก pure function ออกจาก side effect ทำให้โค้ดจาก AI Agent ยังตรวจไหว
pure function คือฟังก์ชันที่ใส่ค่าเดิมแล้วได้ผลเดิม ไม่แตะค่าภายนอก พอ AI Agent เขียนโค้ดเร็วกว่าคนตรวจ การแยกออกจาก side effect จึงช่วยให้ยังตรวจโค้ดไหว

Pure Function หรือฟังก์ชันที่รับค่าเดิมแล้วคืนผลลัพธ์เดิมเสมอ ไม่ใช่แค่ทฤษฎีในตำรา แต่คือหน่วยโค้ดที่อ่านจบได้ในตัวเอง โดยไม่ต้องเปิดไฟล์อื่นประกอบ มันไม่อ่านหรือแก้ไขค่าใดๆ นอกขอบเขตตัวเอง แค่เห็นว่ารับค่าอะไรเข้ามาและคืนค่าอะไรออกไป ก็รู้ครบแล้วว่ามันทำงานกับอะไรบ้าง เพราะไม่มีของนอกตัวให้ต้องตามอ่านต่อ
ส่วนฝั่งตรงข้ามคือ Side Effect หรือจังหวะที่โค้ดออกไปแตะโลกภายนอก ทั้งการบันทึกฐานข้อมูล เรียกบริการภายนอกผ่าน API ส่งอีเมล อ่านเวลาของเครื่อง หรือแม้แต่การสุ่มตัวเลขขึ้นมาสักตัว
สองคำนี้กลับมาสำคัญมากในปัจจุบัน ไม่ใช่เพราะทฤษฎีสวยหรู แต่เพราะระบบช่วยเขียนโค้ดอัตโนมัติอย่าง AI Agent ผลิตโค้ดออกมาได้เร็วกว่าที่คนจะตามอ่านทัน โค้ดใหม่กลายเป็นของที่สร้างได้ง่ายและล้นตลาดที่สุด แต่สิ่งที่มีต้นทุนแพงขึ้นมาแทน คือเวลาของมนุษย์ที่ต้องคอยอ่านตรวจและกดอนุมัติ
คอขวดย้ายจากคนเขียนมาอยู่ที่คนตรวจ

ภาพนี้ชัดเจนขึ้นมากจากรายงานของ LinearB ผู้พัฒนาเครื่องมือวัดประสิทธิภาพทีมวิศวกรรมซอฟต์แวร์ ซึ่งวิเคราะห์ข้อมูลคำขอรวมโค้ดเข้าโปรเจกต์หลักอย่าง Pull Request หรือ PR จำนวน 8.1 ล้านรายการ จาก 4,800 ทีมใน 42 ประเทศ รายงานระบุว่า ปัจจุบันนักพัฒนาถึง 88.3% ใช้ AI เป็นประจำในการทำงาน เพิ่มขึ้นจากไม่ถึง 72% เมื่อช่วงต้นปี 2024
แต่ตัวเลขที่น่าตกใจที่สุดอยู่ตรงปลายทาง PR ที่ AI สร้างขึ้นเองทั้งหมด มีเพียง 32.7% เท่านั้นที่ได้รวมเข้าโปรเจกต์จริงภายใน 30 วัน เทียบกับ PR ที่คนเขียนเองซึ่งรวมเข้าโปรเจกต์ได้ในกรอบเวลาเดียวกันราว 84.5% ยิ่งไปกว่านั้น PR ของ AI ต้องรอนานเฉลี่ยกว่า 16 ชั่วโมงก่อนจะมีคนเริ่มเปิดตรวจ ขณะที่ PR ของคนเขียนเองรอนานเพียงประมาณ 200 นาที
ทว่าเมื่อเปิดตรวจจริง คนกลับใช้เวลาตรวจ PR ของ AI น้อยกว่า คือเฉลี่ย 194 นาที เทียบกับ 252 นาทีสำหรับโค้ดที่คนเขียนเอง ตัวเลขนี้ดูเผินๆ เหมือนจะตรวจได้เร็วขึ้น แต่พอมองคู่กับเวลารอที่ค้างเติ่งเป็นวัน รายงานมองว่าตัวเลขนี้น่าจะสะท้อนว่าคนตรวจดูแค่ผิวเผินมากกว่าตรวจได้เร็วขึ้น คือกวาดสายตาหาจุดพังก้อนใหญ่ แทนที่จะไล่ดูทีละบรรทัด
ขนาดของ PR ก็ไม่ได้ช่วยให้ตรวจง่ายขึ้นเลย เพราะ PR ที่มี AI ช่วยเขียนมีขนาดใหญ่กว่าที่คนเขียนเองถึง 2.5 เท่า โดยกลุ่ม PR ที่ใหญ่ที่สุด 25% แรก มีขนาดยาวทะลุ 400 บรรทัด เทียบกับ 157 บรรทัดสำหรับโค้ดที่คนเขียนเอง ทั้งที่เกณฑ์แนะนำของ LinearB เองคือไม่ควรเกิน 300 บรรทัด เพื่อให้คนตรวจยังพอนึกภาพตามได้ครบทั้งก้อน
นอกจากนี้ ยังมีอีกตัวเลขที่ชี้พฤติกรรมของ AI ได้ชัดเจนมาก คือสัดส่วนการแก้ไขโค้ดเดิมหรือ Refactor Rate ในกลุ่ม 25% บนสุด พบว่างานที่คนเขียนเองแก้โค้ดเดิมราว 37% ส่วนงานที่มี AI ช่วยเขียน สัดส่วนนี้แทบเป็นศูนย์ นั่นแปลว่าสิ่งที่ AI ผลิตออกมาคือโค้ดใหม่แทบล้วนๆ ไม่ใช่การกลับไปเก็บกวาดของเดิม
เมื่อคอขวดของการทำงานย้ายมาอยู่ที่ขั้นตอนการตรวจ คำถามสำคัญจึงไม่ใช่ "จะเขียนโค้ดยังไงให้เร็ว" แต่คือ "จะออกแบบโค้ดยังไงให้คนเปิดตรวจแล้วเข้าใจได้ครบ โดยไม่ต้องเปิดไฟล์อื่นประกอบ"
เปิดทั้งโปรเจกต์เพื่อแก้ส่วนลดสามบรรทัด
ลองดูตัวอย่างฟังก์ชันที่ยัดทุกอย่างไว้ในที่เดียว ซึ่งพบเห็นได้ทั่วไปในโปรเจกต์จริง:
async function checkout(userId) {
const user = await db.users.find(userId)
const cart = await db.carts.find(userId)
let total = 0
for (const item of cart.items) total += item.price * item.qty
if (user.tier === 'gold') total = total * 0.9
if (total > 1000) total = total - 50
await db.orders.insert({ userId, total, at: Date.now() })
await mailer.send(user.email, `ยอดชำระ ${total} บาท`)
return total
}
ฟังก์ชันนี้ทำทุกอย่างตั้งแต่ดึงข้อมูล คำนวณเงิน บันทึกลงฐานข้อมูล ไปจนถึงส่งอีเมล สมมติว่าโจทย์มีแค่ "แก้เงื่อนไขส่วนลด 3 บรรทัดตรงกลาง" คนตรวจก็ไม่มีทางมั่นใจว่าโค้ดที่แก้ปลอดภัยไหม จนกว่าจะไล่ตรวจดูว่า:
db.orders.insertไปแตะต้องตารางไหนบ้างmailer.sendส่งเมลออกทันทีหรือเข้าคิวไว้ก่อนDate.now()ที่แอบเรียกข้างในจะทำให้ผลลัพธ์เปลี่ยนไปตามเวลาที่รันหรือเปล่า
ปัญหาเกิดจากการที่หัวฟังก์ชันไม่ได้ประกาศเลยว่าข้างในไปแตะอะไรข้างนอกบ้าง คนอ่านจึงต้องเปิดไฟล์รอบข้างเพื่อไล่ดูบริบททั้งหมดให้ครบก่อนถึงจะกล้าอนุมัติ ปัญหานี้ไม่ได้เกิดกับคนอ่านอย่างเดียว AI Agent ที่เข้ามาแก้ก็ต้องไล่อ่านบริบทรอบข้างไม่ต่างกัน ต่างกันตรงที่ผลลัพธ์มาถึงเราในสภาพที่แก้เสร็จแล้ว
ยิ่งถ้าชื่อฟังก์ชันสื่อความหมายไม่ตรงกับสิ่งที่ทำ ปัญหาก็ยิ่งหนักขึ้น เช่น ฟังก์ชันชื่อ getUser แต่แอบมีโค้ดพักข้อมูลลงแคชหรือบันทึกข้อมูลลงฐานข้อมูลอยู่ข้างใน คนอ่านที่เชื่อชื่อฟังก์ชันก็จะไม่รู้เลยว่ามี side effect เกิดขึ้น ส่วนโค้ดที่เรียกใช้ฟังก์ชันนี้ต่อ ก็จะคิดว่าเรียกซ้ำกี่ครั้งก็ไม่มีอะไรเปลี่ยน ทั้งที่จริงมันเปลี่ยน
แยกการตัดสินใจออกจากการลงมือ

วิธีรับมือปัญหานี้ที่มักแนะนำกันคือ แบ่งการทำงานเป็น 3 จังหวะ
- รวบรวมข้อมูลที่ต้องใช้ทั้งหมดมากองไว้ก่อน
- คำนวณและตัดสินใจให้จบด้วย Pure Function ที่ไม่แตะต้องสิ่งแวดล้อมภายนอก
- ลงมือทำจริงเพื่อให้ Side Effect เกิดขึ้นทั้งหมดทีเดียวในตอนท้าย
ฟังก์ชันก่อนหน้านี้ แยกออกมาได้ชัดเจนแบบนี้:
// ส่วนตัดสินใจ (Pure Function): ไม่แตะต้องอะไรนอกตัวเอง
function calcTotal(cart, tier) {
let total = 0
for (const item of cart.items) total += item.price * item.qty
if (tier === 'gold') total = total * 0.9
if (total > 1000) total = total - 50
return total
}
// ส่วนลงมือ (Side Effect): ดึงข้อมูล เรียกส่วนคำนวณ แล้วค่อยบันทึก/ส่งเมล
async function checkout(userId, now) {
const user = await db.users.find(userId)
const cart = await db.carts.find(userId)
const total = calcTotal(cart, user.tier)
await db.orders.insert({ userId, total, at: now })
await mailer.send(user.email, `ยอดชำระ ${total} บาท`)
return total
}
หลักการสำคัญมีเพียงข้อเดียว: ส่วนที่ลงมือเรียกส่วนที่คิดได้ แต่ส่วนที่คิด ห้ามเรียกส่วนที่ลงมือเด็ดขาด ดังนั้น จุดเริ่มต้นของโปรแกรมจึงเป็นส่วนที่ลงมือเสมอ เพราะแค่การสั่งพิมพ์ข้อความออกหน้าจอก็นับเป็น side effect แล้ว
จุดที่น่าสังเกตอีกจุดคือ เราส่งค่าเวลาเข้ามาทางพารามิเตอร์ now แทนที่จะให้ calcTotal ไปดึงเวลาระบบเอง เพราะเวลาของเครื่องก็นับเป็นสถานะภายนอกเช่นกัน การแยกแบบนี้สอดคล้องกับแนวคิดการแบ่งขอบเขตของโค้ดเมื่อให้ AI Agent เข้ามาช่วยทำงาน ยิ่งขอบเขตของแต่ละฟังก์ชันชัดเจน บริบทที่ agent ต้องอ่านก่อนลงมือก็ยิ่งน้อยลง และคนตรวจก็ตรวจตรรกะการทำงานได้ง่ายขึ้น
สั่งรันใหม่อีกรอบ ออเดอร์เข้าสองใบ
เวลางานพังกลางทางแล้วเราสั่งรันใหม่ คำถามที่ต้องตอบให้ได้ก่อนคือ รอบที่พังไปนั้นทำอะไรสำเร็จไปแล้วบ้าง ถ้าตอบไม่ได้ การกดสั่งรันใหม่ก็มีต้นทุนสูงขึ้นมาทันที
ในโค้ดเวอร์ชันแรก ถ้าเกิดพังหลังบันทึกออเดอร์แต่ยังไม่ทันส่งเมล การสั่งรันใหม่ก็จะได้ออเดอร์ใบที่สอง และถ้าพังหลังส่งเมลไปแล้ว ลูกค้าก็จะได้เมลซ้ำอีกฉบับ
แต่เมื่อเราแยกตรรกะการทำงานออกเป็นสองส่วน สิ่งที่ต้องกังวลจะเหลือแค่ไม่กี่บรรทัดท้าย เพราะ calcTotal ต่อให้รันซ้ำร้อยรอบก็ไม่มีอะไรในระบบเปลี่ยนแปลง จุดที่ต้องระวังจริงๆ เหลือแค่บรรทัดที่บันทึกข้อมูลและส่งอีเมลเท่านั้น นี่คือความต่างระหว่างการต้องมานั่งไล่ตรวจโค้ดทั้งไฟล์กับการตรวจแค่ 2 บรรทัด
การทำให้ระบบรันซ้ำได้อย่างปลอดภัยโดยไม่พังอย่าง Idempotency จะพึ่งแค่ความระมัดระวังอย่างเดียวไม่ได้ ตัวอย่างมาตรฐานระดับโลกคือ Stripe ผู้ให้บริการชำระเงินออนไลน์ที่นำ Idempotency Key มาใช้เป็นรหัสป้องกันงานซ้ำ:
- เวลาส่งคำขอแบบ POST เพื่อสร้างหรือแก้ไขรายการ ผู้เรียกสามารถแนบ
Idempotency-Keyซึ่งเป็นรหัสเฉพาะของงานชิ้นนั้นไปกับคำขอได้ ส่วน GET กับ DELETE ไม่ต้องแนบ เพราะเรียกซ้ำแล้วผลลัพธ์ไม่เปลี่ยนแปลง - เมื่อคำขอแรกเริ่มทำงานจริงแล้ว Stripe จะบันทึกสถานะและผลลัพธ์ของรอบนั้นไว้ทั้งก้อน ไม่ว่าจะสำเร็จหรือเกิดข้อผิดพลาดของระบบอย่าง error 500 แต่ถ้าข้อมูลที่ส่งมาไม่ผ่านการตรวจ หรือชนกับคำขออีกอันที่ใช้รหัสเดียวกันอยู่พอดี ระบบจะไม่บันทึกอะไร และผู้เรียกก็ส่งคำขอใหม่ได้อย่างปลอดภัย
- หากมีคำขอที่แนบรหัสเดิมส่งเข้ามาซ้ำ Stripe จะส่งผลลัพธ์เดิมที่บันทึกไว้กลับไปทันที โดยไม่ไปประมวลผลหรือตัดเงินซ้ำอีกรอบ
- มีระบบป้องกันความผิดพลาด: ถ้าใช้รหัสเดิมแต่ส่งข้อมูลข้างในเปลี่ยนไป ระบบจะแจ้งเตือนข้อผิดพลาดทันที และจะล้างรหัสนี้ทิ้งอัตโนมัติเมื่อพ้น 24 ชั่วโมง
บทเรียนที่เรานำมาปรับใช้ได้ทันทีคือ side effect ที่ไม่ได้ออกแบบมาให้รันซ้ำได้ ต้องมีระบบกันซ้ำเป็นของตัวเอง ซึ่งชั้นป้องกันเหล่านี้มีต้นทุนทั้งในการพัฒนาและดูแลรักษา ยิ่งเราดันการตัดสินใจออกไปเป็น Pure Function ที่รันซ้ำได้โดยไม่มีผลข้างเคียงมากเท่าไหร่ ส่วนที่เราต้องเสียแรงไปสร้างระบบป้องกันก็ยิ่งน้อยลงเท่านั้น
เทสที่ไม่ต้องสร้างของปลอมมาซ้อนกัน
ข้อดีที่ชัดเจนที่สุดของ Pure Function คือเราเขียนชุดทดสอบย่อยอย่าง Unit Test ได้โดยไม่ต้องสร้างของปลอมหรือ Mock ขึ้นมาแทนของจริงเลยแม้แต่อย่างเดียว เพราะตัวฟังก์ชันไม่มีอะไรที่ผูกติดกับโลกภายนอก
test('ลูกค้า gold ยอดเกินพัน ได้ส่วนลดสองชั้น', () => {
const cart = { items: [{ price: 700, qty: 2 }] }
expect(calcTotal(cart, 'gold')).toBe(1210)
})
ส่วนฟังก์ชันที่ยัดทุกอย่างรวมกันต้องจำลองทั้งฐานข้อมูล ตัวส่งอีเมล และเวลาของเครื่องก่อนจะทดสอบได้แต่ละครั้ง ผลลัพธ์คือ พอทดสอบผ่าน สิ่งที่พิสูจน์ได้อาจมีแค่ "ของปลอมเหล่านั้นทำงานเข้ากันได้" ไม่ใช่ "ตรรกะทางธุรกิจทำงานถูกต้องจริงๆ"
จุดนี้สำคัญมากในยุคที่ให้ AI เขียนชุดทดสอบให้ เพราะฟังก์ชันที่ไม่แตะของนอกตัว มีจุดให้เขียนผิดน้อยกว่ามาก ส่วนฟังก์ชันที่มี side effect ฝังแน่น ต้องปลอมของนอกตัวทีละชิ้นก่อนถึงจะทดสอบได้ พอจำลองของปลอมซ้อนกันหลายชั้นแล้วทดสอบผ่านเขียวทั้งชุด สิ่งที่ยืนยันได้ก็ยังไม่ใช่ว่าของจริงทำงานถูกต้อง ซึ่งเป็นปัญหาตระกูลเดียวกับโค้ดของ AI ที่ผ่านเทสได้แบบฟลุก
สิ่งแวดล้อมภายนอกที่คุ้มค่าที่จะแยกส่วนเชื่อมต่อหรือจำลองของปลอมออกมา มีอยู่เพียงไม่กี่อย่าง เช่น เวลาของระบบ ตัวสุ่มตัวเลข ไฟล์ ฐานข้อมูล และการเชื่อมต่อเครือข่าย เพราะสิ่งเหล่านี้ควบคุมผลลัพธ์ให้แน่นอนได้ยากเวลาทดสอบ ส่วนตรรกะที่เหลือ เขียนเป็น Pure Function ธรรมดาจะดูแลง่ายและคุ้มค่ากว่ามาก
การเรียก LLM ก็คือ side effect ก้อนหนึ่ง
การเรียกใช้โมเดลภาษาขนาดใหญ่อย่าง LLM (Large Language Model) ผ่านบริการภายนอกคือการส่งข้อมูลข้ามเครือข่ายออกไปนอกโปรแกรมของเรา จึงตรงกับนิยามของ side effect เพราะต้องพึ่งสิ่งที่อยู่นอกตัวโปรแกรม เช่นเดียวกับฐานข้อมูลหรือนาฬิกาของเครื่อง ต่างกันตรงที่บริการ LLM อยู่ห่างจากระบบของเรามากที่สุด
จุดที่พลาดได้ง่าย คือการเอาเงื่อนไขการตัดสินใจไปผูกติดกับการเรียก LLM ในฟังก์ชันเดียว พอผลลัพธ์เพี้ยนขึ้นมา เราจะแยกไม่ออกว่าโมเดลตอบไม่ตรงโจทย์ หรือเงื่อนไขที่เราเขียนเองมีบั๊ก และเวลาจะทดสอบเงื่อนไขนั้น ก็ต้องพ่วงการเรียกโมเดลไปด้วยทุกครั้ง ไม่อย่างนั้นก็ต้องสร้างของปลอมมาแทนโมเดลก่อน
แนวทางที่ปลอดภัยกว่าคือ มองว่าการเรียก LLM เป็นเพียงขั้นตอนดึงข้อมูลเพื่อรับคำตอบจากโมเดลกลับมาก่อน แล้วค่อยส่งค่านั้นต่อให้ Pure Function ตัดสินใจและแปลงข้อมูล วิธีนี้ทำให้เราเขียนชุดทดสอบส่วนตรรกะได้โดยไม่ต้องเรียก LLM เราเพียงป้อนข้อความที่เคยได้รับกลับเข้าไป แล้วตรวจดูว่าฟังก์ชันของเราตัดสินใจถูกต้องหรือไม่
ไม่ต้อง pure ทั้งระบบ และไม่ควรด้วย
สิ่งที่มีประโยชน์และคุ้มค่าที่สุดสำหรับงานส่วนใหญ่ มีเพียง 2 ข้อ:
- แยกส่วนตัดสินใจออกจากส่วนลงมือทำจริง
- หลีกเลี่ยงการแอบแก้ไขข้อมูลส่วนกลางหรือ State ที่ใช้ร่วมกับโค้ดส่วนอื่น
ส่วนเทคนิคขั้นสูงอื่นๆ ของสาย Functional Programming หรือ FP เช่น กฎห้ามแก้ไขค่าตัวแปรในระบบอย่าง Immutability แบบเคร่งครัด การแปลงฟังก์ชันให้รับค่าทีละตัวอย่าง Currying หรือการห่อข้อผิดพลาดทั้งระบบให้เป็นชนิดข้อมูลเฉพาะ ไม่ใช่เรื่องผิด แต่ควรเลือกใช้เมื่อเจอปัญหาที่ต้องการสิ่งเหล่านั้นจริงๆ อย่าเพิ่งรีบหยิบมาสร้างความซับซ้อนตั้งแต่วันแรก
ตัวอย่างที่เคยเกิดขึ้นจริง คือการพยายามสร้างโค้ดครอบอย่าง Interface และ Abstraction มาหุ้มสิ่งแวดล้อมภายนอกทุกชิ้น เพียงเพื่อหวังว่าจะจำลองของปลอมมาทดสอบได้ง่าย ผลลัพธ์ที่ตามมาคือ กองโค้ดส่วนเชื่อมต่อชื่อคล้ายๆ กันจนหาไม่เจอว่าของจริงอยู่ที่ไหน มีโครงสร้างครอบโค้ดซ้ำซ้อนข้ามทีม และมีฟังก์ชันสร้างออบเจกต์งอกตามมาอีกชั้น สิ่งที่ต้องแลกจากการสร้างโค้ดครอบเกินความจำเป็น คือทั้งคนตรวจและ AI Agent ต้องไล่เปิดไฟล์ต่อกันเป็นทอดๆ เพื่อตามโค้ดสั้นๆ แค่ท่อนเดียว จนกลายเป็นปัญหาใหม่ที่แย่กว่าเดิม
สัญญาณว่าแยกโค้ดมากเกินไป
จะรู้ได้ยังไงว่าเริ่มแยกโค้ดเยอะเกินไปจนกลายเป็นภาระ? สังเกตสัญญาณเตือน 3 ข้อนี้:
- พารามิเตอร์ยาวเป็นพรืด: เพราะพยายามไม่แตะต้อง State ภายนอกเลย จนต้องส่งทุกตัวแปรผ่านพารามิเตอร์เข้าไปทุกทอด
- มีฟังก์ชันหรือคลาสที่ทำหน้าที่แค่ส่งต่อค่าแบบ Pass-through: โค้ดแยกเป็นชั้นย่อยๆ หลายชั้น แต่ละชั้นไม่มีตรรกะการตัดสินใจเพิ่มขึ้นมาเลย
- ต้องคัดลอกก้อนข้อมูลขนาดใหญ่ใหม่ทุกรอบในลูปการทำงาน: จนเริ่มรู้สึกได้ว่าระบบทำงานช้าลง
ถ้าพบสัญญาณเหล่านี้ ให้ถอยกลับมาหนึ่งก้าว แล้วรวมโค้ดที่แยกย่อยเกินไปกลับเข้ามา เพราะเป้าหมายของการแยกโค้ดคือ "ทำให้ตรวจและเข้าใจง่ายขึ้น" ถ้าแยกแล้วยิ่งอ่านยากขึ้น แปลว่าเรากำลังแยกผิดจุด
สี่คำถามสำหรับตรวจโค้ดของคุณ
ลองเปิดไฟล์ล่าสุดที่ AI Agent เพิ่งเขียนหรือแก้ไขให้ แล้วใช้ 4 คำถามนี้ตรวจฟังก์ชันที่ใหญ่ที่สุดในไฟล์:
- ฟังก์ชันนี้เขียนชุดทดสอบได้ทันทีโดยไม่ต้องจำลองของปลอมขึ้นมาเลยใช่ไหม?
- ถ้าเรียกฟังก์ชันนี้ด้วยค่าเดิม 2 ครั้ง ผลลัพธ์ยังเหมือนเดิมไหม และมีอะไรในระบบภายนอกเปลี่ยนไปหรือเปล่า?
- ถ้าฟังก์ชันนี้พังกลางทางแล้วกดรันใหม่ จะมีงานส่วนไหนทำซ้ำจนเกิดปัญหาไหม?
- แค่อ่านชื่อฟังก์ชัน เราบอกได้ครบไหมว่าฟังก์ชันนี้ไปแตะอะไรข้างนอกบ้าง?
ข้อไหนที่คุณตอบไม่ได้ ตรงนั้นคือจุดที่คนตรวจโค้ดจะเริ่มสะดุด และเป็นจุดที่ AI Agent มักจะสร้างข้อผิดพลาดขึ้นมาเงียบๆ
ยิ่ง AI เขียนโค้ดแทนเราได้เร็วขึ้นเท่าไหร่ นิยามของ "โค้ดที่ดี" ก็ยิ่งขยับ จากโค้ดที่รันครั้งแรกแล้วผ่าน กลายเป็นโค้ดที่กดรันซ้ำเมื่อไหร่ก็ยังทำงานถูกต้อง
ชอบเรื่องแนวนี้ มีอีบุ๊คฟรีให้อ่านต่อ
NotebookLM ฉบับเข้าใจง่าย โยนเอกสารให้ AI อ่าน แล้วได้สรุป พอดแคสต์ และคลังความรู้ส่วนตัว
กดสมัครแล้วเราจะส่งเทคนิค AI และของแจกใหม่ๆ ให้ทางอีเมล เลิกรับได้ตลอด
สร้าง AI Automation Pipeline ทุกแบบ ด้วย Agents และ Skills

ปูจากพื้นฐาน prompt, context และ cost ไปจนปั้น Skill สั่ง Agent กับ Sub-agent แล้วต่อทุกอย่างเป็น pipeline อัตโนมัติที่ออกแบบเองได้ ดูฟรี 7 บทก่อนตัดสินใจ


