Facts in the middle of a long context get missed
In short
Do not reason about attention. Measure. Freeze one question and one passage set, move the chunk containing the answer through every position, run each arrangement 10 times, and plot hit rate against position. A dip in the middle is a position problem, fixed by sending fewer passages. A flat low line at every position is a passage problem, and reordering will not touch it.
Key takeaways
- Run a position sweep before changing anything: same question, same passages, answer chunk moved through every slot.
- A dip in the middle with strong ends is a position effect. Cut k rather than reordering around it.
- A flat low line at every position means the passage never answered the question. This is a retrieval finding.
- Pin the model snapshot for the whole sweep, or you have measured two systems and attributed it to one.
- Passages that could not plausibly hold the answer are not free. They displace attention and cost tokens.
- Rank order is not usefulness order. A fused rank tells you what matched, not what a reader would need first.
Take one question you know the system answers unreliably. Fix the exact set of passages it retrieves. Then run the same request repeatedly with only one thing changed — the position of the chunk that actually contains the answer, moved from first to last through every slot — and record how often the answer comes out right at each position. That curve is the whole diagnosis. It takes about an hour to produce and it replaces a fortnight of theorising about attention.
Two shapes matter. If the hit rate is high at the start and the end and sags in between, position is doing real work and the repair is to send less. If the hit rate is uniformly poor wherever you put the chunk, position is innocent — the passage does not carry the answer in a form the model can use, which is a chunking or retrieval finding rather than a prompting one.
Running the sweep
- Pick one question with a single, checkable answer — a number, a date, a named condition. A question whose answer is a paragraph cannot be graded automatically, and a sweep you grade by hand will be run once and never again.
- Capture the passage set once, as literal text, and store it. From here on retrieval is out of the experiment; you are testing what happens after the passages are chosen.
- Write the grader before the runs. A substring match on the expected value is usually enough, and a grader written afterwards will be tuned, unconsciously, to the results you already saw.
- Generate the arrangements. With 8 passages you have 8 arrangements: the answer chunk at slot 1 with the other 7 in their original relative order, then at slot 2, and so on. Keep every other passage in a fixed order so position is the only variable.
- Run each arrangement 10 times at the lowest temperature the model allows, and record correct or not correct. 10 runs distinguishes 9 out of 10 from 4 out of 10, which is all the resolution this needs.
- Repeat the entire sweep at a second value of k — 6 passages and 16, say. The interaction between k and position is where the actual finding usually lives.
- Record the model snapshot identifier next to the results. A sweep spanning a model change has measured two systems, and what a pinned snapshot actually freezes is worth reading before you assume the identifier means what you think.
The sheet you fill in
| Position of the answer chunk | Correct at k of 6 | Correct at k of 16 |
|---|---|---|
| First | __ of 10 | __ of 10 |
| Second | __ of 10 | __ of 10 |
| Middle | __ of 10 | __ of 10 |
| Second from last | __ of 10 | __ of 10 |
| Last | __ of 10 | __ of 10 |
Five rows is enough for a first pass. Run the full sweep across every slot only if the five-row version shows something worth resolving, because the cost is one model call per run and it multiplies quickly across positions, values of k and repeats.
Reading the shape you get
| Shape | Reading | What to change |
|---|---|---|
| High everywhere at both values of k | Neither position nor context length is your problem on this question. | Return to retrieval: the failing cases involve a different question class |
| High at both ends, sagging in the middle, worse at k of 16 | A genuine position effect, amplified by length. | Cut k to the number of passages that could plausibly hold the answer |
| Low at every position, at both values of k | The passage does not answer the question in a usable form. | Look at the chunk itself — split across a boundary, or too oblique to recognise |
| High at k of 6, poor at every position at k of 16 | Length, not position. Something is being crowded out or trimmed. | Check the rendered payload for silent truncation before anything else |
| High only in slot 1, poor from slot 2 onwards | The prompt structure is treating the first passage as privileged. | Look at the template — a lead-in that frames slot 1 as the source |
The four causes the sweep separates
- Too many passages. k was set once, generously, and never revisited. Every passage that could not plausibly hold the answer is a competitor for the model's attention and a line on your token bill, and it earns neither.
- Low-value padding. A fixed k forces the system to send its 12th-best candidate even when only 3 candidates were any good. A relative cutoff — drop anything more than a stated margin behind the top score — sends 3 passages on easy questions and 12 on hard ones.
- The answer split across a boundary. The condition ends one chunk and the exception begins the next, so no single passage answers the question and the model has to join two fragments. This is the failure that generous overlap exists to prevent, at the price described in chunk overlap and what it duplicates.
- Ordering by raw score. Retrieval order is a similarity ranking, not a usefulness ranking, and a fused list from 2 arms is a compromise between 2 orderings rather than an argument about what the reader needs first — which is what rank fusion across 2 result lists is actually doing.
Every passage you send that could not possibly hold the answer is competing with the one that does. There is no neutral filler in a context window.
Ordering by usefulness rather than by score
Once the sweep shows position matters, the ordering becomes a design decision rather than an accident of the ranker. Four moves are worth making, in this order.
- Deduplicate first. Near-identical chunks occupy 2 slots and contribute one idea, and they are the cheapest slots to reclaim.
- Apply a relative cutoff. Keep passages within a stated score margin of the best one and drop the rest, so k varies with how clear the retrieval was.
- Put the strongest evidence where the sweep says the model reads best — usually the ends. If 2 passages carry the answer, one at each end beats both buried together.
- Label every passage with its source and its effective date in the prompt itself. This does not fix position, and it does give the model something to prefer when 2 passages disagree, which is a distinct failure you will otherwise diagnose as a position problem.
Why sending more is the wrong reflex
The instinct when an answer is missed is to widen k so the evidence is definitely in there. That does raise the chance the answer-bearing passage is present, which is exactly what recall@k measures. It also lowers the chance the passage is used, and the 2 effects run in opposite directions. Somewhere between them is a value of k where total answer quality peaks, and the sweep is how you find it rather than argue about it.
That crossover moves. It moves when you change the reader, when the corpus grows longer chunks, when a new source starts winning slots. Which is the argument for making the sweep a script with a stored fixture rather than a notebook someone ran in April — a small piece of durable internal tooling of exactly the kind we describe under internal tools and operations software. Re-run it on a schedule and on every model change, and the answer to "should we send more context" stops being a matter of opinion.
The neighbouring diagnoses — a passage that never reached the payload at all, and a passage that arrived and was used badly — sit alongside this one in retrieval and grounding, part of the engineering library.
Frequently asked questions
Short answers to the follow-ups this page tends to raise.
Does adding more retrieved chunks make answers worse?
Past a point, yes, and the point is measurable rather than universal. More chunks raise the probability the answer is somewhere in the context and lower the probability the model uses it, because every additional passage competes for attention and pushes the useful one further from the ends. Run a sweep at 2 values of k on your own questions; the value where quality peaks is a property of your corpus, your prompt and your model, not something to copy from anyone else.
How do I test whether position is affecting my answers?
Hold everything constant except the position of the passage containing the answer, and run each arrangement 10 times with a deterministic grader. If the hit rate is high at the ends and low in the middle, position is real. If it is uniformly low, the passage is the problem and reordering will not help. The whole experiment is one script, one stored fixture and about an hour of model calls.
Should I put the most relevant passage first or last?
Let the sweep answer it, because the shape differs by model and by prompt template. Two things hold generally enough to be worth assuming until measured: the extremes of the ordering do better than the middle, and a template that introduces the first passage as the primary source will make slot 1 dominate regardless of content. If 2 passages both carry the answer, splitting them across the 2 ends is a reasonable default.
Why did quality drop when we moved to a longer context window?
Because a bigger window usually arrives with a bigger k, and the 2 changes get shipped together. The window grew, someone raised the number of passages to use it, and the extra passages diluted the ones that mattered. Roll k back to its old value on the new window and measure again — if quality returns, the window was never the problem, and you have found your crossover point the expensive way.
- context
- prompting
- evaluation
- debugging
The work behind this page
Builds from our portfolio that this page draws on.
AskVault
An AI internal knowledge-search platform that answers employee questions from your own docs — grounded in citations, with knowledge gaps surfaced and deflection tracked.
Productivity AINotewell
An AI meeting assistant that records and transcribes every meeting, extracts the decisions and action items, assigns owners and due dates, and tracks follow-through until it's done.
Productivity AIRead next
- The model answered from memory and ignored the passage you gave itPlant a passage that contradicts common knowledge, then ask a question only that passage answers. Whichever the answer follows tells you whether you have an override or a payload that never arrived.diagnostic
- Chunk overlap: what it protects against and what it duplicatesOverlap is insurance against a chunk boundary landing in the middle of one idea. The premium is paid in duplicated candidates crowding a fixed number of prompt slots.definition
- Recall@k, and why it is the number retrieval lives or dies byRecall@k is the share of questions whose answer-bearing passage made the top k. It gates everything downstream, because no reranker or prompt recovers a passage that was never fetched.definition
- The same question returns different passages every runSome of the variation is approximate search doing exactly what it was built to do. The rest is a rewrite step, a moving index or a session-dependent filter — and only that half is worth fixing.diagnostic
- The right passages were retrieved and the answer is still wrongIf the answer-bearing passage was in the context and the answer is still wrong, retrieval tuning cannot help. Four synthesis defects produce this, and each leaves its own mark in the output.diagnostic
- Adding one new source made unrelated answers worseNothing about the old passages changed. A new source ranks moderately well on a great many queries, and a fixed top-k has to give it those slots by taking them from something else.diagnostic
Working on something in this space?
Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.
Start the conversation