Retrieval can only return what your chunks contain. Chunking is therefore the highest-leverage part of a RAG system.
Strategies: - Fixed-size with overlap — e.g. 800 tokens, 100 overlap. Simple baseline. - Structure-aware — split on markdown headings, HTML sections, function/class boundaries for code. Best default for docs. - Semantic chunking — split where embedding similarity between consecutive sentences drops. - Parent-child (small-to-big) — index small precise chunks, but send the larger parent section to the model.
Always store metadata with each chunk: source URL, title, heading path, timestamp, tenant/ACL, and a chunk index.
python
chunks = [{
"text": section_text,
"meta": {"url": url, "heading_path": "Billing > Refunds", "updated": "2026-08-02", "tenant": tid},
} for section_text, url, tid in sections]Gotcha: never split tables, code blocks, or numbered procedures across chunks — half a procedure produces confidently wrong answers.