KB-69A0 rev 2

Nguyên tắc Vector Search Contract Thống nhất — SSOT

7 min read Revision 2
p3dvector-searchssotunified-contractrerankchunkingiu-vectorlegacy-kbdesign-principle

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

  1. 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".

  2. 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.

  3. 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).

  4. 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.

  5. Health audit phải cover TẤT CẢ collections: dot-vector-audit phải kiểm cả production_documents lẫ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