- Passage retrieval won. The 4 best-matching passages of about 200 words (963 tokens) scored 98.8%; the full article (8,585 tokens) scored 97.5%.
- Atomic-fact rewrites ("croutons") did not beat it. The 25 best-matching facts used 594 tokens (−93%) and scored 93.8%. That missed our own pre-stated bar: the interval reaches −10 points against full text.
- Summaries failed. A model-written summary scored 13.8%. It kept the answer to only 17 of 80 questions.
- Rewriting everything as facts saves almost nothing. All croutons together were only 8% smaller than the article. The saving comes from retrieval, not from the rewrite.
Croutons is a product of ours. This result does not favor it. We publish it anyway, because a benchmark that only reports wins is marketing.
Setup
Everything below was written into the protocol before any condition was run.
- Corpus: 10 English Wikipedia articles pinned to exact revisions (James Webb Space Telescope, Lithium-ion battery, Panama Canal, Insulin, Great Barrier Reef, Rust, Tour de France, Marie Curie, Mount Everest, Penicillin), each cut at about 6,000 words. 60,043 words in total.
- Questions: 100. Of these, 80 are answerable: 8 per article, each from a paragraph drawn at random, with gold answers copied from the text. The other 20 are plausible questions whose answer is not in the article; they check whether the model makes things up.
- Model: qwen2.5:7b-instruct through Ollama on one laptop (Apple M5, 17 GB). Temperature 0, seed 0, 16,384-token context window, the same answer prompt in every condition.
- Scoring: an answer is right if it contains a gold string. On unanswerable questions, the model must reply "not stated"; anything else counts as made up.
- Statistics: 95% intervals from 10,000 bootstrap resamples of questions; accuracy differences from full text use a paired bootstrap.
The seven conditions
| ID | What the model was given for each question |
|---|---|
| A | The full article |
| B2, B4 | The top 2 or top 4 passages of about 200 words, ranked by BM25 (plain keyword search) against the question |
| C | A summary of at most 600 words, written once per article by the same model |
| D10, D25 | The top 10 or top 25 croutons, ranked by BM25 against the question |
| Dall | Every crouton for the article, no retrieval |
Croutons are the article rewritten once by the same model into atomic facts: one sentence per fact, the subject named every time, numbers, names and dates kept exactly. For example: "The Great Barrier Reef covers an area of approximately 344,400 square kilometres."
Results
700 answers, 1,393 seconds of model time. Tokens are counted by the model's own tokenizer.
| Condition | Input tokens per question | vs full text | Accuracy, 80 answerable [95% CI] | Difference vs A [95% CI] | Made up, 20 unanswerable |
|---|---|---|---|---|---|
| A · Full text | 8,585 | — | 97.5% [93.8, 100] | — | 0% |
| B2 · 2 passages | 516 | −94% | 95.0% [90.0, 98.8] | −2.5 [−8.8, +3.8] | 0% |
| B4 · 4 passages | 963 | −89% | 98.8% [96.2, 100] | +1.2 [−2.5, +6.2] | 0% |
| C · Summary | 522 | −94% | 13.8% [6.2, 21.2] | −83.8 [−91.2, −75.0] | 0% |
| D10 · 10 croutons | 270 | −97% | 92.5% [86.2, 97.5] | −5.0 [−12.5, +1.2] | 5% (1 of 20) |
| D25 · 25 croutons | 594 | −93% | 93.8% [87.5, 98.8] | −3.8 [−10.0, +2.5] | 0% |
| Dall · All croutons | 7,916 | −8% | 92.5% [86.2, 97.5] | −5.0 [−11.2, 0.0] | 0% |
With 80 answerable questions, one question is worth 1.25 points. Only the summary is clearly worse than full text. The differences among the other conditions are within a few questions of each other, and their intervals overlap.
Why the summaries failed
The model was allowed 600 words and wrote 164 to 331. The summaries kept the gold answer for only 17 of the 80 answerable questions. Of the summary condition's 80 answers, 11 were right, 64 were "not stated" and 5 were wrong. In most cases the model was not confused; the fact was simply no longer there.
Where the croutons lost points
The rewrite kept the gold answer for 78 of 80 questions. Two answers were lost in the rewrite itself (one insulin question and one Great Barrier Reef question), so every crouton condition missed them. The rest of the misses came from retrieval ranking, from the model, and from two borderline answers that strict scoring marks wrong. One D10 answer to an unanswerable question was made up ("Acropora coral").
Hypotheses
Stated in the protocol before any run, about the crouton condition we expected to do best.
| Hypothesis | Result | Verdict |
|---|---|---|
| H1: D25 uses at least 80% fewer input tokens than full text | −93% | Supported |
| H2: D25 accuracy within 5 points of full text (the interval of the difference stays above −5) | −3.8, interval [−10.0, +2.5] | Not supported |
| H3: D25 makes up answers on unanswerable questions no more often than B4 | 0% vs 0% | Supported |
H2 failing does not show that croutons are worse. It shows that 100 questions cannot rule out a loss of up to 10 points. Plain passage retrieval cleared the same bar without any rewrite.
Preparation cost
Summaries and croutons cost tokens to build before the first question is answered.
| Prepared form | Tokens to build, per article | Pays for itself vs full text after |
|---|---|---|
| Summary | 9,043 | 1.1 questions (but it fails) |
| Croutons (D25) | 17,655 | 2.2 questions |
| Passages (B4) | 0 (splitting text is free) | Immediately |
Compared with passage retrieval rather than full text, D25 saves about 370 tokens per question, so its 17,655-token build pays for itself only after about 48 questions on the same article. Build cost is counted in tokens of the same 7B model; with a larger model doing the rewrite, it would cost more.
Caching changes the arithmetic
Providers bill repeated input at a discount when a prompt starts with the same text as a recent one. The protocol treats this as a price calculation, not a separate run. At a 90% discount on cached input, asking a second question about the same full article costs the equivalent of about 860 input tokens, close to passage retrieval (963). At a 50% discount, it costs about 4,290. The discount applies only while the cache is alive (often minutes), only to an identical prefix, and only on providers and models that offer it; rates change, so check current pricing.
We did not use measured prefill time as a compute measure. The local server cached prompts across runs, so a "first" full-text call took 330 ms for 8,585 tokens. Calls with no cache reuse ran at about 270 tokens per second on this laptop. This is logged as a deviation.
Checking our fact-density calculator
Exploratory checks, not part of the protocol. They test the fact-density calculator in INGEST, which this benchmark motivated.
Is "characters ÷ 4" a good token estimate?
The calculator estimates tokens as characters divided by 4. We compared that estimate with this model's own tokenizer:
| Text | Samples | Characters per token | Estimate error, all samples pooled | Error range, sample by sample |
|---|---|---|---|---|
| Wikipedia articles | 10 | 4.47 | +11.7% (too high) | −2.9% to +21.1% |
| Visible text of 12 web pages | 12 | 3.99 | −0.3% | −15.8% to +46.6% |
| Raw HTML of the same pages (first 100,000 characters) | 12 | 2.53 | −36.7% (too low) | −59.6% to +3.3% |
The estimate is fair for text taken as a whole, but it can be off by a fifth or more for a single page. For HTML it runs low, because markup splits into many short tokens. So the calculator understates what raw HTML costs, and the gap between HTML and text is wider than the character counts in the page sample below suggest. The fact-density percentage is a ratio of text to text, so the constant cancels out of it. Other models' tokenizers will give different numbers.
Does the "specific sentence" test keep the sentences that answer questions?
The calculator counts a sentence as specific when it carries a name, number, date or other concrete detail. For 76 of the 80 answerable questions (95%), the sentence holding the gold answer passed the test. The four it dropped explain a mechanism or define a term, for example why antistaphylococcal antibiotics have that name. The questions lean factual, so this recall is likely higher than it would be for "how" and "why" questions.
Across the 10 articles, 69% of the text was in specific sentences, ranging from 45% (Lithium-ion battery) to 92% (Mount Everest).
What a sample of real pages looks like
We ran the calculator on 12 pages, chosen for convenience to cover our site, SaaS homepages, pricing pages, reference pages, news and marketing guides. This is a description of 12 pages, not a statistic about the web.
| Page | Text in specific sentences | Visible text as a share of HTML |
|---|---|---|
| Wikipedia, James Webb Space Telescope | 71.9% | 10.0% |
| BBC News homepage | 41.9% | 2.5% |
| Moz, What is SEO | 38.7% | 13.5% |
| Ahrefs, SEO basics | 35.5% | 2.1% |
| Shopify pricing | 26.9% | 1.5% |
| nrlc.ai homepage | 26.8% | 6.6% |
| MDN, HTML | 24.1% | 6.4% |
| Stripe pricing | 19.2% | 3.4% |
| NerdWallet, credit cards | 12.5% | 3.0% |
| nrlc.ai, salience article | 9.3% | 10.0% |
| Apple, iPhone | 5.3% | 22.3% |
| HubSpot homepage | 3.9% | 2.2% |
Medians: 25.4% of the text in specific sentences, and visible text at 4.9% of the HTML. Pages were fetched on 2026-11-08 and will have changed since.
What this means for growth teams, content teams and agencies
- Write passages that stand alone. Two to four passages of about 200 words were enough for 95–99% accuracy. If AI systems answer from a few retrieved passages rather than your whole page, each section has to answer its own question: name the subject, state the fact, and don't lean on "as mentioned above".
- Put the specifics in the body. Summaries kept the answer to 17 of 80 questions. A TL;DR, meta description or "key takeaways" box helps people skim, but it will not carry your prices, numbers, dates and names. Put them in the sentences that make the claim.
- Don't rewrite your site as fact lists to save tokens. The full fact rewrite was 8% smaller than the original and no more accurate. Clear, well-organized prose did as well as atomic facts once retrieval picked the right passage. Spend the effort on clarity and specifics, not on reformatting.
- Most of a page is not the content. On the 12 pages we sampled, visible text was a median 4.9% of the HTML by characters, and markup costs more tokens per character than prose. Any system that reads raw markup pays for the rest. Keep important facts in server-rendered text, not only in images, tabs or scripts.
- Test pages with questions. The method here is cheap: write the questions your buyers ask, give a model your page, and check the answers against the text. This whole benchmark ran on one laptop in 23 minutes of model time. It is a measurable deliverable an agency can run before and after a rewrite.
- If you build AI tools for clients, try caching before building retrieval. With a 90% cache discount, repeat questions on the same document cost about as much as retrieval, without a search index to maintain. That holds only for repeat questions within the cache's lifetime.
Deviations from the protocol
- An automatic retry on HTTP errors was added to the harness before preparation. It never fired.
- A pilot of 140 answers ran before the full run to check the harness. Its answers are kept separately and excluded from every figure.
- Prefill time was dropped as a compute measure because of cross-run prompt caching (see above).
- The analysis script crashed on the pilot, which had no unanswerable questions. The fix changes no full-run figure.
- The calculator checks and miss diagnostics were added after the run and are labelled exploratory.
Limitations
- One model with 7 billion parameters, run locally. Larger API models read long contexts better and may narrow the gap between full text and retrieval, or widen it.
- 100 questions, so intervals are wide: one question is 1.25 points.
- The questions were written by an AI model (Claude) reading the sampled paragraphs. They lean toward short facts, which favors retrieval and atomic facts over questions that need reasoning across a document.
- Wikipedia prose is cleaner and denser than most business pages.
- One run per question at temperature 0. Strict string scoring marks two borderline answers wrong.
- The summaries and croutons were written by the same 7B model. Human-written summaries, or a larger model's croutons, may do better.
- BM25 is simple keyword ranking. Embedding-based retrieval might change the passage and crouton results.
- The protocol was committed to git on 2026-11-08 at 01:57 (UTC+8), before any model run. The repository is private, so that timestamp cannot be independently verified. The protocol file is published below as it was committed.
Data
Everything needed to check the figures. Question and answer text derived from Wikipedia is CC BY-SA 4.0; article revisions are linked in the manifest.
- protocol.txt: the protocol as committed before the first run
- deviations.txt: every change from the protocol
- corpus-manifest.json: the 10 articles, pinned revision IDs and sampled paragraphs
- questions.json: the 100 questions and gold answers
- answers.json: all 700 answers, with token counts
- summary.json: per-condition statistics, intervals, hypotheses and caching calculation
- answer-recall.json: the specific-sentence check, question by question
- page-sample.json: calculator output for the 12 pages
- token-check.csv: the calculator's token estimate against the model's tokenizer
- bench-harness.py.txt and analysis.py.txt: the code that ran and scored the benchmark