ผมเสียเงินไป $500 กับโครงสร้างพื้นฐาน RAG ก่อนที่จะแก้ไขข้อผิดพลาดทั้ง 7 อย่างนี้
ผมสร้าง RAG pipeline สำหรับการค้นหาเอกสารส่วนตัว มันทำให้ผมต้องเสียค่าประมวลผลไป $500 และเสียเวลาแก้บั๊กไปหลายสัปดาห์ ผลลัพธ์ที่ได้นั้นแย่มาก ผู้ใช้ได้รับคำตอบที่ผิดพลาด และการค้นหาก็ล่าช้า
ผมได้ตรวจสอบ pipeline นั้น และพบข้อผิดพลาด 7 อย่าง การแก้ไขสิ่งเหล่านี้เปลี่ยนทุกอย่างไปโดยสิ้นเชิง
- การแบ่ง Chunk ด้วย Token แบบตายตัว ผมแบ่งเอกสารโดยใช้ 512 tokens ซึ่งมันทำลายบริบท (context) ไปเลย เช่น คำอธิบาย API อาจถูกตัดแบ่งกลางประโยค ทำให้ LLM ได้รับเพียงเศษเสี้ยวของข้อมูลและให้คำตอบที่ไร้สาระ วิธีแก้ไข: ใช้ semantic chunking
- แบ่งตามขอบเขตที่เป็นธรรมชาติ เช่น ย่อหน้าหรือหัวข้อ
- ใช้การดึงข้อมูลแบบ parent-document retrieval
- สร้าง child chunks ขนาดเล็กสำหรับการค้นหา
- ส่งเอกสาร parent ฉบับเต็มกลับไปให้ LLM
- เพิ่มการซ้อนทับ (overlap) ระหว่าง chunk ประมาณ 10-20%
- การตั้งค่าน้ำหนัก Hybrid Search ที่ผิดพลาด ผมใช้สัดส่วน 50/50 ระหว่าง vector search และ keyword search ซึ่งใช้ไม่ได้ผลกับเอกสารทางเทคนิค เพราะผู้ใช้งานสายเทคนิคต้องการการจับคู่คำสำคัญ (keyword) ที่แม่นยำ วิธีแก้ไข: ใช้การถ่วงน้ำหนักแบบไดนามิก (dynamic weights)
- คำถามเชิงข้อเท็จจริง (Factual queries): vector 35%, keyword 65%
- คำถามเชิงความหมาย (Semantic queries): vector 75%, keyword 25%
- คำถามทั่วไป (General queries): vector 60%, keyword 40%
- การปรับจูนพารามิเตอร์ HNSW มากเกินไป
ผมตั้งค่า
ef_constructionไว้ที่ค่าสูงสุด ซึ่งทำให้เซิร์ฟเวอร์ของผมค้าง เพราะมันใช้ RAM ทั้งหมดที่มี วิธีแก้ไข: ใช้พารามิเตอร์ที่เหมาะสม
- ตั้งค่า
Mระหว่าง 8 ถึง 32 - ตั้งค่า
ef_constructionเป็น 200 - ตั้งค่า
ef_searchเป็น 50 การใช้งานหน่วยความจำลดลงถึง 70%
การใช้ Embedding Models แบบทั่วไป ผมใช้โมเดลที่ฝึกฝนด้วยข้อมูลจาก Wikipedia แต่เอกสารของผมเป็นคู่มือการปฏิบัติงานทางวิศวกรรม (engineering runbooks) ซึ่งโมเดลไม่เข้าใจบริบทเฉพาะทางของผมเลย วิธีแก้ไข: ใช้โมเดลที่ผ่านการ fine-tune สำหรับเนื้อหาทางเทคนิคหรือโค้ด
ไม่มีการทำ Query Rewriting ผู้ใช้มักถามด้วยภาษาธรรมชาติ แต่เอกสารทางเทคนิคมักใช้คำศัพท์ที่เป็นทางการ ทำให้ข้อมูลไม่ตรงกัน วิธีแก้ไข: เพิ่มขั้นตอน LLM ขนาดเล็กเพื่อทำการ rewrite คำถาม
- ผู้ใช้ถาม: "why is my build slow"
- ระบบ rewrite เป็น: "CI pipeline performance optimization"
- สิ่งนี้ช่วยเพิ่มค่า recall ได้ถึง 40%
ผลลัพธ์ที่ซ้ำซ้อน การดึง top-10 chunks มักจะได้ย่อหน้าเดิมซ้ำกันถึงสามครั้ง ทำให้ LLM ตอบข้อมูลซ้ำไปซ้ำมา วิธีแก้ไข: ใช้ Maximal Marginal Relevance (MMR) เพื่อให้มั่นใจว่าผลลัพธ์มีความหลากหลาย
การทดสอบผิดจุด ผมทดสอบทั้ง pipeline พร้อมกันทีเดียว ทำให้ไม่รู้ว่าปัญหาอยู่ที่การดึงข้อมูล (retrieval) หรืออยู่ที่ตัว LLM กันแน่ วิธีแก้ไข: แยกการประเมินผลการดึงข้อมูล (retrieval evaluation)
- ติดตามค่า hit rate
- ติดตามค่า Mean Reciprocal Rank (MRR)
- สร้างชุดทดสอบ (test set) ที่ประกอบด้วยคู่คำถาม-เอกสาร 100 คู่
ผลลัพธ์หลังการแก้ไข:
- ความเกี่ยวข้องของคำตอบ: 45% เป็น 85%
- Latency: 3.2s เป็น 1.8s
- ค่าใช้จ่ายรายเดือน: $180 เป็น $95
แก้ไข chunking ก่อน จากนั้นจึงเป็นเรื่อง weights และตามด้วยคุณภาพของ embedding