Vector DB 8 — Vận hành production & use case ngân hàng

13 thg 7, 2026 3 lượt xem
#ai
#rag
#banking
#production
#vector-database

Từ demo đến production — nơi mọi thứ thật sự khó

Cả loạt Vector DB đã đi từ tổng quan, embeddings, ANN indexes, pgvector, vector databases, hybrid search đến retrieval cho RAG. Tất cả những bài đó trả lời câu hỏi "làm sao tìm đúng đoạn". Bài cuối này trả lời câu hỏi khác, khó hơn và ít được nói tới: làm sao cho hệ đó chạy ổn định, an toàn, đúng luật trong nhiều năm ở một ngân hàng.

Một demo RAG dựng trong hai ngày rất ấn tượng. Nhưng demo không phải xử lý tài liệu thay đổi hàng ngày, không phải chịu 500 truy vấn/giây, không bị kiểm toán hỏi "ai đã hỏi gì, hệ trả về tài liệu nào, người đó có quyền xem không", không phải giải trình chi phí hạ tầng, và không bị hỏi "dữ liệu khách hàng có bị gửi ra API bên ngoài không". Khoảng cách giữa demo và production chính là nội dung bài này.

Ta đi qua sáu trụ cột vận hành — cập nhật dữ liệu, scaling, monitoring, chi phí, bảo mật & tuân thủ, đánh giá liên tục — rồi đến kiến trúc tham chiếu self-hostcác use case ngân hàng, cuối cùng là checklist go-live và tổng kết series.

1. Cập nhật dữ liệu — hệ sống, không phải ảnh chụp

Kho vector không phải chụp một lần rồi thôi. Tài liệu ngân hàng đổi liên tục: quy chế sửa, biểu phí cập nhật, thông tư mới ban hành, quy định cũ hết hiệu lực. Nếu index đứng yên, hệ sẽ trả về quy định đã hết hiệu lực — sai lầm nghiêm trọng về nghiệp vụ và pháp lý.

Incremental upsert — cập nhật từng phần

Không re-index cả kho mỗi khi một tài liệu đổi. Thay vào đó cập nhật gia tăng (incremental) theo doc_id:

  • Tài liệu MỚI: chunk → embed → insert.
  • Tài liệu SỬA: xoá toàn bộ chunk cũ của doc_id rồi re-chunk + re-embed + insert. Đơn giản và an toàn hơn cố "vá" từng chunk, vì một lần sửa văn bản có thể dịch chuyển ranh giới mọi chunk phía sau.
  • Tài liệu XOÁ / hết hiệu lực: xoá chunk (hard delete) hoặc đánh dấu valid_until và soft-delete. Ngân hàng thường giữ bản cũ để audit nhưng loại khỏi phạm vi tìm mặc định — dùng soft-delete + filter valid_until >= today.

Cơ chế phát hiện thay đổi: đặt content hash cho mỗi tài liệu; ingest chỉ re-embed khi hash đổi. Điều này tránh embed lại 8.000 tài liệu mỗi đêm chỉ vì 12 tài liệu đổi — tiết kiệm cả tiền lẫn thời gian.

# Minh hoạ (KHÔNG phải SQL chạy được) — vòng lặp ingest gia tăng
for doc in source.changed_since(last_run):
    if doc.deleted:
        store.delete(where={"doc_id": doc.id})           # hoặc soft-delete
        continue
    if store.hash(doc.id) == doc.content_hash:
        continue                                          # không đổi, bỏ qua
    store.delete(where={"doc_id": doc.id})               # xoá chunk cũ
    chunks = chunk(doc)                                   # re-chunk
    vectors = embed_model.encode([c.text for c in chunks])
    store.upsert(build_records(doc, chunks, vectors))    # insert bản mới

Versioning & hiệu lực

Gắn vào metadata mỗi chunk: version, effective_date (ngày có hiệu lực), valid_until (ngày hết hiệu lực). Mặc định query chỉ tìm trong tài liệu đang hiệu lực. Điều này cho phép cả những nghiệp vụ như "so sánh biểu phí bản 2024 và 2025" (multi-hop có kiểm soát version) mà không lẫn lộn.

Re-embed khi đổi mô hình — chiến lược blue-green

Đây là kịch bản đau đầu nhất. Khi bạn nâng cấp mô hình embedding (ví dụ từ một model tiếng Việt cũ sang model mới mạnh hơn), mọi vector cũ trở nên vô nghĩa — vector mới và cũ nằm ở hai không gian khác nhau, không so sánh được. Bạn bắt buộc re-embed toàn bộ kho. Với 1,3 triệu chunk, việc này mất hàng giờ. Không thể dừng dịch vụ suốt thời gian đó.

