Ba dạng kho ngữ liệu RAG và cái giá phải trả khi xây sai kiến trúc

20 tháng 8, 2026·12 phút đọc

Một kho tài liệu doanh nghiệp không phải là một thực thể duy nhất — có ba hình dạng khác nhau, mỗi loại đòi hỏi một kiến trúc RAG riêng. Bài viết chỉ ra ba câu hỏi để xác định hình dạng của bộ sưu tập, phân tích năm kiểu thất bại của pipeline phẳng, và lý do tại sao re-ranker không thể cứu vãn một hệ thống xây sai nền móng. Đồng thời giới thiệu baseline đo lường 'chất thải' trên năm PDF thực tế.

Ba dạng kho ngữ liệu RAG và cái giá phải trả khi xây sai kiến trúc

Ba dạng kho ngữ liệu RAG: Xây sai kiến trúc phải trả giá như thế nào?

Khi đưa RAG từ một tài liệu lên cả một kho lưu trữ doanh nghiệp, hầu hết kỹ sư đều làm theo công thức cũ: nhúng toàn bộ trang vào vector store và gọi similarity search. Cách này chạy tốt với folder demo vài chục file, nhưng sụp đổ hoàn toàn ở quy mô thật — vì similarity search trả về passage, không bao giờ chọn đúng document, và câu trả lời cuối cùng được ráp từ ba file chưa từng có ý định đọc cùng nhau. Vấn đề nằm ở bước bị bỏ qua trước đó: một bộ sưu tập tài liệu không phải là một thứ duy nhất, và việc xác định đúng hình dạng của nó là tiền đề cho mọi quyết định kiến trúc.

Một phần tư triệu tài liệu và một câu hỏi

Một công ty môi giới bảo hiểm quy mô vừa lưu trữ khoảng 250.000 tài liệu: chính sách, chứng chỉ, hợp đồng, khiếu nại và thư từ suốt 15 năm. Người dùng hỏi: "Nghĩa vụ của bên bán trong hợp đồng phân phối với nhà bán lẻ X là gì?"

Một chuyên viên xử lý khiếu nại dày dạn trả lời trong chưa đầy một phút mà không cần đọc thứ gì thừa. Cô biết nghĩa vụ nằm trong hợp đồng phân phối, biết nhà bán lẻ X có một hợp đồng chính từ 2019 và hai phụ lục, biết nghĩa vụ thường ở mục 4. Cô mở ba folder, đọc ba mục, xong.

Pipeline RAG chuẩn lại làm việc khác hẳn. Mọi passage của mọi tài liệu đã được nhúng vào một store duy nhất. Câu hỏi được nhúng, store trả về 30 passage gần nhất theo cosine similarity, và 30 passage đó nhồi vào một prompt duy nhất. Kết quả thường xuyên sai: hai đoạn từ hợp đồng với nhà bán lẻ khác, một chứng chỉ không thuộc hợp đồng nào, và một hóa đơn năm 2017 chỉ vì có chữ "nghĩa vụ". Mô hình viết ra một đoạn văn trôi chảy nhưng không mô tả đúng bất kỳ tài liệu tồn tại nào.

Khoảng cách giữa hai cách làm không phải là độ chính xác — mà là chúng giải quyết những bài toán khác nhau. Chuyên viên con người quyết định tài liệu nào đáng đọc rồi mới đọc. Pipeline chưa bao giờ đưa ra quyết định nào về tài liệu cả.

Năm kiểu thất bại của một đống tài liệu phẳng

Ở quy mô nhỏ, đống tài liệu phẳng (flat pile) hoạt động đủ tốt để demo. Với vài trăm file, tài liệu đúng thường rơi vào top-k nhờ may mắn — và demo được xem như xác nhận cách tiếp cận, thay vì chỉ là xác nhận về kích thước corpus. Năm thứ vỡ ra khi kho lớn lên, và chúng vỡ độc lập với nhau:

  • Thiếu tài liệu (missing document): tài liệu đúng không bao giờ lọt vào kết quả tìm kiếm vì thuật ngữ khác biệt (vocabulary drift) — ví dụ tài liệu viết "indemnification" nhưng câu hỏi hỏi "compensation".
  • Sai tài liệu (wrong document): tài liệu trả về đúng chủ đề nhưng không phải là tài liệu có thẩm quyền — ví dụ một hợp đồng cũ đã bị thay thế.
  • Nhiễu (noise): passage trúng từ khóa nhưng không mang ý nghĩa, chiếm chỗ trong prompt window.
  • Rò rỉ văn bản (text leakage): câu trả lời được ráp từ nhiều file không liên quan, đọc thì hay nhưng không mô tả bất kỳ tài liệu thực nào.
  • Mất ngữ cảnh (lost context): passage tách rời khỏi tài liệu gốc, mất đi thông tin về phần nào của hợp đồng, trước sau là gì, và mối quan hệ với các phần khác.

Hãy đọc cột cuối trước: top-k rộng hơn kéo nhiễu vào cùng tốc độ với tín hiệu. Đổi embedding model chỉ di chuyển chỗ hỏng thay vì xóa bỏ. Kích thước chunk không nói được gì về ranh giới tài liệu — thứ chưa từng được ghi lại ngay từ đầu.

