In a Retrieval-Augmented Generation (RAG) system, the quality of your retrieval is strictly bounded by the quality of your chunking. If an ingestion pipeline chops documents blindly across arbitrary character counts, no amount of downstream prompt engineering or reranking can recover the lost semantic relationships.
Production RAG architectures move beyond fixed-size splitters by implementing advanced preprocessing strategies: Markdown-Aware Semantic Chunking, Parent-Child (Hierarchical) Chunking, and Contextual Chunking.
1. The Granularity Paradox: Small Chunks vs Large Chunks
In vector retrieval, engineers face an inherent trade-off:
- Small Chunks (64–128 tokens): Produce highly specific, focused vector embeddings. They excel at matching granular user queries, but contain too little surrounding context for the LLM to generate comprehensive answers.
- Large Chunks (1,024–2,048 tokens): Provide rich context to the LLM, but their vector embeddings average together dozens of topics, resulting in muddy semantic coordinates that fail to match specific queries.
2. Parent-Child (Hierarchical) Chunking
Parent-Child Chunking eliminates the granularity paradox by decoupling the search unit from the context unit.
How Parent-Child Retrieval Works:
- Ingestion: Slices documents into large Parent Chunks (e.g. 1,024 tokens). Each parent chunk is subdivided into 8 small Child Chunks (128 tokens).
- Indexing: Only the small child chunks are converted into vector embeddings and indexed in the vector database. Each child stores a foreign key pointer
parent_id. - Retrieval: When a query vector matches Child #3, the retriever resolves
parent_idand loads the full 1,024-token Parent Chunk from Redis or Postgres into the LLM prompt.
- Result: You achieve the search precision of a 128-token vector with the rich contextual comprehension of a 1,024-token window!
3. Contextual Chunking: Eliminating Context Orphanage
Introduced by Anthropic in 2024, Contextual Chunking uses a fast language model during ingestion to prepend document-level context to every chunk before generating its embedding.
By prepending 20–50 words of background context:
- Vector retrieval failure rates drop by over 35%.
- BM25 keyword matching succeeds because entity names and dates are now present in every chunk.
4. Python Implementation: Markdown-Aware Structure Chunking
The following Python script splits markdown documentation while preserving headers, code snippets, and tables intact.
5. Summary & Key Takeaways
- Never Use Fixed Blind Splitting: Arbitrary character slicing destroys tables, code blocks, and cross-sentence dependencies.
- Parent-Child Chunking Solves Granularity: Search across small 128-token leaf vectors; inject 1024-token parent blocks into the LLM prompt.
- Contextual Chunking Adds Metadata: Prepending document summaries to chunks before embedding prevents context orphanage.
- Preserve Document Structure: Use markdown-aware parser libraries to retain tables and code routines as single atomic units.