RAG và LLM năm 2026: Retrieval-Augmented Generation cho phỏng vấn Data Science

Retrieval-Augmented Generation (RAG) giải thích cho phỏng vấn data science năm 2026. Bao gồm cơ sở dữ liệu vector, chiến lược chunking, mô hình embedding, agentic RAG, Graph RAG và kiến trúc pipeline sẵn sàng cho sản xuất.

Kiến trúc pipeline RAG retrieval-augmented generation với cơ sở dữ liệu vector và LLM

Retrieval-Augmented Generation (RAG) đã trở thành kiến trúc tiêu chuẩn để neo các đầu ra của LLM vào dữ liệu thực tế và cập nhật. Trong các buổi phỏng vấn data science và kỹ thuật AI năm 2026, câu hỏi về RAG giờ đây xuất hiện song song với các chủ đề ML truyền thống, kiểm tra cả tư duy thiết kế hệ thống lẫn kỹ năng triển khai thực hành.

RAG Là Gì Trong Một Câu?

Retrieval-Augmented Generation kết hợp một hệ thống truy xuất (tìm kiếm vector trên cơ sở tri thức) với một bộ sinh LLM, để mô hình trả lời dựa trên tài liệu thực thay vì dựa vào dữ liệu huấn luyện đã ghi nhớ.

Pipeline RAG Hoạt Động Từ Đầu Đến Cuối Như Thế Nào

Một hệ thống RAG vận hành theo hai pha: pha nạp dữ liệu (ingestion) ngoại tuyến xây dựng cơ sở tri thức, và pha truy vấn trực tuyến truy xuất ngữ cảnh liên quan rồi sinh câu trả lời.

Trong quá trình nạp dữ liệu, tài liệu thô đi qua làm sạch, chia đoạn (chunking) và nhúng (embedding) trước khi lưu vào cơ sở dữ liệu vector. Trong quá trình suy luận, truy vấn của người dùng theo cùng đường nhúng đó, và tìm kiếm láng giềng gần nhất truy xuất các đoạn liên quan nhất. Những đoạn này trở thành một phần của prompt LLM, neo câu trả lời được sinh ra vào tài liệu nguồn.

python
# rag_pipeline.py
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough

# Offline: ingest documents into the vector store
def build_index(documents: list[str]) -> Chroma:
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=512,       # tokens per chunk
        chunk_overlap=64,     # overlap preserves context at boundaries
        separators=["\n\n", "\n", ". ", " "]
    )
    chunks = splitter.create_documents(documents)
    embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
    return Chroma.from_documents(chunks, embeddings)

# Online: retrieve + generate
def query(vectorstore: Chroma, question: str) -> str:
    retriever = vectorstore.as_retriever(
        search_type="mmr",    # Maximal Marginal Relevance for diversity
        search_kwargs={"k": 5, "fetch_k": 20}
    )
    prompt = ChatPromptTemplate.from_template(
        "Answer based on this context only:\n{context}\n\nQuestion: {question}"
    )
    chain = (
        {"context": retriever, "question": RunnablePassthrough()}
        | prompt
        | ChatOpenAI(model="gpt-4o", temperature=0)
    )
    return chain.invoke(question).content

Pipeline này bao quát vòng lặp cốt lõi của RAG: chia đoạn, nhúng, lưu trữ, truy xuất, sinh. Tham số search_type="mmr" đảm bảo các đoạn được truy xuất vừa liên quan vừa đa dạng, giảm dư thừa trong cửa sổ ngữ cảnh.

Chiến Lược Chunking Thực Sự Quan Trọng

Chunking quyết định chất lượng truy xuất hơn bất kỳ thành phần nào khác. Chunking kém nghĩa là bộ truy xuất trả về các mảnh hoặc thiếu ngữ cảnh hoặc làm loãng tín hiệu bằng nội dung không liên quan.

Ba cách tiếp cận chunking chiếm ưu thế trong các hệ thống sản xuất năm 2026:

Chunking kích thước cố định chia văn bản tại một số lượng token đã định (thường là 256-512 token) với phần chồng lấn (overlap). Đơn giản để triển khai, nhưng cắt câu và ý tưởng ở giữa chừng.

