September 12, 2026
CHUNKS, METADATA, AND RETRIEVAL: THE PIECES A SEARCH SYSTEM ACTUALLY USES

In Lesson 22.1 you learned *why* semantic search exists: keyword matching fails when people describe the same thing in different words, and embeddings close that gap by placing related meanings near one another. Now comes the machinery. A vector database is not a magic file upload — somebody has to turn documents into searchable pieces, label them, and assemble the pipeline that answers a question.
Why not one giant record?
The beginner instinct is to embed an entire manual, contract, or knowledge base as a single record: one document, one embedding, done. It fails for three reasons.
First, an embedding blends everything into one average position. A fifty-page manual about setup, billing, security, and troubleshooting averages out into a mush that sits near nothing in particular — and a specific question about password resets retrieves the whole manual rather than the three paragraphs that answer it.
Second, models work best with focused context. Handing a model fifty pages and asking it to find the answer wastes attention and money, and buries the relevant passage in noise. Class 23 will show the model reading only selected material; that only works if the material was selected at the right granularity.
Third, documents change unevenly. One section gets revised while the rest stays fixed. If the whole manual is one record, every small edit forces a full re-embed and you lose track of which part changed, who owns it, and which version the user should see.
The fix is to split deliberately.
A chunk is a coherent, sized piece
A chunk is a deliberately sized, coherent piece of a source — one idea, one section, one procedure — small enough to retrieve precisely and large enough to keep its meaning.
Good chunk boundaries follow the document's own structure: a product-manual section ("Resetting your password"), a handbook policy, a Sonariq research section ("Profitability trends, Q3 2026"). Each chunk should still make sense read on its own — that is the coherence test.
Chunking has a genuine tradeoff, and you should feel both sides:
- Too large: the answer hides in noise. The chunk retrieves for many questions but answers none of them crisply, and the model must sift.
- Too small: the meaning shatters. A single sentence — "It rose 4%." — embeds cleanly but has lost *what* rose, *when*, and *according to whom*. The retrieval looks precise and is useless.
There is no universal chunk size. Start with natural sections, test with real questions, and adjust when retrieval returns almost-right material that is too broad or too fragmentary.
Metadata is what makes chunks usable
An embedding captures *what a chunk is about*. Everything else the product needs — *which* document, *whose*, *how old*, *who may see it* — travels alongside as metadata: ordinary fields stored with each chunk.
Teach yourself this starter set:
| Field | Why it matters |
|---|---|
| Document title | "Password & login help" — lets the product show a human-readable source |
| Source URL | Takes the user to the actual evidence, not a decorative footnote |
| Section | "Resetting your password" — locates the chunk inside its document |
| Date / version | Distinguishes current procedure from last year's; Lesson 22.1's currency check lives here |
| Author / owner | Who stands behind this text and who updates it |
| Permissions / visibility | Who is allowed to retrieve it — enforced *before* the prompt is assembled |
| Product / scope | Which product, region, or account type this chunk applies to |
| Chunk position | Section 3 of 12 — preserves order and makes updates surgical |
Metadata is not decoration. Filters on these fields decide which chunks are even *eligible* before similarity ranking begins. A perfect semantic match the user may not see, or one from the wrong product version, must never reach the model.
The flow, end to end
The whole system is two pipelines — one that prepares material, one that answers questions:
Document → clean → split into chunks → embed → store vector + metadata
Question → embed → retrieve candidates → filter → show source
Walk it briefly:
1. Collect and clean. Gather sources; strip navigation chrome, duplicate headers, and stale drafts. Retrieval quality starts here. 2. Split into chunks. Coherent sections, each passing the read-it-alone test. 3. Embed and store. Run each chunk through an embedding model — the same kind of model introduced in Lesson 22.1 that converts text into a number list for similarity comparison; save the vector alongside its metadata. (Lesson 22.3 shows this as a Postgres table.) 4. Embed the question with the same model at query time. 5. Retrieve, filter, show. Find the nearest chunks, apply metadata filters — product, rights, time, language, scope — and present survivors with titles and links, passing only those to the model in Class 23.
Notice the order: many systems filter *before* ranking (only searching eligible chunks) rather than after. Either way, filters are first-class, not an afterthought.
Filters first: product, rights, time, language, scope
Repeat this until it is reflex: a result should match the user's product, access rights, time period, language, and source scope before semantic similarity alone decides.
- A support answer for Product A must not quote Product B's manual, however similar.
- An internal-only memo must not surface to an external user, however relevant.
- A 2024 tax procedure must not answer a 2026 question without a freshness flag.
- A German manual section must not answer an English user who cannot read it — unless that is the product's explicit design.
Similarity proposes candidates; filters grant eligibility. Record the metadata faithfully at ingest time and enforce it at query time without exception.
Worked example: two pages → five chunks
Source: "Password & login help" (2 pages, help center). Owner: Support team (support@). Date: revised 2026-08-15. Link root: https://help.example.com/login.
| # | Chunk title | Source / section | Owner / date | Filter field + value |
|---|---|---|---|---|
| 1 | When to reset vs. when to contact support | https://help.example.com/login#when-to-reset, Section 1 of 5 | Support team / 2026-08-15 | product_id = 'portal' (portal only, not mobile-admin) |
| 2 | Resetting your password (steps 1–4) | https://help.example.com/login#reset-steps, Section 2 of 5 | Support team / 2026-08-15 | visibility = 'public' (safe for all signed-in users) |
| 3 | Locked out after too many attempts | https://help.example.com/login#locked-out, Section 3 of 5 | Support team / 2026-08-15 | visibility = 'public' + language = 'en' |
| 4 | Admin-assisted reset for SSO accounts | https://help.example.com/login#sso-admin, Section 4 of 5 | IT owner (it@) / 2026-08-01 | visibility = 'internal' (staff/admins only — never retrieve for external users) |
| 5 | What changed in August 2026 | https://help.example.com/login#changelog, Section 5 of 5 | Support team / 2026-08-15 | updated_at = 2026-08-15 (supersedes all chunks dated before 2026-08-01) |
Why these boundaries: each chunk answers one question standalone ("I am locked out — what now?") and keeps its procedure intact. Merging 2 + 3 would bury the lockout wait-time inside the generic reset steps; splitting chunk 2 in half would strand step 4 ("check your spam folder for the code") without its context. Chunk 4 carries the strictest filter — a perfect semantic match there must still lose to eligibility for an external reader.
Practical exercise: a two-page chunk plan
1. Take any two-page document: a product help page, a policy excerpt, a Sonariq-style research note. 2. Propose a chunking plan: split it into coherent chunks (likely three to six), each with a working title. 3. For each chunk, write: title, source link, owner, date — plus one metadata field that should filter it (product/version, visibility, language, time scope, or audience) and the value it carries. 4. Write one paragraph defending your boundaries: where did you split, why there, and what would break if two adjacent chunks were merged or one chunk were split in half?
Finish line: a chunk plan with every chunk labeled (title, link, owner, date, one filter field) plus your boundary-defense paragraph.
Verify: hand one chunk — alone, without its neighbors — to a friend or an AI and ask what question it answers. If it cannot be understood standalone, it is too small or missing context; merge it upward or prepend the section heading into the chunk text.
Common failure mode: splitting by fixed word count ("every 200 words") and slicing procedures in half. Mechanical splits are easy to code and bad to retrieve. Split where the *meaning* changes, then record the position so order survives.
Check your understanding
1. Why is embedding a whole manual as one record a bad idea? Name all three reasons. 2. What is a chunk, and what is the coherence test? 3. Describe the too-large vs. too-small tradeoff in your own words. 4. Which metadata fields make currency and permission checks possible? 5. Recite the two-pipeline flow from document to shown source.
ARTICLE DISCUSSION
JOIN THE
CONVERSATION.
Got a question, a take, or a better way to do this? Log in and leave a comment.
