AI agents

How Many Chunks to Send: A Context Window Budget for Answers

Antonio Evans11 min read

A side view of a prompt window drawn as a fixed-width shelf.
Key points

Key points

  1. 1A retrieved-token cap is a prompt-side budget measured in tokens, separate from the number of rows your retriever returns.
  2. 2Set the cap as a fraction of the usable prompt window after subtracting the system prompt, tool definitions, conversation history and answer space.
  3. 3Rank rows by reranker score, fill from the top until the cap is reached, and drop the lowest-ranked rows first.
  4. 4Test the capped prompt against a no-cap baseline on a fixed question set with a written answer key, so quality loss is measured rather than assumed.

Start with the model window, not the row count

The number of rows your retriever returns and the number of tokens those rows occupy in the prompt are two different settings, and teams routinely tune the first while ignoring the second. A retriever that returns twenty rows may place two thousand tokens into the prompt on one question and twelve thousand on the next, because chunks vary in length. What the model experiences is the token total, not the row count.

The context window is shared between request and response. A worked split from one practitioner write-up uses a model limit of 8,000 tokens, a system prompt of 500 tokens, a user question of 300 tokens, 6,000 tokens of retrieved context, and 1,200 tokens left for the answer, with the note that a longer answer is truncated at the model limit. That is the arithmetic to copy. Everything in the request competes with the retrieved rows and with the answer itself.

One caution about the advertised number. The nominal limit is what the model card states; the effective limit is where accuracy holds, and the same guide reports practitioner guidance that it is often 70 to 80 percent of nominal in that token budgeting overview. Treat that as a planning heuristic, not a law, and confirm it against your own evaluation set.

A second caution is the silent cut. When the assembled prompt exceeds what the server is configured to serve, the prompt can be trimmed without any error field in the response, so the answer is produced from whatever survived as documented in a context budgeting walkthrough. You will not see a warning. You will see a fluent answer missing the one passage that mattered.

Subtract before you allocate the retrieved cap

The cap you set on retrieved tokens is a remainder, not a starting figure. Four costs come out of the window first.

CostWhat to countPractical note
System prompt and rulesFull instruction text as sentKeep it identical per call so a provider cache can match the prefix
Tool definitionsJSON schemas or function descriptions sent on every callEasy to forget; often thousands of tokens in agent setups
Conversation historyPrior turns you resendGrows every turn unless trimmed or summarized
Output roomTokens you want the answer to be able to useReserve it before retrieval, not after

The tool and history lines are where budgets blow up quietly. A published breakdown of a moderate agent conversation totals 15,100 tokens before any retrieved documents are added: 4,500 for system prompt, tool definitions and agent instructions, 2,600 for project context, and 8,000 for twenty turns of messages in a worked context budgeting example. Retrieved rows sit on top of all of it.

A multi-turn context engineering guide makes the same point from the other direction: it lists the components competing for the window as system prompt, conversation history, tool results, retrieved context and the current input, and notes that a single tool result can return thousands of tokens in one call in that guide. Retrieved rows are one claimant among several, not the whole bill.

Then choose the retrieved cap as a fraction of what is left. Two-thirds of the remaining window is a reasonable opening bid for a question-answering product; half is a reasonable opening bid once you resend history. Pick one, write it in configuration, and set a small safety buffer below the hard limit, since production systems commonly hold back a margin to avoid hitting the cap according to the token budgeting guide.

One placement decision makes the rest of the budget readable. Put rules and role in the system message, and put document passages in the user message with the question as recommended in that walkthrough. A document welded into the system prompt changes the prefix on every call, so the provider cache never hits, and your trace no longer shows which passages the answer was grounded on. The same walkthrough prices the mistake on a small corpus: a system prompt with the document baked in ran to 225 tokens and changed every call, while a rules-only system prompt came to 18 tokens and was identical on every call.

What to drop first, and why

Once rows exceed the cap, something must go. The order matters more than the mechanism.

First, drop whole low-ranked rows. If you have a reranker score per row, sort descending and fill until the cap is reached, discarding the tail. This keeps each surviving row intact, which matters because a chunk truncated mid-sentence can lose the sentence that held the answer. Drop whole rows, not halves.

Second, do not keep reranker scores in the prompt. A score is for your ranking logic. Sending it to the model spends tokens on a number the model cannot verify and may overtrust. Keep scores in your logs and your trace, and send only the passage text plus a stable identifier for citation.

Third, drop whole documents before dropping rows from a document that is already represented. If five documents each contribute four rows and only three documents are relevant, the irrelevant document's rows are the cheapest thing to remove. This is also where a deduplication pass pays: near-identical chunks from the same document crowd out distinct evidence.

The choice of retrieval strategy changes what "ranked" means. Recency is fast and returns the latest entries rather than the relevant ones; semantic similarity handles paraphrase but is brittle for rare identifiers such as an exact code or part number; keyword search is the reverse; hybrid search with a cross-encoder reranker is the configuration most production teams settle on, at the cost of an extra index lookup and a reranker call per turn per a survey of retrieval strategies. That reranker call is what gives you a trustworthy order to fill from, and the same survey puts the added latency in its own table, so you can decide whether the ordering quality is worth the wait.

