teach-me-ai / sources / HO-2
⟵ กลับหน้าแทร็กเสริม
HO-2 · Hands-On AI Engineering

RAG 11 แบบ — สเปกตรัมจาก naive ถึง agentic

⏱️ ~28 นาที 🎯 เห็นว่า RAG 11 แบบคือโครงเดียวกัน + การอัปเกรดเฉพาะ stage แล้ว map ลง pgvector 📦 ต้นทาง: rag_apps/ (11 โปรเจกต์)

หมวด RAG มี 11 โปรเจกต์ที่ชื่อฟังดูต่างกันจนน่ากลัว — GraphRAG, HyDE, Hybrid, Vision RAG… แต่ความจริงคือ ทั้ง 11 แบบใช้โครงเดียวกัน ต่างกันแค่ "อัปเกรด stage ไหน" บทนี้จะให้โครงกลางก่อน แล้วเสียบแต่ละแบบเข้าไปตามจุดที่มันแก้ พอเห็นแบบนี้แล้วคุณจะเลือกใช้ถูก และเขียนเองบน PostgreSQL + pgvector ได้ (ควรผ่าน Lv4 · RAG มาก่อน)

ทบทวน: RAG คืออะไร (สั้น ๆ)

RAG คือการให้ LLM ค้นเอกสารจริงมาก่อน แล้วค่อยตอบโดยอิงเอกสารนั้น — แทนที่จะเดาจากความจำ (ซึ่งอาจ hallucinate) README ของ rock_music_rag พูดไว้คมมาก: "instead of guessing what the model knows" ให้ไปดึงหน้า Wikipedia จริงมาตอบพร้อมอ้างอิง URL

โครงกลาง: naive RAG (ทุกแบบต่อยอดจากนี้)

RAG พื้นฐานมี 2 เฟส — เฟส index (เตรียมคลังไว้ล่วงหน้า) กับเฟส query (ตอนถาม):

เฟส INDEX (เตรียมล่วงหน้า) 📄 เอกสาร ✂️ chunk ตัดเป็นชิ้น 🔢 embed → เวกเตอร์ 🗄️ vector store pgvector / Chroma / Qdrant เฟส QUERY (ตอนถาม) ❓ คำถาม 🔢 embed 🔎 retrieve top-k ใกล้สุด 🤖 LLM → คำตอบ ตอบโดยอิง chunk ค้นจากคลังเดียวกัน
โครงกลางของ RAG ทุกแบบ — จำ 5 stage นี้ไว้: chunk · embed · store · retrieve · generate

แว่นหลัก: แต่ละแบบ "อัปเกรด stage ไหน"

ถ้ามอง 11 แบบผ่านคำถามเดียว — "naive RAG พังตรงไหน แล้วแบบนี้แก้ stage อะไร" — ทุกอย่างจะเข้าที่ทันที:

อัปเกรดที่ stageปัญหาของ naiveแบบที่แก้ (โปรเจกต์ในคลัง)
query / embedคำถามสั้นอยู่คนละที่กับคำตอบยาวใน embedding spaceHyDE (hyde_rag)
retrievesemantic search พลาดคำเฉพาะ/ชื่อตรงตัวBM25 / Hybrid (rock_music_rag, hybrid_rag_system)
store (สิ่งที่เก็บ)chunk แยกส่วน ไม่รู้ความสัมพันธ์ระหว่าง entityGraphRAG (graphrag_knowledge_system)
control flowค้นรอบเดียว ถ้าได้ context แย่ก็ตอบแย่Agentic / self-reflection / routing (agentic_rag_system, rag_agent_with_database_routing)
modalityทำได้แค่ข้อความ อ่านชาร์ต/ภาพไม่ได้Vision RAG (vision_rag)
generate (ความโปร่งใส)ตอบมาเฉย ๆ ตรวจสอบที่มาไม่ได้Reasoning RAG (reasoning_rag)

เจาะ 4 แบบที่ควรรู้จริง ๆ

① HyDE — แก้ที่ "สิ่งที่เอาไปค้น"

ปัญหาที่ hyde_rag จับได้: "a short question and a long detailed answer live in very different regions of the embedding space" — คำถามสั้นกับคำตอบยาวอยู่คนละโซนใน embedding พอเอาคำถามไปค้นตรง ๆ เลยมักพลาด HyDE เลย พลิกสัญญาณ: ให้ LLM แต่งคำตอบสมมติก่อน แล้วเอา คำตอบสมมติ ไปค้นแทน (เพราะมันอยู่ใกล้คำตอบจริงมากกว่า)

❓ คำถาม สั้น 🤖 LLM แต่งคำตอบสมมติ N ชุด (hypothetical) 🔢 embed + เฉลี่ย เวกเตอร์เดียว 🔎 retrieve แม่นขึ้น ใกล้คำตอบจริง
HyDE พลิกสัญญาณ: naive เอา "คำถาม" ไปค้น · HyDE เอา "คำตอบสมมติ" ไปค้น

② Hybrid / BM25 — แก้ที่ "วิธี retrieve"

semantic search (เวกเตอร์) เก่งเรื่องความหมายใกล้เคียง แต่พลาดคำเฉพาะ/ชื่อตรงตัว เช่น รหัสสินค้า rock_music_rag เลยใช้ BM25 (ค้นแบบ keyword) ส่วน hybrid_rag_system ไปไกลกว่า: index 2 ทางขนานกัน — knowledge graph (จับ entity + ความสัมพันธ์) + vector store (จับความหมาย) แล้ว fuse (หลอมรวม) ผลจากทั้งสองทางก่อนส่งให้ LLM

