Bỏ qua để đến nội dung

RAG & tìm kiếm agentic

Bài viết được dịch tự động từ bài viết gốc, chưa được kiểm tra lại bởi con người. Chỉ những bài viết có dấu tick xanh cạnh tiêu đề là đã được kiểm tra.

RAG (Retrieval-Augmented Generation) là kỹ thuật nạp thông tin liên quan vào ngữ cảnh trước khi model trả lời, để nó dựa trên dữ liệu thật thay vì kiến thức từ lúc huấn luyện.

Đây là pattern chủ đạo của ứng dụng LLM giai đoạn 2023–2024. Nhưng với agent có tool, có một cách khác thường tốt hơn - và Claude Code chọn cách đó. Trang này giải thích cả hai.

Ngoại tuyến (một lần):
Tài liệu → chia nhỏ (chunk) → embedding → lưu vào vector DB
Khi có câu hỏi:
Câu hỏi → embedding → tìm k chunk gần nhất → nhét vào prompt → gọi model

Các khái niệm liên quan:

Khái niệmNghĩa
EmbeddingBiểu diễn một đoạn văn bản thành vector số. Hai đoạn nghĩa gần nhau → hai vector gần nhau
ChunkingChia tài liệu dài thành đoạn nhỏ vừa nhét prompt. Kích thước và cách cắt ảnh hưởng lớn đến chất lượng
Vector storeDatabase tìm kiếm theo độ gần vector (pgvector, Pinecone, Qdrant…)
Top-k retrievalLấy k chunk gần nhất với câu hỏi
Hybrid searchKết hợp tìm theo vector (nghĩa) với tìm theo từ khoá (BM25) - thường tốt hơn dùng riêng một loại
Re-rankingLấy nhiều ứng viên rồi dùng một model nhỏ xếp lại theo độ liên quan thực sự
  • Một lượt truy xuất, không sửa được. Nếu k chunk lấy được không chứa câu trả lời, model không có cách nào tìm thêm - nó sẽ trả lời dựa trên thứ sai hoặc ảo giác.
  • Chunking phá vỡ cấu trúc. Cắt code theo 500 ký tự sẽ tách hàm khỏi định nghĩa type của nó, tách lời gọi khỏi khai báo.
  • Độ gần vector không phải độ liên quan. Câu hỏi “tại sao API này thiết kế lạ vậy?” không gần vector với đoạn code trả lời được nó - câu trả lời nằm trong git history.
  • Chỉ số dễ lỗi thời. Codebase đổi mỗi giờ; index đổi mỗi đêm.
  • Chi phí hạ tầng. Vector DB, pipeline embedding, job re-index - đều là hệ thống phải vận hành.

Claude Code không index codebase của bạn, không tạo embedding, không có vector DB. Thay vào đó nó dùng đúng những công cụ mà một lập trình viên dùng: grep, glob, ls, đọc file, đọc git history - và lặp lại.

Cần biết auth hoạt động thế nào?
→ grep -r "authenticate" (tìm điểm vào)
→ đọc src/auth/session.ts (đọc file tìm được)
→ grep "validateSession" (theo dấu lời gọi)
→ git log src/auth/ (hiểu vì sao thành ra thế này)
→ tóm tắt

So sánh:

RAGTìm kiếm agentic
Nhiều lượt truy xuấtKhông (một lượt)Có - sửa hướng dựa trên cái vừa tìm thấy
Cần hạ tầngVector DB, pipeline embeddingKhông, chỉ cần tool có sẵn
Độ mới của dữ liệuTheo lần index cuốiLuôn là trạng thái hiện tại trên đĩa
Giữ được cấu trúcKhông - chunk cắt ngangCó - đọc nguyên file, nguyên hàm
Truy vấn quan hệ (“cái gì gọi X?”)YếuMạnh - đó chính là việc grep làm
Độ trễ & token mỗi câu hỏiThấpCao hơn - nhiều lượt gọi model

Đánh đổi rõ ràng: tìm kiếm agentic chậm hơn và tốn token hơn, nhưng chính xác hơn và không cần hạ tầng. Với việc lập trình - nơi trả lời sai đắt hơn trả lời chậm - đánh đổi này gần như luôn có lợi.

Đây cũng là lý do subagent quan trọng: tìm kiếm agentic đọc rất nhiều file, và subagent giữ tất cả thứ đó trong ngữ cảnh riêng của nó.

RAG chưa hết vai trò. Nó vẫn là lựa chọn đúng khi:

  • Dữ liệu quá lớn để duyệt bằng grep - hàng triệu tài liệu, log nhiều năm.
  • Dữ liệu nằm ngoài filesystem - trong database, Confluence, Notion, ticket system.
  • Câu hỏi là tìm theo nghĩa, không theo cấu trúc - “tìm các ticket khiếu nại về việc chờ lâu” (không có từ khoá cố định nào để grep).
  • Độ trễ quan trọng - chatbot hỗ trợ khách hàng không chờ được 5 lượt truy xuất.
  • Chi phí mỗi câu hỏi phải thấp và ổn định.

Trong thực tế, cách kết hợp mạnh nhất là: cho agent một tool tìm kiếm (có thể chính là RAG), rồi để agent tự quyết định gọi bao nhiêu lần và tinh chỉnh truy vấn thế nào. RAG trở thành một tool trong tay agent thay vì là kiến trúc của cả hệ thống. Đây chính là cách MCP server kết nối tới Notion, Sentry hay database hoạt động.