Giải pháp: blue-green index (còn gọi là re-index song song):

Các bước:

  1. Giữ index BLUE (model cũ) tiếp tục phục vụ traffic thật.
  2. Dựng index GREEN mới, re-embed toàn bộ kho bằng model mới ở chế độ offline.
  3. Chạy golden set trên GREEN, so recall/precision với BLUE — chỉ chuyển khi GREEN không tệ hơn.
  4. Đổi alias (con trỏ tên logic) từ BLUE sang GREEN — traffic chuyển tức thì, người dùng không gián đoạn.
  5. Giữ BLUE thêm vài ngày để rollback nhanh nếu GREEN có vấn đề, rồi mới xoá.

Điểm mấu chốt: ứng dụng luôn trỏ tới một alias chứ không phải tên index vật lý, nhờ đó việc switch chỉ là đổi con trỏ. Đây cũng là nơi các vector database (vec-05) hỗ trợ tốt hơn pgvector thuần — nhiều engine có sẵn khái niệm alias/collection swap.

2. Scaling — khi kho và tải lớn lên

Ba đòn bẩy scaling:

Kỹ thuậtGiải quyếtGhi chú
ShardingKho quá lớn cho 1 node (RAM/đĩa)Chia vector ra nhiều shard, query fan-out rồi gộp kết quả
ReplicaQPS cao, cần HANhân bản index để đọc song song; tăng throughput + chịu lỗi node
Tách index theo domainNhiễu chéo, quyền khác nhauMỗi phòng ban/loại tài liệu một collection riêng

Tách index theo domain đặc biệt hợp ngân hàng: index quy chế tín dụng tách khỏi index chăm sóc khách hàng, tách khỏi index nhân sự. Lợi ích kép: giảm nhiễu (tìm trong đúng phạm vi) và đơn giản hoá phân quyền (một số index nhạy cảm chỉ vài vai trò chạm tới). Đánh đổi: câu hỏi liên phòng cần fan-out nhiều index rồi gộp.

Với HNSW (index ANN phổ biến, xem vec-03), RAM là ràng buộc chính vì đồ thị nằm trong bộ nhớ. Sharding chia nhỏ đồ thị; replica nhân đôi để chịu tải đọc. Ghi (insert/upsert) thường tập trung ở một nhánh rồi đồng bộ sang replica.

3. Monitoring — không đo thì không vận hành được

Vector search khác hệ CRUD ở chỗ nó có thể "chạy mà sai": không lỗi, latency ổn, nhưng chất lượng kết quả tụt dần mà không ai biết. Phải giám sát cả hạ tầng lẫn chất lượng.

NhómChỉ sốVì sao quan trọng
Hiệu năngĐộ trễ p95/p99Trải nghiệm; rerank/HyDE dễ đẩy đuôi latency lên
Hiệu năngQPS / throughputLập kế hoạch capacity, phát hiện quá tải
Chất lượngRecall @KĐo trên golden set định kỳ — có bỏ sót đoạn đúng không
Chất lượngTỷ lệ "no good result"% truy vấn mà điểm tương đồng cao nhất vẫn dưới ngưỡng → hệ đang bí
Dữ liệuFreshness / độ trễ indexTài liệu đổi bao lâu thì vào kho — chống trả quy định cũ
Chi phíToken LLM, chi phí embedKiểm soát ngân sách vận hành

Hai chỉ số dễ bị bỏ quên nhưng cực giá trị:

  • Tỷ lệ truy vấn không có kết quả tốt: khi similarity cao nhất vẫn thấp hơn ngưỡng, đó là dấu hiệu thiếu tài liệu hoặc câu hỏi ngoài phạm vi. Thu thập các câu này → biết cần bổ sung tri thức gì. Thà trả lời "tôi không tìm thấy quy định về việc này" còn hơn bịa.
  • Freshness: đo khoảng cách từ lúc tài liệu được duyệt ban hành đến lúc nó xuất hiện trong kết quả tìm. Ngân hàng cần con số này nhỏ và có SLA.

4. Chi phí — vector rất "ngốn"

