Skip to content

Repository files navigation

Local RAG Knowledge Base

Ứng dụng RAG chạy hoàn toàn trên máy: nhập tài liệu, lập chỉ mục và trả lời như chat dựa trên kho dữ liệu nội bộ. Web server/API dùng Node.js; Ollama chạy mô hình local; SQLite lưu metadata và FAISS tìm vector.

Mặc định hiện tại dùng Qwen3 8B và bật toàn bộ pipeline chất lượng cao: phân loại AI, tách sub-query, hybrid search, LLM rerank và tool-call tra cứu sâu.

1. Ứng dụng làm được gì?

  • Nhập nhiều tài liệu TXT, MD, CSV, JSON, DOCX và PDF có lớp text.
  • Tự lưu file, tách nội dung thành các đoạn nhỏ (chunks), tạo embedding và lưu FAISS index.
  • Hiểu cấu trúc Markdown, heading, Điều, Khoản, Mục, Chương, Phụ lục và cặp FAQ hỏi/đáp.
  • Trả lời theo các đoạn tài liệu được tìm thấy và đưa trích dẫn [N].
  • Stream câu trả lời theo thời gian thực qua SSE.
  • Hiển thị tiến trình RAG và có Nhật ký AI để kiểm tra prompt, context, rerank, tool-call và output đang stream.

Toàn bộ dữ liệu, vector index và model chạy local. Không có tài liệu nào được gửi tới Cloudflare hay API AI bên ngoài.

2. Cài đặt một lần

Yêu cầu: Node.js, Python 3 và Ollama.

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-local.txt
npm install

# Mô hình trả lời/chạy agent
ollama pull qwen3:8b

# Mô hình tạo embedding cho FAISS
ollama pull qwen3-embedding:0.6b

Chạy web:

npm start

Mở http://localhost:3000.

3. Kiến trúc

Tài liệu upload
  └─ Đọc text / phân loại / chunk theo cấu trúc
       └─ qwen3-embedding:0.6b tạo vector
            ├─ SQLite: tài liệu, chunks, FTS5 keyword index
            └─ FAISS: semantic vector index

Câu hỏi khách hàng
  └─ Qwen3 8B tách sub-query
       └─ Embedding + FAISS + FTS5 hybrid search
            └─ Qwen3 8B rerank các đoạn phù hợp
                 └─ Qwen3 8B quyết định tool-call tra cứu sâu (nếu cần)
                      └─ Qwen3 8B stream câu trả lời + trích dẫn

Vai trò từng thành phần

Thành phần Vai trò Tốc độ tương đối
qwen3-embedding:0.6b Biến text thành vector để tìm nghĩa tương đồng Nhanh, nhẹ
FAISS Tìm các chunks gần câu hỏi nhất trong kho lớn Rất nhanh
SQLite FTS5 Tìm theo từ khóa chính xác, ví dụ mã hợp đồng hoặc tên sản phẩm Rất nhanh
Qwen3 8B Phân loại AI, tách câu hỏi, rerank, gọi tool, sinh câu trả lời Chậm nhất
SSE Đẩy trạng thái và text trả lời dần về giao diện Realtime

4. Quy trình nhập tài liệu

  1. File được đưa vào hàng đợi để tránh nhiều file cùng tranh tài nguyên máy.
  2. Server đọc text từ file. PDF scan không có lớp text cần OCR trước khi upload.
  3. AI/rule phân loại thành faq, contract, guide hoặc general.
  4. Text được chia theo heading hoặc Điều/Khoản. Chunk dài được cắt có overlap để tránh mất ngữ cảnh tại ranh giới.
  5. Từng chunk được embedding theo batch, lưu vào SQLite rồi thêm vào FAISS.
  6. Khi hoàn tất, tài liệu có thể được truy vấn ngay.

Nhiều file được xử lý lần lượt, không phải song song. Điều này giữ máy ít bị nghẽn RAM/CPU, nhưng tổng thời gian tăng theo số chunks.

Vì sao upload file dài có thể lâu?

Thời gian index gần đúng tỉ lệ với số chunk:

thời gian import ≈ đọc file + phân loại + (số chunks / EMBED_BATCH_SIZE) × thời gian embedding + ghi FAISS

Ví dụ tài liệu dài tạo 500 chunks sẽ cần embedding 500 đoạn. Đây là công việc chạy một lần khi nhập; sau đó chat không phải đọc lại toàn bộ file.

Các thông số mặc định giảm số lần gọi embedding bằng CHUNK_SIZE=1800EMBED_BATCH_SIZE=48. Tăng chunk quá lớn có thể làm retrieval kém chính xác hơn; tăng batch quá cao có thể làm máy thiếu RAM.

5. Quy trình trả lời RAG full

Khi bật toàn bộ chức năng, một câu hỏi có thể đi qua các bước sau:

  1. Tách sub-query: AI tách câu hỏi có nhiều ý thành tối đa 4 truy vấn độc lập.
  2. Hybrid retrieval: mỗi truy vấn được embedding; FAISS tìm theo ngữ nghĩa và FTS5 tìm theo từ khóa.
  3. Rerank: Qwen3 8B đọc các ứng viên và xếp lại đoạn nào trả lời trực tiếp nhất.
  4. Tool-call: AI quyết định có cần tra cứu sâu thêm một tài liệu cụ thể không.
  5. Generation: Qwen3 8B chỉ nhận 5 chunks đã chọn làm context và stream câu trả lời bằng Markdown, kèm [N] tương ứng nguồn.