Chunking ngữ nghĩa phát hiện ranh giới chủ đề bằng cách đo độ tương đồng nhúng giữa các câu liên tiếp. Khi độ tương đồng giảm xuống dưới ngưỡng, một đoạn mới bắt đầu. Mỗi đoạn mang một ý tưởng mạch lạc thay vì một lát cắt văn bản tùy ý.

Late chunking áp dụng mô hình transformer cho toàn bộ tài liệu trước, tạo ra các nhúng token theo ngữ cảnh, rồi mới chia thành đoạn. Cách này giữ lại các phụ thuộc tầm xa mà chunking truyền thống phá hủy.

python
# semantic_chunking.py
import numpy as np
from sentence_transformers import SentenceTransformer

def semantic_chunk(text: str, threshold: float = 0.3) -> list[str]:
    """Split text where semantic similarity drops below threshold."""
    model = SentenceTransformer("all-MiniLM-L6-v2")
    sentences = text.split(". ")
    embeddings = model.encode(sentences)

    chunks, current_chunk = [], [sentences[0]]

    for i in range(1, len(sentences)):
        # Cosine similarity between consecutive sentences
        sim = np.dot(embeddings[i-1], embeddings[i]) / (
            np.linalg.norm(embeddings[i-1]) * np.linalg.norm(embeddings[i])
        )
        if sim < threshold:       # topic shift detected
            chunks.append(". ".join(current_chunk))
            current_chunk = [sentences[i]]
        else:
            current_chunk.append(sentences[i])

    chunks.append(". ".join(current_chunk))  # final chunk
    return chunks

Hiểu biết phỏng vấn then chốt: kích thước đoạn là một sự đánh đổi giữa độ chính xác và độ bao phủ (precision-recall). Đoạn nhỏ (100 token) cải thiện độ chính xác truy xuất nhưng phân mảnh ngữ cảnh. Đoạn lớn (1000 token) giữ ngữ cảnh nhưng làm loãng tính đặc thù của nhúng. Hầu hết hệ thống sản xuất dừng ở 256-512 token với phần chồng lấn 10-20%.

Cơ Sở Dữ Liệu Vector và Mô Hình Embedding Trong Sản Xuất

Cơ sở dữ liệu vector lưu trữ các nhúng và hỗ trợ tìm kiếm láng giềng gần nhất xấp xỉ (ANN) nhanh chóng. Việc chọn đúng tổ hợp mô hình embedding và cơ sở dữ liệu vector ảnh hưởng trực tiếp đến độ trễ và độ chính xác truy xuất.

Các mô hình embedding năm 2026 đã hội tụ quanh một vài lựa chọn hiệu năng cao. text-embedding-3-large của OpenAI (3072 chiều) và các lựa chọn mã nguồn mở như bge-m3 của BAAI hay embed-v4 của Cohere cung cấp khả năng truy xuất đa ngôn ngữ mạnh mẽ. Bảng xếp hạng MTEB vẫn là chuẩn benchmark để so sánh chất lượng embedding.

Các cơ sở dữ liệu vector như Pinecone, Weaviate, Milvus, Qdrant và pgvector mỗi loại có những đánh đổi khác nhau:

| Cơ sở dữ liệu | Lập chỉ mục | Có quản lý | Thế mạnh | |----------|----------|---------|----------| | Pinecone | Độc quyền | Có | Đơn giản, mở rộng serverless | | Weaviate | HNSW | Có/Tự host | Tìm kiếm lai (vector + BM25) | | Milvus | IVF, HNSW | Có/Tự host | Tập dữ liệu quy mô tỷ | | Qdrant | HNSW | Có/Tự host | Lọc + lưu trữ payload | | pgvector | IVF, HNSW | Tự host | Tích hợp PostgreSQL |

Đối với phần thảo luận phỏng vấn, điểm then chốt là hiểu thuật toán HNSW (Hierarchical Navigable Small World): nó xây dựng một đồ thị nhiều lớp trong đó mỗi nút kết nối với các láng giềng gần nhất, cho phép tìm kiếm O(log n) với cái giá là sử dụng bộ nhớ cao hơn.

Sẵn sàng chinh phục phỏng vấn Data Science & ML?

Luyện tập với mô phỏng tương tác, flashcards và bài kiểm tra kỹ thuật.

Truy Xuất Lai: Kết Hợp Tìm Kiếm Dày Đặc và Thưa