Vì sao re-ranker không cứu được hệ thống

Phản ứng thường thấy là dùng cross-encoder: truy xuất top-100, chấm điểm lại từng ứng viên so với câu hỏi, giữ lại ba kết quả tốt nhất. Re-ranker là công cụ thật và đáng có — nhưng không phải ở đây, không phải lúc này. Nó chỉ sắp xếp lại danh sách mà embedding trả về. Nếu tài liệu đúng không bao giờ lọt vào danh sách đó, và vocabulary drift chính là điều kiện khiến nó không lọt — thì không có gì để sắp xếp lại.

Còn một cái giá thứ hai ít được chú ý: re-ranker thêm một con số. Khi được hỏi tại sao hệ thống trả lời như vậy, giờ bạn có thể đưa ra cosine score, cross-encoder score và ngưỡng top-3. Ba con số, không con số nào một chuyên viên khiếu nại có thể phản bác lại được.

Cách sửa nằm ở phía trước tất cả những thứ đó. Ghi nhận hình dạng của bộ sưu tập trước khi bất kỳ câu hỏi nào đến, rồi dùng hình dạng đó để cắt giảm tập ứng viên. Một điều kiện như doc_type = 'distribution agreement' AND client = 'retailer X' là chính xác, nhanh, và dễ đọc đối với người chịu trách nhiệm về câu trả lời. Nó đưa 250.000 tài liệu xuống còn ba trước khi tính một phép embedding nào — và với ba ứng viên, pipeline đơn tài liệu là đủ.

Ba câu hỏi xác định hình dạng của kho ngữ liệu

Phần hay là bạn có thể biết kho của mình thuộc dạng nào mà không cần viết một dòng code nào. Ba câu hỏi dưới đây dành cho con người, không phải cho script:

  1. Hai tài liệu trong kho có bao giờ trỏ vào nhau không? Một phụ lục đặt tên cho hợp đồng chính. Một giấy gia hạn đề cập đến chính sách năm ngoái. Một chứng chỉ thuộc về một hợp đồng cụ thể. Trả lời "có" không chọn hình dạng — nó thêm một yêu cầu cho bất kỳ hình dạng nào bạn chọn: cần bảng quan hệ và ngày hiệu lực.

  2. Một người dùng doanh nghiệp có thể kể tên một trường mà mọi tài liệu đều mang, theo cùng một nghĩa không? Khách hàng, ngày hiệu lực, phí bảo hiểm, số hợp đồng. Điều quyết định câu trả lời là tốc độ, không phải từ ngữ. Nếu bốn ví dụ được đưa ra trong hai giây, kho của bạn là một cơ sở dữ liệu chưa được "đánh máy" — và việc đánh máy nó chính là công việc cần làm. Nếu câu trả lời đến sau một khoảng dừng kèm dè dặt, coi như là "không".

  3. Các tài liệu có đến thành từng bó, nhiều tài liệu về một vụ việc không? Một khiếu nại, một đơn xin tín dụng, một hồ sơ y tế. Không phải folder để giữ gọn gàng: mà là một bộ cố định các phần được kỳ vọng, và câu hỏi thú vị là về cả bó chứ không phải từng phần.

Câu 2 và 3 chọn hình dạng. Khi cả hai đều "có" — và trong bảo hiểm thường là vậy — hàng của bảng trở thành vụ việc (case), không phải tài liệu. Đó là hình dạng thứ ba, không phải hình dạng thứ tư.

Một lưu ý thực tế: chạy bài test trên một nhánh (subtree), không chạy trên toàn ổ đĩa. Một ổ đĩa dùng chung phát triển 10 năm thường chứa hai trong ba hình dạng cạnh nhau, và câu trả lời đúng cho cả ổ đĩa là câu trả lời sai cho từng phần của nó.

Ba hình dạng, ba kiến trúc, ba cái giá khi đoán sai

  • Đống tài liệu không liên quan (pile). Không có trường nào để lọc, nên không có gì để xây bộ lọc. Việc chuẩn bị rút xuống còn hai thành phần: một dòng tóm tắt cho mỗi file (file nói về cái gì), và mục lục của từng file. Truy xuất điều hướng qua hai cấp này — về bản chất là hierarchical retrieval áp dụng ở một tầng cao hơn.

  • Một loại tài liệu, nhiều bản sao (typed corpus). Năm nghìn chính sách cùng sản phẩm, mười năm hóa đơn, mọi đơn bảo hiểm từng nhận. Các tài liệu giống nhau vì cùng quy trình tạo ra chúng — chính vì thế các cột tồn tại và ai đó có thể đặt tên chúng. Đây là hình dạng cần một bảng chỉ mục (index table), không phải vector store.

  • Các bó về một vụ việc (case files). Một folder khiếu nại gồm tờ khai, biên bản công an, ba hóa đơn, một tấm ảnh và hai lá thư. Không đồng nhất bên trong, lặp lại trên toàn bộ: mọi folder khiếu nại chứa những phần xấp xỉ cùng loại. Đơn vị làm việc là cả bó, nên truy xuất lắp ráp bó trước, đọc chéo trong bó sau.

