The split
The chunk you keep is the answer you can find
Drag the two knobs and watch the same underwriting note re-chop live. The question only gets answered when its evidence lands inside a single chunk.
- A chunk is the unit of retrieval. Search returns whole chunks, never half of one. Whatever the split leaves stranded, the system can’t hand back.
- Size is a trade-off. Too small and the answer spans several chunks, so no single passage carries the full fact. Too large and each chunk is mostly noise, which dilutes the match and burns the model’s context budget.
- Overlap is the safety net. Chunks share a few characters at their edges, so a fact sitting on a boundary still lands whole in at least one neighbour. It costs storage; it buys recall.
- This is decided once, upstream. Nothing downstream — reranking, a bigger model, a smarter prompt — can rejoin a fact the split already tore apart.
↳ Small chunks fracture the fact; big chunks bury it. Overlap is what saves a fact sitting on a boundary.
Following claim 88431, the account was re-tiered and the annual premium increased 18% at renewal, reflecting the water-loss history and the absence of a leak-detection device.
This split keeps the whole answer sentence inside one chunk, so a search for “why did POL-55012 go up?” can return the reason in full. That is a retrieval hit.
Set overlap to 0 and shrink the chunk size until a boundary lands inside the answer sentence — the verdict flips to split. Now nudge overlap up: the same fact reappears whole in the next chunk, because neighbours share their edges. That shared margin is cheap insurance against a fact falling on a seam.
Two ways to cut
Cut by character count, or cut where the meaning changes
The baseline counts characters. The upgrade cuts on the document’s own structure — and that changes what each chunk is about.
- Naive = fixed-size window. Slide an 800-character window across the raw text with a little overlap. Simple, fast, and blind to meaning — a chunk can start mid-sentence and mix the roof detail with the premium reason.
- Structure-aware = cut on the document’s seams. Split on the record’s real boundaries: headings and paragraphs for a prose claim note, fields for a structured policy record. Each chunk becomes one coherent thing.
- Same evidence, cleaner packaging. Structure-aware chunks put “premium change + reason” in one passage and “roof / mitigation” in another, so the reason isn’t diluted by unrelated facts.
- It’s still the honest baseline first. The spine ships naive on purpose — it’s the measurable floor. Structure-aware is the upgrade you reach for when retrieval quality needs it, not a reflex.
A single window straddles two unrelated topics — the match for “why did premium rise” is diluted by coverage text it happened to include.
Each chunk is about one thing. The “rating decision” chunk is the reason and nothing else — easy to retrieve, easy to cite.
Both strategies split the exact same document. The naive window is blind to meaning, so some chunks mix topics and dilute the match. Cutting on the document’s own structure gives you chunks that are each about one thing — easier to retrieve and easier to cite. The spine ships only the naive splitter today; structure-aware is the upgrade this post argues for, not shipped code.
What rides along
A chunk carries its document’s guardrails, not just its words
When you cut a document into chunks, each piece has to keep the labels that say who can see it and where it came from — or you’ve quietly broken security and citations.
- Provenance rides along. Every chunk keeps its
source_id(e.g.claim/88431) so any answer built from it can cite the exact record it came from. - Isolation rides along. Every chunk keeps its
scope— the tenant + environment — so one insurer’s data and dev/prod never blur together at search time. - Permissions ride along. Every chunk keeps its
acl_roles, so a passage from an underwriter-only memo stays underwriter-only after it’s been split. - Lose any of these and the split silently leaks. A chunk with no roles is a chunk the filter can’t gate; a chunk with no
source_idis an answer you can’t trace.
That’s why the real splitter copies scope, doc_type, source_id, acl_roles and updated_at onto every chunk verbatim — it isn’t incidental, it’s what lets the retrieval filter run in the query and every answer cite its source. Chunking preserves the guardrails; it doesn’t just cut the text. That thread — permissions enforced at retrieval — is what Post 04 pulls on.
This isn’t pseudocode. The spine ships NaiveChunker: a fixed-size character window with overlap that copies each document’s isolation and ACL metadata onto every chunk, so the rest of the pipeline keeps working. Check out the tag and read the whole thing — it’s about 40 lines.
The whole chunker is the fixed window you just drove, plus the metadata copy that keeps each chunk filterable and citable:
It implements one small Chunker Protocol, so swapping in a structure-aware splitter later is a one-line change in the wiring — nothing else in the pipeline moves:
Teaching-grade reference implementation, not a production insurance product. Only the naive splitter ships at this tag; structure-aware chunking is the argued next step, not shipped code. Bring your own data and keys. MIT-licensed. The demo command splits the sample note locally and prints which chunk holds the answer — illustrative, and it runs.
Explain it back
A teammate says: “Chunking is just preprocessing — we’ll tune it later once retrieval and the model are good.” In one or two sentences, why is that backwards?
Reveal a model answer
Chunking isn’t downstream of retrieval — it defines what retrieval can return, because a chunk is the smallest unit search can hand back. If the split tore the answer across a boundary, it’s already gone: no reranker, bigger model or better prompt can retrieve a passage that was never stored whole. Chunking is the first thing to get right, not the last — a retrieval decision, not preprocessing.
Now the document is split into clean, self-contained, permission-carrying chunks. Next we go find them: turn the question into a vector, pull the closest chunks out of the store, then rerank so the passage that actually answers the question rises to the top of a small context budget. Good chunks make retrieval possible — the next post makes it precise.
Continue to Retrieve & rerank →