Xây dựng Private RAG: Hỏi đáp tài liệu bảo mật với LlamaIndex và Ollama

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Khủng hoảng bảo mật lúc 2 giờ sáng

Thông báo Slack từ CTO của tôi đến lúc 2 giờ sáng, và đó không phải là một tin tốt. Bộ phận pháp lý của chúng tôi vừa mới yêu cầu dừng dự án thí điểm AI trên đám mây. Lý do? Việc gửi các trang Confluence nội bộ và lộ trình sản phẩm nhạy cảm đến nhà cung cấp LLM bên thứ ba là một rủi ro tuân thủ khổng lồ. Họ muốn tốc độ của AI, nhưng yêu cầu dữ liệu phải nằm sau tường lửa của chúng tôi.

Đây là lúc bộ công cụ Retrieval-Augmented Generation (RAG) nội bộ phát huy tác dụng. Bằng cách kết hợp Ollama để host mô hình với LlamaIndex để điều phối dữ liệu, bạn có thể xây dựng một hệ thống đọc tài liệu nội bộ mà không một byte nào rời khỏi mạng của mình. Tôi đã triển khai hệ thống này để xử lý hơn 1.500 thông số kỹ thuật và 4.000 trang wiki nội bộ. Kết quả rất nhanh nhạy, đáng tin cậy và quan trọng nhất là riêng tư. Sau 6 tháng đồng hành cùng AI cục bộ, tôi nhận thấy đây là hướng đi bền vững nhất cho doanh nghiệp.

Bắt đầu nhanh: Hỏi đáp riêng tư trong 5 phút

Bạn có thể chạy thử nghiệm (proof of concept) trước khi buổi họp stand-up tiếp theo bắt đầu. Hãy chuẩn bị một thư mục chứa các tệp PDF; chúng ta sẽ bắt đầu từ đó.

1. Cài đặt Ollama và tải mô hình

Tải xuống Ollama từ trang web chính thức của họ. Sau khi nó đang chạy, hãy mở terminal để tải xuống một mô hình 8B tham số hiệu quả và một mô hình embedding.

# Tải LLM (Llama 3.1 là một lựa chọn cân bằng tuyệt vời)
ollama pull llama3.1

# Tải mô hình embedding (cần thiết để tìm kiếm dữ liệu của bạn)
ollama pull nomic-embed-text

2. Thiết lập môi trường Python

Tạo một môi trường ảo để giữ mọi thứ sạch sẽ. Bạn sẽ cần thư viện LlamaIndex cốt lõi và các connector dành riêng cho Ollama.

pip install llama-index llama-index-llms-ollama llama-index-embeddings-ollama

3. Chương trình “Hello World” của Local RAG

Tạo một tệp có tên app.py. Script này sẽ quét thư mục /data và xây dựng một index có thể tìm kiếm chỉ trong vài giây.

from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.embeddings.ollama import OllamaEmbedding

# Cấu hình engine nội bộ
Settings.llm = Ollama(model="llama3.1", request_timeout=120.0)
Settings.embed_model = OllamaEmbedding(model_name="nomic-embed-text")

# Tải tài liệu từ thư mục cục bộ của bạn
documents = SimpleDirectoryReader("./data").load_data()

# Xây dựng index có thể tìm kiếm
index = VectorStoreIndex.from_documents(documents)

# Đặt câu hỏi
query_engine = index.as_query_engine()
response = query_engine.query("Chính sách làm việc từ xa của chúng ta là gì?")
print(response)

Cơ chế hoạt động bên dưới của Local Engine

LlamaIndex đóng vai trò như người điều phối giao thông giữa các tệp tin hỗn độn của bạn và LLM. Nó tuân theo một quy trình đơn giản: Loading (Tải) -> Indexing (Lập chỉ mục) -> Querying (Truy vấn).

Tại sao chọn LlamaIndex cho Local RAG?

LangChain rất tốt cho các chuỗi logic phức tạp, nhưng LlamaIndex được xây dựng chuyên biệt để truy xuất dữ liệu. Nó quản lý các tác vụ tẻ nhạt như chia nhỏ tài liệu thành các “chunks” (đoạn) dễ quản lý. Bạn cũng có thể kết hợp thêm công cụ Trích Xuất và Xử Lý Bảng PDF để làm sạch dữ liệu đầu vào. Sau đó, nó chuyển đổi các đoạn đó thành vector — bản đồ toán học của ý nghĩa — và lưu trữ chúng cục bộ. Khi bạn đặt câu hỏi, hệ thống không gửi toàn bộ thư viện cho LLM. Thay vào đó, nó chỉ gửi 3 hoặc 4 đoạn trích liên quan nhất được tìm thấy trong vector store nội bộ của bạn.

Kết nối với Confluence và Notion