Vector chiếm nhiều bộ nhớ. Một vector 1024 chiều float32 = 4KB; 1,3 triệu chunk ≈ 5,3 GB chỉ riêng vector thô, chưa kể đồ thị HNSW (thường gấp rưỡi–gấp đôi). Ba hướng tối ưu:

  • Quantization (lượng tử hoá): giảm độ chính xác số để tiết kiệm RAM. Scalar quantization (float32 → int8) giảm ~4× bộ nhớ, mất rất ít recall. Binary quantization (mỗi chiều → 1 bit) giảm ~32×, nhanh khủng khiếp nhưng mất recall nhiều hơn — thường dùng làm tầng lọc thô rồi rerank lại bằng vector gốc. Product quantization (PQ) nén mạnh hơn, cân bằng khác.
  • Giảm số chiều: chọn model embedding chiều thấp hơn nếu chất lượng chấp nhận được; một số model hỗ trợ Matryoshka (cắt bớt chiều mà vẫn dùng được).
  • Phân tầng lưu trữ: vector "nóng" (hay tra) để RAM, vector "nguội" đẩy xuống đĩa/tầng rẻ hơn.

Self-host vs SaaS

Đây là quyết định lớn, và với ngân hàng thường không chỉ là bài toán tiền:

Tiêu chíSelf-hostSaaS (vector DB cloud)
Chi phí ban đầuCao (hạ tầng, vận hành)Thấp, trả theo dùng
Vận hànhĐội ngũ tự loNhà cung cấp lo
Chủ quyền dữ liệuDữ liệu ở lại nội bộDữ liệu rời khỏi ngân hàng
Tuân thủDễ kiểm soát, dễ auditPhụ thuộc chứng chỉ nhà cung cấp
Mở rộngTự làmCo giãn sẵn

Với dữ liệu nhạy cảm (hồ sơ tín dụng, PII khách hàng), yếu tố chủ quyền dữ liệu và tuân thủ thường áp đảo yếu tố chi phí. Nhiều ngân hàng chọn self-host cho lớp dữ liệu nội bộ dù đắt hơn — xem thêm góc chi phí ở Snowflake 6 — Quản lý chi phíBigQuery 5 — Chi phí & hiệu năng để đối chiếu tư duy tối ưu, dù bối cảnh khác.

5. Bảo mật & tuân thủ — trụ cột sống còn với ngân hàng

Đây là phần khiến một dự án RAG ngân hàng khác hẳn một chatbot thông thường. Bốn ràng buộc cứng:

Phân quyền tài liệu ở tầng retrieval

Nguyên tắc thép: lọc quyền ở retrieval, KHÔNG ở generation. LLM không được phép "nhìn thấy" đoạn mà người dùng không có quyền — ngay từ bước tìm, chứ không dựa vào việc "hy vọng LLM không lộ". Mỗi chunk mang acl_roles/acl_groups trong metadata; mọi truy vấn bắt buộc kèm filter theo vai trò người đang hỏi. Chi tiết cơ chế xem Vector DB 7 — Retrieval cho RAGGovernance — Kiểm soát truy cập.

# Minh hoạ (KHÔNG phải SQL chạy được) — filter quyền là BẮT BUỘC, không tuỳ chọn
results = store.hybrid_search(
    query_vector=embed(query), query_text=query, top_n=40,
    filter={"must": [
        {"acl_roles has_any": user.roles},   # KHÔNG có dòng này = lỗ hổng bảo mật
        {"valid_until >=": today()},
    ]},
)
# Nếu thiếu filter ACL, LLM có thể trích dẫn tài liệu ngoài quyền → rò rỉ.

Không rò rỉ PII qua embedding/RAG

Vector embedding không phải mã hoá — nó là biểu diễn ngữ nghĩa và trong nhiều trường hợp có thể bị đảo ngược một phần để suy ra nội dung gốc (embedding inversion). Do đó:

  • Đừng embed thông tin nhạy cảm không cần thiết: mask/tokenize số CCCD, số thẻ, số tài khoản trước khi embed nếu chúng không cần cho tìm kiếm.
  • Coi vector store như dữ liệu nhạy cảm: cùng mức bảo vệ với dữ liệu gốc, không "hạ cấp" vì "nó chỉ là số".
  • Kiểm soát cả câu trả lời: LLM có thể vô tình nhắc lại PII trong context — thêm bước lọc/redaction đầu ra khi cần.

Mã hoá & audit

  • Mã hoá: at-rest (kho vector, metadata) và in-transit (TLS mọi kết nối). Metadata thường chứa doc_title, department — cũng cần bảo vệ.
  • Audit truy vấn: log ai hỏi gì, lúc nào, hệ trả về tài liệu nào, người đó có quyền không, câu trả lời gì. Đây là yêu cầu kiểm toán bắt buộc. Log này cũng là feedback loop để cải tiến.

