Nguyên tắc Vector Search Contract Thống nhất — SSOT
Nguyên tắc Vector Search Contract Thống nhất — SSOT
Date: 2026-05-11 Origin: Thảo luận Huyên + Opus, phiên P3D Pack 1 + Vector Search Boost Tinh thần: SSOT tuyệt đối — 1 search contract, mọi collection dùng chung Liên quan: P3D Spec §M (Vector Boundary), IU-0 §6 (Vector design), Track A (Legacy vector)
1. Bối cảnh
Hệ thống hiện có 1 kho vector (legacy KB production_documents, 2400+ docs, chunk theo ký tự). Tương lai sẽ có kho thứ 2 (IU vector, chunk theo ranh giới miếng thông tin). Nếu mỗi kho xây search logic riêng → sửa 1 quên 1 → vi phạm SSOT.
Phát sinh từ việc xử lý lỗi search ranking (root cause: SEARCH_RANKING_NO_PATH_TITLE_BOOST). Giải pháp hybrid rerank (boost path/title/tag) phải trở thành tiêu chuẩn chung cho mọi vector search, không chỉ riêng legacy KB.
2. Nguyên tắc — 3 tầng
| Tầng | Mô tả | Dùng chung? | Ghi chú |
|---|---|---|---|
| Chunking (cách cắt thành chunks) | Quy tắc chia nhỏ nội dung trước khi embed | ❌ KHÁC per collection | Legacy: cắt theo ký tự (~4000/400). IU: cắt theo ranh giới miếng (1 chunk ⊂ 1 logical_unit + 1 unit_version). Đây là điểm khác duy nhất. |
| Storage (kho Qdrant) | Collection riêng per use case | ❌ RIÊNG per use case | Legacy: production_documents. IU: collection riêng (IU-0 đã quyết: song song, không mutate legacy). Nhưng metadata payload format phải thống nhất. |
| Search + Rerank (tìm + xếp hạng) | Logic tìm kiếm + hybrid rerank | ✅ CHUNG — SSOT | 1 function _rerank_results() serve tất cả collections. Boost path/title/tag/basename/directory. Không có version riêng per collection. |
3. Hình tượng
2 kho sách (legacy + IU), cách xếp sách lên kệ khác nhau (chunking), nhưng 1 quầy trợ lý duy nhất (search + rerank) phục vụ cả 2 kho. Khách hỏi sách → trợ lý tìm trong cả 2 kho bằng cùng 1 cách → trả kết quả thống nhất.
4. IU vector kế thừa từ legacy (không xây lại)
| Thành phần | Kế thừa nguyên từ legacy |
|---|---|
| Hybrid rerank (boost path/title/tag) | ✅ Dùng chung _rerank_results() |
| Dedup by document_id | ✅ Cùng logic |
Health audit pattern (/kb/audit-sync) |
✅ Mở rộng cho IU collection |
| Sync trigger pattern (PG → Qdrant) | ✅ Cùng pg_notify + listener pattern |
| Qdrant payload metadata format | ✅ Thống nhất: document_id, title, tags, chunk_index, total_chunks |
Feature flag (SEARCH_RERANK_ENABLED) |
✅ Áp dụng toàn cục |
5. IU vector bổ sung (legacy không có)
| Thành phần | Chỉ IU có | Lý do |
|---|---|---|
logical_unit_id trong Qdrant payload |
✅ | Search filter "tìm trong đúng miếng này" — legacy KB không biết "miếng" là gì |
unit_version_id trong Qdrant payload |
✅ | Truy vết chunk thuộc version nào |
| Chunk boundary guarantee | ✅ | 1 chunk luôn nằm trọn trong 1 miếng — legacy chunk có thể cắt ngang giữa câu |
unit_kind trong Qdrant payload |
✅ | Filter theo loại miếng (law_unit, sop_step, knowledge_atom...) |
6. Quy tắc SSOT cho vector
-
Search contract là SSOT:
_rerank_results()là function duy nhất quyết định ranking. Mọi collection phải đi qua function này. Không có "search riêng cho IU" hay "search riêng cho legacy". -
Metadata payload format là SSOT: Mọi Qdrant point phải có ít nhất:
document_id,metadata.title,metadata.tags,metadata.chunk_index,metadata.total_chunks. IU thêm:metadata.logical_unit_id,metadata.unit_version_id,metadata.unit_kind. -
Chunking strategy là biến, không phải SSOT: Mỗi collection có chunking strategy riêng phù hợp use case. Nhưng chunk không bao giờ span 2 miếng (đối với IU vector).
-
Cải tiến search phải áp dụng cho TẤT CẢ collections: Nếu thêm boost mới (vd: recency boost, revision boost) → thêm vào
_rerank_results()→ tự động áp dụng cho mọi collection. Không patch riêng. -
Health audit phải cover TẤT CẢ collections:
dot-vector-auditphải kiểm cảproduction_documentslẫn IU collection (khi có). Không để 1 collection "vô hình" với audit.
6b. Lưu ý quan trọng khi triển khai IU vector (miếng thông tin)
Quy tắc sắt: 1 vector chunk TUYỆT ĐỐI chỉ chứa data từ đúng 1 miếng thông tin (1 logical_unit + 1 unit_version). KHÔNG BAO GIỜ có chuyện 1 vector chunk chứa nội dung từ 2 miếng khác nhau.
Hình tượng: Mỗi miếng thông tin là 1 căn phòng. Vector chunk là tấm ảnh chụp trong phòng. Tấm ảnh chỉ được chụp trong đúng 1 phòng — không bao giờ có tấm ảnh chụp nửa phòng này nửa phòng kia.
Nếu miếng dài (vượt giới hạn chunk) → cắt thành nhiều chunks nhưng tất cả chunks đều nằm trong cùng 1 miếng. Đây là điểm khác duy nhất giữa IU vector và legacy KB vector:
| Legacy KB vector | IU vector (miếng thông tin) | |
|---|---|---|
| Cắt chunk | Theo số ký tự (~4000/400) — có thể cắt ngang giữa 2 miếng | Theo ranh giới miếng — KHÔNG BAO GIỜ cắt vượt ranh giới |
| Hệ quả | 1 chunk có thể chứa nội dung "nửa miếng A + nửa miếng B" | 1 chunk luôn thuộc đúng 1 miếng, 1 version |
| Truy vết | Chỉ biết chunk thuộc document nào | Biết chính xác chunk thuộc miếng nào, version nào |
Mọi search contract khác (rerank, boost, canary, audit) → dùng chung, chỉ chunking strategy là khác.
7. Áp dụng khi nào
- Ngay bây giờ: Hybrid boost cho legacy KB (
production_documents) — đang implement. - Khi làm IU vector (P3D Pack 9): Tạo IU collection riêng, nhưng search function dùng chung
_rerank_results(), metadata format thống nhất, audit mở rộng. - Khi reconcile TAC↔IU (Pack 1 resume): 86 TAC units migrate vào IU → IU vector chunks replace legacy chunks cho những docs đã migrate. Legacy chunks cho docs chưa migrate vẫn giữ nguyên.
8. Liên kết luật
| Luật | Liên quan |
|---|---|
| Đ38 §A3 | Vector projection = PG là SoT, Qdrant là projection |
| Đ39 (Knowledge Graph) | Vector + KG bidirectional sync — Tier 5 |
| Đ44 NS-1 | 1 family, 1 contract — không duplicate search logic |
| LSL-01 v0.4 P9 | Vector chunk ⊂ 1 unit |
| IU-0 §6 | IU vector = hệ song song, không mutate legacy |
| P38-XC §5.7 | UMC independent of TAC — vector contract cũng independent |
Vector Search Contract Thống nhất | SSOT | 2026-05-11 | Huyên + Opus