คู่มือ Prompt Engineering สำหรับโปรแกรมเมอร์
(addyo.substack.com)- ผู้ช่วยเขียนโค้ดด้วย AI ช่วยเพิ่มประสิทธิภาพการทำงานของนักพัฒนาได้ แต่คุณภาพของผลลัพธ์นั้นขึ้นอยู่กับ Prompt Engineering อย่างมาก
- หากต้องการผลลัพธ์ที่มีประสิทธิภาพ ควรยึดหลักอย่าง การให้บริบทที่ครบถ้วน เป้าหมายที่ชัดเจน ตัวอย่าง การกำหนดบทบาท และการปรับปรุงแบบวนซ้ำ
- มีการนำเสนอแพตเทิร์นการออกแบบพรอมป์และตัวอย่างสำหรับงานพัฒนาหลัก เช่น การดีบัก การรีแฟกเตอร์ และการพัฒนาฟีเจอร์ใหม่
- พรอมป์ที่ดี ควรมีข้อมูลเฉพาะ เช่น วัตถุประสงค์ ภาษา สภาพแวดล้อม ข้อความผิดพลาด และตัวอย่างอินพุต/เอาต์พุต
- เป็น วิธีออกแบบพรอมป์ที่แม้แต่วิศวกรใหม่ก็ทำตามได้ พร้อมตัวอย่างเปรียบเทียบคำตอบของ AI และคอมเมนต์ประกอบ
ภาพรวม: ความสำคัญของ Prompt Engineering ที่ประสบความสำเร็จ
- ช่วงหลังมานี้ นักพัฒนาใช้ AI coding assistant เพื่อเร่งเวิร์กโฟลว์ตั้งแต่การเติมโค้ดอัตโนมัติ การแก้บั๊ก ไปจนถึงการเขียนทั้งโมดูล
- อย่างไรก็ตาม คุณภาพของคำตอบจาก AI ถูกกำหนดอย่างสำคัญโดยคุณภาพของพรอมป์
- พรอมป์ที่ดีช่วยชี้นำให้ได้โซลูชันโค้ดที่ชัดเจนและสร้างสรรค์ ขณะที่พรอมป์ที่กำกวมหรือคุณภาพต่ำมักนำไปสู่คำตอบที่จำกัดและไร้สาระ
- เพลย์บุ๊กนี้สรุป วิธีออกแบบพรอมป์ที่มีประสิทธิภาพและนำไปใช้กับงานพัฒนาประจำวันได้จริง ในเชิงปฏิบัติ
หลักการพื้นฐานของพรอมป์สำหรับโค้ดที่มีประสิทธิภาพ
- ให้บริบทอย่างครบถ้วน: AI ไม่ได้รู้จักโปรเจกต์หรือเจตนาไว้ล่วงหน้า จึงควรระบุข้อมูลที่เกี่ยวข้องทั้งหมด เช่น ภาษา เฟรมเวิร์ก ไลบรารี ข้อความ error และจุดประสงค์ของโค้ด
- ระบุเป้าหมายหรือคำถามให้ชัดเจน: แทนที่จะถามแบบกำกวมอย่าง “ทำไมโค้ดถึงไม่ทำงาน?” ควรอธิบายผลลัพธ์ที่ต้องการและสถานการณ์ปัจจุบันให้ชัด
- แยกงานที่ซับซ้อนออกเป็นส่วนย่อย: งานอย่างการพัฒนาฟีเจอร์ขนาดใหญ่ไม่ควรขอทั้งหมดในครั้งเดียว แต่ควรแบ่งเป็นขั้นเล็ก ๆ และค่อย ๆ ขอเพิ่ม
- ใส่ตัวอย่างอินพุต/เอาต์พุตหรือพฤติกรรมที่คาดหวัง: หากให้ตัวอย่างอินพุต เอาต์พุต หรือพฤติกรรมจริง จะช่วยให้ AI เข้าใจได้ดีขึ้นมาก (“few-shot prompting”)
- ใช้บทบาท (persona): เช่น “รีวิวโค้ดเหมือนนักพัฒนา React ระดับซีเนียร์” หรือ “ช่วยปรับแต่งประสิทธิภาพในฐานะผู้เชี่ยวชาญด้าน performance” เพื่อยกระดับคุณภาพคำตอบของ AI
- ปรับปรุงแบบสนทนาและวนซ้ำ: ใช้คำตอบแรกของ AI เป็นฐาน แล้วค่อยขอเพิ่มเติมหรือแก้ไข เพื่อค่อย ๆ ไปสู่ผลลัพธ์ที่ต้องการ
- รักษาความสอดคล้องของโค้ด: AI จะอ้างอิงสไตล์โค้ด การตั้งชื่อ และคอมเมนต์ ดังนั้นควรรักษาความสม่ำเสมอและความชัดเจนของโค้ดอยู่เสมอ
แพตเทิร์นพรอมป์สำหรับการดีบัก
วิธีออกแบบพรอมป์ดีบักอย่างเป็นระบบ
- อธิบายปัญหาและอาการให้ชัดเจน: ให้ข้อมูลที่ครบถ้วน เช่น ภาษา จุดประสงค์ของฟังก์ชัน พฤติกรรมที่คาดหวัง ข้อความ error จริง และ code snippet
- ขอการวิเคราะห์ทีละขั้นหรือทีละบรรทัด: สำหรับข้อผิดพลาดเชิงตรรกะหรือบั๊กที่ละเอียดอ่อน สามารถขอให้ “ไล่ตัวแปรทีละบรรทัด” หรืออธิบายบางส่วนของโค้ดเพื่อหาสาเหตุได้
- ใช้โค้ดที่ทำให้เกิดปัญหาแบบย่อที่สุด: แทนที่จะส่งโค้ดขนาดใหญ่ที่ซับซ้อน ให้ตัดออกมาเฉพาะหน่วยเล็กที่สุดที่ทำให้เกิด error เพื่อวิเคราะห์ปัญหาได้ตรงจุด
- ถามตรง ๆ และขอคำตอบต่อเนื่อง: เช่น “บั๊กเกิดขึ้นตรงไหน?” หรือ “ช่วยส่งโค้ดที่แก้แล้ว” ซึ่งเป็นการขอฟีดแบ็กที่ชัดเจนและทำซ้ำได้
ตัวอย่าง: พรอมป์ที่ไม่ดี vs. พรอมป์ที่ปรับปรุงแล้ว
ตัวอย่างโค้ดที่มีปัญหา
function mapUsersById(users) {
const userMap = {};
for (let i = 0; i <= users.length; i++) {
const user = users[i];
userMap[user.id] = user;
}
return userMap;
}
const result = mapUsersById([{ id: 1, name: "Alice" }]);
พรอมป์ที่ไม่ดี:
“ทำไมฟังก์ชัน mapUsersById ถึงไม่ทำงาน?”
- คำตอบจาก AI: เสนอการคาดเดาแบบกำกวม เช่น “อาจเป็นเพราะอาร์เรย์ว่าง หรือ user ไม่มี id”
- ได้เพียงคำแนะนำทั่วไปจาก การขาดบริบท และ ความไม่ชัดเจน
พรอมป์ที่ปรับปรุงแล้ว:
“ฟังก์ชัน mapUsersById ควรแมปอาร์เรย์ผู้ใช้ตาม id แต่เมื่อป้อน [ {id: 1, name: "Alice"} ] กลับเกิด error ว่า TypeError: Cannot read property 'id' of undefined โค้ดเป็นดังนี้: [แนบโค้ด] ผลลัพธ์ที่คาดหวังคือ { "1": ... } สาเหตุของอาการนี้คืออะไร และควรแก้อย่างไร?”
- คำตอบจาก AI: ชี้ว่าค่าเงื่อนไขของลูป (i <= users.length) ทำให้เกินขอบเขต จนเกิด undefined ในรอบสุดท้าย และเสนอให้แก้เป็น i < users.length
- เมื่อให้ บริบทที่เฉพาะเจาะจง ข้อความผิดพลาด และพฤติกรรมที่คาดหวัง ก็จะได้วิธีแก้ที่แม่นยำ
กลยุทธ์พรอมป์ดีบักเพิ่มเติม
- ขอให้ลิสต์สาเหตุที่เป็นไปได้ของบั๊ก (“สาเหตุที่เป็นไปได้ของ TypeError มีอะไรบ้าง?”)
- อธิบายตรรกะการทำงานของโค้ดด้วยตัวเองก่อน แล้วขอให้ช่วยตรวจ (“คำอธิบายของฉันถูกไหม ช่วยหาจุดผิดพลาดให้หน่อย”)
- ขอ test case สำหรับสถานการณ์ผิดปกติ (“ช่วยเสนออินพุต 2 แบบที่ทำให้ฟังก์ชันนี้ล้มเหลว”)
- มอบบทบาทเป็นผู้รีวิวโค้ดที่ละเอียดรอบคอบ (“ช่วยรีวิวโค้ดนี้พร้อมอธิบายปัญหาและจุดที่ควรปรับปรุง”)
แพตเทิร์นพรอมป์สำหรับการรีแฟกเตอร์/ปรับแต่งประสิทธิภาพ
ระบุเป้าหมายการปรับปรุงให้ชัดเจน
- คำสั่งอย่าง “รีแฟกเตอร์หน่อย” นั้นกำกวมเกินไป จึงควรระบุ เป้าหมายที่ชัดเจน เช่น ความอ่านง่าย ประสิทธิภาพ การบำรุงรักษา หรือการลดโค้ดซ้ำซ้อน
- ให้โค้ดทั้งหมด (หรือบริบทที่จำเป็น) พร้อมข้อมูลสภาพแวดล้อม ภาษา และเวอร์ชันของเฟรมเวิร์กอย่างเพียงพอ
- ขอ คำอธิบาย ของการเปลี่ยนแปลงด้วย (“บอกทั้งโค้ดและจุดที่ปรับปรุงให้ด้วย”)
- ใช้ การกำหนดบทบาท เพื่อยกระดับคุณภาพที่คาดหวัง เช่น “ในฐานะผู้เชี่ยวชาญ TypeScript ช่วยปรับให้เป็นไปตามแนวปฏิบัติล่าสุด”
ตัวอย่าง: เปรียบเทียบพรอมป์สำหรับรีแฟกเตอร์
โค้ดต้นฉบับ
(มีปัญหาอย่าง fetch ซ้ำ และโครงสร้างข้อมูลที่ไม่มีประสิทธิภาพ)
async function getCombinedData(apiClient) {
// Fetch list of users
const usersResponse = await apiClient.fetch('/users');
if (!usersResponse.ok) {
throw new Error('Failed to fetch users');
}
// ... (ละต่อจากนี้)
}
พรอมป์ที่กำกวม
“รีแฟกเตอร์ฟังก์ชัน getCombinedData”
- AI อาจเปลี่ยนเป็น fetch แบบขนาน หรือรวมข้อความ error เองตามอำเภอใจ (เพราะไม่ได้ระบุข้อกำหนด จึงคาดเดาพฤติกรรมได้ยาก)
พรอมป์ที่ระบุเป้าหมายชัดเจน
“ช่วยลดโค้ดซ้ำ ปรับปรุงประสิทธิภาพ ทำ fetch ทั้งสองแบบขนานกัน แยกข้อความ error และปรับการรวมข้อมูลให้มีประสิทธิภาพมากขึ้น พร้อมใส่คอมเมนต์และอธิบายจุดที่ปรับปรุง”
- คำตอบจาก AI: รีแฟกเตอร์ตามเป้าหมายอย่างชัดเจน เช่น fetch แบบขนาน แยกประเภท error และใช้โครงสร้างข้อมูลแบบ map ที่มีประสิทธิภาพ พร้อมคำอธิบายโดยละเอียด
ทิปเพิ่มเติมสำหรับการรีแฟกเตอร์
- ขอแบบเป็นขั้นตอน (“ปรับความอ่านง่ายก่อน → แล้วค่อย optimize อัลกอริทึม”)
- ขอแนวทางอื่นเพิ่มเติม (“ช่วยเขียนแบบฟังก์ชันนัลสไตล์ด้วย” เป็นต้น)
- ขอทั้งโค้ดและคำอธิบาย เพื่อใช้เรียนรู้และทำให้กลายเป็นบทสอนย่อย ๆ
- ขอให้เพิ่มการทดสอบสำหรับโค้ดผลลัพธ์
แพตเทิร์นพรอมป์สำหรับการพัฒนาฟีเจอร์ใหม่
ชี้นำการสร้างโค้ดแบบทีละขั้น
- เริ่มจากคำอธิบายระดับสูงก่อน (ต้องการสร้างฟีเจอร์อะไร) แล้วค่อยแยกเป็นรายละเอียดทีละขั้น
- ส่งมอบบริบทของสภาพแวดล้อมการทำงาน เช่น โค้ดเดิมที่คล้ายกัน แพตเทิร์นของโปรเจกต์ หรือไลบรารีที่ใช้อยู่
- ใช้คอมเมนต์หรือ TODO เป็นพรอมป์ เพื่อชี้นำการเขียนโค้ดของ AI ได้โดยตรงใน IDE
- ให้ตัวอย่างอินพุต/เอาต์พุตหรือ test case เพื่อกำหนดความคาดหวังของผลลัพธ์ให้ชัดเจน
- หากผลลัพธ์แรกยังไม่ดีพอ ให้ระบุจุดที่ต้องปรับหรือสไตล์โค้ดเพิ่มเติม แล้วขอซ้ำทันที
ตัวอย่าง: สร้างคอมโพเนนต์ React ProductList
“สร้าง React functional component ชื่อ ProductList โดยดึงอาร์เรย์สินค้าจาก /api/products แล้วแสดงเป็นลิสต์ และเมื่อพิมพ์ชื่อสินค้าในช่องกรอก ให้กรองแบบไม่สนตัวพิมพ์เล็ก/ใหญ่ พร้อมรองรับ loading และ error handling ระหว่างการดึงข้อมูล”
- คำตอบจาก AI: รวมการ fetch ข้อมูลด้วย useState และ useEffect การจัดการอินพุต การกรอง และ UI สำหรับ error/loading
- หากในโปรเจกต์ใช้ custom hook อยู่แล้ว ก็สามารถสั่งเพิ่มได้ เช่น “ช่วยรีแฟกเตอร์ให้ใช้ hook ชื่อ useProducts()”
ตัวอย่างการยกระดับพรอมป์ในงานจริง
- สามารถขอขยายฟีเจอร์แบบค่อยเป็นค่อยไปได้ เช่น “เพิ่มการเรียงลำดับ: ต้องมีดรอปดาวน์ A-Z และ Z-A”
- แยกขั้นตอนการเขียนโค้ดออกเป็นส่วน ๆ และใช้พรอมป์ต่างกันในแต่ละขั้น เพื่อรักษาคุณภาพและความสม่ำเสมอของโค้ด
บทสรุป
- หากต้องการใช้ศักยภาพของ AI coding assistant ให้เต็มที่ การออกแบบพรอมป์คือทักษะสำคัญ
- การเขียนพรอมป์ที่ประสบความสำเร็จควรคำนึงถึง บริบทที่เฉพาะเจาะจง วัตถุประสงค์ ตัวอย่าง ฟีดแบ็กแบบวนซ้ำ และการกำหนดบทบาท อยู่เสมอ เพื่อให้ได้ผลลัพธ์ที่มีประสิทธิภาพ
- มอง AI เสมือนเป็น นักพัฒนาจูเนียร์ หรือ ผู้รีวิวโค้ด ภายในโปรเจกต์ แล้วชี้นำอย่างละเอียดตามทิศทางที่ต้องการ พร้อมค่อย ๆ ยกระดับคุณภาพทีละขั้น คือกุญแจสู่ความสำเร็จ
1 ความคิดเห็น
ความเห็นจาก Hacker News
จากประสบการณ์ของผม ผมคิดว่าเทคนิค prompt engineering ที่แท้จริงมีอยู่แค่สามอย่าง
In Context Learning (ให้ตัวอย่างภายในบริบท กล่าวคือแบบ one-shot หรือ few-shot เทียบกับ zero-shot)
Chain of Thought (สั่งให้คิดเป็นลำดับขั้น)
Structured output (เช่น กำหนดรูปแบบผลลัพธ์ให้ชัดเจนอย่าง JSON)
นอกจากนี้อาจเพิ่ม Role Prompting ที่บทความนี้พูดถึงเข้าไปได้ด้วย
ส่วน RAG แยกออกไปต่างหาก เพราะเป็นวิธีที่โมเดลสรุปบริบทที่ให้มา
สุดท้ายแล้วที่เหลือก็เป็นเพียงการสรุปวิธีขอสิ่งที่ต้องการด้วยภาษาที่ชัดเจนและเรียบง่าย
ใน prompt นั้น บริบทคือองค์ประกอบที่สำคัญที่สุด
ตัวอย่างเช่น ถ้าเริ่มจาก Typescript แล้วค่อยถามคำถามด้าน data science จะเห็นว่ามันตอบได้ไม่ค่อยดี
แต่ถ้าถามคำถามเดียวกันด้วย Python ผลลัพธ์จะดีกว่ามาก
LLM ยังถ่ายโอนความรู้ข้ามโดเมนได้ไม่เก่งนัก จึงสำคัญมากที่จะต้องตั้งบริบทให้ตรงกับเป้าหมาย
ส่วนตัวผมก็คิดว่า role prompting เป็นวิธีที่ไม่มีความหมายเท่าไร
อาจจะใช่ในยุค GPT-3 แต่ LLM ส่วนใหญ่ทุกวันนี้รู้จักบทบาท "ผู้เชี่ยวชาญ" อยู่แล้ว
การหมกมุ่นกับ "prompt engineering" มากเกินไป ผมมองว่าเป็นการหลอกตัวเอง
แค่สื่อสาร requirement ให้ชัด ถ้าจำเป็นก็เพิ่มตัวอย่าง ตรวจดูผลลัพธ์หรือ reasoning trace แล้วถ้ายังไม่ได้อย่างที่ต้องการก็ค่อยปรับแล้วลองใหม่
ถ้าลองหลายครั้งแล้วยังไม่ได้คำตอบ ก็อาจต้องเลือกใช้สมองตัวเอง reasoning แทน AI
มีความเห็นว่าปัญหาคือหลายคนพยายาม "ใส่ทุกอย่างลงใน prompt เดียวให้จบ"
ทางที่ดีกว่าคืออย่าโยนคำขอขนาดใหญ่ครั้งเดียว แต่แยกเป็นหลาย prompt ที่มีบริบทเล็กลง พร้อมเชื่อมผลลัพธ์แบบ structured output ที่ชัดเจนเข้าด้วยกัน
ให้แต่ละ prompt โฟกัสที่เป้าหมายและตัวอย่างของตัวเอง หลีกเลี่ยง context overload
แบบนั้นวิธีหลัก 3 อย่างที่กล่าวไว้ข้างบนก็จะถูกนำมาใช้โดยธรรมชาติ
เกี่ยวกับวิธีที่สาม (Structured output) ผมกับเพื่อนร่วมงานมีกรณีศึกษาการประยุกต์ใช้ในงานวิทยาศาสตร์
ลิงก์งานวิจัย
เผื่อเป็นข้อมูลเพิ่มเติม ทีมของพวกเราอาศัย fine tuning มากกว่า prompt engineering
วิธี few-shot prompt ไม่ได้ผลในเคสของพวกเรา
ผมมักรู้สึกว่าเมื่อ prompt ยาวหรือซับซ้อนเกินไป ประสิทธิภาพการรับรู้ของโมเดลกลับลดลง
prompt ที่ซับซ้อนอาจทำให้รู้สึกว่าควบคุมได้มากขึ้น แต่ในความเป็นจริงมันอาจไม่ได้มีข้อดีเสมอไป
เลยค่อยๆ ลงเอยกับรูปแบบใช้งานที่เรียบง่ายมาก ใช้ prompt แบบมินิมอลให้พอได้เค้า แล้วค่อยปรับซ้ำไม่กี่รอบ
ผมเองก็เริ่มใช้แนวทางเดียวกันเป๊ะ
วิธีนี้ยังคุ้มต้นทุนด้วย
เคยใช้ agent แล้วหมดเงินทีละ $30 แถม codebase ก็เละ หรือไม่ก็วนกลับไปโค้ดเดิมบ่อยเกินไป
และอยากเตือนอีกอย่างว่า ถ้าปล่อยให้ AI เขียนโค้ดในโปรเจกต์ของเรามากเกินไป สุดท้ายโค้ดนั้นจะไม่ค่อยอยู่ในหัวเรา และดูแลรักษายากขึ้น
ยังมีหลักฐานด้วยว่าถ้าใส่ prompt ด้วยศัพท์ของผู้เชี่ยวชาญ ประสิทธิภาพจะดีกว่า
โดยทั่วไปแล้วสภาพแวดล้อมที่ผู้คนพูดกันด้วยภาษาชีวิตประจำวันจะให้ความแม่นยำน้อยกว่า แต่ศัพท์เฉพาะของสายวิชาชีพมักพาไปสู่คำตอบที่น่าเชื่อถือกว่า
ข้อมูลฝึกก็สะท้อนการกระจายลักษณะนี้เช่นกัน
ผมก็มีประสบการณ์คล้ายกัน
แต่พอไปดู system prompt ของ agent กลับเจอหลายอันที่ยาวและซับซ้อนมาก เลยสงสัยขึ้นมา
อยากรู้ว่าจริงๆ prompt แบบนั้นทำงานอย่างไร
ลิงก์ตัวอย่าง system prompt
ในงานบางอย่าง เพื่อนร่วมงานของผมใช้ prompt ที่ยืดยาวมาก
ตอนรวมระบบมีการเพิ่ม CRUD operation เข้าไป แล้วผมลองเปลี่ยนแบบสั้นมากประมาณว่า "วิเคราะห์สิ่งนี้จากมุมมองของ <สายอาชีพ>"
สุดท้ายผลลัพธ์ของทั้งสองฝั่งแทบไม่ต่างกัน และ prompt ยาวกลับมีอาการเอาบางประโยคไปใช้ซ้ำตรงๆ ในผลลัพธ์
ตัวผลลัพธ์เองถือว่าโอเค แต่สรุปแล้วโมเดล (gemini 2.5) เหมือนจะหยิบเฉพาะข้อมูลสำคัญมาใช้ แล้วก็ละลายส่วนเกินที่ไม่จำเป็นเข้าไปในผลลัพธ์ด้วย
อย่างน้อยสำหรับงานนี้เลยรู้สึกว่าความยืดยาวไม่ได้ส่งผลน่าสนใจต่อ "วิธีคิด" ของโมเดล
ผมก็ได้ข้อสรุปเหมือนกัน แต่ก็ยังสงสัยว่าควรตีความตัวอย่างการใช้ prompt ยาวๆ ที่ห้องแล็บ AI ต่างๆ เผยแพร่อย่างไร
ตัวอย่าง system prompt ของ Anthropic
ผมคิดว่า "prompt engineering" ไม่ได้มีอยู่เป็นเรื่องเฉพาะต่างหาก
ไม่เข้าใจว่าแค่เริ่มเขียนประโยคที่มีความหมายดีๆ ตั้งแต่เมื่อไรถึงเรียกว่า engineering
ผมว่าแย่กว่าเรียกตัวเองว่า "software engineering" เสียอีก
แต่ก็น่าเสียดายที่ต่อไปสิ่งนี้อาจจะกลายเป็นอาชีพจริงๆ (prompt engineer) และถูกมองเป็นความสามารถพิเศษในการเขียนประโยค
จริงๆ แล้ว "ประโยคที่มีความหมายดี" เป็นเรื่องที่เปลี่ยนไปตามตัวแปรมากมาย
ในทางปฏิบัติ ถ้ารวมเรื่อง testing, management, logging และ version control เข้าไป มันก็กลายเป็น engineering ไม่ใช่แค่สัญชาตญาณ
โครงสร้างอย่างลำดับที่แน่นอน สไตล์ หรือการพูดทวนปัญหาใหม่ ล้วนสำคัญมาก
ถ้าต้องทำงานกับ family model ที่มีพารามิเตอร์จำนวนมาก โมเดลแบบ API ก็ต้องเช็กความเข้ากันได้ของ prompt เดิมทุกครั้งที่มีการออกรุ่นใหม่
การเช็กและการทดสอบแบบนี้ก็เป็นส่วนหนึ่งของ prompt engineering
มีความเห็นว่าหลายคนต่อต้านกระแสหรือ hype มากเกินไปจนมองข้ามแก่นสำคัญ
ถ้าบาริสต้าร้านแถวบ้านผมเติมคำว่า coffee engineer ต่อท้ายชื่อตัวเอง ผมยังน่าจะเชื่อมากกว่า
ผู้บริโภคทุกวันนี้เสพติดอัลกอริทึมจนแม้แต่ความสามารถในการอ่านข้อความยาวๆ ก็ถดถอยลง
ผมว่าไม่ต้องกังวลถึงขั้นประกาศรับสมัคร "prompt engineer" หรอก
พวก AI sloperators พยายามเต็มที่เพื่อทำให้งานตัวเองดูเท่
จากประสบการณ์ของผม ปัญหาที่ LLM แก้ไม่ได้ ต่อให้ทำ "engineering" กับ prompt แค่ไหนก็มักไม่ช่วย
สุดท้ายมีแต่ต้องแยกเป็นปัญหาย่อยแล้วค่อยๆ ให้มันทำไปทีละส่วน
ถ้าใครมีประสบการณ์ตรงข้ามก็อยากฟังตัวอย่าง
ส่วนสำคัญของการใช้ LLM คือการจับทางให้ได้ว่าควรแยกปัญหาอย่างไร
ต้องมีความสามารถแยกให้ออกว่าเมื่อไรควรแยก เมื่อไรควรปล่อยให้มันจัดการเอง
อย่างที่บทความก็พูดไว้ ทักษะแบบนี้สำคัญ
ต่อไปน่าจะมีวิธีจัดระเบียบโค้ดหรือใส่คอมเมนต์ให้ดีขึ้นเพื่อปรับปรุงการโต้ตอบกับ LLM มากขึ้นอีก
และตัว LLM เองก็น่าจะพัฒนาไปในทิศทางนี้เรื่อยๆ จนเสนอวิธีแตกปัญหาให้ได้ด้วย
จุดประสงค์ของ prompt engineering คือเพื่อให้ได้คำตอบที่ดีในรูปแบบที่ต้องการและเร็วขึ้น
ในอุดมคติเราอยากให้โมเดลตอบเองได้ทั้งหมด แต่ในโลกจริง ตัวคำถามเองก็ต้องมีการ optimize เช่นกัน
เวลาจะเขียน prompt ผมยังรู้สึกแปลกๆ กับการสั่งงานด้วยภาษาธรรมชาติ เพราะติดนิสัยเดิม
รู้สึกเหมือนมันควรต้องเขียนให้เหมือนอาร์กิวเมนต์ที่เป๊ะๆ หรือเหมือน SQL query มากกว่า
การสั่งเครื่องมือแบบคุยกันเหมือนในแชตก็ยังรู้สึกน่าทึ่ง
ถึงอย่างนั้น ผมก็คิดว่าการกลายเป็นเครื่องมือที่เข้าใจคำสั่งภาษาธรรมชาติได้ทำให้การเข้าถึงง่ายขึ้นอย่างมหาศาล
แต่ถึงอย่างนั้น เวลาผมเขียน prompt แบบพูดกับคนอยู่ ก็ยังรู้สึกว่าตัวเองตลกๆ ดี
เดี๋ยวนี้มีพวกคู่มือ prompt เยอะมาก
แต่ผมคิดว่าในทางปฏิบัติมันไม่ค่อยจำเป็น
แค่ลองใช้เครื่องมือเอง ทำความคุ้นเคย และเรียนรู้วิธีใช้งาน เดี๋ยวก็จะรู้เองตามธรรมชาติว่า prompt แบบไหนดี
คล้ายกับสมัยก่อนที่ Google กำลังฮิตและมีกระแส FOMO
ตอนนั้นมีคนบอกว่าถ้าไม่ซื้อหนังสือเกี่ยวกับมันก็จะล้าหลังเหมือนมนุษย์ยุคหิน แต่จริงๆ แล้วเป็นเรื่องง่ายมากที่เรียนรู้ได้หมดภายในวันเดียว ไม่ต้องคิดให้ซับซ้อน
แน่นอนว่าคู่มือหรือวิดีโอเทคนิคก็ช่วยคนบางกลุ่มได้จริง
หลายคนไม่ได้ตั้งใจจะปรับปรุงด้วยตัวเอง แต่แค่ดูคู่มือหรือวิดีโอของคนเก่งสักครั้งก็ช่วยยกระดับฝีมือได้
ตัวผมเองก็เรียนรู้เคล็ดลับจากวิธีใช้งานของคนอื่นหรือจากประสบการณ์ในชุมชนอยู่เรื่อยๆ
เพียงแต่ว่าถ้าฝึกเองคนเดียวก็มีข้อจำกัดในการได้ทิปพวกนี้
เมื่อก่อนก็มีสูตรแบบเดียวกับ "คู่มือเขียน user story" อย่าง “As a [role], I want to [task] so I can [objective]”
ไม่ว่าจะมือเก๋าหรือมือใหม่ ส่วนใหญ่ก็ยังต้องการความช่วยเหลือในการสื่อสาร requirement ให้ชัด
ต่อให้เป็นนักพัฒนาที่เก่งมาก ก็ยังพลาดหรือเข้าใจผิดได้เมื่อ requirement ไม่มีโครงสร้าง
การดูว่าคนอื่นใช้เครื่องมือนี้สร้าง productivity อย่างไรก็มีประโยชน์มากเหมือนกัน
ทำให้เจอไอเดียที่ผมพลาดไป
ก่อนจะต้องลองผิดลองถูกเองทั้งหมด การได้เรียนรู้จากประสบการณ์ที่มีคนทำไว้ก่อนแล้วสักเล็กน้อยย่อมมีประสิทธิภาพกว่า
สำหรับผมที่ไม่มีเวลาไปลองทุกอย่างเอง การแชร์ประสบการณ์แบบนี้ถือเป็นข้อมูลที่น่าขอบคุณมาก
ยังมีทริกที่มองไม่ค่อยเห็นอยู่แน่นอน
ตัวอย่างเช่น จากประสบการณ์พบว่าไม่จำเป็นต้องใส่คำสุภาพอย่าง “please” ใน prompt เลย
เมื่อนานมาแล้วตอนเรียนปริญญาโทสายคอมพิวเตอร์ ผมได้นำกระบวนการพิสูจน์ที่เรียนในวิชา Science of programming มาประยุกต์ใช้กับการเขียน prompt สำหรับ data engineering ได้ดีมาก
ตัวอย่างเช่น “ให้ input(…) และสมมติฐาน(…) แล้วขอให้เขียน spark code ที่ทำให้ post-condition(…) เป็นจริง”
ถ้าระบุ input, สมมติฐาน และเงื่อนไขผลลัพธ์ให้ชัด ก็สามารถได้โค้ดที่ดี
หนังสืออ้างอิง
ผมรู้สึกว่าการจริงจังกับ prompt engineering มากเกินไปมันเกินเหตุ
แค่คัดลอกโค้ดหรือ error มาวางแล้วถามแบบตรงๆ ทุกวันนี้โมเดลส่วนใหญ่ก็จัดการได้ดีเองอยู่แล้ว
เลยไม่รู้สึกว่าจำเป็นต้องเขียนวกวนเกินไป
เมื่อไม่กี่วันก่อน Sergey Brin บอกว่านี่เป็นข้อเท็จจริงที่ไม่ค่อยถูกพูดถึงในชุมชน AI ว่า "ถ้าข่มขู่ทางกายภาพ ประสิทธิภาพของโมเดลจะดีขึ้น"
บทความที่เกี่ยวข้อง
นึกถึงมุกของโปรแกรมเมอร์สายโปร vibe coder ใน YouTube ช่อง “Programmers are also human” ที่ชอบลงท้ายคำสั่ง LLM ว่า ".. ไม่งั้นเข้าคุก"
งั้นนี่คงเป็นเหตุผลที่ Google ค่อยๆ ทิ้งคำว่า "Don't Be Evil" สินะ
การเรียกการเขียน prompt ว่า "engineering" ให้ความรู้สึกว่าไม่จริงจังเอามากๆ
ตอนกระแส prompt "engineering" มาแรง ผมเคยได้ยินอุปมาเปรียบเทียบที่ตลกดีอยู่แบบหนึ่ง
สุดท้ายข้อถกเถียงนี้ก็วนกลับมาเหมือนทุกครั้งที่พูดถึง software engineering
อาจเป็นเพราะจินตนาการของผู้คนหยุดอยู่แค่การใช้หน้าแชตขอรูปแมว
ทั้งที่จริงแล้วยังมี prompt ที่ใช้กับ API และ workflow อัตโนมัติด้วย ซึ่งไปไกลกว่านั้นมาก
ในอเมริกายังมีตำแหน่ง "sales engineer" ด้วย แต่จากประสบการณ์ของผม คนกลุ่มนี้หลายคนไม่รู้เลยว่าสินค้าที่ตัวเองขายทำงานอย่างไร
วงการ IT เป็นที่ที่คำศัพท์และความหมายของมันค่อยๆ เลือนหายไป
จนทำให้สงสัยว่าคำคำหนึ่งจำเป็นต้องมีความหมายดั้งเดิมอยู่หรือเปล่า