Dữ liệu nội bộ KHÔNG gửi ra API ngoài

Ràng buộc nền tảng: với dữ liệu nội bộ/khách hàng, cả bước embedding lẫn bước gọi LLM đều phải tự host — không gửi nội dung tài liệu hay câu hỏi chứa dữ liệu nhạy cảm ra API bên ngoài. Nghĩa là:

  • Mô hình embedding chạy nội bộ (self-host).
  • Mô hình LLM sinh câu trả lời chạy nội bộ (open-weight tự vận hành trong hạ tầng ngân hàng).
  • Reranker cũng self-host.

Đây là lý do kiến trúc tham chiếu bên dưới hoàn toàn self-host. Về góc triển khai/vận hành mô hình, đối chiếu ML 8 — Deployment & MLOps.

6. Đánh giá & cải tiến liên tục

Đưa lên production không phải điểm kết thúc mà là điểm bắt đầu của vòng lặp cải tiến:

  • Golden set: bộ vài trăm câu hỏi nghiệp vụ + đoạn đúng + câu trả lời chuẩn do chuyên gia duyệt. Chạy lại sau mỗi thay đổi (đổi chunk size, model, top-K, ngưỡng) để bắt hồi quy. Đây là "unit test" của RAG.
  • Feedback loop: nút 👍/👎 và ô góp ý trong ứng dụng. Câu bị 👎 → đưa vào hàng đợi rà soát; câu tốt → có thể bổ sung golden set. Kết hợp với log truy vấn "không có kết quả tốt" để biết thiếu tri thức ở đâu.
  • A/B & offline eval: thay đổi lớn nên A/B trên tập nhỏ trước khi rollout, đo bằng số (RAGAS: context precision/recall, faithfulness — xem vec-07) chứ không theo cảm tính.

Kiến trúc tham chiếu end-to-end (self-host)

Ghép tất cả lại thành một kiến trúc production ngân hàng tự host hoàn toàn:

Điểm cốt lõi: ba mô hình (embedding, reranker, LLM) đều nằm trong biên giới ngân hàng; ACL được áp ở retrieve; mọi truy vấn được audit; feedback quay lại nuôi golden set. Về luồng RAG chi tiết, xem LLM 4 — RAG.

Cạm bẫy thường gặp

  • Index đứng yên: quên incremental update → trả quy định hết hiệu lực.
  • Đổi embedding model mà không re-embed: trộn hai không gian vector → kết quả rác. Luôn re-embed toàn bộ + blue-green.
  • Filter ACL ở tầng sai: dựa vào LLM "tự giác" không lộ thay vì lọc ở retrieve → rò rỉ dữ liệu.
  • Coi vector là ẩn danh: embedding có thể lộ nội dung → phải bảo vệ như dữ liệu gốc.
  • Gửi dữ liệu nội bộ ra API ngoài: vi phạm tuân thủ. Self-host cả embedding lẫn LLM.
  • Không có golden set: tinh chỉnh theo cảm tính, không bắt được hồi quy.
  • Nhồi quá nhiều context: chi phí tăng, "lost in the middle", chất lượng giảm.
  • Bỏ qua monitoring chất lượng: hệ "chạy mà sai" âm thầm.

Use case thực tế

Vector search/RAG ở ngân hàng không chỉ là chatbot. Các use case chính:

Use caseMô tảKỹ thuật chính
Trợ lý tra cứu quy định nội bộNhân viên hỏi quy chế/quy trình/biểu phíRAG + citation + ACL
Chatbot CSKHTrả lời khách về sản phẩm, phí, thủ tụcRAG trên FAQ/tài liệu công khai
Tìm kiếm ngữ nghĩa tài liệu/email/hồ sơTìm theo ý nghĩa thay vì từ khoáHybrid search + filter
Entity resolution / phát hiện trùng lặp KHGộp hồ sơ cùng một khách hàng dù dữ liệu lệchEmbedding text hồ sơ + tìm gần
Gợi ýSản phẩm/tài liệu tương tựSimilarity search
Phân tích khiếu nạiGom cụm, tìm khiếu nại tương tự, định tuyếnEmbedding + clustering

Bối cảnh triển khai (nối tiếp vec-07): NCB đưa trợ lý tra cứu quy định nội bộ cho ~2.000 nhân viên lên production. Kho 8.400 tài liệu → 1,3 triệu chunk trong vector store self-host.