Cái giá khi xây sai rất khác nhau:

Xem kho có kiểu như là đống hỗn độn là lỗi mặc định — vì nó không đòi hỏi quyết định nào. Mọi thứ vào vector store, năm kiểu thất bại ở trên xảy ra đúng lịch. Cái giá thật không phải là phí tính toán: mà là hệ thống sai theo cách không thể truy vết, trên một kho mà người dùng doanh nghiệp có thể viết filter chính xác bằng tay trong mười giây.

Xem đống hỗn độn như là kho có kiểu thì tốn kém theo cách khác, vì trông giống sự cẩn thận. Một đội chạy classification và extraction trên mọi file để điền vào các cột không người dùng nào nghĩ ra. Nhiều tháng sau có một bảng mà hầu hết ô trống, và các ô được điền mang nghĩa khác nhau theo từng dòng: một ngày là ngày xuất bản ở đây, ngày hiệu lực ở kia, hạn đánh giá ở nơi khác. Rồi một filter chạy trên cột đó và lặng lẽ loại bỏ tài liệu đúng. Một cột mang ba nghĩa còn tệ hơn không có cột, vì filter tin nó.

Xem hồ sơ vụ việc như các tài liệu độc lập là lỗi thầm lặng. Mỗi phần tự trả lời, nên không có gì trông hỏng. Điều không bao giờ xảy ra là sự so sánh. Hợp đồng nói bảo hiểm bắt đầu từ 1/3, chứng chỉ nói 1/4 — và không câu hỏi nào đặt hai thứ cạnh nhau. Nửa còn lại là thiếu phần: khi biên bản y tế không được lưu, hệ thống xử lý từng tài liệu trả về kết quả trống, và kết quả trống đọc là "không có thông tin" thay vì "một phần bắt buộc không có ở đây".

Ba câu hỏi xác định hình dạng của kho tài liệuBa câu hỏi xác định hình dạng của kho tài liệu

Baseline: Vòng lặp đơn giản phơi bày "chất thải" truy xuất

Trước khi xây bất kỳ kiến trúc nào, hãy chạy một baseline đơn giản nhất có thể: vòng lặp quanh pipeline đơn tài liệu. Với năm PDF NIST công khai (Cybersecurity Framework, FIPS 199, SP 800-207, AI 100-1, CSWP 29) và câu hỏi "What is a Profile in the Cybersecurity Framework?" — kết quả: chỉ một tài liệu trả lời đúng (trang 5, độ tin cậy 0.95), bốn tài liệu còn lại trả về trống, "NA", hoặc một dấu gạch chéo đơn.

Chi tiết đáng chú ý: một dấu gạch chéo lọt qua bài kiểm tra heuristics (khác rỗng, khác "NA") và bị đẩy lên cao trong bảng xếp hạng — một tài liệu chưa nói gì. Baseline chạy 14.3 giây cho năm tài liệu, tức khoảng 2.9 giây mỗi tài liệu. Tuyến tính trong số tài liệu vì không có gì dùng chung giữa chúng. 250.000 tài liệu của công ty môi giới với tốc độ đó tương đương tám ngày tường minh cho một câu hỏi.

Pipeline không hỏng — câu trả lời đúng đến từ tài liệu đúng. Hỏng ở tỷ lệ: bốn trong năm lần gọi không làm gì cả, và tỷ lệ này chỉ tăng khi kho lớn lên.

Một câu hỏi, năm tài liệu, một câu trả lời, bốn lần gọi lãng phíMột câu hỏi, năm tài liệu, một câu trả lời, bốn lần gọi lãng phí

Kết luận

Một folder không phải là một corpus, và một corpus không phải là một thứ duy nhất. Ba câu hỏi quyết định bạn có hình dạng nào, chỉ tốn một buổi trò chuyện với một người dùng doanh nghiệp, và đáng để hỏi trước khi viết một dòng code ingestion.

Những gì chúng mua lại rất nhỏ và cụ thể. Câu 1 cho biết bạn có cần bảng quan hệ và ngày hiệu lực không. Câu 2 cho biết có bảng để xây không. Câu 3 cho biết hàng của bảng đó là một tài liệu hay một vụ việc.

Vòng lặp for-loop từ baseline sống sót qua cả ba câu trả lời. Mọi bài viết trong nhóm này đều nói về cùng một điều: thu nhỏ thứ mà vòng lặp đó lặp qua, từ mọi tài liệu trên kệ xuống còn một nắm tài liệu có khả năng trả lời. Với độc giả Việt Nam đang xây dựng hệ thống tư vấn hợp đồng, tra cứu pháp lý, hay hồ sơ tín dụng — nơi mọi tài liệu đều mang trường như số hợp đồng, ngày hiệu lực, mã khách hàng — việc dành nửa ngày để hỏi đúng ba câu hỏi sẽ tiết kiệm hàng tháng trời xây sai kiến trúc.

Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