Các thành phần có trong EzyRAG
Back to ezyragEzyRAG là lớp truy hồi tri thức dành cho hệ sinh thái EzyPlatform. Hệ thống tiếp nhận nội dung từ website, chuyển nội dung thành vector để tìm kiếm theo ngữ nghĩa, rồi cung cấp các đoạn liên quan cho EzyAI hoặc thành phần AI khác.
EzyRAG tập trung vào phần Retrieval của kiến trúc Retrieval-Augmented Generation. Việc gọi mô hình ngôn ngữ và sinh câu trả lời cuối cùng thuộc trách nhiệm của EzyAI.
Kiến trúc tổng thể
Mã nguồn EzyRAG được chia thành bốn module chính:
- SDK lõi: định nghĩa mô hình dữ liệu, abstraction và pipeline RAG.
- Admin plugin: cấu hình hệ thống và quản trị dữ liệu.
- Web plugin: cung cấp các thành phần RAG trong web runtime.
- Socket plugin: kết nối RAG với EzyAI và luồng chat thời gian thực.
flowchart TB
subgraph EzyPlatform["EzyPlatform"]
ADMIN["Admin plugin<br/>Cấu hình và quản trị"]
WEB["Web plugin<br/>Web runtime"]
SOCKET["Socket plugin<br/>Chat thời gian thực"]
AI["EzyAI<br/>Sinh câu trả lời"]
end
subgraph CORE["EzyRAG SDK"]
PIPELINE["Pipeline RAG"]
MODELS["Mô hình dữ liệu"]
EXTENSIONS["Các điểm mở rộng"]
end
EMBEDDING["Dịch vụ embedding"]
VECTOR["Cơ sở dữ liệu vector"]
APP_DB["Cơ sở dữ liệu ứng dụng"]
CONTENT["Bài viết, sản phẩm,<br/>media và văn bản"]
ADMIN --> CORE
WEB --> CORE
SOCKET --> CORE
CONTENT --> PIPELINE
PIPELINE --> EMBEDDING
PIPELINE --> VECTOR
PIPELINE --> APP_DB
WEB --> AI
SOCKET --> AI
CORE --> AI
SDK lõi
SDK chứa các hợp đồng và triển khai dùng chung cho toàn bộ hệ thống. Đây là nơi điều phối hai luồng chính:
- Lập chỉ mục dữ liệu.
- Tìm kiếm và xây dựng tri thức.
Các plugin admin, web và socket cung cấp dependency theo runtime nhưng cùng sử dụng pipeline trong SDK. Nhờ vậy, cách chunk dữ liệu và tìm kiếm được giữ nhất quán giữa các môi trường.
flowchart LR
CLIENT["Bộ điều phối RAG"]
CLIENT --> LOADER["Data loader"]
CLIENT --> CLEANER["Text cleaner"]
CLIENT --> CHUNKER["Data chunker"]
CLIENT --> EMBEDDING["Embedding service"]
CLIENT --> VECTOR["Vector database service"]
CLIENT --> RETRIEVER["Data retriever"]
CLIENT --> BUILDER["Knowledge data builder"]
CLIENT --> SETTINGS["Setting service"]
Bộ nạp dữ liệu
Data loader chuyển từng loại nguồn dữ liệu thành đầu vào văn bản thống nhất cho pipeline.
EzyRAG hiện hỗ trợ:
| Nguồn | Nội dung được lập chỉ mục | Metadata đi kèm |
|---|---|---|
| Văn bản trực tiếp | Nội dung do người quản trị nhập | Metadata của yêu cầu |
| Bài viết | Tiêu đề và nội dung | Tiêu đề, slug, tóm tắt |
| Sản phẩm | Tên, mã, mô tả và nội dung đa ngôn ngữ | Tên, slug, mã sản phẩm, giá, tiền tệ |
| Media | Thuộc tính mô tả và nội dung tài liệu | Tiêu đề, URL tài nguyên |
Một nguồn có thể sinh nhiều đầu vào. Ví dụ, sản phẩm đa ngôn ngữ có thể tạo một đầu vào cho nội dung mặc định và các đầu vào tiếp theo cho từng bản dịch.
flowchart LR
SOURCE["Nguồn dữ liệu"] --> SELECT{"Loại nguồn"}
SELECT -->|Văn bản| TEXT["Text loader"]
SELECT -->|Bài viết| POST["Post loader"]
SELECT -->|Sản phẩm| PRODUCT["Product loader"]
SELECT -->|Media| MEDIA["Media loader"]
TEXT --> INPUT["RAG input"]
POST --> INPUT
PRODUCT --> INPUT
MEDIA --> INPUT
Bộ đọc tài liệu
Khi nguồn là media, hệ thống chọn bộ đọc theo MIME type hoặc phần mở rộng của tệp.
Các định dạng được hỗ trợ gồm:
- PDF.
- Microsoft Word
.docx. - Microsoft Excel
.xlsx. - Microsoft PowerPoint
.pptx. - Văn bản thuần và Markdown.
Bộ đọc tài liệu hoạt động như một lớp con của media loader:
flowchart TD
MEDIA["Media"] --> INFO["Đọc tiêu đề và mô tả"]
MEDIA --> FILE{"Tệp có bộ đọc phù hợp?"}
FILE -->|PDF| PDF["PDF reader"]
FILE -->|DOCX| WORD["Word reader"]
FILE -->|XLSX| EXCEL["Excel reader"]
FILE -->|PPTX| PPT["PowerPoint reader"]
FILE -->|Text hoặc Markdown| TEXT["Text reader"]
FILE -->|Không| SKIP["Chỉ dùng thông tin media"]
PDF --> BLOCKS["Các khối văn bản"]
WORD --> BLOCKS
EXCEL --> BLOCKS
PPT --> BLOCKS
TEXT --> BLOCKS
INFO --> INPUTS["Danh sách RAG input"]
BLOCKS --> INPUTS
SKIP --> INPUTS
Bộ làm sạch văn bản
Text cleaner chuẩn hóa dữ liệu trước khi chia đoạn:
- Chuẩn hóa Unicode theo NFC.
- Chuyển kiểu xuống dòng về một định dạng.
- Loại bỏ ký tự điều khiển không cần thiết.
- Thu gọn khoảng trắng và tab.
- Loại bỏ khoảng trắng quanh dấu xuống dòng.
- Giới hạn số dòng trống liên tiếp.
- Cắt khoảng trắng ở đầu và cuối nội dung.
Bước này giúp cùng một nội dung không tạo ra embedding khác nhau chỉ vì khác biệt về định dạng.
Bộ chia đoạn
EzyRAG sử dụng chiến lược chia đoạn phân cấp. Nội dung được ưu tiên chia theo ranh giới tự nhiên trước khi phải cắt cứng.
flowchart TD
RAW["Văn bản đã làm sạch"] --> HTML["Loại bỏ HTML<br/>Giữ ranh giới khối"]
HTML --> CHECK{"Độ dài có nằm<br/>trong giới hạn?"}
CHECK -->|Có| SINGLE["Tạo một chunk"]
CHECK -->|Không| PARA["Chia và ghép theo đoạn văn"]
PARA --> LONG_PARA{"Đoạn văn quá dài?"}
LONG_PARA -->|Không| CHUNKS["Danh sách chunk"]
LONG_PARA -->|Có| SENTENCE["Chia và ghép theo câu"]
SENTENCE --> LONG_SENTENCE{"Câu vẫn quá dài?"}
LONG_SENTENCE -->|Không| CHUNKS
LONG_SENTENCE -->|Có| HARD["Cắt theo số ký tự"]
HARD --> CHUNKS
Giới hạn độ dài chunk, dấu phân cách đoạn và biểu thức xác định ranh giới câu đều có thể cấu hình.
Thuật toán hiện chia theo số ký tự, chưa phải theo số token của model embedding hoặc mô hình ngôn ngữ.
Dịch vụ embedding
Embedding service chuyển văn bản thành vector số.
Triển khai mặc định sử dụng OpenAI và cho phép cấu hình model embedding. Kích thước vector được lấy từ collection đích, giúp embedding và cấu trúc collection thống nhất với nhau.
Embedding service nằm sau một interface và manager, vì vậy có thể bổ sung nhà cung cấp khác mà không phải thay đổi pipeline chính.
flowchart LR
TEXT["Nội dung hoặc câu hỏi"] --> SERVICE["Embedding service"]
CONFIG["Model và cấu hình"] --> SERVICE
SIZE["Kích thước collection"] --> SERVICE
SERVICE --> VECTOR["Vector embedding"]
Cơ sở dữ liệu vector
EzyRAG hiện có hai adapter lưu trữ vector:
- EzyVector.
- Qdrant.
Vector database service cung cấp các thao tác chung:
- Tạo collection nếu chưa tồn tại.
- Upsert các vector point.
- Xóa vector point.
- Tìm các vector gần nhất.
- Nhận diện tên dịch vụ đang sử dụng.
Mỗi vector point dùng định danh của chunk làm ID. Payload chỉ chứa thông tin tối thiểu như loại nguồn, ID nguồn và vị trí chunk. Nội dung đầy đủ được lưu tại cơ sở dữ liệu ứng dụng.
flowchart LR
CHUNK["Data chunk"] --> EMB["Embedding"]
EMB --> POINT["Vector point"]
POINT --> VECTOR_DB["Kho vector<br/>Vector và payload tối thiểu"]
CHUNK --> APP_DB["Cơ sở dữ liệu ứng dụng<br/>Nội dung, hash và metadata"]
VECTOR_DB -. "chunk ID" .-> APP_DB
Collection
Collection mô tả không gian vector mà dữ liệu được lưu vào. Một collection gắn với:
- Tên collection.
- Dịch vụ vector database.
- Kích thước vector.
- Trạng thái hoạt động.
- Thông tin tạo và cập nhật.
Hệ thống hỗ trợ collection mặc định cho từng dịch vụ vector. Khi truy vấn không chỉ định rõ collection, EzyRAG sử dụng collection mặc định trong cấu hình.
Kho chunk và metadata
EzyRAG lưu dữ liệu chunk trong cơ sở dữ liệu ứng dụng, tách biệt với kho vector.
Một chunk chứa:
- Loại nguồn dữ liệu.
- ID nguồn.
- ID collection.
- Vị trí chunk trong nguồn.
- Nội dung.
- Hash nội dung.
- Tên dịch vụ embedding.
- Vector embedding.
Metadata được lưu riêng theo chunk, có thể bao gồm:
- Tiêu đề.
- Slug.
- Tóm tắt.
- URL tài nguyên.
- Mã sản phẩm.
- Giá.
- Đơn vị tiền tệ.
Cách tách này cho phép kho vector tập trung vào tìm kiếm tương đồng, còn cơ sở dữ liệu ứng dụng giữ nội dung nghiệp vụ đầy đủ.
Pipeline lập chỉ mục
Khi lập chỉ mục một nguồn dữ liệu, bộ điều phối thực hiện các bước sau:
sequenceDiagram
participant A as Admin hoặc ứng dụng
participant R as Bộ điều phối EzyRAG
participant L as Data loader
participant C as Cleaner và chunker
participant D as Cơ sở dữ liệu
participant E as Embedding service
participant V as Kho vector
A->>R: Lập chỉ mục nguồn vào collection
R->>L: Nạp dữ liệu theo loại nguồn
L-->>R: Một hoặc nhiều đầu vào
loop Mỗi đầu vào
R->>C: Làm sạch và chia đoạn
C-->>R: Danh sách chunk
loop Mỗi chunk
R->>D: Tìm chunk cũ theo nguồn và vị trí
D-->>R: Hash và embedding hiện có
R->>D: Lưu nội dung cùng metadata
alt Nội dung mới hoặc đã thay đổi
R->>E: Tạo embedding
E-->>R: Vector
R->>D: Lưu embedding
else Nội dung không đổi
R->>R: Tái sử dụng embedding
end
R->>V: Upsert vector point
end
end
R->>D: Xóa các chunk cũ nằm ngoài phiên bản mới
Mỗi chunk được tính hash từ nội dung. Với các nguồn có định danh ổn định, hash được dùng để tránh gọi lại embedding service khi nội dung không thay đổi.
Đối với văn bản nhập trực tiếp, pipeline hiện tạo chunk mới thay vì tìm lại embedding theo nguồn và vị trí.
Một giới hạn đáng chú ý: sau khi lập chỉ mục lại với số chunk ít hơn, dữ liệu chunk dư được xóa khỏi cơ sở dữ liệu ứng dụng. Luồng lập chỉ mục không thể hiện thao tác xóa đồng thời các vector point dư khỏi vector database; việc đồng bộ phần này cần được kiểm soát ở lớp vận hành.
Bộ xử lý truy vấn
Trước khi tạo embedding, câu truy vấn đi qua query processor. Triển khai mặc định chuẩn hóa khoảng trắng trong câu hỏi.
Query processor cũng được quản lý qua manager, cho phép bổ sung các bước như:
- Chuẩn hóa theo ngôn ngữ.
- Viết lại truy vấn.
- Loại bỏ từ không cần thiết.
- Mở rộng từ đồng nghĩa.
Những khả năng trên là điểm mở rộng; chúng không đồng nghĩa tất cả đã được triển khai trong phiên bản hiện tại.
Pipeline tìm kiếm
Luồng tìm kiếm chuyển câu hỏi thành vector, tìm các chunk gần nhất rồi tái dựng tài liệu đầy đủ.
sequenceDiagram
participant U as Người dùng
participant AI as EzyAI
participant R as EzyRAG
participant Q as Query processor
participant E as Embedding service
participant V as Kho vector
participant D as Cơ sở dữ liệu
participant B as Knowledge builder
U->>AI: Gửi câu hỏi
AI->>R: Tìm tri thức
R->>Q: Chuẩn hóa câu hỏi
Q-->>R: Truy vấn đã xử lý
R->>E: Tạo embedding truy vấn
E-->>R: Vector truy vấn
R->>V: Tìm kiếm trong collection
V-->>R: Danh sách chunk ID
R->>D: Lấy chunk và metadata
D-->>R: Các tài liệu liên quan
R->>B: Chuyển thành KnowledgeData
B-->>R: Ngữ cảnh cho AI
R-->>AI: Danh sách tri thức
AI-->>U: Sinh câu trả lời
Nếu dịch vụ vector hoặc collection không được truyền trong tham số, search strategy sử dụng cấu hình mặc định. Nếu không tìm thấy cấu hình hoặc collection, kết quả trả về là danh sách rỗng.
Bộ truy hồi dữ liệu
Vector database chỉ trả về kết quả tìm kiếm chứa định danh chunk. Data retriever chịu trách nhiệm:
- Thu thập ID của các chunk tìm được.
- Đọc nội dung chunk từ cơ sở dữ liệu ứng dụng.
- Đọc metadata tương ứng.
- Chuyển chúng thành tài liệu RAG hoàn chỉnh.
Thiết kế này tránh lưu toàn bộ nội dung nghiệp vụ trong payload của vector database.
Bộ dựng dữ liệu tri thức
Knowledge data builder chuyển tài liệu RAG thành cấu trúc mà EzyAI hiểu được.
Kết quả có thể chứa:
- ID và loại nguồn.
- Tiêu đề.
- Nội dung chunk.
- Slug.
- Tóm tắt.
- URL tài nguyên.
- Mã sản phẩm.
- Giá và đơn vị tiền tệ.
Ngoài tìm kiếm vector, nguồn tri thức còn hỗ trợ lấy nội dung trực tiếp theo loại nguồn và ID hoặc mã. Khi một nguồn có nhiều chunk, chúng được ghép theo thứ tự để tái tạo nội dung đầy đủ.
Hệ thống manager và khả năng mở rộng
Mỗi giai đoạn quan trọng đều có một manager dùng để tìm implementation theo tên hoặc loại dữ liệu:
flowchart TB
CONFIG["Cấu hình"] --> MANAGERS["Các manager"]
MANAGERS --> L["Data loader"]
MANAGERS --> C["Text cleaner"]
MANAGERS --> H["Data chunker"]
MANAGERS --> E["Embedding service"]
MANAGERS --> Q["Query processor"]
MANAGERS --> V["Vector database service"]
MANAGERS --> R["Data retriever"]
MANAGERS --> K["Knowledge data builder"]
CUSTOM["Implementation mở rộng"] -. "Đăng ký qua dependency container" .-> MANAGERS
Khi có nhiều implementation xử lý cùng một loại dữ liệu, độ ưu tiên quyết định implementation được chọn. Kiến trúc này cho phép mở rộng từng bước của pipeline độc lập.
Admin plugin
Admin plugin cung cấp giao diện và API quản trị cho:
- Cấu hình chunker, retriever và knowledge builder.
- Cấu hình OpenAI embedding.
- Cấu hình EzyVector và Qdrant.
- Quản lý collection.
- Chọn collection mặc định.
- Lập chỉ mục bài viết, sản phẩm, media hoặc văn bản.
- Xem danh sách chunk.
- Tìm kiếm thử trên collection.
- Kích hoạt hoặc vô hiệu hóa collection.
flowchart LR
ADMIN["Quản trị viên"] --> UI["Giao diện quản trị"]
UI --> API["API quản trị"]
API --> SETTINGS["Cấu hình"]
API --> COLLECTIONS["Quản lý collection"]
API --> INDEXING["Lập chỉ mục dữ liệu"]
API --> SEARCH["Kiểm tra tìm kiếm"]
Các API quản trị được bảo vệ bởi cơ chế xác thực của EzyPlatform. Giá trị nhạy cảm như API key được truy cập qua dịch vụ cấu hình dành cho mật khẩu, không được nhúng trực tiếp trong mã nguồn.
Web plugin
Web plugin cung cấp phiên bản runtime của các thành phần SDK:
- Repository và service truy cập dữ liệu.
- Data loader cho bài viết, sản phẩm, media và văn bản.
- Bộ đọc tài liệu.
- Cleaner, chunker và query processor.
- Embedding service.
- Adapter EzyVector và Qdrant.
- Data retriever và knowledge builder.
- Knowledge data source cho EzyAI.
Web plugin chủ yếu đóng vai trò kết nối SDK với dependency container và tài nguyên của web runtime.
Socket plugin
Socket plugin tích hợp nguồn tri thức RAG vào luồng socket và chat thời gian thực.
flowchart LR
CLIENT["Ứng dụng chat"] --> SOCKET["Socket runtime"]
SOCKET --> AI["EzyAI"]
AI --> SOURCE["Nguồn tri thức EzyRAG"]
SOURCE --> SEARCH["Tìm kiếm vector"]
SEARCH --> CONTEXT["Các đoạn liên quan"]
CONTEXT --> AI
AI --> SOCKET
SOCKET --> CLIENT
Socket plugin không tạo ra một giao thức RAG độc lập cho client. Nó đăng ký search strategy và knowledge data source để hạ tầng EzyAI gọi nội bộ.
Ranh giới trách nhiệm
flowchart LR
CONTENT["Nội dung website"] --> RAG["EzyRAG<br/>Chuẩn bị và truy hồi tri thức"]
QUESTION["Câu hỏi"] --> RAG
RAG --> CONTEXT["Ngữ cảnh liên quan"]
CONTEXT --> AI["EzyAI<br/>Điều phối LLM và sinh câu trả lời"]
QUESTION --> AI
AI --> ANSWER["Câu trả lời"]
EzyRAG chịu trách nhiệm:
- Nạp và chuẩn hóa dữ liệu.
- Chia dữ liệu thành chunk.
- Tạo và lưu embedding.
- Quản lý collection.
- Tìm kiếm theo vector.
- Khôi phục nội dung và metadata.
- Cung cấp tri thức cho EzyAI.
EzyRAG không chịu trách nhiệm:
- Huấn luyện mô hình ngôn ngữ.
- Sinh câu trả lời cuối cùng.
- Quản lý hội thoại.
- Tự động đánh giá độ chính xác của câu trả lời.
- Đảm bảo mọi vector cũ được dọn khỏi vector database trong chính luồng tái lập chỉ mục.