RAG คืออะไร? ทำไมถึงสำคัญสำหรับ AI
RAG (Retrieval-Augmented Generation) เป็นเทคนิคที่เปลี่ยนวิธีการทำงานของ AI อย่างสิ้นเชิง จากที่เคยตอบคำถามจากความรู้ที่ถูก train มา กลายเป็น AI ที่สามารถค้นหาและใช้ข้อมูลล่าสุดของคุณในการตอบคำถามได้
RAG คืออะไร?
RAG ย่อมาจาก Retrieval-Augmented Generation หมายถึงการเสริมพลังให้ AI ด้วยการ "ดึงข้อมูล" (Retrieval) ที่เกี่ยวข้องมาก่อน แล้วจึง "สร้างคำตอบ" (Generation) จากข้อมูลนั้น
แนวคิดพื้นฐาน
Traditional LLM:
คำถาม → AI (ความรู้จาก Training) → คำตอบ
❌ ข้อมูลอาจล้าสมัย
❌ ไม่รู้จักข้อมูลเฉพาะของคุณ
RAG:
คำถาม → ค้นหาข้อมูลที่เกี่ยวข้อง → AI + ข้อมูล → คำตอบ
✅ ใช้ข้อมูลล่าสุด
✅ รู้จักข้อมูลของคุณ
✅ อ้างอิงแหล่งที่มาได้
สถาปัตยกรรม RAG
┌─────────────────────────────────────────────────────────────────┐
│ RAG Architecture │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ User │ │
│ │ Query │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────────┐ │
│ │ Embedding │────▶│ Vector Database │ │
│ │ Model │ │ (ค้นหาข้อมูล) │ │
│ └──────────────┘ └────────┬─────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Retrieved │ │
│ │ Documents (Top-K)│ │
│ └────────┬─────────┘ │
│ │ │
│ ┌────────────────────────┼────────────────────────┐ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ Prompt = Query + Retrieved Documents │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ LLM (GPT-4/Claude) │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────┬────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Generated Answer │ │
│ │ + Source │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
ทำไม RAG ถึงสำคัญ?
1. แก้ปัญหา Knowledge Cutoff
LLM ทั่วไปมีจุดตัดความรู้ (Knowledge Cutoff) หมายความว่าไม่รู้จักข้อมูลหลังจากวันที่ถูก train
# Without RAG
# Q: "ราคา Bitcoin วันนี้เท่าไหร่?"
# A: "ผมไม่มีข้อมูลราคาปัจจุบัน ข้อมูลของผมถูกตัดขาดที่..."
# With RAG
# System ค้นหาราคา Bitcoin ล่าสุดจาก database
# Q: "ราคา Bitcoin วันนี้เท่าไหร่?"
# A: "ราคา Bitcoin ณ เวลา 14:00 อยู่ที่ $42,350 (อ้างอิงจาก: CoinGecko API)"
2. ใช้ข้อมูลเฉพาะขององค์กร
# ข้อมูลภายในบริษัทที่ AI ทั่วไปไม่รู้จัก
internal_docs = [
"นโยบายวันลาของบริษัท 2025",
"Product Roadmap Q1 2025",
"Employee Handbook",
"Technical Documentation"
]
# RAG ทำให้ AI ตอบคำถามเกี่ยวกับข้อมูลเหล่านี้ได้
3. Transparency & Traceability
RAG สามารถอ้างอิงแหล่งที่มาได้ ทำให้ตรวจสอบความถูกต้องได้
{
"answer": "พนักงานมีสิทธิ์ลาพักร้อน 15 วันต่อปี",
"sources": [
{
"document": "Employee Handbook 2025",
"page": 23,
"relevance_score": 0.95
}
]
}
4. Cost-Effective
เมื่อเทียบกับ Fine-tuning:
| Aspect | RAG | Fine-Tuning |
|---|---|---|
| ต้นทุนเริ่มต้น | ต่ำ | สูง |
| Update ข้อมูล | ทันที | ต้อง re-train |
| เวลาในการ deploy | นาที | ชั่วโมง-วัน |
| Technical complexity | ปานกลาง | สูง |
การทำงานของ RAG ทีละขั้นตอน
Step 1: Document Ingestion (เตรียมข้อมูล)
from langchain.document_loaders import PyPDFLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
class DocumentProcessor:
def __init__(self):
self.text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
length_function=len,
separators=["\n\n", "\n", " ", ""]
)
def load_documents(self, file_paths: list) -> list:
"""โหลดเอกสารจากหลายแหล่ง"""
documents = []
for path in file_paths:
if path.endswith('.pdf'):
loader = PyPDFLoader(path)
elif path.endswith('.txt'):
loader = TextLoader(path)
else:
continue
docs = loader.load()
documents.extend(docs)
return documents
def split_documents(self, documents: list) -> list:
"""แบ่งเอกสารเป็น chunks"""
chunks = self.text_splitter.split_documents(documents)
# เพิ่ม metadata
for i, chunk in enumerate(chunks):
chunk.metadata['chunk_id'] = i
chunk.metadata['chunk_size'] = len(chunk.page_content)
return chunks
Step 2: Embedding (แปลงเป็น Vector)
from langchain.embeddings import OpenAIEmbeddings
import numpy as np
class EmbeddingService:
def __init__(self, model="text-embedding-3-small"):
self.embeddings = OpenAIEmbeddings(model=model)
def embed_documents(self, texts: list) -> list:
"""แปลง texts เป็น vectors"""
vectors = self.embeddings.embed_documents(texts)
return vectors
def embed_query(self, query: str) -> list:
"""แปลง query เป็น vector"""
return self.embeddings.embed_query(query)
def compute_similarity(self, vec1: list, vec2: list) -> float:
"""คำนวณ cosine similarity"""
return np.dot(vec1, vec2) / (
np.linalg.norm(vec1) * np.linalg.norm(vec2)
)
Step 3: Vector Storage (เก็บใน Vector Database)
from langchain.vectorstores import Chroma, Pinecone
import chromadb
class VectorStore:
def __init__(self, store_type="chroma"):
self.store_type = store_type
if store_type == "chroma":
self.client = chromadb.Client()
self.collection = self.client.create_collection(
name="knowledge_base",
metadata={"hnsw:space": "cosine"}
)
def add_documents(self, chunks: list, embeddings: list):
"""เพิ่มเอกสารเข้า vector store"""
ids = [f"doc_{i}" for i in range(len(chunks))]
documents = [chunk.page_content for chunk in chunks]
metadatas = [chunk.metadata for chunk in chunks]
self.collection.add(
ids=ids,
embeddings=embeddings,
documents=documents,
metadatas=metadatas
)
def search(self, query_embedding: list, top_k: int = 5) -> list:
"""ค้นหาเอกสารที่เกี่ยวข้อง"""
results = self.collection.query(
query_embeddings=[query_embedding],
n_results=top_k,
include=["documents", "metadatas", "distances"]
)
return results
Step 4: Retrieval (ค้นหาข้อมูล)
class Retriever:
def __init__(self, vector_store, embedding_service):
self.vector_store = vector_store
self.embedding_service = embedding_service
def retrieve(self, query: str, top_k: int = 5) -> list:
"""ค้นหาเอกสารที่เกี่ยวข้องกับ query"""
# 1. แปลง query เป็น embedding
query_embedding = self.embedding_service.embed_query(query)
# 2. ค้นหาใน vector store
results = self.vector_store.search(query_embedding, top_k)
# 3. จัดรูปแบบผลลัพธ์
retrieved_docs = []
for i, doc in enumerate(results['documents'][0]):
retrieved_docs.append({
'content': doc,
'metadata': results['metadatas'][0][i],
'distance': results['distances'][0][i],
'relevance_score': 1 - results['distances'][0][i]
})
return retrieved_docs
Step 5: Generation (สร้างคำตอบ)
from openai import OpenAI
class RAGGenerator:
def __init__(self):
self.client = OpenAI()
def generate(
self,
query: str,
retrieved_docs: list,
model: str = "gpt-4"
) -> dict:
"""สร้างคำตอบจาก query และ retrieved documents"""
# สร้าง context จาก retrieved documents
context = "\n\n---\n\n".join([
f"Document {i+1} (relevance: {doc['relevance_score']:.2f}):\n{doc['content']}"
for i, doc in enumerate(retrieved_docs)
])
# สร้าง prompt
system_prompt = """คุณเป็น AI assistant ที่ตอบคำถามโดยใช้ข้อมูลที่ให้มา
กฎ:
1. ตอบเฉพาะจากข้อมูลที่ให้มาเท่านั้น
2. ถ้าไม่มีข้อมูลเพียงพอ ให้บอกว่าไม่พบข้อมูล
3. อ้างอิงแหล่งที่มาเสมอ
4. ตอบเป็นภาษาไทย"""
user_prompt = f"""ข้อมูลอ้างอิง:
{context}
คำถาม: {query}
กรุณาตอบคำถามโดยใช้ข้อมูลอ้างอิงด้านบน พร้อมระบุแหล่งที่มา"""
response = self.client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.3
)
return {
"answer": response.choices[0].message.content,
"sources": [doc['metadata'] for doc in retrieved_docs],
"model": model
}
RAG Pipeline แบบครบวงจร
class RAGPipeline:
"""Complete RAG Pipeline"""
def __init__(self):
self.doc_processor = DocumentProcessor()
self.embedding_service = EmbeddingService()
self.vector_store = VectorStore()
self.retriever = None
self.generator = RAGGenerator()
def ingest(self, file_paths: list):
"""Ingest documents into the system"""
# 1. โหลดและแบ่ง documents
documents = self.doc_processor.load_documents(file_paths)
chunks = self.doc_processor.split_documents(documents)
print(f"Loaded {len(documents)} documents, split into {len(chunks)} chunks")
# 2. สร้าง embeddings
texts = [chunk.page_content for chunk in chunks]
embeddings = self.embedding_service.embed_documents(texts)
# 3. เก็บใน vector store
self.vector_store.add_documents(chunks, embeddings)
# 4. สร้าง retriever
self.retriever = Retriever(self.vector_store, self.embedding_service)
print("Ingestion complete!")
def query(self, question: str, top_k: int = 5) -> dict:
"""Query the RAG system"""
if not self.retriever:
raise ValueError("Please ingest documents first")
# 1. Retrieve relevant documents
retrieved_docs = self.retriever.retrieve(question, top_k)
# 2. Generate answer
result = self.generator.generate(question, retrieved_docs)
return result
# การใช้งาน
rag = RAGPipeline()
# Ingest documents
rag.ingest([
"documents/employee_handbook.pdf",
"documents/company_policies.pdf",
"documents/product_guide.pdf"
])
# Query
result = rag.query("พนักงานสามารถลาพักร้อนได้กี่วันต่อปี?")
print(result['answer'])
print("Sources:", result['sources'])
Advanced RAG Techniques
1. Hybrid Search (ค้นหาแบบผสม)
รวม Semantic Search และ Keyword Search เพื่อผลลัพธ์ที่ดีขึ้น
from rank_bm25 import BM25Okapi
import numpy as np
class HybridRetriever:
def __init__(self, vector_store, documents):
self.vector_store = vector_store
self.documents = documents
# BM25 for keyword search
tokenized_docs = [doc.split() for doc in documents]
self.bm25 = BM25Okapi(tokenized_docs)
def hybrid_search(
self,
query: str,
query_embedding: list,
top_k: int = 5,
alpha: float = 0.5 # weight between vector and keyword
) -> list:
# Vector search
vector_results = self.vector_store.search(query_embedding, top_k * 2)
# BM25 keyword search
tokenized_query = query.split()
bm25_scores = self.bm25.get_scores(tokenized_query)
bm25_top_k = np.argsort(bm25_scores)[-top_k * 2:][::-1]
# Combine scores with RRF (Reciprocal Rank Fusion)
combined_scores = {}
for rank, idx in enumerate(vector_results['ids'][0]):
combined_scores[idx] = combined_scores.get(idx, 0) + \
alpha * (1 / (rank + 60))
for rank, idx in enumerate(bm25_top_k):
doc_id = f"doc_{idx}"
combined_scores[doc_id] = combined_scores.get(doc_id, 0) + \
(1 - alpha) * (1 / (rank + 60))
# Sort by combined score
sorted_results = sorted(
combined_scores.items(),
key=lambda x: x[1],
reverse=True
)[:top_k]
return sorted_results
2. Re-ranking
ใช้ Cross-encoder เพื่อจัดลำดับผลลัพธ์ใหม่
from sentence_transformers import CrossEncoder
class Reranker:
def __init__(self, model_name="cross-encoder/ms-marco-MiniLM-L-12-v2"):
self.model = CrossEncoder(model_name)
def rerank(
self,
query: str,
documents: list,
top_k: int = 5
) -> list:
"""Rerank documents using cross-encoder"""
# Create query-document pairs
pairs = [[query, doc['content']] for doc in documents]
# Get scores
scores = self.model.predict(pairs)
# Sort by score
ranked_indices = np.argsort(scores)[::-1][:top_k]
reranked_docs = []
for idx in ranked_indices:
doc = documents[idx].copy()
doc['rerank_score'] = float(scores[idx])
reranked_docs.append(doc)
return reranked_docs
3. Query Expansion
สร้างหลาย query จาก query เดียวเพื่อค้นหาได้ครอบคลุมขึ้น
class QueryExpander:
def __init__(self):
self.client = OpenAI()
def expand_query(self, original_query: str, n_expansions: int = 3) -> list:
"""Generate multiple queries from original query"""
response = self.client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": f"""Generate {n_expansions} alternative queries
that could help find relevant information for the original query.
Return as JSON array of strings."""
},
{"role": "user", "content": original_query}
]
)
expanded_queries = json.loads(response.choices[0].message.content)
return [original_query] + expanded_queries
4. Contextual Compression
บีบอัด context ให้กระชับก่อนส่งให้ LLM
class ContextCompressor:
def __init__(self):
self.client = OpenAI()
def compress(
self,
query: str,
documents: list,
max_tokens: int = 2000
) -> str:
"""Compress retrieved documents to essential information"""
combined_docs = "\n\n".join([doc['content'] for doc in documents])
response = self.client.chat.completions.create(
model="gpt-4",
messages=[
{
"role": "system",
"content": f"""Extract only the information relevant to
answering the query. Keep it under {max_tokens} tokens.
Preserve important facts and details."""
},
{
"role": "user",
"content": f"Query: {query}\n\nDocuments:\n{combined_docs}"
}
]
)
return response.choices[0].message.content
Vector Databases สำหรับ RAG
เปรียบเทียบ Vector Databases
| Database | Open Source | Managed | Best For |
|---|---|---|---|
| Pinecone | No | Yes | Production, Scale |
| Weaviate | Yes | Yes | Hybrid Search |
| Chroma | Yes | No | Prototyping |
| Qdrant | Yes | Yes | Performance |
| Milvus | Yes | Yes | Large Scale |
| pgvector | Yes | - | PostgreSQL users |
อ่านรายละเอียดเพิ่มเติมได้ที่ Vector Database สำหรับ AI
Use Cases ของ RAG
1. Customer Support Chatbot
# Customer support with RAG
support_rag = RAGPipeline()
support_rag.ingest([
"docs/faq.pdf",
"docs/product_manual.pdf",
"docs/troubleshooting.pdf"
])
# Handle customer query
def handle_support_query(query: str):
result = support_rag.query(query)
# Check confidence
if result['sources'][0]['relevance_score'] < 0.7:
return {
"answer": "ขออภัย ไม่พบข้อมูลที่เกี่ยวข้อง กรุณาติดต่อทีม support",
"escalate": True
}
return result
2. Legal Document Analysis
# Legal RAG system
legal_rag = RAGPipeline()
legal_rag.ingest([
"contracts/*.pdf",
"legal_terms/*.pdf",
"case_studies/*.pdf"
])
# Find relevant clauses
def find_relevant_clauses(contract_type: str, topic: str):
query = f"ข้อกำหนดเกี่ยวกับ {topic} ใน {contract_type}"
return legal_rag.query(query, top_k=10)
3. Internal Knowledge Base
# Company knowledge base
kb_rag = RAGPipeline()
kb_rag.ingest([
"hr/policies/*.pdf",
"it/guides/*.pdf",
"operations/sop/*.pdf"
])
# Employee assistant
def ask_hr_question(question: str, employee_id: str):
result = kb_rag.query(question)
# Log query for analytics
log_query(employee_id, question, result)
return result
สรุป
RAG เป็นเทคนิคที่ทรงพลังในการทำให้ AI ฉลาดขึ้นและใช้งานได้จริงในองค์กร โดยไม่ต้อง fine-tune model ใหม่ การเลือกใช้ RAG ที่เหมาะสมจะช่วยให้คุณสร้าง AI application ที่แม่นยำ อัปเดตได้ง่าย และตรวจสอบได้
อ่านบทความที่เกี่ยวข้อง
- Fine-Tuning และ RAG: เทคนิคขั้นสูงในการสอน AI - เปรียบเทียบ RAG กับ Fine-Tuning
- Vector Database สำหรับ AI - เจาะลึก Vector Database
- สร้าง AI Chatbot สำหรับธุรกิจ - นำ RAG ไปใช้กับ Chatbot
พร้อมเริ่มสร้าง RAG System แล้วหรือยัง?
เรียนรู้เพิ่มเติมและรับคำปรึกษาจากทีมผู้เชี่ยวชาญของเราได้ที่ AI Unlocked เราพร้อมช่วยคุณออกแบบและพัฒนา RAG System ที่ตอบโจทย์ธุรกิจของคุณ
เขียนโดย
AI Unlocked Team
บทความอื่นๆ ที่น่าสนใจ
ระบบ AI ทำงานแทน คืออะไร? ออกแบบยังไงให้ช่วยได้จริง ไม่ใช่แค่บอทคุยเก่ง
ระบบ AI ทำงานแทน ไม่ใช่แชทบอท อธิบายส่วนประกอบ ตัวอย่าง Grok Bot, Hermes Bot, Claude Cowork, ChatGPT Work และวิธีเริ่มจากงานซ้ำในธุรกิจไทย
ช่องสอน AI ดี ๆ ปี 2026 — คัดยูทูบภาษาไทยและสากลแบบใช้เป็น ไม่ใช่ตามยอดวิว
ช่องสอน AI ดี ๆ ต้องอัปเดตเครื่องมือใหม่ สอนลงมือ และไม่ขายความกลัว บทความนี้ให้เกณฑ์คัดคลิป พร้อมกลุ่มช่องภาษาไทยและสากลที่เรียนต่อได้จริง
แนะนำที่เรียน AI เชียงใหม่ ปี 2026 — เลือกตามเป้าหมาย ไม่ใช่ตามโฆษณา
แนะนำที่เรียน AI เชียงใหม่แบบตัดสินใจได้จริง แยกคอร์สออนไลน์ มหาวิทยาลัย เวิร์กช็อป และติวตัวต่อตัว พร้อมตารางเลือกตามงบ เวลา และอาชีพ