Kiến thức nội bộ hiếm khi chỉ nằm trong file PDF. Nó thường nằm trên Confluence hoặc Notion. Để đưa dữ liệu này về máy, hãy sử dụng các trình tải của LlamaHub. Mặc dù bạn sẽ cần một API token để lấy văn bản, nhưng quá trình xử lý thực tế diễn ra ngay trên máy của bạn. Dữ liệu nhạy cảm của bạn không được dùng để huấn luyện mô hình công khai; nó nằm lại trong bộ nhớ cục bộ của bạn.

# Ví dụ: Lấy dữ liệu từ Confluence
from llama_index.readers.confluence import ConfluenceReader

loader = ConfluenceReader(base_url="https://your-domain.atlassian.net/wiki")
documents = loader.load_data(space_key='ENGINEERING')

Sử dụng nâng cao: Lưu trữ lâu dài và Hiệu suất

Script cơ bản sẽ xây dựng lại index mỗi khi chạy. Điều này làm lãng phí chu kỳ CPU và thời gian. Đối với một công cụ sẵn sàng cho sản xuất, bạn phải lưu index vào ổ đĩa.

1. Lưu Index

import os.path
from llama_index.core import StorageContext, load_index_from_storage

PERSIST_DIR = "./storage"
if not os.path.exists(PERSIST_DIR):
    # Tải tài liệu và tạo index mới nếu chưa tồn tại
    documents = SimpleDirectoryReader("./data").load_data()
    index = VectorStoreIndex.from_documents(documents)
    index.storage_context.persist(persist_dir=PERSIST_DIR)
else:
    # Tải index hiện có từ ổ đĩa
    storage_context = StorageContext.from_defaults(persist_dir=PERSIST_DIR)
    index = load_index_from_storage(storage_context)

2. Yêu cầu phần cứng

Chạy Llama 3.1 8B yêu cầu các tài nguyên cụ thể để có trải nghiệm mượt mà. Nếu bạn dùng Mac với chip dòng M, hãy hướng tới 16GB Unified Memory. Người dùng Windows và Linux nên sử dụng GPU có ít nhất 12GB VRAM, đồng thời đừng quên Cài đặt NVIDIA Container Toolkit để tối ưu hóa hiệu suất trên môi trường production. Nếu bạn bị giới hạn ở server chỉ có CPU, hãy thử các mô hình phi3 hoặc tinyllama. Chúng nhanh hơn đáng kể trên phần cứng cũ, mặc dù kém thông minh hơn một chút.

Lời khuyên thực chiến để hệ thống ổn định

Tôi đã dành nhiều tháng để tinh chỉnh thiết lập này. Đây là cách để ngăn hệ thống bị chậm lại khi dữ liệu của bạn lớn dần.

  • Tối ưu hóa Chunk Size: LlamaIndex mặc định là các đoạn 1024 token. Đối với các tài liệu kỹ thuật dày đặc, hãy giảm xuống 512. Điều này cung cấp cho LLM ngữ cảnh cụ thể hơn và giảm tình trạng “ảo giác” (hallucinations).
  • Lọc dữ liệu của bạn: Đừng index mọi thứ. Nếu không gian Confluence của bạn đầy rẫy các ghi chú cuộc họp từ năm 2019, AI sẽ bị bối rối. Sử dụng các bộ lọc của LlamaIndex để chỉ bao gồm các trang được sửa đổi trong 12 tháng qua.
  • Mô hình Embedding rất quan trọng: Nếu AI đưa ra câu trả lời chung chung hoặc không chính xác, LLM thường không phải là vấn đề. Thường thì mô hình embedding (nomic-embed-text) đã thất bại trong việc tìm đúng đoạn trích tài liệu. Hãy thực hiện Đánh Giá LLM bài bản để đo lường chất lượng truy xuất trước khi thay đổi LLM.
  • Quản lý người dùng đồng thời: Ollama hoạt động hiệu quả, nhưng nó có giới hạn. Nếu 50 nhân viên truy vấn API nội bộ cùng lúc, máy chủ của bạn sẽ bị chậm lại. Sử dụng hàng đợi công việc như Redis để quản lý tải và giữ thời gian phản hồi dưới 3 giây.

Xây dựng một hệ thống RAG nội bộ không chỉ mang lại sự riêng tư; nó mang lại cho bạn quyền kiểm soát hoàn toàn. Việc Xây dựng AI Gateway tại chỗ sẽ giúp bạn quản lý tập trung các mô hình và cơ sở hạ tầng. Bạn sẽ không phải đối mặt với hóa đơn API 2.000 USD bất ngờ vì một script tự động đã index toàn bộ kho lưu trữ của công ty qua đêm. Hãy gắn bó với local stack, và cuối cùng bạn có thể ngừng lo lắng về việc rò rỉ dữ liệu.

Share: