/Retrieval quality

Kerf Online against Firecrawl, on 639 RAG questions

We read the same pages with both products, cut each result into chunks the way a retrieval pipeline does, asked the same questions of the chunks a retriever picked from each, and had the answers written and graded by models that never knew which extraction they were reading. Here is the whole run: why a retrieval test is a different measure, what we compared, how it was scored, every page, and what the numbers do not show.

Quorum Technologies · Firecrawl fetched 13 September 2026 · Kerf fetched 14 September 2026 · scored 14 September 2026

Pages110 scored
Questions639
Judgeblind models, audited
Chunker1,200 chars, BM25 top 4

01

A retriever never sees the page. It sees a few chunks of it.

Our other study scores Markdown against the page's own HTML: headings kept, tables kept, reading order. This one asks the question that study cannot: once the Markdown is cut up and indexed, does the right answer come back?

Almost nobody hands a whole page to a model. A retrieval pipeline cuts the Markdown into chunks of a few hundred to a couple of thousand characters, stores them, and at question time hands the model the few that look most like the question. What the model can answer depends on whether the fact it needs landed in one chunk, with enough around it to say what it is.

That is a property of the extraction as much as of the chunker. A price that arrives on its own line, three headings away from the name of the product, is retrievable only by luck. A table row that arrives without its column names answers nothing. A page that came back as a shell, because its figures are written in by a script the extractor never ran, answers nothing at all, however tidy the Markdown looks.

Why not measure this with the structure scores we already publish? Because they measure the wrong end of the pipe for this question. Headings kept is a good proxy for a person reading a document and a poor one for a retriever, which does not read headings, and the same page can score well on structure and badly on answers. So this study puts a retriever between the extraction and the reader and counts answers.

02

What we compared

Two products that turn a URL into Markdown, each called through its public API from the United States, and Kerf a second time with the option it offers for exactly this use.

ColumnCalled asWhat it is
Kerfmode auto · location usOurs, as a customer calls it: the direct read where a page allows it, a browser where it does not, and the routing between the two left to Kerf. Links off, which is what a retrieval caller sends.
Kerf, optimiseForRAG+ optimiseForRAG trueThe same fetches, with the option that shapes the Markdown for a chunker: fewer headings, table rows that carry their column names, a product's name kept beside its figures. The same words come back.
Firecrawlv2 scrape · location USBrowser-backed scraping, Markdown format, at its own defaults with the location set to match ours. Described here as they describe themselves.

We picked Firecrawl because it is the extractor most retrieval pipelines reach for first, and because it fetches from the United States by default, which is where prices and terms on most of these pages are decided. Kerf was asked to fetch from there too, so neither column is reading a different country's page.

03

The test set

110 pages of the kind people put into retrieval systems, and 639 questions written from them.

Pricing pages, product pages, API references, standards, encyclopaedia articles, repositories and essays: pages with facts in them that someone would ask a model about. Up to six questions were written for each page by a model that could see two extractions of it, in random order and without knowing which product made which, and was told to draw half its facts from each. Every question names a short gold answer.

KindnWhat it asks for
numeric181A figure: a price, a limit, a version, a count.
fact139A name, a date, a definition, a yes or no.
list101Several items, all of which have to arrive.
qualified218The right answer depends on a qualifier the page sets: which plan, which model, which case. An answer lifted from the wrong part of the page is wrong.

Kinds of question, and how many of each were scored.

Were the questions written to favour either product? The writer could not tell the products apart, and was told to take half its facts from each extraction. The audit below checked every gold answer it could against the page.

04

How we score

The same chunker and the same retriever for every extraction, so any difference in what the answering model sees comes from the extraction and nothing else. Nobody in the chain knows which product they are reading.

StepWhat happens
ChunkEach extraction is cut at its headings and packed into windows of 1,200 characters, the common production default. No chunk carries its heading path: if a figure needs its section title to mean anything, the extraction has to have put that title within reach.
RetrieveBM25 over the chunks, top four for each question, for every extraction alike.
AnswerA model answers each question from those four chunks and nothing else, twice: once from each extraction, labelled X and Y in an order randomised per question. It is told to say NOT FOUND rather than guess, and to say NOT FOUND when a figure is there but the chunk does not say which plan, model or case it belongs to.
GradeA second model marks each answer against the gold answer as correct, partial, wrong or not found, without knowing which side is which. Correct counts one, partial a half.
AuditA stronger model re-graded 242 items and checked their gold answers. It agreed with the first grader on 99.0% of grades and corrected 9 gold answers. Later rounds were graded against the corrected gold.

Why models rather than people? 639 questions, three columns, answered and graded more than once as the extraction improved, is several thousand judgements. A model does them the same way every time, and the audit says how often it is right. The other study on this site uses no model at all, and we keep it that way where the thing measured allows it.

What is the noise in this? Firecrawl's documents were fetched once and never changed, but its answers were regenerated beside every Kerf round. Its score on the re-answered pages moved by up to 1.8 points between rounds with nothing on its side different, so a gap inside that is not a result. The gaps reported below are larger than it.

05a

What came back

Every figure below is written by the harness's exporter from the saved grades, and nothing on this page is typed by hand. The orange dot marks the best of the three where the measure has one.

MeasureKerfKerf, optimiseForRAGFirecrawlWhat it means
Answered correctly80.8%83.7%78.0%Of 639 questions. A partial answer counts a half.
Not found17.8%15.0%20.8%The answer was on the page and the retriever never handed it over, or it was not on the page at all.
Wrong0.9%0.8%0.8%A confident answer that contradicts the page. The figure that matters most and moves least.
Pages ahead of Firecrawl2932Of 110 pages, how many this column scored higher on than Firecrawl did.
Pages behind Firecrawl118And how many it scored lower on. The rest were level.
Median time a page1,634ms2,036msWall clock, as the caller sees it, on the last fetch of every page. The optimiseForRAG column reuses those fetches, so it has no time of its own.
Median characters18,98733,370How much Markdown a page became, before any shaping; the shaped output was not measured separately. Less that answers the same questions is fewer tokens to index.

639 questions over 110 pages. Firecrawl's column is its answers from the same rounds as Kerf's optimiseForRAG column; beside the plain Kerf column it scored 77.5%.

Read the three columns together. Kerf as called answers 80.8% against Firecrawl's 77.5% on the same rounds. The option adds 2.9 points on top, to 83.7%, from the same fetches: nothing new was read, the Markdown was shaped so that a chunk holds whole facts. Wrong answers stay under one per cent for every column, which is the figure to check first in any test that lets a model answer.

05b

By kind of question

Where the difference comes from. The set is built so no one kind of question can carry the result.

KindnKerfKerf, optimiseForRAGFirecrawlWhat it asks for
numeric18174.3%78.2%71.0%A figure: a price, a limit, a version, a count.
fact13991.0%91.0%86.7%A name, a date, a definition, a yes or no.
list10183.2%86.1%78.2%Several items, all of which have to arrive.
qualified21878.7%82.6%78.2%The right answer depends on a qualifier the page sets: which plan, which model, which case. An answer lifted from the wrong part of the page is wrong.

Correct answers, per kind of question.

The qualified questions are the ones a retrieval pipeline gets wrong most quietly: the figure is on the page, the chunk has a figure, and it is the wrong plan's. They are also where the shaping helps most, because keeping a name beside its figures is what stops a chunk from carrying a number without its qualifier.

06

Two pages in detail

A summary table can hide what a difference actually looks like, so here are two pages, every scored question, with each column's answer as the grader saw it.

github.com/openssl/openssl. A repository page: a README inside a great deal of application chrome, with the counts and the latest release written in by script after the page loads.

QuestionGoldKerfKerf, optimiseForRAGFirecrawl
What is the latest OpenSSL release version listed on its GitHub repository page?OpenSSL 4.0.2
OpenSSL 4.0.2correct
OpenSSL 4.0.2correct
NOT FOUNDnot found
What three components make up the OpenSSL toolkit, according to its README?libssl, libcrypto, and the openssl command-line tool
libssl, libcrypto, and the openssl command line toolcorrect
libssl, libcrypto, and the openssl command line toolcorrect
libssl, libcrypto, and the openssl command line toolcorrect
OpenSSL is described as descended from the SSLeay library developed by which two people?Eric A. Young and Tim J. Hudson
Eric A. Young and Tim J. Hudsoncorrect
Eric A. Young and Tim J. Hudsoncorrect
Eric A. Young and Tim J. Hudsoncorrect
Under what license is OpenSSL distributed?The Apache License 2.0
Apache License 2.0correct
Apache License 2.0correct
Apache License 2.0correct

Answers as written by the answering model from the four chunks it was given. Grades as the grader gave them.

apple.com/iphone-18-pro. A product page whose price, colours and specifications are drawn by script into a layout the markup only sketches. The kind of page a direct read gets the words of and not the figures.

QuestionGoldKerfKerf, optimiseForRAGFirecrawl
What is the starting price of iPhone 18 Pro?$1199
From $1199correct
From $1199 (or $49.95/mo. for 24 mo.)correct
From $1199 (or $49.95/mo. for 24 mo.)correct
What color options are available for iPhone 18 Pro?Burgundy, Glacier, Silver, Black
Burgundy, Glacier, Silver, Blackcorrect
Burgundy, Glacier, Silver, Blackcorrect
Burgundy, Glacier, Silver, Blackcorrect
How many more hours of video playback does iPhone 18 Pro Max get compared with iPhone 16 Pro Max?12 more hours
Up to 12 more hourscorrect
Up to 12 more hourscorrect
NOT FOUNDnot found
What are the four aperture settings available on the iPhone 18 Pro's variable-aperture Main camera?ƒ/1.48, ƒ/1.8, ƒ/2.8, and ƒ/4.0
NOT FOUNDnot found
ƒ/1.48, ƒ/1.8, ƒ/2.8, ƒ/4.0correct
NOT FOUNDnot found
In Apple's carrier deal for iPhone 18 Pro, what is the maximum trade-in credit offered specifically through Verizon (as opposed to AT&T or T-Mobile)?up to $1020
Up to $1020correct
Up to $1020correct
Up to $1020correct
With faster wired charging, how long does it take iPhone 18 Pro to reach 50 percent battery?around 15 minutes
Around 15 minutescorrect
Around 15 minutes (with compatible power adapter)correct
Around 15 minutes (with compatible power adapter)correct

07

Every page, and what each one answered

The whole dataset. Points scored out of the questions asked, for each column; which path Kerf took; how much Markdown came back and how long the fetch took.

PagenKerfK +RAGFirecrawlK pathK charsF charsK msF ms
astro.build65/65/65/6fast9,32014,4799722,022
aws.amazon.com/ec2/pricing/on-demand63/63/63/6fast9,91917,1501,7954,547
blog.codinghorror.com/the-best-code-is-no-code-at-al64/64/64/6fast9,352103,8248822,539
blog.regehr.org/archives/21366/66/65/6fast42,91942,5421,1644,001
books.toscrape.com64/64/64/6fast3,6579,1161,1741,047
bun.sh/docs/installation65/66/66/6fast7,2527,2711,1882,003
caniuse.com/css-grid53/53/52/5browser1,9112,6866,5101,554
creativecommons.org/licenses/by-sa/4.0/legalcode.en66/66/66/6fast18,98722,1861,0531,322
danluu.com/everything-is-broken66/66/64/6fast19,62221,0251,1151,606
datatracker.ietf.org/doc/html/rfc723165/65/65/6fast240,387235,2201,2061,935
developer.mozilla.org/en-US/docs/Web/API/Fetch_API66/66/66/6browser7,48721,2759,0061,375
developer.mozilla.org/en-US/docs/Web/CSS/Reference/P65/66/64/6browser12,21315,28211,7701,231
developer.mozilla.org/en-US/docs/Web/HTTP/Reference/66/66/66/6browser32,90560,40511,6591,714
developer.mozilla.org/en-US/docs/Web/HTTP/Reference/66/66/66/6browser16,52429,8569,4591,316
doc.rust-lang.org/std/vec/struct.Vec.html63/65/63/6fast227,138578,2862,5293,187
docs.github.com/en/actions/writing-workflows/quickst66/66/66/6fast8,86711,2601,6801,438
docs.python.org/3.12/library/asyncio-task.html66/66/66/6fast38,72064,9868992,474
docs.python.org/3.12/library/pathlib.html66/66/66/6fast45,02275,6481,3991,593
docs.stripe.com/webhooks66/66/66/6fast24,77635,3271,6158,175
en.wikipedia.org/wiki/Comparison_of_file_systems61/65/60.5/6fast213,451261,3301,4644,556
en.wikipedia.org/wiki/Dot-com_bubble66/65/65/6fast60,530181,2468901,763
en.wikipedia.org/wiki/List_of_countries_by_GDP_(nomi64/64/65/6fast56,827170,0911,1342,036
en.wikipedia.org/wiki/List_of_countries_by_populatio44/43/44/4fast71,244150,8881,2281,851
en.wikipedia.org/wiki/PageRank66/66/66/6fast55,200126,6022,1661,908
en.wikipedia.org/wiki/Transmission_Control_Protocol65/65/65/6fast102,316198,0181,6373,480
en.wikipedia.org/wiki/Web_scraping66/66/65/6fast30,11358,0211,4151,532
fastapi.tiangolo.com/tutorial/background-tasks66/66/66/6fast12,05111,1248872,189
gdpr-info.eu/art-17-gdpr66/66/66/6fast2,9913,7951,1153,103
github.com/curl/curl52/53/52/5browser8,63831,0827,6492,807
github.com/microsoft/playwright54/54/54/5browser15,72837,1527,3524,604
github.com/openssl/openssl44/44/43/4browser16,93672,9947,8714,502
github.com/pallets/flask53/54/53/5browser5,71216,2287,6931,808
github.com/postgres/postgres65/66/65/6browser5,78725,0917,6931,844
github.com/pricing65/66/62/6fast24,43539,1711,2021,645
github.com/rust-lang/rust33/33/33/3browser9,11430,7857,2342,033
github.com/sqlite/sqlite44/44/44/4browser24,30941,6479,7722,802
github.com/vercel/next.js54/53/53/5browser14,369184,4387,7173,193
go.dev/blog/loopvar-preview66/66/66/6fast7,7548,6967561,667
html.spec.whatwg.org/multipage/introduction.html66/66/66/6browser54,22560,6718,2151,428
learn.microsoft.com/en-us/azure/virtual-machines/siz66/66/65/6fast45,83982,7211,5832,019
linear.app/pricing66/66/66/6browser2,8243,4389,2052,666
martinfowler.com/articles/microservices.html65/65/63/6fast50,06351,3077051,271
martinfowler.com/bliki/TechnicalDebt.html66/66/66/6fast7,2767,4511,3331,056
motherfuckingwebsite.com66/66/66/6fast3,3823,3129131,343
nextjs.org/docs/app/getting-started/installation66/66/66/6fast18,59014,9301,1122,273
nodejs.org/docs/latest-v22.x/api/fs.html66/66/64/6fast194,860437,9342,8584,114
openai.com/api/pricing50/50/50/5fast15,60617,7454,0633,068
opensource.org/license/mit64.5/64.5/62.5/6browser1,3223,5267,1711,779
overreacted.io/a-complete-guide-to-useeffect65/65/65/6fast65,53271,7031,3732,739
pkg.go.dev/net/http64/64/63/6fast164,012207,3541,9831,792
playwright.dev/docs/locators66/66/66/6fast24,39233,8659902,942
policies.google.com/terms63/63/63/6fast30,15539,2961,2021,780
react.dev/learn/thinking-in-react65/65/64/6fast21,76324,2418521,511
semver.org66/66/66/6fast17,73417,7948311,137
slack.com/pricing65/65/65/6fast23,04336,7343,0282,018
store.google.com/us/product/pixel_10_pro63/64/63/6fast34,93184,3113,9377,009
stripe.com/gb/pricing66/66/66/6fast24,85834,4281,2322,755
supabase.com/pricing62.5/64/62.5/6fast29,14922,4688671,374
tailwindcss.com64/64/64/6fast8,40211,4241,1113,936
unicode.org/emoji/charts/full-emoji-list.html63/65/64/6fast153,581453,1779,1165,890
vercel.com/pricing64/65/65/6fast13,32715,6091,5014,185
vite.dev/guide65/65/65/6fast9,28113,1491,2881,850
www.adobe.com/creativecloud/plans.html54/54/53/5browser3,91123,89010,441726
www.anthropic.com/pricing62/63/63/6fast17,57624,3172,9341,958
www.apache.org/licenses/LICENSE-2.065.5/65.5/66/6fast11,15611,5146884,522
www.apple.com/airpods-pro65/65/66/6browser16,94937,78720,7481,838
www.apple.com/iphone-1764/64/64/6browser27,07952,99913,3142,442
www.apple.com/iphone-18-pro65/66/64/6browser117,60864,7519,3872,343
www.apple.com/iphone/compare61/61/61/6fast47,761299,4192,6672,519
www.apple.com/macbook-pro66/66/64/6browser15,48846,5219,7362,429
www.apple.com/watch62/61.5/65/6browser5,0135,4839,4331,869
www.atlassian.com/software/confluence/pricing65/65/65/6browser14,79731,32213,7332,964
www.atlassian.com/software/jira/pricing64/64/64/6browser13,36837,91812,226695
www.canva.com/pricing65/65/65/6browser16,17624,75312,378772
www.cloudflare.com/plans64/65/64/6fast12,50126,9501,2681,956
www.dell.com/en-us/shop/dell-laptops/scr/laptops65.5/65.5/66/6fast20,18266,5701,6317,893
www.digitalocean.com/pricing/droplets65/65/65/6fast96,45126,9827811,558
www.dropbox.com/plans63/63/63/6fast6,2508,7861,6343,898
www.figma.com/pricing63/65/63/6fast29,82337,1781,1423,544
www.garmin.com/en-US/p/88678566/66/66/6browser1,4776,08519,5332,097
www.gnu.org/licenses/gpl-3.0.en.html66/66/66/6fast35,58339,0408421,010
www.hetzner.com/cloud64/65/63/6browser8,85732,1849,9913,347
www.hubspot.com/pricing/marketing62/64/65/6browser16,88417,73216,170794
www.iana.org/assignments/http-status-codes66/66/66/6fast4,4827,8011,2182,136
www.ikea.com/us/en/p/billy-bookcase-white-0026385055/55/55/5browser37,38055,91613,5262,745
www.indeed.com/career-advice50/50/54/5033,3708,2843,591
www.joelonsoftware.com/2000/04/06/things-you-should-64/64/64/6fast8,9699,3299371,687
www.kalzumeus.com/2012/01/23/salary-negotiation66/66/66/6browser41,65343,0036,6632,314
www.lg.com/us/tvs/lg-oled65c5pua-oled-4k-tv64.5/64/63/6browser32,01251,02125,5365,086
www.microsoft.com/en-us/surface65/65/65/6fast11,36014,0981,0746,038
www.mongodb.com/pricing65/64/64/6fast27,04122,4852,9604,907
www.netcup.com/en/server/vps66/66/65/6fast14,74619,6132,5704,357
www.notion.com/pricing65/65/65/6fast21,74323,414893685
www.paulgraham.com/ds.html66/66/66/6fast25,24028,3251,0821,708
www.paulgraham.com/makersschedule.html66/66/66/6fast6,8598,7941,5732,210
www.postgresql.org/docs/16/datatype-json.html66/66/66/6fast30,37435,9731,4474,047
www.postgresql.org/docs/16/sql-select.html66/66/66/6fast63,20971,3661,0372,447
www.rei.com/product/222507/rei-co-op-flash-55-pack-m43/43/42/4browser4,75620,11236,3046,061
www.rfc-editor.org/rfc/rfc1925.html66/66/66/6fast4,3274,2809096,178
www.rfc-editor.org/rfc/rfc6749.html65/65/65/6fast163,533164,0709821,124
www.rfc-editor.org/rfc/rfc8259.html66/66/66/6fast28,35928,4411,4021,039
www.rfc-editor.org/rfc/rfc9110.html65/64/64/6fast442,756750,9912,0923,852
www.rfc-editor.org/rfc/rfc9309.html66/65.5/65.5/6fast22,75334,0651,6801,322
www.samsung.com/us/smartphones/galaxy-s25-ultra66/66/66/6browser42,76290,43613,9184,331
www.shopify.com/pricing65/64.5/64.5/6fast26,79750,2741,8131,241
www.spotify.com/us/premium55/55/54/5fast6,5386,5928151,625
www.tesla.com/modely62/62/62/6browser19,82750,99626,6375,144
www.twilio.com/en-us/sms/pricing/us66/66/66/6fast10,54113,7469483,821
www.w3.org/TR/WCAG2266/66/66/6fast133,606285,9071,2471,817
zoom.us/pricing64/64/63/6browser14,092202,02020,146879

Points are correct answers plus half for each partial answer, out of the questions scored on that page. Characters and time are from the last fetch of each page.

08

What this does not show

The choices that shape the result, kept in one place so the figures above can stand without qualifying themselves.

01

Write

Questions are written from both extractions of a page, blind to which is which, and frozen with their gold answers before anything is answered.

02

Answer and grade

Chunks are retrieved the same way for every extraction, answered blind, graded blind against the gold. Nothing is scored by hand.

03

Round

When Kerf changes, only the pages whose extraction changed are answered and graded again, both columns together, so a page is never scored against a stale rival.

Models answer and grade. A person did not read 639 answers three times over. The audit above says how far to trust that, and the noise figure says how much of a gap it takes to mean anything. Both are published for exactly that reason.

The rounds are not one fetch. Kerf was fetched again as it improved, over 10 rounds, and each page's answers come from the latest round in which its extraction changed. Firecrawl was fetched once and its documents never changed; its answers were regenerated beside each Kerf round so the two columns on any page always come from the same sitting. This dataset was also used during Kerf development, and as such, treat it as a transparent development benchmark rather than a held-out generalisation test. We will run the final implementation unchanged against a fresh frozen set.

One chunker, one retriever. 1,200-character chunks cut at headings, and BM25 over them, are a common production default and not the only one. We checked the shaping at 500 and 2,000 characters too and the direction held, but a pipeline with a different chunker or an embedding retriever will see a different size of gap.

Kerf was called with links off. That is what a retrieval caller sends, since addresses match nothing anyone asks, and it is the setting the option is meant to sit beside. Firecrawl was called at its defaults, which keep links.

The shaping trades structure for retrieval. Fewer headings and no Markdown tables come back with the option on. On the structure measures our other study scores, the same Markdown does worse, which is why the option is off by default and this page shows both columns.

09

How it was run

Four steps, in this order, with everything saved between them so the scoring can be re-run as often as the argument needs.

1Fetch every page with each product from the United States, and save what came back verbatim.
2Write up to six questions per page from the two extractions, blind, and freeze them with their gold answers.
3Chunk, retrieve, answer and grade, blind, both columns in the same sitting. Audit the first round.
4Export every grade to the dataset behind this page. Nothing on it is typed.

Firecrawl fetched 13 September 2026, Kerf fetched 14 September 2026, scored 14 September 2026. Firecrawl is called through its own public API at its own defaults, with the location set to match ours. Naming another product is not a claim about anything except what it returned on these pages on that day.