Tìm kiếm vector thuần túy thất bại với khớp từ khóa chính xác và các thuật ngữ hiếm. Tìm kiếm từ vựng thuần túy (BM25) bỏ lỡ độ tương đồng ngữ nghĩa. Truy xuất lai kết hợp cả hai, và năm 2026 đây là mặc định cho các hệ thống RAG sản xuất.

Mẫu hình tiêu chuẩn dùng Reciprocal Rank Fusion (RRF) để hợp nhất kết quả đã xếp hạng từ cả hai bộ truy xuất:

python
# hybrid_retrieval.py
from rank_bm25 import BM25Okapi
import numpy as np

def reciprocal_rank_fusion(
    dense_results: list[str],
    sparse_results: list[str],
    k: int = 60
) -> list[str]:
    """Merge dense (vector) and sparse (BM25) results using RRF."""
    scores: dict[str, float] = {}

    for rank, doc_id in enumerate(dense_results):
        scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)

    for rank, doc_id in enumerate(sparse_results):
        scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)

    # Sort by combined RRF score, highest first
    return sorted(scores.keys(), key=lambda d: scores[d], reverse=True)

Truy xuất lai giải quyết vấn đề "không khớp từ vựng" khi người dùng hỏi về "hủy đăng ký" nhưng tài liệu liên quan dùng cụm "chính sách chấm dứt tài khoản". BM25 bắt được sự trùng lặp thuật ngữ chính xác trong khi tìm kiếm vector nắm bắt mối quan hệ ngữ nghĩa.

Reranking: Bộ Lọc Giai Đoạn Hai

Truy xuất trả về các ứng viên. Reranking sắp xếp chúng theo độ liên quan thực sự. Các bộ rerank kiểu cross-encoder như Cohere Rerank hay bge-reranker-v2.5-gemma2-lightweight chấm điểm từng cặp truy vấn-tài liệu cùng nhau, tạo ra điểm liên quan chính xác hơn nhiều so với độ tương đồng bi-encoder.

Pipeline truy xuất hai giai đoạn — recall giai đoạn đầu rộng (top 50-100 ứng viên qua vector + BM25), rồi rerank chính xác (top 5-10 cho prompt) — là chuẩn trong sản xuất. Cách này giữ độ trễ ở mức quản lý được: giai đoạn đầu dùng tìm kiếm ANN nhanh, còn cross-encoder tốn kém chỉ xử lý một tập ứng viên nhỏ.

Hiểu Biết Phỏng Vấn Về Reranking

Cross-encoder chính xác hơn bi-encoder vì chúng xử lý truy vấn và tài liệu cùng nhau qua tất cả các lớp transformer. Bi-encoder nhúng chúng độc lập, làm mất các tín hiệu tương tác tinh tế. Sự đánh đổi là tốc độ: cross-encoder không thể được lập chỉ mục trước.

Agentic RAG: Vượt Ra Ngoài Truy Xuất Một Lần

RAG ngây thơ truy xuất một lần rồi sinh. Agentic RAG coi LLM như một tác nhân suy luận, quyết định khi nào truy xuất, truy xuất gì, và liệu ngữ cảnh truy xuất đã đủ hay chưa.

Năm 2026, agentic RAG là mẫu hình chủ đạo cho các truy vấn phức tạp đòi hỏi suy luận nhiều bước. Tác nhân có thể:

  • Tự đánh giá: Xác định liệu tài liệu truy xuất có trả lời được câu hỏi
  • Truy vấn lại: Diễn đạt lại truy vấn tìm kiếm nếu kết quả ban đầu chưa đủ
  • Định tuyến (routing): Chọn giữa các nguồn tri thức khác nhau (vector DB, cơ sở dữ liệu SQL, API)
  • Xác minh: Đối chiếu chéo sự kiện qua nhiều đoạn được truy xuất
python
# agentic_rag.py
from langgraph.graph import StateGraph, END
from typing import TypedDict

class RAGState(TypedDict):
    question: str
    documents: list[str]
    generation: str
    retries: int

def retrieve(state: RAGState) -> RAGState:
    """Retrieve documents from vector store."""
    docs = vectorstore.similarity_search(state["question"], k=5)
    return {"documents": [d.page_content for d in docs]}

