Skip to content

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

How we use AISend a correction

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
Why these scores

Claim ledger

Ranked by verification strength, evidence, and original report placement.

  1. [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.

    ReportedSupportedView cited source
  2. [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.

    ReportedSupportedView cited source
  3. [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.

    ReportedSupportedView cited source

Sources

1 independent publisher whose own reporting we read for this story.

  1. dev.to

    1 article · August 24, 2026

    Three things I got wrong measuring my own cache

Share your take

Let Clarity write the post for you.

Signed-in readers get a short post drafted on this story in the register they choose — narrative, analytical, or a direct position — editable to the last word before it goes anywhere. The share buttons at the top of this story work without an account.

Topics and entities

Follow any of these and your For You feed starts watching them — no settings page required.

Topics

Loading related stories