[Agentic AI #3] RAG Là Gì? Hướng Dẫn Nạp 'Kiến Thức' Cho AI Local (Chat Với Tài Liệu)
Chào 500 anh em developer! 👋
Quay trở lại với series "Kỷ Nguyên Agentic AI".
- Bài 1: Chúng ta đã tạo Agent biết dùng Google Search.
- Bài 2: Chúng ta đã chạy AI miễn phí trên máy cá nhân (Local LLM).
Hôm nay, chúng ta sẽ giải quyết bài toán hóc búa nhất: Làm sao để con AI (vốn chỉ được train bằng dữ liệu công cộng) hiểu được dữ liệu riêng tư (Private Data) của chúng ta?
Ví dụ: Bạn muốn build một con Chatbot trả lời quy trình nhân sự cho công ty, hoặc một con Bot tra cứu luật dựa trên các file PDF văn bản luật Việt Nam.
Kỹ thuật đó gọi là RAG. Và tin vui là: Bạn có thể làm nó hoàn toàn Local, bảo mật 100%.
1. RAG là gì? (Giải thích bằng 1 ví dụ)
RAG (Retrieval-Augmented Generation) - Thế hệ tăng cường truy xuất. Nghe tên thì nguy hiểm, nhưng bản chất nó thế này:
Hãy tưởng tượng bạn đang làm bài thi.
- LLM thuần túy (ChatGPT/Llama): Giống như bạn đi thi mà phải học thuộc lòng mọi thứ. Nếu đề thi hỏi về một kiến thức mới (chưa học), bạn sẽ "bịa" ra câu trả lời (Hallucination).
- RAG: Giống như bạn đi thi được mở sách (Open Book Exam). Khi gặp câu hỏi khó, bạn mở sách giáo khoa ra, tìm đoạn liên quan, và chép vào bài làm.
Quy trình của RAG gồm 3 bước:
- Retrieval (Truy xuất): Tìm kiếm các đoạn tài liệu liên quan đến câu hỏi trong kho dữ liệu của bạn.
- Augmentation (Tăng cường): Ghép câu hỏi của user + đoạn tài liệu vừa tìm được vào một cái Prompt.
- Generation (Tạo sinh): Gửi cái Prompt "đã được mớm bài" đó cho AI để nó trả lời nuột nà.
2. Tech Stack cho RAG Local
Để build hệ thống này miễn phí trên máy, chúng ta cần combo "hủy diệt" sau:
- LLM: Ollama (chạy model Llama 3.2) - Đã cài ở Bài 2.
- Embedding Model:
nomic-embed-text(Chạy qua Ollama luôn). Đây là model chuyên dùng để biến văn bản thành các con số (vector) để máy tính hiểu và so sánh. - Vector Database:
ChromaDB. Kho chứa dữ liệu đã được số hóa, chạy local cực nhẹ. - Framework:
LangChain. "Keo dính" để kết nối các thành phần trên.
3. Thực hành: Chat với "Sổ tay nhân viên"
Giả sử chúng ta có một văn bản quy định của một công ty hư cấu tên là "TechHub". Chúng ta sẽ dạy AI trả lời các câu hỏi về quy định này.
Bước 1: Chuẩn bị môi trường
Anh em mở Terminal và cài thêm model Embedding (để biến chữ thành số):
ollama pull nomic-embed-text
Sau đó cài thư viện Python:
pip install langchain langchain-community langchain-chroma bs4
Bước 2: Code RAG hoàn chỉnh (rag_local.py)
Đây là đoạn code "thần thánh". Anh em copy về và chạy thử:
import bs4
from langchain_community.llms import Ollama
from langchain_community.embeddings import OllamaEmbeddings
from langchain_chroma import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.documents import Document
# --- 1. DỮ LIỆU GIẢ LẬP (SỔ TAY CÔNG TY) ---
# Thực tế bạn có thể load từ PDF, Web, Text file...
company_policy = """
Chào mừng đến với TechHub! Đây là quy định nội bộ:
1. Giờ làm việc: Từ 9h sáng đến 6h chiều, thứ 2 đến thứ 6.
2. Chính sách remote: Nhân viên được làm việc từ xa 2 ngày/tuần (đăng ký trước thứ Hai).
3. Nghỉ phép: Mỗi nhân viên có 12 ngày phép năm. Không dùng hết sẽ được trả tiền vào cuối năm.
4. Trang phục: Thoải mái (Casual), nhưng cấm mặc quần đùi đi gặp khách hàng.
5. Lương thưởng: Lương tháng 13 được trả vào ngày 25/12 hàng năm.
"""
# Chuyển text thành Document object
docs = [Document(page_content=company_policy, metadata={"source": "so_tay_nhan_vien.txt"})]
print("🔄 Đang nạp dữ liệu vào Vector DB...")
# --- 2. VECTOR STORE (BỘ NHỚ) ---
# Dùng model 'nomic-embed-text' để biến văn bản thành vector
embeddings = OllamaEmbeddings(model="nomic-embed-text")
# Lưu vào ChromaDB (DB tạm thời trong RAM)
vectorstore = Chroma.from_documents(
documents=docs,
embedding=embeddings
)
# Tạo Retriver (Công cụ tìm kiếm)
retriever = vectorstore.as_retriever(search_kwargs={"k": 1}) # Lấy 1 đoạn liên quan nhất
# --- 3. KHỞI TẠO LLM (BỘ NÃO) ---
llm = Ollama(model="llama3.2")
# --- 4. TẠO PROMPT ---
# Đây là kỹ thuật "mớm bài" cho AI
template = """Bạn là trợ lý AI của công ty TechHub.
Chỉ trả lời câu hỏi dựa trên thông tin được cung cấp dưới đây (Context).
Nếu thông tin không có trong Context, hãy nói "Tôi không biết thông tin này".
Context: {context}
Câu hỏi: {question}
"""
prompt = ChatPromptTemplate.from_template(template)
# --- 5. TẠO CHAIN (DÂY CHUYỀN XỬ LÝ) ---
# Luồng đi: Câu hỏi -> Tìm dữ liệu (Retriever) -> Ghép vào Prompt -> Gửi cho LLM -> Trả về String
rag_chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
# --- 6. CHẠY THỬ ---
print("\n--- BẮT ĐẦU CHAT ---")
questions = [
"Quy định làm việc remote thế nào?",
"Tôi có được mặc quần đùi đi làm không?",
"Công ty CEO tên là gì?" # Câu này không có trong dữ liệu
]
for q in questions:
print(f"\nUser: {q}")
print(f"AI: {rag_chain.invoke(q)}")
Bước 3: Phân tích kết quả
Khi chạy đoạn code trên, bạn sẽ thấy kết quả kiểu như sau:
- User: Quy định làm việc remote thế nào?
- AI: Theo quy định, nhân viên được làm việc từ xa 2 ngày/tuần và cần đăng ký trước thứ Hai. (Chính xác 100%)
- User: Tôi có được mặc quần đùi đi làm không?
- AI: Bạn có thể mặc thoải mái, nhưng quy định cấm mặc quần đùi khi đi gặp khách hàng. (Hiểu ngữ cảnh rất tốt)
- User: Công ty CEO tên là gì?
- AI: Tôi không biết thông tin này. (Rất trung thực, không bịa đặt vì trong dữ liệu nạp vào không có tên CEO).
4. Tại sao cái này lại "Đỉnh"?
- Dữ liệu của bạn không bao giờ rời khỏi máy: Toàn bộ quá trình từ Embed, Store, Retrieve đến Generate đều chạy trên Localhost. Sếp bạn sẽ rất thích điều này.
- Khắc phục Hallucination: AI chỉ trả lời dựa trên những gì bạn cung cấp (Grounding).
- Chi phí 0 đồng: Không tốn xu nào cho Vector DB (Chroma Open Source) hay OpenAI.
5. Kết nối với Agent (Mảnh ghép cuối cùng)
Bây giờ hãy tư duy rộng hơn. RAG thực chất chỉ là một Tool (Công cụ).
Bạn hoàn toàn có thể quay lại code CrewAI ở Bài 1, tạo một CustomerSupportAgent và trang bị cho nó một công cụ gọi là search_company_policy.
Khi đó, Agent sẽ hoạt động như sau:
- Khách hỏi: "Chính sách đổi trả hàng thế nào?"
- Agent suy nghĩ: "Mình cần tra cứu quy định đổi trả." -> Gọi RAG Tool.
- RAG Tool: Trả về văn bản quy định.
- Agent: Trả lời khách hàng một cách khéo léo.
Đó chính là sức mạnh của Agentic RAG.
Kết luận
Vậy là chúng ta đã đi qua 3 bài viết nền tảng:
- Biết tạo Agent (Nhân viên).
- Biết chạy Local (Tiết kiệm & Bảo mật).
- Biết dạy Knowledge (RAG).
Bạn đã có đủ "vũ khí" để build những ứng dụng AI cực xịn rồi đấy.
Trong bài tiếp theo (có thể là bài cuối của Series), mình sẽ hướng dẫn anh em Build một giao diện Chat (UI) bằng Streamlit để đóng gói toàn bộ mớ code Python này thành một App hoàn chỉnh mà ai cũng dùng được.
Anh em thấy RAG có khó không? Hãy thử thay đổi biến company_policy bằng dữ liệu thật của anh em xem AI trả lời thế nào nhé! 👇
All rights reserved