def grade_documents(state: RAGState) -> str:
    """Decide if documents are relevant enough to answer."""
    prompt = f"Are these documents relevant to: {state['question']}?\n"
    prompt += "\n".join(state["documents"])
    relevance = llm.invoke(prompt)  # returns 'relevant' or 'not_relevant'
    return "generate" if "relevant" in relevance.content else "rewrite"

def rewrite_query(state: RAGState) -> RAGState:
    """Reformulate the query for better retrieval."""
    new_query = llm.invoke(
        f"Rewrite this query for better search results: {state['question']}"
    )
    return {"question": new_query.content, "retries": state["retries"] + 1}

# Build the agent graph
workflow = StateGraph(RAGState)
workflow.add_node("retrieve", retrieve)
workflow.add_node("grade", grade_documents)      # conditional routing
workflow.add_node("rewrite", rewrite_query)
workflow.add_node("generate", generate_answer)

workflow.set_entry_point("retrieve")
workflow.add_edge("retrieve", "grade")
workflow.add_conditional_edges("grade", grade_documents,
    {"generate": "generate", "rewrite": "rewrite"})
workflow.add_edge("rewrite", "retrieve")          # retry loop
workflow.add_edge("generate", END)

Mẫu hình này — truy xuất, chấm điểm, tùy chọn diễn đạt lại và thử lại — được gọi là Corrective RAG (CRAG). Framework LangGraph mô hình hóa quy trình như một đồ thị có hướng có chu trình với phân nhánh điều kiện, giúp dễ dàng thêm các bước xác minh, điểm kiểm tra human-in-the-loop, hay định tuyến đa nguồn.

Graph RAG: Truy Xuất Tri Thức Có Cấu Trúc

Graph RAG trích xuất các thực thể và mối quan hệ từ tài liệu vào một đồ thị tri thức, rồi truy vấn cả đồ thị lẫn kho vector. Kiến trúc này giảm ảo giác trên các truy vấn dữ kiện bằng cách neo câu trả lời vào các mối quan hệ thực thể tường minh thay vì độ tương đồng văn bản phi cấu trúc.

Pipeline nạp dữ liệu trích xuất các bộ ba (chủ thể, vị từ, đối tượng) từ mỗi đoạn tài liệu. Tại thời điểm truy vấn, hệ thống xác định các thực thể liên quan trong câu hỏi, duyệt đồ thị tri thức để tìm các sự kiện kết nối, và kết hợp ngữ cảnh truy xuất từ đồ thị với các đoạn truy xuất bằng vector.

Graph RAG xuất sắc với các câu hỏi suy luận nhiều bước (multi-hop) như "Đội nào dẫn dắt dự án sử dụng framework được nhắc đến trong tài liệu X?" — những truy vấn đòi hỏi kết nối sự kiện qua nhiều tài liệu. Tìm kiếm vector thuần túy gặp khó ở đây vì không một đoạn đơn lẻ nào chứa câu trả lời hoàn chỉnh.

Sự Đánh Đổi Của Graph RAG

Graph RAG cải thiện đáng kể độ chính xác dữ kiện (giảm tới 40% ảo giác trên các truy vấn nặng thực thể) nhưng đòi hỏi một pipeline trích xuất thực thể trưởng thành. Trích xuất nhiễu tạo ra đồ thị nhiễu, có thể làm kết quả tệ hơn cả RAG ngây thơ.

Đánh Giá Hệ Thống RAG: Những Chỉ Số Quan Trọng

Đánh giá RAG chia thành các chỉ số truy xuất và các chỉ số sinh. Cả hai phải được đo độc lập để chẩn đoán lỗi.

Chỉ số truy xuất:

  • Recall@k: Tài liệu liên quan có xuất hiện trong top k kết quả không?
  • MRR (Mean Reciprocal Rank): Kết quả liên quan đầu tiên được xếp hạng cao đến đâu?
  • NDCG: Thứ hạng có khớp với thứ tự liên quan lý tưởng không?

Chỉ số sinh:

  • Faithfulness (độ trung thực): Câu trả lời có chỉ dùng thông tin từ ngữ cảnh truy xuất không? (Đo ảo giác)
  • Độ liên quan của câu trả lời: Câu trả lời có giải quyết câu hỏi gốc không?
  • Độ chính xác ngữ cảnh: Các đoạn truy xuất có thực sự được dùng trong câu trả lời không?