③ GraphRAG — แก้ที่ "สิ่งที่เก็บ"

naive RAG เก็บ chunk เป็นชิ้น ๆ ที่ไม่รู้จักกัน ตอบคำถามแบบ "สรุปภาพรวมทั้งเอกสาร" ได้แย่ graphrag_knowledge_system ทำตามเมโธดอโลยี GraphRAG ของ Microsoft: สกัด entity + ความสัมพันธ์ ออกมาเป็น knowledge graph (NetworkX) แล้วรองรับ 2 โหมด — Local Search (เจาะ entity เฉพาะ) กับ Global Search (สังเคราะห์ธีมข้ามทั้งกราฟ)

④ Agentic RAG — แก้ที่ "control flow"

นี่คือจุดบรรจบกับ HO-1: RAG ที่ไม่ค้นรอบเดียวจบ แต่มี agent คุม agentic_rag_system วน retrieve → เกรด context → rewrite แล้วค้นใหม่ (self-reflection loop ที่เราผ่าไปแล้วใน HO-1) ส่วน rag_agent_with_database_routing ใช้ router แบบ structured-output จัดคำถามไปคลัง Qdrant ที่ถูกตัว (สินค้า/ซัพพอร์ต/การเงิน) และถ้าไม่มีอะไรผ่านเกณฑ์ ก็ fallback ไปค้นเว็บ

💡

เห็น pattern ซ้ำจาก HO-1 ไหม? agentic RAG = RAG + agent loop — retrieval กลายเป็น "tool" ตัวหนึ่งที่ agent เรียกซ้ำได้ นี่คือเหตุผลที่หมวด Agents กับ RAG ทับกันเยอะ

map ลง PostgreSQL + pgvector (งานจริงของคุณ)

ในคลังใช้ ChromaDB/Qdrant/Milvus แต่ในงาน backend ที่มี PostgreSQL อยู่แล้ว คุณทำ naive RAG ได้ด้วย pgvector โดยไม่ต้องเพิ่ม vector DB แยกเลย:

-- เฟส index: เก็บ chunk + เวกเตอร์ไว้ในตารางเดียว
CREATE EXTENSION vector;
CREATE TABLE chunks (id bigserial, content text, embedding vector(1536));

-- เฟส query: ดึง top-5 chunk ที่ใกล้ที่สุด (<=> = cosine distance)
SELECT content FROM chunks
ORDER BY embedding <=> $1  -- $1 = เวกเตอร์ของคำถาม (<=> = cosine distance)
LIMIT 5;
  • Hybrid บน Postgres ก็ทำได้: ผสม pgvector (semantic) กับ full-text search (tsvector/keyword) แล้วรวมคะแนน — ได้ hybrid retrieval โดยไม่ต้องมี BM25 แยก
  • Agentic: ห่อ query ด้านบนเป็น "tool" ตัวหนึ่งใน agent loop (HO-1) แล้วให้ agent เกรด/ค้นซ้ำ
  • chunking สำคัญกว่าที่คิด: ตัด chunk ดี = retrieve ดี — เริ่มที่ ~500–800 token ต่อ chunk มี overlap เล็กน้อย แล้วค่อยจูน

เลือกใช้แบบไหน — เริ่มง่ายก่อนเสมอ

เริ่มที่ naive RAG ก่อนทุกครั้ง วัดผลว่าพังตรงไหน แล้วค่อยอัปเกรดเฉพาะ stage นั้น: retrieve พลาดคำเฉพาะ → เติม hybrid/BM25 · ต้องการภาพรวม/ความสัมพันธ์ → GraphRAG · context บางทีแย่ → agentic loop · ต้องอ่านชาร์ต/ภาพ → Vision RAG — อย่าเริ่มที่ GraphRAG+agentic ตั้งแต่แรกโดยไม่มีหลักฐานว่า naive พัง

⚠️

ระวัง: ยิ่งอัปเกรด ยิ่งแพง/ช้า — HyDE เรียก LLM เพิ่มก่อนค้น, agentic วนหลายรอบ, GraphRAG ต้องสกัด entity ตอน index (ช้าและเปลือง) เลือกเท่าที่ปัญหาจริงต้องการ และอย่าลืม วัดผล (eval) — ถ้าไม่วัด จะไม่รู้ว่าอัปเกรดแล้วดีขึ้นจริงหรือแค่ซับซ้อนขึ้น

🎯 แบบฝึกหัด
  1. เปิด README ของ rag_apps/hyde_rag/ แล้วอธิบายด้วยคำพูดตัวเองว่า "ทำไมการเอาคำตอบสมมติไปค้น ถึงแม่นกว่าเอาคำถามไปค้น"
  2. เทียบ hybrid_rag_system กับ graphrag_knowledge_system — ทั้งคู่ใช้ knowledge graph แต่ต่างกันตรงไหน (ใบ้: อันหนึ่งใช้ graph ร่วมกับ vector, อีกอันเน้น graph)
  3. นึกงานจริงในโปรเจกต์คุณที่ควรใช้ RAG (เช่น "ตอบคำถามจากคู่มือภายในบริษัท") แล้วเขียนว่าจะเริ่มด้วย naive + pgvector ยังไง และถ้ามันพลาด "รหัสสินค้า/ชื่อเฉพาะ" คุณจะอัปเกรด stage ไหน

เมื่อทำเสร็จ พิมพ์ /quiz HO-2 เพื่อทดสอบความเข้าใจ