If the evidence lives across many small records, sorting rows can fragment it. Systems that store observations as isolated records struggle to aggregate evidence about the same person or task, which is the fragmentation failure mode described in a memory architecture paper. When that applies, the fix upstream is grouping related rows under a topic before ranking, not a larger cap.

Order the surviving rows for the model

Order is not cosmetic. In the tasks studied in Lost in the Middle, accuracy is often highest when the relevant information sits at the beginning or the end of the input, and degrades when the model must find it in the middle of a long context, even for models built for long inputs. That finding alone changes how you place what survives the cap.

Two placements follow from it. Put your highest-ranked row first, and put the next most important evidence last, immediately before the question. Bury the marginal rows in the middle. If you use the common pattern of sorting ascending so the best chunk lands nearest the question, you have optimized for one end only; a symmetric order (best first, second-best last) uses both.

Keep a stable wrapper around each row: an identifier, the source title, and the text. Stable wrappers let the model cite and let you score faithfulness later. Send them in the same shape every call so the prompt is easy to diff when an answer goes wrong.

For long sessions, the ordering question is compounded by growth. The context window behaves like RAM rather than disk: it holds what the model reasons over on this call and disappears when the call returns as described in that multi-turn guide. If a tool result arrives mid-session, your retrieved cap has to be recomputed, not assumed.

An alternative to fitting everything in one prompt is paging evidence in over several calls, which is the operating-system analogy behind MemGPT. The paper's design treats the prompt as a small fast tier and the archive as external storage, moving material in and out as needed, and its own overview notes that enlarging the window does not guarantee the model uses all of its contents well as summarized in a paper overview. On a multi-session question-answering task the paper reports 92.5% accuracy for MemGPT against 32.1% for a fixed-context baseline, with the caveat, stated in the same overview, that the baseline received a lossy summary while MemGPT could search full history. The lesson for budgeting is modest: sometimes the right cap is small because the second hop is cheap.

Work the arithmetic on a real request

Here is a concrete case. Suppose the window is 32,000 tokens, the system prompt and tool definitions come to 4,000, you reserve 4,000 for output, and you set retrieved context at half of what remains. You have 24,000 left after the first two subtractions, so the retrieved cap is 12,000 tokens.

Now suppose the reranker returns these rows, with token counts taken from your tokenizer before the call:

RankRowTokensRunning totalDecision
1Handbook, section 4.22,1002,100Keep
2Ticket thread 88133,4005,500Keep
3Policy memo2,9008,400Keep
4FAQ entry1,80010,200Keep
5Old wiki page2,60012,800Drop (over cap)
6Duplicate of row 12,000-Drop
7Unrelated doc3,100-Drop

Four rows survive at 10,200 tokens, about 1,800 tokens under the cap. You could fill the remainder with a shorter fifth row if one exists; do not split row 5 to squeeze it in. Place row 1 first and row 2 last, with rows 3 and 4 in the middle.

Measure token counts with the tokenizer for the model you are actually calling. Counting words and multiplying is inaccurate for code, identifiers and non-English text, and the error compounds across a dozen rows. Where you send the same documents to several providers, keeping one tokenizer per call path is the difference between a budget and an estimate.

A rough shape for the fill loop, in pseudocode:

cap = retrieved_token_cap  # e.g. 12000, from the subtraction above
kept, used = [], 0
for row in sorted(rows, key=lambda r: r.rerank_score, reverse=True):
    n = count_tokens(row.text)
    if used + n <= cap and not is_near_duplicate(row, kept):
        kept.append(row)
        used += n
# order: best first, next best last, the rest in between
ordered = [kept[0]] + kept[2:] + [kept[-1]] + kept[1:-1] if len(kept) > 2 else kept

The duplicate check matters more than it looks. Near-identical chunks from the same page pass a similarity threshold in bulk, and each one spends tokens that a distinct row could have used.

Test the cap against a no-cap baseline

A budget you have not evaluated is a guess with a config file. The test is a fixed set of questions with a written answer key, run twice: once with the cap, once with whatever you sent before the cap existed.

The measurement discipline is the same one used for retrieval latency, where the guidance is to compare changes on a fixed question set with an explicit quality criterion and to watch for evidence falling outside a smaller candidate set per a latency budgeting guide. That guide also lists a smaller candidate set as one of its experiments, with the failure to watch being supporting evidence that falls outside the set. Smaller context is an experiment with a hypothesis and a failure mode, not a cost saving.

Here is a checklist to run each variant against:

CheckWhat you record
Answer correctnessJudged against the answer key, per question
Evidence presenceWhether the supporting row reached the prompt at all
FaithfulnessWhether every claim in the answer traces to a supplied row
Token countPrompt tokens actually sent, retrieved portion and total
LatencyRetrieval, rerank, and time to first token, recorded separately
Failure modeMissing evidence, contradicted evidence, or verbose non-answer