Các framework như RagasDeepEval tự động hóa các đánh giá này bằng mẫu hình LLM-làm-giám-khảo (LLM-as-judge). Các câu hỏi phỏng vấn data science hàng đầu ngày càng bao gồm thiết kế đánh giá RAG — hãy chuẩn bị giải thích cách đo lường xem một hệ thống RAG có hoạt động đúng hay không.

Các Chế Độ Lỗi Trong Sản Xuất và Gỡ Lỗi

Hệ thống RAG thất bại theo những cách có thể dự đoán. Biết các mẫu hình này là thiết yếu cho cả phỏng vấn lẫn triển khai thực tế.

Ô nhiễm cửa sổ ngữ cảnh xảy ra khi quá nhiều đoạn truy xuất làm loãng tín hiệu liên quan. LLM nhận 10 đoạn nhưng chỉ 2 chứa thông tin hữu ích. Cách khắc phục: dùng bộ rerank để lọc, và giảm top-k từ bộ truy xuất.

Tạo phẩm chunking xảy ra khi việc chia kích thước cố định cắt câu, bảng, hay khối mã ở giữa phần tử. Đoạn được truy xuất không hoàn chỉnh về cú pháp và vô dụng về ngữ nghĩa. Chunking ngữ nghĩa hay chia có nhận biết tài liệu (tôn trọng tiêu đề, đoạn văn, code fence) giải quyết điều này.

Trôi dạt embedding (embedding drift) xuất hiện khi mô hình embedding được cập nhật nhưng kho vector vẫn chứa các nhúng từ mô hình cũ. Các truy vấn được mã hóa bằng mô hình mới tìm kiếm trong một không gian vector do mô hình cũ xây dựng, làm giảm chất lượng truy xuất. Giải pháp: nhúng lại toàn bộ kho ngữ liệu sau mỗi lần đổi mô hình.

Chỉ mục lỗi thời cung cấp thông tin cũ vì pipeline nạp dữ liệu tụt lại sau các cập nhật tài liệu. Trong các hệ thống machine learning, điều này tương tự lệch huấn luyện-phục vụ (training-serving skew) — hệ thống truy xuất thấy một phân bố dữ liệu khác với cái tồn tại trong sản xuất.

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Kết Luận

  • RAG kết hợp truy xuất (tìm kiếm vector trên cơ sở tri thức) với sinh LLM để tạo ra câu trả lời có cơ sở dữ kiện mà không cần huấn luyện lại mô hình
  • Chiến lược chunking có tác động lớn nhất đến chất lượng truy xuất — chunking ngữ nghĩa và late chunking vượt trội hơn chia kích thước cố định trong hầu hết trường hợp sử dụng
  • Truy xuất lai (vector dày đặc + BM25 thưa) với Reciprocal Rank Fusion là mặc định sản xuất, giải quyết vấn đề không khớp từ vựng mà tìm kiếm vector thuần túy không xử lý được
  • Bộ rerank cross-encoder thêm một lớp chính xác sau truy xuất rộng, chỉ xử lý một tập ứng viên nhỏ để giữ độ trễ ở mức chấp nhận được
  • Agentic RAG (truy xuất, chấm điểm, diễn đạt lại, thử lại) và Graph RAG (trích xuất quan hệ thực thể) đại diện cho hai bước tiến kiến trúc lớn của năm 2026, xử lý các truy vấn multi-hop phức tạp mà RAG ngây thơ thất bại
  • Đánh giá phải tách biệt chỉ số truy xuất (Recall@k, MRR) khỏi chỉ số sinh (faithfulness, độ liên quan câu trả lời) để chẩn đoán nơi pipeline gãy
  • Các lỗi sản xuất phổ biến nhất — ô nhiễm ngữ cảnh, tạo phẩm chunking, trôi dạt embedding, chỉ mục lỗi thời — đều có cách khắc phục đơn giản một khi đã xác định

Bắt đầu luyện tập!

Kiểm tra kiến thức với mô phỏng phỏng vấn và bài kiểm tra kỹ thuật.

Thẻ

#RAG
#retrieval augmented generation
#LLM
#data science
#vector database
#interview preparation
#AI engineering

Chia sẻ

Bài viết liên quan