LESSON 55 Β· RAG

RAG with Multiple Documents

Learn how to build a RAG system that can search across an entire collection of documents while preserving document identity, metadata, permissions, and source context.

45 min readβ€’Intermediateβ€’Generative AI

By the end of this lesson, you will be able to:

  • Understand how multi-document RAG differs from single-document RAG.
  • Design an ingestion pipeline for many files.
  • Preserve document-level and chunk-level metadata.
  • Index chunks from different documents in one searchable collection.
  • Retrieve and rank evidence across multiple documents.
  • Build grounded context without mixing unrelated sources.
  • Handle versions, duplicates, freshness, and access control.
1

Why Multiple Documents?

Real knowledge assistants rarely depend on one file. A company may have hundreds of policies, product manuals, FAQs, contracts, technical guides, and reports. The user's question may require information from one document or several documents.

DocumentsMany source files
β†’
ExtractUsable content
β†’
ChunkRetrieval units
β†’
IndexOne searchable collection
QuestionUser query
β†’
RetrieveAcross the collection
β†’
RerankBest evidence
β†’
AnswerGrounded response
Key idea:Multi-document RAG is not simply β€œput many files into a folder.” Every chunk must remain traceable to its source document and searchable in a controlled way.
2

Single-Document vs Multi-Document RAG

SINGLE DOCUMENT

One knowledge source

The pipeline can focus on one file, such as a single handbook or report.

β†’
MULTIPLE DOCUMENTS

Shared knowledge collection

Retrieval must choose the right evidence across many sources and preserve their identities.

The retrieval problem becomes more interesting as the collection grows: irrelevant documents, duplicate content, outdated versions, and permission boundaries can all affect the answer.

3

The Multi-Document RAG Pipeline

Separate the system into ingestion time and query time. Ingestion happens when documents enter or change in the knowledge base. Query time happens for every user question.

INGESTION

1. Discover files

Find PDFs, text files, web exports, manuals, and other supported sources.

INGESTION

2. Identify documents

Assign a stable document ID and capture source metadata.

INGESTION

3. Extract + clean

Convert each file into reliable machine-readable content.

INGESTION

4. Chunk + index

Create chunks, embeddings, and searchable records.

QUERY

5. Process question

Normalize the query and apply relevant user or tenant constraints.

QUERY

6. Retrieve candidates

Search across the authorized document collection.

QUERY

7. Rerank + select

Improve ordering and choose evidence that fits the context budget.

QUERY

8. Generate

Answer using the selected evidence and cite its sources.

4

Document Identity Is Essential

When thousands of chunks share one vector collection, you still need to know exactly where every chunk came from.

</> Python
document = {
    "document_id": "travel-policy-2026",
    "title": "Domestic Travel Policy",
    "source": "policies/travel-policy-2026.pdf",
    "version": "2026.1",
    "department": "finance",
}

chunk = {
    "text": "Domestic travel reimbursement is limited to ...",
    "document_id": document["document_id"],
    "title": document["title"],
    "version": document["version"],
    "department": document["department"],
    "page": 7,
}

print(chunk["document_id"], chunk["page"])
Rule:Never treat a retrieved chunk as anonymous text. Source metadata is part of the retrieval record.
5

Choose a Metadata Schema

Metadata lets you filter, group, debug, cite, and reason about documents before and after vector search.

IDENTITYdocument_id

A stable identifier for the source document.

SOURCEtitle + path

Human-readable source information.

VERSIONversion + updated_at

Helps prevent stale information from winning retrieval.

LOCATIONpage + section

Useful for citations and debugging.

OWNERSHIPdepartment + tenant

Supports scoped retrieval in multi-team systems.

ACCESSaccess_scope

Helps enforce which evidence a user may retrieve.

6

Process Many Documents

A simple ingestion loop can process a collection one document at a time. Production systems usually add queues, retries, change detection, and batch processing.

</> Python
documents = [
    {"id": "policy-01", "path": "policies/leave.txt"},
    {"id": "policy-02", "path": "policies/travel.txt"},
    {"id": "manual-01", "path": "manuals/product.txt"},
]

records = []

for document in documents:
    with open(document["path"], "r", encoding="utf-8") as file:
        text = file.read()

    words = text.split()
    for start in range(0, len(words), 300):
        chunk = " ".join(words[start:start + 300])
        if chunk:
            records.append({
                "document_id": document["id"],
                "text": chunk,
            })

print("Documents:", len(documents))
print("Chunks:", len(records))

This example demonstrates the data flow. A production ingestion service would also create embeddings and persist the records in a vector database.

7

One Collection or Separate Collections?

One shared collection
  • Simple global search
  • Easy to search across related documents
  • Metadata filters become important
  • Good for many related sources
Separate collections
  • Useful for strong isolation
  • Can simplify tenant boundaries
  • Requires choosing which collection to search
  • More infrastructure to manage

There is no universal rule. Choose the design based on tenant isolation, document relationships, scale, operational complexity, and retrieval requirements.

8

Embed Chunks from Every Document

All chunks that need to be compared in the same vector search should use a compatible embedding representation.

</> Python
from sentence_transformers import SentenceTransformer

model = SentenceTransformer("all-MiniLM-L6-v2")

texts = [record["text"] for record in records]
vectors = model.encode(texts, normalize_embeddings=True)

print("Chunks:", len(texts))
print("Vector dimensions:", vectors.shape[1])

The model name is a teaching example. In a real application, select an embedding model appropriate for your language, quality, latency, and infrastructure requirements.

9

Retrieve Across the Whole Collection

A user's question should be compared against the indexed chunks from all documents the user is allowed to access.

</> Python
import numpy as np

question = "What is the domestic travel reimbursement limit?"
query_vector = model.encode(question, normalize_embeddings=True)

scores = vectors @ query_vector
best_indices = np.argsort(scores)[::-1][:5]

for index in best_indices:
    record = records[index]
    print(round(float(scores[index]), 3), record["document_id"])
    print(record["text"][:180], "\n")
Notice:The top results can come from several documents. That is useful when the question needs cross-document evidence, but it also makes source grouping and context construction important.
10

Use Metadata Filtering Before Retrieval

Do not search every document if the application already knows a useful constraint. Filtering can reduce noise and prevent unauthorized sources from entering the candidate set.

</> Python
allowed = [
    record for record in records
    if record.get("department") in {"finance", "hr"}
]

print("Authorized candidates:", len(allowed))

In a real vector database, apply supported metadata filters as part of the search request rather than loading the entire collection into application memory.

11

Top-K Can Return Duplicate Sources

Suppose the top five chunks all come from the same document. That may be correct, but it can also leave useful evidence from another relevant document out of the context.

QUESTIONβ€œWhat changed in the 2026 policy?”

The answer may require the current policy and the previous version.

RISKFive chunks from one source

Retrieval can over-represent one document.

OPTIONSource diversity

Group or diversify candidates when the task benefits from multiple sources.

GOALUseful evidence

Optimize for answer quality, not simply the largest raw Top-K.

12

Rerank the Candidates

For larger collections, a first-stage vector search can retrieve a candidate set and a reranker can reorder those candidates using the full query and passage together.

100,000+Indexed chunks
β†’
Top 50Fast retrieval
β†’
Top 8Reranking
β†’
Top 5Context

This two-stage approach balances broad recall with more precise final ranking.

13

Build Context Without Losing Sources

Before sending evidence to an LLM, format each selected chunk with enough metadata to keep its origin visible.

</> Python
selected = [
    {
        "title": "Domestic Travel Policy",
        "document_id": "travel-policy-2026",
        "page": 7,
        "text": "Domestic travel reimbursement is limited to ...",
    },
    {
        "title": "Expense FAQ",
        "document_id": "expense-faq",
        "page": 3,
        "text": "Receipts are required for claims above ...",
    },
]

context = "\n\n".join(
    f"Source: {item['title']} | page {item['page']}\n{item['text']}"
    for item in selected
)

print(context)
14

When One Question Needs Multiple Documents

Some questions are naturally cross-document questions. The system should allow evidence from multiple sources when the task requires it.

COMPARISON

Old vs new policy

Retrieve both versions and explain the change.

PRODUCT

Manual + FAQ

Combine technical instructions with support guidance.

RESEARCH

Multiple reports

Compare findings across several reports.

OPERATIONS

Policy + procedure

Connect the rule with the steps needed to follow it.

LEGAL

Agreement + amendment

Retrieve related clauses while preserving document versions.

SUPPORT

Several manuals

Find evidence across product generations or components.

15

Handle Versions and Duplicates

Multiple documents often contain the same information. Old versions can be especially dangerous because they may look highly relevant to the query.

01Version confusion

The old policy ranks above the current policy.

02Duplicate uploads

The same document is indexed more than once.

03Partial updates

Some chunks are updated while old chunks remain searchable.

04Missing timestamps

The system cannot distinguish current and stale records.

Good practice:Store version and update metadata, define a clear active-version policy, and remove or exclude obsolete chunks when appropriate.
16

Access Control in Multi-Document RAG

A retrieval system must not expose content merely because it is semantically relevant. Authorization is a separate requirement from relevance.

WRONG

Search everything β†’ filter later

Sensitive chunks can enter logs, prompts, caches, or model context before the final filter.

β†’
SAFER

Authorize β†’ retrieve β†’ generate

Apply tenant, role, or document permissions before candidate evidence is returned.

For multi-tenant systems, treat tenant or access scope as a hard retrieval boundary rather than a soft ranking preference.

17

Document-Level and Chunk-Level Retrieval

Sometimes the first question is not β€œwhich chunk?” but β€œwhich documents are relevant?” A system can use a two-step approach: discover useful documents, then retrieve precise chunks inside them.

QuestionUser intent
β†’
DocumentsFind relevant sources
β†’
ChunksFind precise evidence
β†’
AnswerGrounded response

This can be useful when documents have strong identities, such as product manuals, case files, projects, or policy collections.

18

Cross-Document Context Assembly

More retrieved chunks do not automatically mean a better answer. Select evidence that is relevant, non-redundant, recent, authorized, and small enough to fit the context budget.

