Marketing

When a Retrieval Snippet Needs the Paragraph Above It

Antonio Evans7 min read

A printed marketing page on a desk with three outlined regions, a tight sentence box, a taller box including the heading and qualifier above it, and a full-page outline, each beside a stack of paper tokens.
Key points

Key points

  1. 1A retrieval hit that begins mid-claim is not usable for an auditor, because the model never sees the qualifier that makes the claim true.
  2. 2You have three expansion options after the hit: return the enclosing section, return a fixed token window before and after, or return the whole page.
  3. 3Parent-section expansion usually gives the smallest block that still holds a complete claim, at a predictable token cost you can measure.
  4. 4A fixed window is cheaper to build and sometimes wins, but it can drag in a neighboring section's disclaimer or miss a qualifier three paragraphs up.

Why a mid-claim hit is a failing hit

Chunking sets a ceiling on answer quality at ingest time. A chunk is a few hundred tokens embedded as its own retrievable unit, and retrieval can only rank chunks that exist, so a policy split across two chunks answers no question on its own (The AI Engineer). Most teams solve this with overlap: the tail of each chunk is copied onto the head of the next, usually at 10 to 20 percent of chunk size (The AI Engineer).

Overlap fixes sentences that straddle a cut. It does not fix claims that depend on a qualifier sitting in a different paragraph. Marketing copy produces this failure constantly. A bold number in one paragraph ("cuts setup time by half") is often governed by a condition two paragraphs earlier ("for teams already on the pro tier") and a disclaimer three paragraphs later ("results vary by catalog size"). Overlap is blind to both because neither sits near the cut boundary.

The damage shows up as a specific error type rather than a vague "bad answer". Splunk's write-up of common RAG failures lists "not extracted (FP4)": the answer is in the context, but noise or conflict hides it, and "incomplete (FP7)": accurate but omits information from context (Splunk). A mid-claim hit with no qualifier is FP7 by construction. The chunk is relevant, ranks well, and still cannot support a defensible citation.

This is the next decision after chunk size, and it matters as much. Chunk size decides what can be retrieved. Expansion decides what the model actually reads.

The three expansion strategies, precisely

Each strategy answers the same question ("how much text do I hand the model around the hit?") with a different rule.

Parent-section expansion. Index small child chunks, retrieve on them, then return the parent that encloses the hit. Parent-document retrieval splits index granularity from context granularity: index at roughly 200 tokens, retrieve at that level, then return the larger parent (typically 1,000 to 2,000 tokens) to the model (ZeroEntropy). In practice the parent you want is not always the whole document; it is the section under its nearest heading.

Fixed window. Retrieve a sentence or small chunk, then return a set number of tokens before and after it. This is sentence-window retrieval: fetch a single sentence during retrieval and return a window of text around the sentence (Sophia Yang, LlamaIndex). LlamaIndex implements it as a node-parser pattern where each node carries previous and next relationships as metadata (LlamaIndex docs).

Whole page. Skip expansion logic entirely and return the full document for any hit. This is the "just stuff it in" approach, which is only practical when the corpus fits the context window and does not change often (SitePoint, Meilisearch).

The distinction between the first two is easy to miss. Parent expansion follows document structure; a window follows token distance. On a well-sectioned marketing page, those two boundaries rarely coincide.

Token cost per hit, with a worked example

Take a blog post of 1,400 tokens: intro, three sections under H2 headings, and a closing legal note. A team chunks it at 200 tokens with 20 percent overlap, giving 8 child chunks. A query hits chunk 5, which starts with "which cuts setup time by half" and carries no subject.

StrategyWhat the model receivesTokens per hitWhat it may miss or drag in
Child chunk onlyThe 200-token child200The qualifier in the previous section, the disclaimer at the end
Fixed window, 200 before and afterSliding span around the hitAbout 600May cross into the next section and pull its disclaimer, or stop short of a qualifier three paragraphs up
Parent sectionThe section under its nearest heading350 to 600Nothing inside the section, but drops cross-section qualifiers
Whole pageThe full post1,400Cost only: 2.3x to 7x the parent section for no extra completeness

