Multi-Document RAG: Một thư mục PDF không liên quan là một tài liệu dài với dàn bài lồng nhau
Khi một thư mục chứa các tài liệu không có trường dữ liệu chung, việc xây dựng index truyền thống trở nên vô nghĩa. Bài viết đề xuất cách tiếp cận: xem toàn bộ thư mục như một tài liệu dài, với mỗi file là một chương và dàn bài riêng của nó là các mục con, từ đó định tuyến truy vấn qua hai cấp độ. Phương pháp này giúp giảm tải tính toán và tăng độ chính xác khi chỉ cần đọc một dòng tóm tắt cho mỗi file thay vì toàn bộ nội dung.

Multi-Document RAG: Một thư mục PDF không liên quan là một tài liệu dài với dàn bài lồng nhau
Khi một thư mục chứa các tài liệu không có trường dữ liệu chung, việc xây dựng index truyền thống trở nên vô nghĩa. Bài viết đề xuất cách tiếp cận: xem toàn bộ thư mục như một tài liệu dài, với mỗi file là một chương và dàn bài riêng của nó là các mục con, từ đó định tuyến truy vấn qua hai cấp độ. Phương pháp này giúp giảm tải tính toán và tăng độ chính xác khi chỉ cần đọc một dòng tóm tắt cho mỗi file thay vì toàn bộ nội dung.
Lời khuyên tiêu chuẩn khi đưa hệ thống RAG (Retrieval-Augmented Generation) vượt qua một tài liệu là xây dựng một index: một hàng cho mỗi tài liệu, một cột cho mỗi trường bạn có thể muốn lọc, sau đó là một bộ lọc trước khi tìm kiếm.
Lời khuyên đó giả định các tài liệu có chung trường dữ liệu. Nhưng có rất nhiều thư mục không như vậy.
Lấy một thư mục nghiên cứu làm ví dụ: một danh mục 492 trang về các kiểm soát an ninh, một đặc tả kiến trúc zero-trust, một khung rủi ro AI, ba mươi mốt bài báo về machine learning, và bảy báo cáo thị trường hàng hóa. Hãy thử tìm một cột dữ liệu chung. Không có client, số tiền, ngày hiệu lực nào có nghĩa giống nhau trên tất cả các tài liệu này, và cũng không có một trường nào khác mà người dùng doanh nghiệp có thể đặt tên.
Khi không có trường dữ liệu chung, không có bảng nào để xây dựng. Điều đó nghe có vẻ như là một thiếu sót. Nhưng thực tế thì ngược lại. Nó có nghĩa là bước chuẩn bị được thu gọn lại thành hai sản phẩm, và một trong số đó trình phân tích cú pháp đã trả về miễn phí.
Bài viết này đi sâu vào trường hợp đó:
- Hai câu hỏi giúp phân biệt trường hợp này với trường hợp cần index
- Công việc chuẩn bị, chỉ là một dòng tóm tắt cho mỗi file cùng với mục lục của từng file
- Tại sao dòng tóm tắt phải được viết cho bộ định tuyến thay vì cho người đọc
- Cách định tuyến hai cấp độ trả lời một câu hỏi và tại sao dàn bài lồng nhau không bao giờ được đưa toàn bộ vào prompt
- Bốn cách hệ thống có thể gặp sự cố, bao gồm cả điểm mà danh sách file phẳng ngừng mở rộng
Bài viết này nằm trong Phần IV của loạt bài “Enterprise Document Intelligence”, một loạt bài xây dựng hệ thống RAG doanh nghiệp từ bốn viên gạch cơ bản. Phần IV đặt câu hỏi: điều gì thay đổi khi đầu vào là một thư mục thay vì một file? Câu trả lời phụ thuộc vào loại thư mục bạn có. Trường hợp này là loại cần ít cơ chế mới nhất.
1. Bạn có loại thư mục nào?
Bài viết 14A đã đưa ra ba hình dạng mà một bộ sưu tập tài liệu có thể có, và nói rằng mỗi hình dạng cần một kiến trúc khác nhau. Bài viết này xử lý trường hợp các tài liệu không có điểm chung. Trước khi xây dựng bất cứ điều gì, cần chắc chắn rằng bạn đang ở đúng trường hợp, vì đoán sai sẽ tốn kém theo cả hai hướng.
1.1. Hai câu hỏi quyết định
Câu hỏi đầu tiên: hai tài liệu trong thư mục có bao giờ tham chiếu lẫn nhau không? Một bản sửa đổi tham chiếu đến thỏa thuận chính. Một hợp đồng gia hạn tham chiếu đến chính sách năm ngoái. Một chứng chỉ thuộc về một hợp đồng. Nếu điều này xảy ra, thư mục có một cấu trúc bạn phải mô hình hóa, và bài viết này không dành cho bạn.
Câu hỏi thứ hai: người dùng doanh nghiệp có thể đặt tên một trường mà mọi tài liệu đều có, và trường đó có nghĩa giống nhau trong mỗi tài liệu không? Ví dụ: client, ngày hiệu lực, phí bảo hiểm, số hợp đồng. Nếu câu trả lời đến nhanh và tự tin, thư mục đó là một cơ sở dữ liệu chưa được định kiểu, và việc định kiểu chính là công việc của bạn.
Nếu cả hai câu trả lời đều là “không”, không có gì để đưa vào các cột. Bạn vẫn có thể trích xuất metadata (tên file, số trang, ngày tạo), nhưng không có cái nào là trường mà người dùng sẽ lọc. Một cột trống với hầu hết các hàng và có nghĩa khác nhau trong số còn lại không phải là một cột.
Các thư mục hỗn hợp tồn tại và rất phổ biến. Một ổ đĩa dùng chung có thể chứa 5.000 hợp đồng giống nhau bên cạnh 300 file linh tinh không thuộc về ai. Đó không phải là mâu thuẫn, mà là hai kho dữ liệu dùng chung một ổ đĩa. Hãy tách chúng ra và chạy kiến trúc phù hợp cho mỗi loại.
1.2. Trường hợp khác có gì mà trường hợp này không có
Trường hợp đồng nhất (khi doanh nghiệp đã biết các cột dữ liệu) có ba thứ mà trường hợp này không thể có.
- Bộ lọc: Một câu hỏi như “nhà bán lẻ X, đang còn hiệu lực” trở thành một mệnh đề SQL, và 18.000 hàng giảm xuống còn ba trước khi đọc bất kỳ tài liệu nào.
- Tổng hợp: Câu hỏi “có bao nhiêu hợp đồng hết hạn trong quý này” được trả lời bằng chính index, không cần mở bất kỳ tài liệu nào.
- Từ vựng dùng chung: Mỗi hàng có client và ngày tháng, nên ontology ánh xạ từ người dùng sang giá trị cột sẽ hiệu quả trên toàn bộ kho dữ liệu.
Không có gì trong số đó áp dụng được ở đây. Không có mệnh đề nào để viết, không có gì để đếm, và một từ vựng dùng chung giữa một danh mục kiểm soát an ninh và một báo cáo hàng hóa sẽ là một từ vựng về hư không.
Phần còn lại sau khi loại bỏ những thứ đó nhỏ hơn bạn nghĩ, và nó chính là toàn bộ kiến trúc cho trường hợp này: một thư mục có các tài liệu không liên quan là một tài liệu dài. Các file là các chương. Các phần của chúng là các mục con. Bạn đã biết cách đọc một tài liệu dài. Bạn đọc mục lục của nó.
2. Chuẩn bị: một dòng cho mỗi file, cộng với dàn bài mà trình phân tích trả về
Chỉ có hai sản phẩm, được xây dựng một lần khi đưa dữ liệu vào.
Level 0 là danh sách các file, mỗi file một dòng, mô tả file đó nói về điều gì. Level 1 là mục lục của từng file. Cùng nhau, chúng tạo thành một dàn bài lồng nhau: các chương của thư mục, sau đó là các phần của từng chương.
Đó là toàn bộ công việc chuẩn bị. Không có bước phân loại, trích xuất trường, schema, hay ontology.
2.1. Dòng tóm tắt chính là index, vì vậy hãy viết nó cho bộ định tuyến
Đây là nơi tập trung phần lớn chất lượng, và rất dễ bị đánh giá thấp vì sản phẩm chỉ là một câu.
Dòng tóm tắt không phải là tài liệu. Không ai đọc nó. Người tiêu dùng duy nhất của nó là lệnh gọi định tuyến phải quyết định, từ 63 dòng, file nào có thể chứa câu trả lời. Nó nên được viết như cách bạn viết một định nghĩa cột, không phải như cách viết một đoạn giới thiệu.
Ba điều tạo nên sự khác biệt giữa hai phiên bản:
- Chủ đề trong cả hai từ vựng: Từ người dùng sẽ gõ và từ tài liệu tự sử dụng. Một câu hỏi về “quản lý tài khoản” phải trúng một file có dòng mô tả “quản lý tài khoản” và cả “AC-2”, vì bộ định tuyến khớp trên văn bản, không phải trên ý định.
- Hình dạng của câu trả lời: Một kiểm soát được đánh số trong mỗi phần là một lời hứa khác với một báo cáo tường thuật. Nó cho bộ định tuyến biết câu trả lời là một phần hay toàn bộ chương, điều mà cấp độ thứ hai sẽ hành động.
- Nội dung file không nói về điều gì: Đây là phần mọi người bỏ qua, và nó là thứ làm cho việc định tuyến chính xác. “Không phải là hướng dẫn triển khai” loại file đó khỏi mọi câu hỏi “how-to” chỉ trong một mệnh đề. Thông tin phủ định là thứ cho phép bộ định tuyến loại bỏ 62 file mà không cần mở bất kỳ file nào.
Việc tạo ra các dòng này rất rẻ. Một lệnh gọi cho mỗi tài liệu khi đưa vào, đọc vài trang đầu cộng với mục lục, sẽ cho một bản nháp dùng được; với thư mục cỡ này, bạn cũng có thể tự viết tay trong một buổi chiều. Dù bằng cách nào, chi phí được trả một lần cho mỗi tài liệu và chỉ trả lại khi file thay đổi. Điều quan trọng là các dòng này phải được xem xét như schema, không phải như văn bản quảng cáo.
2.2. Cấp độ thứ hai không tốn gì mới
Viên gạch phân tích cú pháp đã trả về một toc_df, một hàng cho mỗi tiêu đề kèm phạm vi trang của nó. Bài viết 5B xây dựng nó từ dàn bài gốc của PDF. Không có gì trong bài viết này mở rộng nó. Level 1 chính là bảng đó, được lưu riêng cho từng file.
Với thư mục ở đây, 47 trong số 63 PDF có dàn bài gốc, và 47 file đó tốn một lần phân tích mỗi file. 16 file còn lại không có: một bản ghi nhớ được quét, một file xuất từ slide, một ghi chú hai trang.
Có hai giải pháp cho 16 file đó, và độ dài là yếu tố quyết định. Một file ngắn trở thành một “lá” (leaf): khi bộ định tuyến giữ lại, bạn đọc toàn bộ file, và level 1 không bao giờ chạy. Một file dài cần được tái tạo dàn bài trước khi xử lý.
Toàn bộ thư mục: 63 file, 4.211 trang, và một index chỉ dài 63 câu. Con số 63 là thứ mà model đọc trên mỗi câu hỏi. Con số 2.422 là thứ nó có thể tiếp cận, mỗi lần một file, và gần như không bao giờ chạm tới.
3. Thời điểm truy vấn: định tuyến xuống hai cấp độ
Hãy đưa một câu hỏi qua thư mục: “Kiểm soát quản lý tài khoản yêu cầu điều gì?”. Câu trả lời nằm trong năm trang của NIST SP 800-53 Rev. 5, kiểm soát AC-2, từ trang 46 đến 50. 62 file khác không thể chứa câu trả lời, và không file nào trong số đó sẽ được mở.
3.1. Level 0: chọn file
Một lệnh gọi. Model đọc 63 dòng, mỗi dòng là tên file, dòng tóm tắt định tuyến, và một bảng đếm từ khóa. Nó trả về các id file có thể chứa câu trả lời, kèm lý do cho mỗi file. Thường có từ một đến ba file được trả về.
Bảng đếm từ khóa chạy song song, không phải thay thế. Việc đếm xem có bao nhiêu thuật ngữ trong câu hỏi xuất hiện trong dòng tóm tắt và tiêu đề dàn bài của file tốn gần như không có chi phí, và nó bắt được những gì một câu tóm tắt làm tròn: một mã chính xác như AC-2 hoặc GV.OC-01 mà câu văn không bao giờ viết ra. Hai tín hiệu được đưa vào cùng một prompt và model quyết định.
Hai thuộc tính của lệnh gọi này đáng được nêu tên. Nó có giới hạn: 63 dòng ngắn, bất kể thư mục nặng bao nhiêu trên đĩa. Và nó có thể kiểm tra: chuỗi lý do cho biết tại sao một file được giữ lại, để một câu trả lời sai có thể được truy vết về quyết định định tuyến thay vì một điểm số tương đồng.
3.2. Level 1: đi sâu vào các file sống sót
Từ đây, nó là trường hợp một tài liệu, không có gì thêm. Dàn bài của file trở thành cấp độ hiện tại, model chọn một nhánh, và nếu nhánh đó có các mục con, vòng lặp mở chúng và lặp lại. Nó dừng ở một “lá”, hoặc ở một phần đủ ngắn để đọc toàn bộ.
Hai cấp độ là cùng một lệnh gọi.
Mỗi dòng được trả về đều giữ id file của nó, vì vậy một trích dẫn có thể chỉ tên file nguồn. Trên một thư mục có các tài liệu không dùng chung từ vựng, điều này quan trọng hơn bình thường: một câu trả lời ghép từ một danh mục kiểm soát và một báo cáo thị trường trôi chảy nhưng chẳng có giá trị gì.
3.3. Tại sao toàn bộ dàn bài lồng nhau không bao giờ được đưa vào một prompt
Dàn bài lồng nhau là một đối tượng duy nhất: 63 dòng cộng 2.422 hàng. Không gì ngăn bạn tuần tự hóa tất cả vào một lệnh gọi. Nhưng có ba lý do để không làm vậy.
- Nó không còn vừa: Nhân thư mục này với hai mươi, dàn bài một mình đã là một prompt dài không còn chỗ để suy luận. Các thư mục cần kiến trúc này là những thư mục tiếp tục phát triển.
- Độ chính xác giảm trước khi cửa sổ ngữ cảnh đầy: Ở level 0, model so sánh 63 mô tả toàn tài liệu, một quyết định nó làm tốt. Với 2.485 hàng hỗn hợp, phần nó cần phải cạnh tranh với 357 mục anh em từ một tài liệu không liên quan, và một tiêu đề phần bị tách khỏi tài liệu gốc là một tín hiệu yếu.
- Tốn kém cho mỗi câu hỏi: Level 0 chỉ là 63 dòng ngắn, trả phí mỗi lần. Level 1 chỉ là dàn bài của các file sống sót, nên chi phí chỉ cho một file thay vì sáu mươi ba.
Việc đi xuống cũng là tùy chọn. Với một thư mục tám file ngắn có dàn bài nông, level 0 chọn một file và không có gì để đi xuống: vòng lặp chạy một lần và hoạt động như định tuyến phẳng. Model quyết định ở mỗi cấp độ liệu việc đi sâu hơn có mang lại lợi ích gì không, cùng một quy tắc dừng như vòng lặp một tài liệu.
4. Nơi hệ thống gặp sự cố
Có bốn thứ có thể sai với index thư mục hai cấp độ, và mức độ nghiêm trọng không giống nhau. Đầu tiên là vấn đề viết lách bạn sửa trong một buổi chiều. Hai tiếp theo là vấn đề phân tích cú pháp biểu hiện thành vấn đề truy xuất. Cuối cùng là một giới hạn thực sự.
4.1. Dòng tóm tắt chẳng nói lên điều gì
“Một báo cáo kỹ thuật về an ninh mạng.” Mười hai file khớp với mô tả đó, vì vậy level 0 trả về cả mười hai, hoặc chọn ba trong số đó mà không có lý do nào bạn có thể tái tạo. Dấu hiệu nhận biết rất cụ thể: lệnh gọi level 0 giữ quá nhiều file, trong khi level 1 trông hoàn toàn khỏe mạnh với từng file được đưa vào.
Giải pháp là viết lại dòng, và bài kiểm tra rất rẻ. Giữ lại mười câu hỏi thật, chạy lệnh gọi level 0 trên mỗi câu, và kiểm tra rằng file bạn tự chọn bằng tay sẽ được trả về. Mười câu hỏi bắt được hầu hết các lỗi, vì một dòng tóm tắt tệ thường tệ cho cả một lớp câu hỏi chứ không chỉ một câu.
Hãy coi các dòng này như một sản phẩm cần được xem xét. Chúng là index; một dòng cẩu thả là một định nghĩa cột cẩu thả, và nó sẽ không tự báo lỗi.
4.2. Tài liệu không có cấu trúc
Level 1 cần một thứ gì đó để đi xuống. Một file không có tiêu đề khiến vòng lặp không có gì để chọn, nên bộ định tuyến hoặc đọc toàn bộ hoặc không đọc gì.
Đọc toàn bộ thường là ổn. Một bản ghi nhớ ba trang là một “lá”, và sơ đồ hai cấp độ xử lý các “lá” một cách tự nhiên. Trường hợp thất bại thì hẹp và cụ thể: dài và không có cấu trúc. Một gói tài liệu quét 200 trang không có tiêu đề không thể được định tuyến ở bất kỳ cấp độ nào, vì không có gì để định tuyến qua.
Đó không phải là vấn đề truy xuất. Đó là vấn đề phân tích cú pháp, và nó được giải quyết trước khi cơ chế của bài viết này chạy, bằng cách tái tạo một dàn bài từ bất kỳ tín hiệu nào tài liệu mang theo.
4.3. Danh sách file phẳng ngừng mở rộng
Level 0 là một danh sách phẳng. Nó hoạt động khi danh sách vẫn đọc được trong một lệnh gọi.
Vài trăm file là thoải mái. Vài nghìn thì không, và lỗi không phải là điều mọi người mong đợi. Cửa sổ ngữ cảnh không phải là thứ cạn kiệt đầu tiên; độ chính xác định tuyến mới là. Với 3.000 dòng, lệnh gọi level 0 trở thành cùng một vấn đề top-k mà toàn bộ kiến trúc này được xây dựng để tránh, chỉ là chuyển lên một tầng.
Giải pháp là thêm một cấp độ nữa, không phải một kiến trúc khác. Nhóm các file, theo thư mục, theo nguồn, theo năm, theo bất kỳ nhóm nào kệ tài liệu đã có sẵn, và cho mỗi nhóm một dòng tóm tắt riêng. Level 0 trở thành 40 dòng nhóm, level 1 là các file trong nhóm mà bộ định tuyến giữ lại, level 2 là dàn bài của chúng. Cùng một lệnh gọi định tuyến, thêm một vòng lặp nữa.
Đó cũng là điểm mà trường hợp này bắt đầu đòi hỏi những gì trường hợp đồng nhất đã có từ ngày đầu. Nếu việc nhóm tự nhiên hóa ra là một trường mà mọi file đều có, câu hỏi thứ hai ở phần 1.1 đã âm thầm thay đổi câu trả lời, và thư mục cuối cùng vẫn muốn một index.
5. Kết luận
Một thư mục có các tài liệu không có điểm chung là một tài liệu dài, và nó muốn cơ chế truy xuất bạn đã có, thay vì cơ chế kho dữ liệu như các bài viết xung quanh nó.
Những gì nó không cần đáng được liệt kê, vì mỗi mục là một dự án ai đó sẽ đề xuất. Không có index quan hệ: không có cột nào để điền. Không có ontology: một từ vựng dùng chung giữa một danh mục kiểm soát và một báo cáo hàng hóa chẳng mô tả gì cả. Không có agent SQL: không có gì để truy vấn. Không có bước trích xuất thực thể trên toàn kho: các thực thể không lặp lại giữa các file, nên không có gì để liên kết.
Những gì nó cần là một câu cho mỗi file, viết cho bộ định tuyến, và mục lục trình phân tích cú pháp đã trả về. Sau đó định tuyến chạy hai lần: một lần trên danh sách file, một lần bên trong các file sống sót. Sáu mươi ba file và 4.211 trang, và model chỉ đọc 63 dòng cộng một dàn bài trước khi đến được năm trang cần thiết.
6. Đọc thêm và nguồn tham khảo
Trong loạt bài này, về những phần bài viết tái sử dụng:
- Building Document Structure with Loop Engineering: Cách xử lý 16 file không có dàn bài gốc.
- Most RAG Hallucinations Are Retrieval Failures: Vì sao lỗi định tuyến ở level 0 xuất hiện như lỗi sinh văn bản sau này.
- Context engineering for RAG question parsing: Nguồn gốc của các từ khóa trong bảng đếm level 0.
- Prompt Engineering Isn’t Enough: Bốn viên gạch ngữ cảnh giúp ngăn chặn ảo giác RAG.
- Most RAG Hallucinations Are Extraction Errors: Cách sinh văn bản xử lý các dòng trả về và vì sao mỗi dòng mang id file.
Nguồn ngoài:
- Document Summary Index, LlamaIndex: Ý tưởng level 0 như một thành phần mã nguồn mở.
- Parth Sarthi et al., RAPTOR, 2024: Xây cây bằng phân cụm và tóm tắt đệ quy khi không có cấu trúc. Điểm tương phản: một thư mục tài liệu đã có sẵn cây.
- Anthropic, Introducing Contextual Retrieval, 2024: Thêm ngữ cảnh cấp tài liệu vào mỗi chunk để tránh mồ côi. Dòng tóm tắt ở đây là cùng một động thái ở mức file.
- Yunfan Gao et al., RAG Survey, 2023: Từ vựng naive, advanced, modular.
- Scott Barnett et al., Seven Failure Points, 2024: Các lỗi missing-document và wrong-document chính là những gì level 0 được xây dựng để loại bỏ.
Biểu đồ minh họa định tuyến hai cấp độ trong Multi-Document RAG
Ví dụ về dòng tóm tắt file cho bộ định tuyến
Cấu trúc dàn bài lồng nhau của thư mục tài liệu
Bài viết liên quan

Công nghệ
W. Kamau Bell tiết lộ 'công cụ không thể thiếu' thực tế nhất: Sạc pin điện thoại
22 tháng 8, 2026

Công nghệ
Làm quen với Racket: Ngôn ngữ lập trình nơi mã nguồn tự viết ra mã nguồn
22 tháng 8, 2026

Công nghệ
Các nhà sáng tạo Hollywood đang tự đào mồ chôn sự nghiệp của mình khi huấn luyện AI thay thế chính họ
22 tháng 8, 2026