Một trong những hạn chế lớn nhất của LLM là “knowledge cutoff” — mô hình chỉ biết những gì có trong dữ liệu training, không thể cập nhật theo thời gian thực. Hỏi GPT-4 về sự kiện xảy ra sau tháng training của nó, và bạn sẽ nhận được câu trả lời sai hoặc “Tôi không có thông tin về sự kiện này”. RAG (Retrieval-Augmented Generation) ra đời để giải quyết vấn đề này — và Agentic RAG 2026 đang đẩy khả năng này lên một tầm cao hoàn toàn mới.
RAG Cơ Bản: Cách Hoạt Động
RAG kết hợp hai thành phần: Retrieval (tìm kiếm thông tin liên quan) và Generation (tạo ra câu trả lời dựa trên thông tin đó). Luồng hoạt động cơ bản:
- Người dùng đặt câu hỏi
- Query được chuyển thành vector embedding
- Vector database tìm kiếm các đoạn văn bản tương đồng nhất
- Các đoạn tìm được được đưa vào context của LLM cùng với câu hỏi gốc
- LLM tạo ra câu trả lời dựa trên context được cung cấp
Xây Dựng RAG Pipeline Cơ Bản
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader
from langchain.chains import RetrievalQA
# Bước 1: Nạp và xử lý documents
loader = PyPDFLoader("company_handbook.pdf")
documents = loader.load()
# Chia thành chunks nhỏ
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000, # ~1000 ký tự mỗi chunk
chunk_overlap=200, # Overlap để không mất context ở ranh giới
separators=["nn", "n", " ", ""]
)
chunks = text_splitter.split_documents(documents)
print(f"Chia thành {len(chunks)} chunks")
# Bước 2: Tạo embeddings và lưu vào vector store
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db" # Lưu local để tái sử dụng
)
# Bước 3: Tạo RAG chain
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # stuff, map_reduce, refine
retriever=vectorstore.as_retriever(
search_type="mmr", # Maximum Marginal Relevance — đa dạng hơn cosine
search_kwargs={"k": 5, "fetch_k": 20}
),
return_source_documents=True # Trả về nguồn tham khảo
)
# Bước 4: Query
result = qa_chain.invoke({"query": "Chính sách nghỉ phép hàng năm là gì?"})
print("Câu trả lời:", result["result"])
print("nNguồn:", [doc.metadata for doc in result["source_documents"]])
Nâng Cao: Hybrid Search
from langchain_community.retrievers import BM25Retriever
from langchain.retrievers import EnsembleRetriever
# BM25 — keyword search truyền thống, tốt cho tên riêng, số liệu
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 5
# Vector retriever — semantic search
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
# Hybrid: kết hợp cả hai
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.4, 0.6] # 40% BM25, 60% vector
)
# Hybrid thường tốt hơn mỗi phương pháp riêng lẻ ~10-20%
Agentic RAG: Retrieval Thông Minh Hơn
RAG cổ điển có một vấn đề: nó luôn tìm kiếm, kể cả khi không cần thiết (câu hỏi về kiến thức phổ thông) và chỉ tìm kiếm một lần. Agentic RAG giải quyết điều này:
from langchain_openai import ChatOpenAI
from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain.tools import Tool
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
llm = ChatOpenAI(model="gpt-4o", temperature=0)
def smart_retrieval(query: str) -> str:
"""
Retrieval thông minh: tìm kiếm, đánh giá chất lượng,
tìm kiếm lại nếu cần với query khác.
"""
docs = vectorstore.similarity_search(query, k=3)
if not docs:
return "Không tìm thấy thông tin liên quan."
# Đánh giá relevance
context = "n---n".join([d.page_content for d in docs])
relevance_check = llm.invoke(
f"Context: {context}nQuery: {query}n"
"Đánh giá từ 1-10: context này có trả lời được query không? "
"Chỉ trả lời con số."
).content
if int(relevance_check.strip()) < 6:
# Reformulate query và tìm lại
better_query = llm.invoke(
f"Reformulate query để tìm kiếm tốt hơn: {query}"
).content
docs = vectorstore.similarity_search(better_query, k=3)
context = "n---n".join([d.page_content for d in docs])
return context
# Định nghĩa tool cho agent
retrieval_tool = Tool(
name="KnowledgeBase",
func=smart_retrieval,
description="Tìm kiếm thông tin trong cơ sở kiến thức công ty. Dùng khi cần thông tin cụ thể về chính sách, quy trình, hoặc dữ liệu nội bộ."
)
web_search_tool = Tool(
name="WebSearch",
func=lambda q: f"Web search results for: {q}",
description="Tìm kiếm thông tin mới nhất trên internet. Dùng khi cần thông tin thời sự hoặc thông tin không có trong knowledge base."
)
# Agent với self-reflective RAG
prompt = ChatPromptTemplate.from_messages([
("system", """Bạn là assistant thông minh với khả năng tự phán đoán khi nào cần
tìm kiếm thông tin. Không phải câu hỏi nào cũng cần tìm kiếm.
Khi tìm kiếm, đánh giá kết quả và tìm lại nếu không đủ liên quan."""),
MessagesPlaceholder("chat_history"),
("human", "{input}"),
MessagesPlaceholder("agent_scratchpad"),
])
agent = create_openai_tools_agent(llm, [retrieval_tool, web_search_tool], prompt)
agent_executor = AgentExecutor(agent=agent, tools=[retrieval_tool, web_search_tool], verbose=True)
Đánh Giá RAG System: RAGAS Framework
from ragas import evaluate
from ragas.metrics import (
faithfulness, # Câu trả lời có dựa trên context không?
answer_relevancy, # Câu trả lời có liên quan đến câu hỏi không?
context_precision, # Context retrieved có chính xác không?
context_recall # Context có đủ để trả lời không?
)
from datasets import Dataset
# Chuẩn bị evaluation dataset
eval_data = {
"question": ["Chính sách nghỉ phép là gì?", "Quy trình onboarding kéo dài bao lâu?"],
"answer": ["30 ngày nghỉ phép/năm...", "Onboarding kéo dài 2 tuần..."],
"contexts": [["Nhân viên được hưởng..."], ["Quy trình onboarding..."]],
"ground_truth": ["Nhân viên được 30 ngày nghỉ phép...", "2 tuần onboarding..."]
}
dataset = Dataset.from_dict(eval_data)
results = evaluate(
dataset=dataset,
metrics=[faithfulness, answer_relevancy, context_precision, context_recall]
)
print(results.to_pandas())
RAG và Agentic RAG đang trở thành backbone của phần lớn ứng dụng AI doanh nghiệp thực tế. Chúng giải quyết vấn đề cốt lõi: LLM rất giỏi reasoning nhưng không biết thông tin riêng của công ty bạn và không thể cập nhật real-time. RAG là cầu nối — và Agentic RAG là cầu nối thông minh, biết khi nào cần tìm kiếm và tìm gì.