The parent-to-child ratio is where the budget goes. ZeroEntropy puts a 1,500-token parent against a 200-token child at roughly 7.5x the tokens per result, and their guidance is to send fewer results to compensate, because more complete context per result is usually a better trade than more partial results (ZeroEntropy).

Run the arithmetic on a realistic volume. Suppose you answer 10,000 questions a month with five retrieved results each. At 200 tokens per child that is 10 million input tokens monthly. At a 1,500-token parent it is 75 million. Drop to two parent results per query and you land at 30 million, still complete per result and three times the original. Whether that matters depends on your input price, and token counts are not comparable across providers: the same prompt can register differently under different tokenizers (Silicon Data).

Near-miss hits: the case against the fixed window

The fixed window is the tempting middle option. It is simple to implement, needs no heading parser, and costs a predictable number of tokens. It also fails in exactly the way marketing copy punishes.

Consider a claim in section two and the qualification for it in section one, three paragraphs back. A 200-token window before the hit does not reach it. The model reads an unqualified claim and writes a confident sentence you cannot defend. A parent-section rule has the same blind spot if the qualifier lives in the previous section, which is why the section rule usually needs one adjustment: prepend the nearest heading and, when the claim contains a number, the paragraph immediately above the heading.

The window's other failure is opposite in direction. If the hit lands near the end of a section and the window extends 200 tokens past it, you can pull in the next section's disclaimer about a different product line. That is not harmless noise. It is a contradictory fact the model must reconcile, and Splunk lists conflicting context as one of the failure points that produces wrong answers even when the right passage was retrieved (Splunk).

The general finding from the long-context literature applies here: quality depends on context relevance as much as quantity, and retrieved noise is a real cost, not a neutral addition (Long Context vs RAG evaluation). Adding tokens lowers nothing; it raises cost and can raise confusion.

Setting it up so the expansion is cheap

Expansion is only cheap if you stored the structure at ingest time. Two IDs per chunk do most of the work.

Store each child chunk with a heading ID and a paragraph index. At retrieval, group results by heading ID, deduplicate, and return each heading's text once. ZeroEntropy's implementation notes are explicit about this step: if several retrieved children point to the same parent, deduplicate before sending, or you pay for the same parent repeatedly (ZeroEntropy).

# Store at ingest, resolve at query time
chunk = {
    "text": child_text,
    "heading_id": "h2-shipping-policy",   # nearest heading above the chunk
    "section_id": "post-4821-h2-3",        # the section this chunk belongs to
    "para_index": 4,
}

def expand(hits, section_store, max_tokens=800):
    seen, out = set(), []
    for hit in sorted(hits, key=lambda h: -h["score"]):
        sec = section_store[hit["section_id"]]
        if sec["id"] in seen:
            continue
        if sec["tokens"] <= max_tokens:
            seen.add(sec["id"])
            out.append(sec)
    return out

The max_tokens guard matters. Some sections run long, and a single oversized section can crowd out every other result. Cap it, and let the section spill into the next retrieval slot rather than truncating mid-sentence.

Reranking belongs at the parent level, not the child level, when you use section expansion. Child-level retrieval is deliberately wide; reranking the deduplicated sections gives you a second, sharper pass over what the model will actually read (ZeroEntropy).

If your sections are already short (an FAQ, a set of product cards), skip the expansion. ZeroEntropy names self-contained chunks as a case where parent expansion is wasted tokens (ZeroEntropy). Marketing teams often have both kinds of page and should treat them differently.

A decision rule you can defend with your own numbers

Build a small evaluation set before choosing. LangChain's evaluation checklist says to manually review 20 to 50 real traces before building any eval infrastructure, because failure patterns from reading real traffic beat anything an automated system produces first (LangChain). Twenty traces is an afternoon.