The evidence-presence line is the one most teams skip, and it is the most diagnostic. If the supporting row was dropped by the cap, no amount of prompt tuning recovers it. If it was present and the answer still missed it, the problem is placement or instruction, and a larger cap will not fix it. That distinction is the argument for keeping a trace of which rows were sent, not just which were retrieved.

Presentation in the prompt is itself a lever. One practical guide to RAG and prompt engineering frames context assembly as one of the layers separating retrieved evidence from the model's response, distinct from the system rules and from the way the question is phrased in that guide. Treat that structure as the point: separate system rules, context block and question, so you can change one without disturbing the others, and so a bad answer can be traced to the layer that caused it.

When a budget variant wins, promote it to the default and rerun the set when the corpus, the chunker or the retriever changes. A cap tuned against one corpus does not transfer automatically to another with different chunk lengths. The same warning applies to any comparison of retrieval engines: keep benchmark comparisons matched on dataset, filters, recall target and cache state, because an isolated vendor number does not establish what is fastest for your application per the latency guide.

When to raise the cap instead of cutting

Cutting is the default, but three situations justify a larger retrieved budget, each with a condition attached.

The answer genuinely spans multiple documents. Comparison questions need evidence from both sides. If your evaluation shows failures concentrated on multi-document questions with the supporting rows present but truncated, raising the cap is cheaper than building a second retrieval hop.

The query is a lookup for a rare identifier. Exact codes and part numbers are where semantic similarity is weakest and keyword search is strongest per the retrieval survey. Here the right move is usually a narrower query with a keyword path, not a bigger cap, because a bigger cap just adds more near-misses around the one exact row you need.

The session is long and history is eating the window. If history consumes the budget, the fix is trimming or summarizing history, not shrinking retrieval. Long-term memory holds stable facts outside the context window and pulls back only what bears on the current task, which is a different job from keeping the last twenty turns verbatim as a practical guide puts it. That guide draws the distinction sharply: memory is storage, the context window is working space, and a larger window does not create persistence by itself because the application still decides what to assemble per request. Move durable preferences and conventions into a retrieved memory entry with its own small budget, and let conversation history shrink.

Budgeting is also available at finer grain than one cap for the whole request. A runtime memory framework routes queries across memory modules at low, mid or high budget tiers, and reports better accuracy-to-cost trade-offs under tighter budgets across three benchmarks according to that paper. You do not need the routing model to borrow the idea: classify the question, then apply a small cap for lookups and a larger one for synthesis.

If you would rather not maintain separate tokenizers, caps and routing per provider, Quanta Inference puts text, image, video, audio and embedding models behind one OpenAI-compatible API key, which keeps the accounting in one place: https://quantaintelligence.ai/inference.

FAQ

FAQ

Is the retrieved-token cap the same as the number of chunks I return?

No. The cap is a token total inside the prompt; the chunk count is a setting on the retriever. Because chunks vary in length, the same row count can produce very different token totals across questions. Set the cap explicitly, count tokens with the model's tokenizer, and let the row count fall out of the fill.

Should I send reranker scores to the model?

No. Send the passage text and a stable identifier so the answer can cite its evidence. The score belongs in your ranking logic and your logs, where it helps you debug why a row was kept or dropped. A number in the prompt spends tokens and invites the model to reason about a confidence figure it has no way to check.

My prompt fits the limit but the answer still misses the right passage. Why?

Two likely causes. The passage may have been dropped by a server-side cut, which leaves no error in the response as this walkthrough warns. Or it reached the prompt but sat in the middle, where models attend least reliably per Lost in the Middle. Log which rows were sent, then reorder with the best evidence first and last before changing the cap.

How do I know the cap is too tight?

Run the fixed question set with and without the cap and count how often the supporting row was dropped. If failures concentrate on questions where the evidence was cut, the cap is too tight for that question class. If the evidence was present and the answer was wrong, the cap is not the problem and the fix belongs in ordering or instructions.

Does a bigger window remove the need for a budget?

It moves the number, it does not remove the arithmetic. The window is shared with the system prompt, tool definitions, history and the answer itself, and a larger window still does not guarantee that the model uses all of its contents well per the MemGPT overview. A budget makes the trade-off explicit and testable instead of leaving it to whichever component happens to grow.

Sources

Sources

  1. Understanding the Context Window in RAG and Agentic RAG
  2. How to Budget an LLM Context Window
  3. Giving AI Agents Memory Without Breaking the Token Budget
  4. Context Engineering in Multi-Turn AI Agents
  5. Memory Retrieval Strategies for AI Agents
  6. Maintainable Topic Documents for Long-Term LLM Agent ...
  7. Lost in the Middle: How Language Models Use Long ...
  8. 2310.08560 MemGPT: Towards LLMs as Operating Systems - arXiv
  9. MemGPT: Towards LLMs as Operating Systems - alphaXiv
  10. Latency Budgets for Memory Retrieval
  11. From Tokens to Tools: A Practical Guide to LLMs, RAG, MCP ...
  12. What Is Long-Term Memory in AI Agents? A Practical Guide
  13. Learning Query-Aware Budget-Tier Routing for Runtime ...
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