Skip to content
awesome-applied-ai
← Design problems

03Retrieval

Chunking a mixed corpus

Our knowledge base is 40% PDFs with tables, 30% Confluence pages, 20% source code, 10% support tickets. One chunking configuration is used for all of it and quality is poor everywhere. What do you change?

The constraint. Chunk size is not a hyperparameter to tune globally. It is a consequence of the document's structure, and these four corpora have nothing structurally in common. A fixed 512-token recursive splitter destroys tables, splits functions from their signatures, and merges unrelated tickets.

Per-corpus treatment.

CorpusUnitFailure if you get it wrong
PDF with tablesLayout-detected block; tables kept whole, serialized to MarkdownA table split across chunks yields rows without headers — the single worst retrieval artifact
ConfluenceHeading hierarchy, with the heading path prepended to each chunkOrphaned sections that read as authoritative but lack scope
Source codeSyntactic unit: function, class, or module, from a parserHalf a function retrieved is worse than nothing
TicketsWhole ticket, never split; embed a summary, retrieve the threadSplitting a conversation destroys resolution context

The pattern underneath. Retrieve small, provide large. Embed a precise unit for matching, then expand to its natural container before it reaches the model — the parent section, the full function, the entire ticket. This decouples matching granularity from grounding granularity, and it removes most of the chunk-size argument.

Also prepend context to every chunk: document title, heading path, and for tables the caption and column headers. A chunk that cannot identify itself cannot be reranked well.

Stack. Docling for PDFs when per-page cost matters and the documents are local; LlamaParse or Reducto when the documents are genuinely messy and the accuracy is worth the invoice. Chonkie for the chunking strategies themselves — token, semantic, recursive, late. Tree-sitter for code, not a text splitter. Unstructured if the format spread is wider than these four.

Where answers fail. Proposing "semantic chunking" as a universal answer. It is a reasonable default for prose and actively wrong for code and tables.