Then construct a gold set. You need queries paired with the specific chunks that count as correct context, or you cannot compute recall at all (Rajan Mehta). For this decision, gold labels should record whether a complete, citable claim is present, not merely whether the right topic was retrieved. A passage containing "cuts setup time by half" without its condition is a miss even though it ranks first.

Run one evaluation per strategy and score two things: whether the full claim (with qualifiers and disclaimers) was present in what the model read, and tokens spent per answer. The rule that falls out, for marketing copy specifically:

Condition on the pageUse this
Section under a heading holds the whole claimParent section
Section is short (under about 300 tokens)Parent section, no cap needed
Claim's qualifier sits in the previous sectionParent section plus the paragraph above the heading
Page is under about 800 tokens totalWhole page, and stop maintaining expansion logic
Corpus is short FAQ answers or product cardsNo expansion
Legal review needs full context on every hitWhole page, budgeted separately

The cross-over is the useful part. Whole-page retrieval ceases to be extravagant once the page is short enough that the section and the page cost nearly the same. Below roughly 800 tokens there is no decision to make. Set a threshold, check the page's token count, and fall back to the full document rather than debugging a parser.

Above that threshold, expand to the section and measure. If your hit-rate for complete claims does not improve over the fixed window on 20 to 50 labeled traces, keep the window and save the engineering. If it does, the section rule pays for itself in defensible citations.

Once you have the rule and the eval set and you would rather not maintain the parsing and reranking yourself, Quanta Inference puts text, embedding and reranking models behind one OpenAI-compatible key, which keeps the cost side of the comparison in a single bill while you tune the retrieval side.

FAQ

FAQ

Why not always return the whole page?

Because the token cost scales with page length while the completeness gain stops as soon as the claim is fully covered. A 1,400-token post costs several times a 400-token section for identical coverage of the claim, and longer context raises cost and latency (Meilisearch). Return the whole page only when it is short (under about 800 tokens) or when a reviewer needs full document context.

Does a bigger context window make expansion unnecessary?

Not for this problem. Long-context models can read entire documents and often outperform retrieval when given the full text, but retrieval remains far cheaper and scales to corpora that do not fit any window (arXiv 2407.16833). The expansion decision is about which slice of a page to send, not whether to retrieve at all.

How many tokens should a fixed window use?

Start at roughly 200 tokens before and 200 after the hit, which keeps you near the 600-token range for a 200-token chunk. Then check it on your traces. Window size interacts with retrieval effectiveness in ways that vary by document type, so it needs measuring rather than assuming (Priyanthan Govindaraj).

Can I skip the evaluation set and just pick the section rule?

You can, and it is a reasonable default for long-form prose, where ZeroEntropy says parent-document retrieval is almost always a net win (ZeroEntropy). But without 20 to 50 labeled traces you cannot tell whether your heading structure is clean enough for the section rule to help, or whether a fixed window would have been cheaper for the same result.

What changes if my pages are generated by an AI writer?

Nothing about the tradeoff, and quite a lot about the failure rate. AI-generated marketing copy tends to place qualifiers far from the claim and to distribute disclaimers per section, which widens the gap between parent-section and fixed-window behavior. Treat generated pages as higher risk and weight your eval set toward them.

Sources

Sources

  1. What is Chunking? - The AI Engineer - Substack
  2. How to Architect an Enterprise Retrieval-Augmented ...
  3. Parent-document retrieval: small-chunk index, full-doc ...
  4. Advanced RAG 01: Small-to-Big Retrieval
  5. Sentence window - LlamaParse documentation
  6. Long Context vs RAG: When 1M Token Windows Replace ...
  7. RAG vs. long-context LLMs: A side-by-side comparison
  8. Understanding LLM Cost Per Token: A 2026 Practical Guide
  9. Long Context vs. RAG for LLMs: An Evaluation and Revisits
  10. Agent Evaluation Readiness Checklist - LangChain
  11. Evaluating Retrieval in RAG: A Guide to Measuring ...
  12. Retrieval Augmented Generation or Long-Context LLMs?A ...
  13. Advanced RAG: Building and Evaluating a Sentence ...
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles