ผมเสียเงินไป $500 กับโครงสร้างพื้นฐาน RAG ก่อนที่จะพบกับ 7 ข้อผิดพลาด
ผมสร้าง RAG pipeline สำหรับการค้นหาเอกสารส่วนตัว มันทำให้ผมต้องเสียค่าประมวลผลไป 500 ดอลลาร์ และเสียเวลาแก้บั๊กไปหลายสัปดาห์ ผลลัพธ์ที่ได้นั้นแย่มาก ผู้ใช้ได้รับคำตอบที่ไม่เกี่ยวข้อง และการค้นหาก็ล่าช้า
ผมได้ตรวจสอบ pipeline และพบข้อผิดพลาดทั่วไป 7 ประการ ซึ่งการแก้ไขสิ่งเหล่านี้ได้เปลี่ยนทุกอย่างไปอย่างสิ้นเชิง
- การแบ่ง Chunk ด้วยจำนวน Token แบบตายตัว (Fixed Token Chunking) ผมแบ่งเอกสารตามจำนวน token ที่กำหนดไว้ตายตัว ซึ่งทำให้บริบท (context) เสียหาย ประโยคอาจถูกตัดแบ่งครึ่ง ทำให้ LLM ได้รับข้อมูลที่ขาดตอนและให้คำตอบที่แย่
- วิธีแก้ไข: ใช้ semantic chunking ร่วมกับ parent-document retrieval
- แบ่งตามขอบเขตที่เป็นธรรมชาติ เช่น ย่อหน้าหรือหัวข้อ
- สร้าง child chunks ขนาดเล็กสำหรับการค้นหา
- ส่งคืนเอกสารต้นฉบับ (parent document) ฉบับเต็มให้แก่ LLM เมื่อพบข้อมูลที่ตรงกัน
- เพิ่มส่วนที่ซ้อนทับกัน (overlap) ระหว่าง chunk ประมาณ 10-20%
- การกำหนดน้ำหนักการค้นหาแบบเริ่มต้น (Default Search Weights) ผมใช้น้ำหนักแบบ 50/50 ระหว่าง vector search และ keyword search แต่สำหรับเอกสารทางเทคนิค คำสำคัญ (keywords) ที่แม่นยำมีความสำคัญมากกว่า
- วิธีแก้ไข: ใช้น้ำหนักแบบไดนามิก (dynamic weights)
- คำถามเชิงข้อเท็จจริง: vector 35%, keyword 65%
- คำถามเชิงความหมาย (semantic): vector 75%, keyword 25%
- การปรับแต่งพารามิเตอร์ HNSW ที่มากเกินไป (Over-optimizing HNSW Parameters)
ผมตั้งค่า
ef_constructionไว้ที่ค่าสูงสุด ซึ่งเมื่อใช้กับ index ขนาดใหญ่ มันทำให้เซิร์ฟเวอร์ของผมค้างและใช้ RAM จนหมด
- วิธีแก้ไข: ใช้การตั้งค่า HNSW ที่เหมาะสม
- ตั้งค่า M ระหว่าง 8 ถึง 32
- ตั้งค่า
ef_constructionเป็น 200 - ตั้งค่า
ef_searchเป็น 50
- การใช้ Embedding Models ที่ไม่เหมาะสม ผมใช้โมเดลทั่วไปที่ฝึกฝนด้วยข้อความจากเว็บ ซึ่งมันไม่เข้าใจเอกสารทางวิศวกรรมเชิงเทคนิคของผม
- วิธีแก้ไข: เปลี่ยนไปใช้โมเดลที่ผ่านการ fine-tune สำหรับเนื้อหาทางเทคนิคหรือโค้ด
- ความไม่สอดคล้องกันของภาษาธรรมชาติ (Natural Language Mismatch) ผู้ใช้ถามคำถามเช่น "ทำไมการ build ของฉันถึงช้า" แต่ในเอกสารกลับใช้คำว่า "CI pipeline optimization" ซึ่งไม่มีความเกี่ยวข้องกันเลย
- วิธีแก้ไข: เพิ่มขั้นตอนการเขียนคำถามใหม่ด้วย LLM (query rewrite)
- เขียนคำถามของผู้ใช้ใหม่ให้เป็นคำศัพท์ทางเทคนิคก่อนทำการค้นหา
- บริบทที่ซ้ำซ้อน (Redundant Context) การดึงข้อมูล 10 chunk แรกมักจะทำให้ได้ย่อหน้าเดิมซ้ำกันถึงสามครั้ง ซึ่งเป็นสาเหตุให้เกิดอาการหลอน (hallucinations) ของ AI
- วิธีแก้ไข: ใช้ Maximal Marginal Relevance (MMR) เพื่อให้มั่นใจว่าผลลัพธ์มีความหลากหลาย
- การประเมินผลแบบ End-to-End เพียงอย่างเดียว ผมตรวจสอบแค่คำตอบสุดท้ายเท่านั้น ทำให้ไม่รู้ว่าปัญหาอยู่ที่ขั้นตอนการดึงข้อมูล (retrieval) หรืออยู่ที่ตัว LLM
- วิธีแก้ไข: ประเมินผลการดึงข้อมูล (retrieval) แยกต่างหาก
- ติดตามค่า hit rate และ Mean Reciprocal Rank (MRR)
- สร้างชุดทดสอบ (test set) ที่ประกอบด้วยคู่คำถาม-เอกสาร 100 คู่
ผลลัพธ์หลังการแก้ไข: • ความเกี่ยวข้องของคำตอบ: 45% เป็น 85% • ความหน่วงในการค้นหา (Query latency): 3.2 วินาที เป็น 1.8 วินาที • ค่าใช้จ่ายรายเดือน: $180 เป็น $95
จัดการเรื่อง chunking ก่อน ตามด้วย weights และสุดท้ายคือ embedding quality
ปัญหา RAG ที่น่าปวดหัวที่สุดของคุณคืออะไร? คอมเมนต์บอกกันหน่อยครับ
ชุมชนแห่งการเรียนรู้ (เลือกเข้าร่วมได้): https://t.me/GyaanSetuAi