Trong lĩnh vực học máy và xử lý ngôn ngữ tự nhiên, RAG (Retrieval-Augmented Generation) là một phương pháp được ứng dụng phổ biến để giúp các hệ thống trả lời câu hỏi và tìm kiếm thông tin từ các tập dữ liệu lớn. Hãy cùng khám phá Basic Retriever - nền tảng để tạo nên các hệ thống RAG với hiệu quả tối ưu.
Basic Retriever là một loại truy xuất dựa trên RAG đơn giản và dễ thực hiện. Đặc điểm nổi bật của nó là không yêu cầu quá nhiều các kỹ thuật phức tạp, điều này giúp người dùng dễ dàng triển khai và bắt đầu với mô hình RAG. Phương pháp này thường được sử dụng khi cần tìm kiếm các thông tin cụ thể từ một tập dữ liệu lớn mà không cần thực hiện các phép tính tổng hợp hay truy xuất phức tạp.
Để tạo ra một hệ thống RAG hiệu quả, tài liệu lớn nên được chia thành các đoạn nhỏ hơn trước khi tạo embedding. Embedding là một dạng biểu diễn ngữ nghĩa của văn bản, giúp hệ thống hiểu được ý nghĩa tổng quát của văn bản. Khi văn bản quá dài hoặc chứa nhiều chủ đề khác nhau, embedding của nó sẽ trở nên kém chính xác và không giữ được giá trị thông tin cốt lõi. Vì vậy, chia nhỏ tài liệu giúp embedding trở nên sắc nét và chính xác hơn, từ đó cải thiện hiệu quả truy xuất thông tin.
Các Bước Triển Khai Basic Retriever
- Chia nhỏ tài liệu lớn: Trước tiên, cần phải chia tài liệu lớn thành các đoạn nhỏ hơn để chuẩn bị cho việc tạo embedding. Điều này giúp tối ưu hóa độ chính xác của embedding.
- Tạo embedding cho từng đoạn: Mỗi đoạn nhỏ được biểu diễn dưới dạng embedding thông qua một mô hình ngữ nghĩa. Embedding này giúp nắm bắt ý nghĩa tổng quát của đoạn văn bản.
- Tạo embedding cho câu hỏi của người dùng: Khi người dùng đặt câu hỏi, câu hỏi đó sẽ được đưa vào hệ thống và chuyển thành embedding để so sánh với các đoạn embedding đã có.
- Tìm kiếm tương đồng vector: Hệ thống sẽ sử dụng phương pháp tìm kiếm vector tương đồng để lấy ra các đoạn văn bản có nội dung gần nhất với câu hỏi.
Hiện thực hóa một Basic Retriever
1. Load văn bản, sau đó chia văn bản gốc thành các đoạn nhỏ (chunk).
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import CharacterTextSplitter
loader = TextLoader("../../state_of_the_union.txt"
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
2. Chuyển đổi các đoạn nhỏ thành embedding, rồi lưu vào vector database FAISS:
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)
3. Tạo Retrieval để kiểm tra độ tương đồng.
retriever = db.as_retriever()
docs = retriever.invoke("what did he say about ketanji brown jackson")
4. Sử dụng Retrieval với cài đặt độ tương đồng (tương đồng hơn ngưỡng thì mới lấy)
retriever = db.as_retriever(search_type="similarity_score_threshold", search_kwargs={"score_threshold": 0.5})
docs = retriever.invoke("what did he say about ketanji brown jackson")
5. Sử dụng Retrieval với cài đặt topK (trả về top K trường hợp tương đồng)
retriever = db.as_retriever(search_kwargs={"k": 1})
docs = retriever.invoke("what did he say about ketanji brown jackson")
len(docs)