Nút Nhật ký AI ở sidebar cho biết chính xác prompt/context nào được gửi vào các bước trên và text model đang trả về. Nhật ký không hiển thị suy luận ẩn của model.

6. Vì sao full pipeline chậm?

FAISS và SQLite rất nhanh. Điểm tốn thời gian là Qwen3 8B phải đọc prompt và sinh text.

Ở full mode, một câu hỏi thường gọi Qwen3 8B 3–4 lượt liên tiếp:

tách sub-query → rerank → quyết định tool → trả lời cuối

Rerank còn đưa nhiều chunks vào prompt, nên model phải đọc lượng context lớn. Vì vậy full mode phù hợp kiểm thử chất lượng, câu hỏi hợp đồng phức tạp hoặc màn hình quản trị; không phù hợp để trả lời mọi FAQ của khách trong vài giây.

7. Cấu hình mặc định: Qwen3 8B + full pipeline

File .env đang được đặt như sau:

PORT=3000
OLLAMA_BASE_URL=http://127.0.0.1:11434

CHAT_MODEL=qwen3:8b
EMBEDDING_MODEL=qwen3-embedding:0.6b

CLASSIFY_WITH_AI=true
SUBQUERY_ENABLED=true
RERANK_ENABLED=true
TOOL_CALL_ENABLED=true

EMBED_BATCH_SIZE=48
CHUNK_SIZE=1800
CHUNK_OVERLAP=140
RETRIEVAL_CANDIDATES=16
CONTEXT_CHUNKS=5

Sau khi sửa .env, cần khởi động lại npm start.

8. Cấu hình nên dùng khi đưa ra website chăm sóc khách hàng

Khách hàng không nên chờ full pipeline. Mục tiêu nên là trả lời trong khoảng 1–3 giây cho câu FAQ thông thường.

Để chuyển sang fast mode, đặt:

CLASSIFY_WITH_AI=false
SUBQUERY_ENABLED=false
RERANK_ENABLED=false
TOOL_CALL_ENABLED=false
CONTEXT_CHUNKS=5

Fast mode vẫn giữ:

  • embedding model;
  • FAISS semantic search;
  • FTS5 keyword search;
  • trích dẫn nguồn;
  • một lượt Qwen3 8B để viết câu trả lời cuối.

Vì vậy độ chính xác tìm tài liệu vẫn tốt cho FAQ, còn thời gian phản hồi giảm mạnh vì không gọi 8B nhiều lần.

Chiến lược thực tế cho kho khoảng 10.000 FAQ:

  1. Câu FAQ phổ biến: cache câu trả lời hoặc trả trực tiếp từ FAQ chunk tốt nhất.
  2. Câu hỏi bình thường: fast mode.
  3. Hợp đồng/dữ liệu nhiều điều khoản: bật rerank hoặc tool-call theo điều kiện, không bật cho mọi câu hỏi.
  4. Nhập dữ liệu theo lô ngoài giờ; không index tài liệu lúc khách đang chờ trả lời.

9. Độ chính xác và chống bịa thông tin

Prompt hiện yêu cầu model chỉ trả lời theo CONTEXT; nếu không đủ thông tin phải nói chưa tìm thấy trong tài liệu. Tuy nhiên RAG local với model 8B không thể cam kết tuyệt đối không bịa.

Với dữ liệu pháp lý hoặc chính sách quan trọng, nên áp dụng thêm các luật ở tầng ứng dụng:

  • Không có nguồn thì không trả lời nội dung cụ thể.
  • Mỗi ý quan trọng phải có citation [N].
  • Kiểm tra citation có thật sự thuộc nguồn được chọn trước khi gửi khách.
  • Khi cần, trả nguyên văn Điều/Khoản liên quan kèm diễn giải ngắn.
  • Cho phép khách chuyển sang nhân viên khi confidence thấp.

10. Dữ liệu lưu ở đâu?

data/
  files/       File gốc đã upload
  rag.sqlite   Metadata, chunks, embedding và FTS5
  faiss.index  Chỉ mục vector FAISS

data/.venv/ đã được bỏ qua khỏi Git. Sao lưu thư mục data/ để giữ lại kho tài liệu đã index.

11. Giới hạn hiện tại

  • PDF scan cần OCR trước khi nhập.
  • Hàng đợi index chạy tuần tự.
  • Full pipeline dùng cùng Qwen3 8B cho nhiều tác vụ nên chậm trên laptop.
  • Nhật ký AI có thể chứa các đoạn tài liệu được đưa vào context; chỉ nên dùng ở môi trường nội bộ.

Hướng nâng cấp phù hợp nhất là tách model: embedding nhỏ, cross-encoder reranker nhỏ chuyên dụng và Qwen3 8B chỉ cho câu trả lời cuối.

12. Giấy phép

Dự án phát hành theo giấy phép MIT. Mọi người được tự do sử dụng, sao chép, sửa đổi, phân phối và dùng thương mại, với điều kiện giữ lại thông báo bản quyền và giấy phép.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages