BuildNot yet confirmed elsewhere1 publisher3 min readPublished
A semantic cache shipped on by default at 0.92, and the label error that moved its own numbers
Six days after a reviewer asked him to prove a 0.92 similarity threshold was safe, the author switched his cache off. Then he found two of his own test labels were wrong.
The Engineer · Build desk
What happened
- The reference implementation shipped a semantic cache keyed on question-embedding cosine similarity at 0.92, always on, with no flag to disable it.
- Giulio D'Erme asked for proof the threshold was safe, offering a Spanish clinical pair one token apart whose correct answers are opposite.
- The test was twenty hand-written Spanish administrative pairs in four categories, scored with nomic-embed-text on Ollama and no retrieval stack at all.
- No single threshold rejected the adversarial pairs while still accepting the paraphrases, so the cache was disabled by default.
- An erratum now restates the negation row after two pairs were found mislabelled, cutting both the numerator and the denominator of the headline count.
Why it matters
- exposure A false accept is invisible by construction: the model never runs, so the reader receives a confident, sourced-looking answer to the opposite rule with no cue to go and check it.
- cost Switching the cache off hands tens of seconds of CPU back to every repeated question on hardware with no GPU. That is what the correctness costs, and the answering team pays it.
- constraint Tuning is not a route out, because the interval a safe threshold would need to occupy has nothing in it. Cheap reuse has to come from something other than question similarity.
- decision Test discipline buys nothing against this class of bug, so whoever ships a similarity threshold has to fund native-speaker review of the label set or accept that the safety claim is unmeasured.
Where the embedder fails matters more than the fact that it fails. Negation has been a known weakness of embedding models for years [19]. Put that weakness in a reranker and you get a worse-ordered list, with the answer still in front of a user who can judge it. Put it in a cache lookup and generation is suppressed: the stored answer for the opposite rule comes back at full confidence, with nothing in the output to say a substitution happened [6]. Since the product's whole format is a summary plus the document it came from [2], a false accept does not look broken. It looks sourced.
The shipped default was wrong in both directions at once. At 0.92 [3], the threshold sat 0.0784 below the worst adversarial pair the author measured and 0.1730 above his weakest genuine paraphrase [16], which means it was simultaneously admitting a pair with opposite correct answers and rejecting paraphrases the cache existed to catch [8]. Raising the number does not rescue it, because the band the fix would have to live in is empty [9].
Then the measurement itself came apart, and this is the part worth keeping. Two of the five negation pairs were negative interrogatives, which in Spanish ask for confirmation of the same fact rather than its opposite, so a correct system answers both identically and the cache should accept them [12]. The author had them labelled as must-rejects. The published minimum for that row, 0.9702, turned out to belong to one of the invalid pairs [14], and the headline fraction of adversarial pairs above threshold moved from 60 percent to roughly 54 percent [17]. No test suite would have caught this, because the error was in the linguistics, not the code [13].
That is the argument against hit rate as the metric of record. A cache can count its own hits with no labels at all, which is why hit rate is the number that ships. A false-accept rate cannot be computed without someone deciding, pair by pair, whether two questions mean the same thing, and the person best placed to do that decided wrong on two of five pairs in a corpus he wrote himself. None of the corrections changed a single response the system returned. The served answers were identical before and after the erratum; only the claim about their correctness moved.
The honest limit is that the pairs were hand-built rather than drawn from a query log [7], so nothing here says how often the collision fires in production. It says something stronger about defaults: there is no setting of this component that makes the question unnecessary to ask. The reviewer's challenge took six days to answer, with the commits running 6 to 11 August [10], and the conclusion only survived because the 0.9984 pair happened to be a valid one [15]. A component that suppresses the model, shipped with no flag [3], puts that kind of luck between the user and the rule.
What to watch
- Whether the larger corpus the author was building moves the corrected adversarial fraction again, or forces a second erratum.
- Whether the cache returns behind a flag with a published false-accept measure, or stays off for good.
- Whether the remaining corrections in the write-up touch the 0.9984 pair, since the standing conclusion rests on that pair being valid.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence42
- Adoption10
- Hype gap+12
- Incentives32
- Confidence46
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
A team producing regulatory documents kept receiving questions of the form "does the current rule allow X?"; answering meant someone reading memos, manuals and regulations to find where the rule was stated, then writing a summary with the source cited.
- [2]
The retrieval system's output is a summary that cites which document the answer came from; the author states a summary without a source is useless when the question is about a rule.
- [3]
The semantic cache was implemented with cosine similarity between question embeddings and a threshold of 0.92, and went out in the reference implementation the repository publishes, always on, with no flag to turn it off.
- [4]
System constraints: the documents cannot leave the perimeter, there is no GPU, and each generated answer costs tens of seconds on CPU.
- [5]
Giulio D'Erme asked the author to prove the threshold was safe, using the clinical example "pacientes con fiebre" against "pacientes sin fiebre": one token apart, opposite correct answers.
- [6]
A bad ranking degrades an answer the user can still see and judge, whereas a cache hit skips the model entirely and returns the opposite rule with full confidence and no signal that anything happened.
- [7]
The experiment used twenty hand-written pairs of Spanish administrative questions in four categories (negation, temporal, entity, and paraphrase as a control), with cosine similarity measured using nomic-embed-text on Ollama; no harness, no vector store, no retrieval, and the pairs were not drawn from any query log.
- [8]
The highest adversarial similarity was 0.9984, for a pair whose two questions have opposite correct answers; the lowest genuine paraphrase sat at 0.7470.
- [9]
Any threshold high enough to reject the adversarial pairs also rejected every paraphrase the cache existed to catch; no safe threshold existed, so the author disabled the cache by default.
- [10]
Answering the challenge took six days, with commit history running from 6 to 11 August.
- [11]
D'Erme's follow-up caveat: with five pairs per category, counts at a fixed threshold are fragile and readers will quote them as rates.
- [12]
Two of the five "negation" pairs were negative interrogatives, which in Spanish are confirmatory: they ask for confirmation of the same fact rather than its opposite, and a correct system answers both identically, so they should have been labelled accepts rather than pairs the cache must reject.
- [13]
The author describes this as a linguistics error rather than a code error, which no amount of testing would have caught.
- [14]
The published minimum for the negation row, 0.9702, belongs to one of the invalid pairs, and the count reported as "9 of 15 adversarial pairs" is 7 of 13.
- [15]
The conclusion survived because the highest adversarial similarity, 0.9984, belongs to a valid pair; the report now carries an erratum and the two mislabelled pairs live on as a separate confirmatory category.
- [16]
The shipped threshold of 0.92 sits 0.0784 below the highest adversarial similarity and 0.1730 above the lowest genuine paraphrase.
- [17]
The corrected count of 7 of 13 is about 54 percent, against 60 percent for the published 9 of 15, a drop of roughly 6 percentage points.
- [18]
Three adversarial categories at five pairs each account for the 15-pair denominator in the original report, with the paraphrase control making up the remaining five of the twenty pairs.
- [19]
Embedders handle negation badly, and the literature has said so for years.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toThree things I got wrong measuring my own cache
1 article · August 24, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.
Topics
- Embeddings and negation sensitivityFollow
- Semantic CachingFollow
- On-premise CPU-only inference constraintsFollow
- Retrieval-Augmented GenerationFollow
- Evaluation methodology and errataFollow