RAG
AI
LLM
Vector Database
Integration
Advanced

RAG คืออะไร? ทำไมถึงสำคัญสำหรับ AI

เจาะลึก RAG (Retrieval-Augmented Generation) เทคนิคที่ทำให้ AI ตอบคำถามได้แม่นยำยิ่งขึ้นด้วยการดึงข้อมูลจากแหล่งความรู้ของคุณ พร้อมตัวอย่างการใช้งานจริง

AI Unlocked Team
27/01/2568
RAG คืออะไร? ทำไมถึงสำคัญสำหรับ AI

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:

AspectRAGFine-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

DatabaseOpen SourceManagedBest For
PineconeNoYesProduction, Scale
WeaviateYesYesHybrid Search
ChromaYesNoPrototyping
QdrantYesYesPerformance
MilvusYesYesLarge Scale
pgvectorYes-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
# 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 ที่แม่นยำ อัปเดตได้ง่าย และตรวจสอบได้


อ่านบทความที่เกี่ยวข้อง


พร้อมเริ่มสร้าง RAG System แล้วหรือยัง?

เรียนรู้เพิ่มเติมและรับคำปรึกษาจากทีมผู้เชี่ยวชาญของเราได้ที่ AI Unlocked เราพร้อมช่วยคุณออกแบบและพัฒนา RAG System ที่ตอบโจทย์ธุรกิจของคุณ


เขียนโดย

AI Unlocked Team