Luồng truy vấn dữ liệu trong EzyRAG
Back to ezyragEzyRAG tiếp nhận câu hỏi, biến câu hỏi thành vector, tìm các chunk gần nhất trong kho vector, rồi đọc lại nội dung đầy đủ từ cơ sở dữ liệu ứng dụng. Kết quả cuối cùng là dữ liệu tri thức để EzyAI hoặc một thành phần AI khác sử dụng khi sinh câu trả lời.
Tổng quan luồng truy vấn
flowchart LR
USER["Câu hỏi"] --> SELECT["Chọn dịch vụ vector<br/>và collection"]
SELECT --> PROCESS["Tiền xử lý truy vấn"]
PROCESS --> EMBED["Sinh embedding"]
EMBED --> SEARCH["Tìm kiếm vector"]
SEARCH --> IDS["Chunk ID, điểm tương đồng<br/>và payload"]
IDS --> RETRIEVE["Đọc chunk và metadata<br/>từ cơ sở dữ liệu"]
RETRIEVE --> BUILD["Chuyển thành<br/>dữ liệu tri thức"]
BUILD --> AI["EzyAI hoặc<br/>ứng dụng AI"]
Luồng này chỉ đảm nhiệm phần truy hồi của Retrieval-Augmented Generation. EzyRAG không trực tiếp gọi mô hình ngôn ngữ để sinh câu trả lời cuối cùng.
Chọn collection
Mỗi truy vấn cần xác định hai thành phần:
- Dịch vụ vector database.
- Collection chứa các vector cần tìm kiếm.
Ứng dụng có thể truyền hai thông tin này qua tham số của truy vấn. Nếu không được cung cấp, EzyRAG lần lượt sử dụng:
- Dịch vụ vector database mặc định.
- Collection mặc định của dịch vụ vector đó.
Sau khi có tên dịch vụ và tên collection, hệ thống đọc thông tin collection từ cơ sở dữ liệu ứng dụng. Thông tin này bao gồm tên collection, địa chỉ kết nối riêng nếu có và kích thước vector.
Nếu thiếu cấu hình mặc định hoặc không tìm thấy collection tương ứng, nguồn tri thức trả về danh sách rỗng thay vì tiếp tục truy vấn.
Trạng thái kích hoạt của collection hiện không được kiểm tra trong luồng tìm kiếm. Vì vậy, một collection tồn tại nhưng được đánh dấu không hoạt động vẫn có thể được dùng nếu được chọn trực tiếp hoặc đang là collection mặc định.
Tiền xử lý câu hỏi
Câu hỏi đi qua một chuỗi query processor trước khi được chuyển thành embedding. Các processor được đăng ký trong dependency container và được thực thi tuần tự.
Processor mặc định thực hiện hai thao tác:
- Xóa khoảng trắng ở đầu và cuối câu hỏi.
- Gom nhiều ký tự khoảng trắng liên tiếp thành một khoảng trắng.
Ví dụ:
" chính sách đổi trảncủa cửa hàng "
được chuẩn hóa thành:
"chính sách đổi trả của cửa hàng"
Mỗi processor nhận kết quả của processor đứng trước. Thiết kế này cho phép bổ sung các bước như sửa chính tả, chuẩn hóa từ khóa, mở rộng truy vấn hoặc chuyển đổi ngôn ngữ mà không cần thay đổi pipeline chính.
EzyRAG không từ chối truy vấn rỗng tại bước này. Nếu đầu vào rỗng hoặc chỉ chứa khoảng trắng, dữ liệu đó vẫn có thể được gửi tới embedding service và lỗi, nếu có, sẽ phụ thuộc vào nhà cung cấp embedding.
Sinh embedding cho truy vấn
Sau khi tiền xử lý, câu hỏi được gửi tới embedding service đang được cấu hình.
Request embedding gồm:
- Nội dung truy vấn đã xử lý.
- Kiểu dữ liệu là văn bản.
- Kích thước vector lấy từ collection.
Việc dùng kích thước của collection giúp vector truy vấn tương thích với các vector chunk đã được lập chỉ mục.
Embedding service hiện tại xử lý đầu vào văn bản. Dữ liệu không phải chuỗi hoặc kiểu nội dung không được hỗ trợ sẽ bị từ chối. Pipeline cũng không tự kiểm tra xem model embedding hiện tại có giống model đã dùng khi lập chỉ mục hay không.
Điều này dẫn đến một yêu cầu vận hành quan trọng: truy vấn và dữ liệu trong collection phải được tạo bằng các model có không gian vector tương thích. Chỉ trùng số chiều là chưa đủ để bảo đảm kết quả tìm kiếm có ý nghĩa.
Tìm kiếm trong vector database
Vector truy vấn được gửi tới adapter của vector database cùng với:
- Tên collection.
- Số lượng kết quả tối đa.
- Vector truy vấn.
EzyRAG hiện hỗ trợ hai backend vector. Cả hai adapter đều chuyển response về một mô hình kết quả chung:
{
"chunkId": 456,
"score": 0.87,
"payload": {
"sourceType": "post",
"sourceId": 123,
"chunkIndex": 2
}
}
Trong đó:
-
chunkIdlà ID dùng để đọc lại chunk trong cơ sở dữ liệu ứng dụng. -
scorelà điểm tương đồng do vector database trả về. -
payloadchứa thông tin tối thiểu về nguồn và vị trí của chunk.
Số lượng kết quả được chuyển thẳng xuống vector database. Luồng hiện tại không áp dụng:
- Ngưỡng điểm tối thiểu.
- Bộ lọc metadata.
- Hybrid search giữa vector và từ khóa.
- Reranking.
- Loại bỏ các chunk trùng nguồn.
- Điều chỉnh
limittheo kích thước context của mô hình ngôn ngữ.
Do đó, chất lượng và thứ tự kết quả ở bước này chủ yếu phụ thuộc vào embedding, dữ liệu đã lập chỉ mục và thuật toán của vector database.
Đọc lại nội dung chunk
Kho vector chỉ cung cấp định danh, điểm và payload tối thiểu. Nội dung đầy đủ không được lấy trực tiếp từ payload.
Data retriever thực hiện các bước sau:
- Trích danh sách
chunkIdtừ kết quả tìm kiếm vector. - Đọc các chunk tương ứng từ cơ sở dữ liệu ứng dụng.
- Đọc metadata theo cùng danh sách ID.
- Ghép nội dung chunk với metadata.
- Chuyển từng chunk thành một tài liệu RAG trung gian.
flowchart TB
VECTOR["Kết quả vector"] --> CHUNK_IDS["Danh sách chunk ID"]
CHUNK_IDS --> CONTENT["Đọc nội dung chunk"]
CHUNK_IDS --> META["Đọc metadata"]
CONTENT --> DOCUMENT["Tài liệu RAG"]
META --> DOCUMENT
Việc dùng chung ID giữa bản ghi chunk và vector point giúp quá trình ánh xạ không cần thêm một bảng liên kết.
Tuy nhiên, điểm tương đồng và payload từ vector database không được đưa vào tài liệu trung gian mặc định. Sau bước truy hồi nội dung, dữ liệu tri thức chỉ còn thông tin nguồn, nội dung và metadata.
Ngoài ra, việc đọc nhiều bản ghi theo tập ID không thể hiện rõ cam kết giữ nguyên thứ tự xếp hạng từ vector database. Nếu repository không bảo toàn thứ tự của danh sách ID đầu vào, thứ tự tài liệu trả về có thể khác thứ tự theo điểm tương đồng.
Xây dựng dữ liệu tri thức
Knowledge builder chuyển tài liệu RAG thành cấu trúc mà EzyAI hiểu được.
Mỗi kết quả thường chứa:
- ID của nguồn gốc.
- Loại nguồn.
- Tiêu đề.
- Slug.
- Nội dung chunk.
- Tóm tắt.
- URL dữ liệu.
- Thông tin sản phẩm như mã, giá và đơn vị tiền tệ nếu có.
Kết quả được đánh dấu là dữ liệu đã chia chunk. Mỗi vector match tạo thành một phần tử tri thức riêng; pipeline tìm kiếm không tự ghép các chunk thuộc cùng một nguồn.
Đây là khác biệt đáng chú ý so với luồng lấy dữ liệu trực tiếp theo ID hoặc mã nguồn. Với truy vấn trực tiếp, hệ thống có thể đọc toàn bộ chunk của một nguồn và ghép nội dung theo thứ tự. Với tìm kiếm ngữ nghĩa, EzyRAG chỉ trả về các chunk phù hợp được vector database chọn.
Tích hợp với EzyAI
Trong luồng chat, EzyAI gọi nguồn tri thức EzyRAG với câu hỏi, tham số tìm kiếm và giới hạn kết quả.
sequenceDiagram
participant U as Người dùng
participant AI as EzyAI
participant R as EzyRAG
participant E as Embedding service
participant V as Vector database
participant D as Cơ sở dữ liệu ứng dụng
U->>AI: Gửi câu hỏi
AI->>R: Tìm dữ liệu tri thức
R->>R: Chọn collection và chuẩn hóa truy vấn
R->>E: Sinh embedding
E-->>R: Vector truy vấn
R->>V: Tìm kiếm vector với limit
V-->>R: Chunk ID, score và payload
R->>D: Đọc chunk và metadata
D-->>R: Nội dung đầy đủ
R-->>AI: Danh sách dữ liệu tri thức
AI-->>U: Sinh câu trả lời dựa trên ngữ cảnh
Nếu có lỗi trong quá trình tìm kiếm, lớp tích hợp nguồn tri thức ghi log cảnh báo và trả về danh sách rỗng. Nhờ đó luồng chat có thể tiếp tục, nhưng mô hình ngôn ngữ sẽ không nhận được ngữ cảnh từ EzyRAG cho truy vấn đó.
Khi gọi trực tiếp SDK thay vì thông qua nguồn tri thức, lỗi từ embedding provider, vector database hoặc cấu hình có thể được truyền ngược cho bên gọi.
Truy vấn trực tiếp theo nguồn
Ngoài tìm kiếm ngữ nghĩa, EzyRAG hỗ trợ đọc tri thức trực tiếp theo:
- Loại nguồn và danh sách ID.
- Loại nguồn cùng một ID.
- Loại nguồn cùng slug hoặc mã sản phẩm.
Luồng này không tạo embedding và không truy vấn vector database:
Loại nguồn + ID hoặc mã → tìm chunk trong cơ sở dữ liệu → đọc metadata → sắp xếp và ghép các chunk của cùng nguồn → tạo dữ liệu tri thức
Khi một nguồn có nhiều chunk, nội dung được ghép bằng hai ký tự xuống dòng. Thông tin mô tả của kết quả hợp nhất được lấy từ chunk đầu tiên.
Đây là cơ chế truy xuất theo định danh, không phải semantic search.
Cấu hình và tính mở rộng
Các giai đoạn chính của luồng truy vấn đều nằm sau interface và manager:
- Query processor.
- Embedding service.
- Vector database adapter.
- Data retriever.
- Knowledge data builder.
Nhờ đó, ứng dụng có thể bổ sung cách chuẩn hóa truy vấn, provider embedding, backend vector hoặc định dạng tri thức mới mà không thay đổi bộ điều phối chính.
Các implementation được lấy từ dependency container và tra cứu theo tên cấu hình. Nếu tên đã cấu hình không ánh xạ tới implementation nào, truy vấn không thể tiếp tục.
Bảo mật và ranh giới trách nhiệm
API key của embedding provider và vector database được đọc từ dịch vụ cấu hình tại runtime. Các giá trị này không nên xuất hiện trong nội dung truy vấn, metadata hoặc source code.
Adapter vector database chỉ gửi API key khi cấu hình có giá trị. Embedding provider dùng cơ chế bearer token cho lời gọi API.
Pipeline lõi không tự thực hiện xác thực người dùng hay kiểm tra quyền truy cập theo từng chunk. Việc xác thực, phân quyền truy cập collection và giới hạn dữ liệu người dùng phải được xử lý ở lớp web, socket hoặc ứng dụng gọi EzyRAG.
Điều này đặc biệt quan trọng trong hệ thống nhiều tenant: nếu nhiều nhóm người dùng dùng chung collection, semantic search có thể trả về chunk mà người gọi không có quyền xem, vì truy vấn hiện chưa có bộ lọc quyền ở tầng vector.
Các điểm cần lưu ý
- Vector database service dùng để thực thi tìm kiếm được lấy từ cấu hình runtime chung. Collection được chọn cần thuộc đúng backend này; pipeline chưa tự chuyển service theo thông tin collection.
- Không có kiểm tra trạng thái hoạt động của collection trước khi tìm kiếm.
- Không có kiểm tra truy vấn rỗng hoặc giới hạn kết quả không hợp lệ.
- Không có score threshold, metadata filter hoặc reranking.
- Điểm tương đồng bị loại khỏi kết quả tri thức cuối cùng.
- Thứ tự sau khi đọc chunk từ cơ sở dữ liệu có thể không giữ nguyên xếp hạng vector nếu repository không cam kết thứ tự.
- Các chunk từ cùng một nguồn không được hợp nhất hoặc loại trùng trong semantic search.
- Lỗi ở lớp tích hợp EzyAI được chuyển thành danh sách rỗng, nên bên gọi không phân biệt được “không có kết quả” với “truy vấn thất bại” chỉ từ giá trị trả về.
- Model embedding dùng khi truy vấn phải tương thích với model đã dùng để lập chỉ mục.
- Pipeline không thực hiện authorization ở cấp tài liệu hoặc chunk.
Tóm tắt
Nhận câu hỏi → chọn dịch vụ vector và collection → chuẩn hóa câu hỏi → tạo embedding theo kích thước collection → tìm các vector gần nhất → lấy danh sách chunk ID → đọc nội dung và metadata từ cơ sở dữ liệu → xây dựng dữ liệu tri thức → chuyển cho EzyAI
Thiết kế tách kho vector khỏi cơ sở dữ liệu nội dung giúp payload vector gọn và việc quản lý dữ liệu nghiệp vụ linh hoạt hơn. Các điểm mở rộng cho phép thay thế từng giai đoạn độc lập. Khi triển khai thực tế, ứng dụng nên bổ sung kiểm tra truy vấn, bảo toàn thứ tự theo score, lọc quyền truy cập, score threshold, xử lý lỗi có quan sát và bảo đảm collection sử dụng đúng embedding model cùng vector backend.