Bad context
  • Many near-duplicate chunks
  • Old and new versions mixed
  • Unrelated documents
  • No source labels
Better context
  • Relevant evidence only
  • Useful source diversity
  • Current authorized versions
  • Clear document/page labels
19

Common Multi-Document RAG Problems

01Wrong document wins

A semantically similar source is relevant to the words but not to the user's actual intent.

02Source mixing

The model combines conflicting statements without recognizing their origins.

03Stale evidence

Old versions remain in the candidate set.

04Too much context

Large Top-K values add noise and increase cost.

05Missing metadata

The application cannot explain which document produced the answer.

06Permission leakage

Retrieval crosses a tenant or access boundary.

20

Evaluate Retrieval Across the Collection

Test more than whether the final answer sounds good. Build questions whose correct evidence is known and measure whether the right documents and chunks are retrieved.

RECALL@KWas the right evidence retrieved?

Checks whether relevant chunks appear in the top K.

MRRHow early is the first useful result?

Rewards systems that place a relevant result near the top.

NDCGHow good is the ranking?

Useful when multiple results have different relevance levels.

SOURCE ACCURACYDid the answer cite the right source?

Check document and page attribution separately.

21

A Simple End-to-End Mental Model

</> Python
def multi_document_rag(question, documents):
    # 1. Keep only documents the user may access.
    authorized = [
        doc for doc in documents
        if doc["access"] == "allowed"
    ]

    # 2. Retrieve relevant chunks across the collection.
    candidates = retrieve(question, authorized)

    # 3. Improve ranking and remove redundant evidence.
    selected = rerank_and_select(question, candidates)

    # 4. Build source-aware context.
    context = "\n\n".join(
        f"[{item['title']} | page {item['page']}] {item['text']}"
        for item in selected
    )

    # 5. Generate only from the supplied evidence.
    return generate_answer(question, context)
Mental model:Many documents β†’ authorized candidates β†’ retrieval β†’ reranking/selection β†’ source-aware context β†’ grounded answer.
22

When Multi-Document RAG Works Well

COMPANY KNOWLEDGE

Internal assistant

Search policies, guides, FAQs, and procedures.

SUPPORT

Product assistant

Search manuals and troubleshooting documents across product lines.

RESEARCH

Research assistant

Compare evidence from many papers or reports.

LEGAL

Contract search

Retrieve clauses across authorized agreements and amendments.

FINANCE

Policy assistant

Search current financial procedures and controlled documents.

EDUCATION

Course assistant

Answer questions from a collection of course materials.

23

Production Checklist

INGESTION

Stable IDs

Every document and chunk has a traceable identity.

QUALITY

Validate extraction

Check text, tables, OCR, and document structure.

METADATA

Preserve context

Keep version, page, source, tenant, and access information.

SECURITY

Authorize retrieval

Enforce permissions before protected evidence reaches context.

RETRIEVAL

Measure ranking

Evaluate Recall@K, MRR, NDCG, and source accuracy.

FRESHNESS

Manage updates

Re-index changed files and retire obsolete versions.

24

Practice: Design a Multi-Document RAG System

You have 500 company documents across HR, Finance, Engineering, and Sales. A user asks: β€œWhat is the current remote-work allowance, and who is eligible?”

TASK

Design the retrieval flow

Write down: 1) what metadata you would store, 2) how you would restrict the search to authorized documents, 3) how you would handle old policy versions, 4) how you would retrieve and rerank candidates, and 5) how you would show the source documents in the final answer.

Quick Quiz

1. What makes multi-document RAG different from single-document RAG?

The system must retrieve useful evidence across a collection while preserving source identity, versions, metadata, and access boundaries.

2. Why is document_id important?

It keeps every chunk traceable to its source and supports citations, debugging, updates, and filtering.

3. Why can a large Top-K hurt?

It can add irrelevant or duplicate evidence, increase context size, and make the model's job harder.

4. Why should access control happen before retrieval results enter model context?

Unauthorized evidence should never become available to downstream prompts, logs, caches, or model generation.

5. Why can old versions be dangerous?

They may be semantically relevant and rank highly even though the current policy has changed.

6. When might document-level retrieval help?

When documents have strong identities and the application benefits from first selecting relevant sources before finding precise chunks.

30-Second Recap

1. Collect

Gather many sources.

2. Identify

Assign document IDs.

3. Chunk

Create retrieval units.

4. Index

Store searchable vectors.

5. Filter

Apply authorization.

6. Retrieve

Search the collection.

7. Rerank

Select best evidence.

8. Ground

Answer with sources.

Key Takeaways

  • Multi-document RAG searches a collection rather than a single source.
  • Every chunk should retain document identity and useful metadata.
  • Metadata supports filtering, version control, citations, debugging, and access control.
  • Top-K retrieval may need reranking, source diversity, or document-level selection.
  • Old versions and duplicate documents can create misleading retrieval results.
  • Authorization should be enforced before protected evidence reaches model context.
  • Evaluate both retrieval quality and source attribution, not only final answer quality.
  • Good multi-document RAG is a controlled evidence-selection system, not simply a larger prompt.