Bài toán vận hành sau go-live:

  • Cập nhật: ~15–40 tài liệu đổi mỗi ngày. Job ingest chạy 2 lần/ngày, dùng content hash → chỉ re-embed tài liệu đổi. Freshness đạt < 6 giờ.
  • Re-embed model: sau 8 tháng nâng cấp embedding model tiếng Việt. Dùng blue-green: dựng GREEN qua đêm (~4 giờ re-embed 1,3 triệu chunk), chạy golden set 300 câu — recall GREEN 0,95 vs BLUE 0,93 → switch alias lúc 6h sáng, người dùng không gián đoạn. Giữ BLUE 5 ngày rồi xoá.
  • Chi phí: bật scalar quantization (int8) → RAM cho vector giảm ~4× (từ ~12 GB xuống ~3 GB kể cả đồ thị), recall chỉ giảm 0,01 — chấp nhận được.
  • Bảo mật: toàn bộ embedding + reranker + LLM self-host trong DC ngân hàng; ACL filter ở retrieve; audit mọi truy vấn. Red-team ACL định kỳ: không rò rỉ tài liệu ngoài quyền.
  • Monitoring: p95 ~380ms; theo dõi "tỷ lệ no-good-result" ~7% → phần lớn là câu hỏi ngoài phạm vi tài liệu hiện có, đưa vào backlog bổ sung tri thức. Feedback 👎 gom vào golden set, nâng dần bộ test lên 480 câu.

Kết quả: hệ chạy ổn định, cập nhật kịp thời, không rò rỉ dữ liệu, chi phí RAM giảm 4×, và mỗi thay đổi đều được golden set gác cửa. Đây mới là "production", khác hẳn demo ban đầu.

Tổng kết series

Cả loạt Vector DB đi từ nguyên lý đến vận hành: vector hoá ý nghĩa (vec-01, vec-02), tìm nhanh trong không gian nhiều chiều bằng ANN (vec-03), triển khai trên pgvector hay vector DB chuyên dụng (vec-04, vec-05), kết hợp ngữ nghĩa với từ khoá (vec-06), lấy đúng tri thức cho RAG (vec-07), và cuối cùng — đưa tất cả vào production ngân hàng an toàn, đúng luật, cải tiến liên tục (bài này). Sợi chỉ đỏ xuyên suốt: chất lượng nằm ở retrieval, còn sự sống còn ở ngân hàng nằm ở tuân thủ và vận hành.

Ghi nhớ

  • Cập nhật gia tăng: upsert theo doc_id, content hash để bỏ qua tài liệu không đổi, soft-delete + valid_until cho tài liệu hết hiệu lực → không trả quy định cũ.
  • Đổi embedding model = re-embed toàn bộ; dùng blue-green index + alias switch để không gián đoạn, giữ BLUE để rollback.
  • Scaling: sharding (kho lớn), replica (QPS/HA), tách index theo domain (giảm nhiễu + dễ phân quyền).
  • Monitoring cả hạ tầng (p95, QPS) lẫn chất lượng (recall, freshness, tỷ lệ no-good-result) — hệ có thể "chạy mà sai" âm thầm.
  • Chi phí: quantization (int8 giảm ~4× RAM, ít mất recall), giảm chiều, phân tầng; self-host vs SaaS ở ngân hàng thường do chủ quyền dữ liệu quyết định, không chỉ tiền.
  • Bảo mật & tuân thủ (cốt lõi): lọc ACL ở retrieval không ở generation; không embed PII thừa; mã hoá at-rest/in-transit; audit mọi truy vấn; self-host cả embedding lẫn LLM — dữ liệu nội bộ không ra API ngoài.
  • Cải tiến liên tục: golden set gác cửa mọi thay đổi + feedback loop từ người dùng và log no-good-result.
  • Kiến trúc tham chiếu self-host: ingest→embed→index→retrieve→rerank→LLM, ba model đều trong biên giới ngân hàng, ACL + audit + eval xuyên suốt.

Bài viết liên quan

Phân biệt AI/ML/DL, các kiểu học máy, quy trình ML end-to-end và thuật ngữ nền tảng.

13 thg 7, 2026 15

Chất lượng dữ liệu, xử lý thiếu/ngoại lai, mã hoá, chuẩn hoá, tạo đặc trưng và tránh data leakage.

13 thg 7, 2026 13

Mô hình ngôn ngữ lớn hoạt động ra sao, token, context window, tham số sinh, và kỹ thuật viết prompt.

13 thg 7, 2026 13

Retrieval-Augmented Generation, vector database, tool calling, agent và MCP để xây ứng dụng LLM thực tế.

13 thg 7, 2026 11