The model you paid for may not be the one answering you — and one random number can prove it
- When you buy AI through a reseller or an aggregator, you pick a name and you get back a block of text. Nothing in between proves the answer came from the model you selected. One earlier study probed 31 commercial endpoints serving Llama; 11 produced outputs that didn't match the released weights.
- The test is a single sentence: ask it over and over for "a random number between 1 and 100." It keeps landing on the same handful of numbers, and every model plays favorites differently. That table of answers is the fingerprint, and each query costs exactly one output token.
- Why it's hard to dodge: benchmarks measure whether a model gets the answer right; the fingerprint measures how it splits probability across several answers that are all equally fine. Quietly swapping in a compressed build disturbs exactly that layer.
- Accuracy and price: 40 questions per endpoint gives a 7.3% error rate — roughly one wrong call in 14. Just 8 questions (about 120 queries) still gets you 10.6%. An audit costs a few cents, so you can re-run it on the same endpoint daily.
- The headline finding: Tomáš Bruckner of the Prague University of Economics and Business tested all 165 models for a total of $34.44. One endpoint sold as a proprietary in-house flagship (
writer/palmyra-x5) fingerprints indistinguishably from open-source Qwen — the numbers are in the dek, the details in the "What the survey found" section.
You pay for a name, not for a machine
You pay for a top-tier model; the thing answering you might be something much cheaper. Aggregators like OpenRouter are genuinely convenient — hundreds of models behind one endpoint. But all you select is a name. Which machine your request lands on, and what's running there, is invisible to you, and nothing certifies it.
Checking is genuinely hard. From the outside you can't get the weights (the big bundle of parameters that is the model itself), and you can't get the logitsthe raw scores the model assigns to each candidate answer. Most production endpoints hand back only the final text and withhold these entirely either. Watermarking and backdoors require planting a mark in the model ahead of time, so only the model's owner can use them. And you need to probe dozens of endpoints repeatedly, cheaply enough to keep doing it.
Where the existing approaches stall
| Approach | What it needs | Where it stalls |
|---|---|---|
| Text attribution classifiers | full long-form generations | Can trace a whole chat reply back to its source model with 97% accuracy across five candidates, but the classifier has to consume long outputs, which drives up the cost of a single audit |
| Purpose-built probes LLMmap / TRAP | hand-designed or adversarially optimized prompts | LLMmap identifies 42 model versions from eight queries, but the distinctiveness of those prompts is itself the weakness: a provider spots them instantly and routes just those to the real model |
| Rank-based statistical tests uniformity tests over ranks | log probabilities returned by the model | Built for quantization detection, but plenty of endpoints return text only, so the premise never holds |
| Statistical equivalence testing | full sampled strings, plus a reference deployment of the same model for calibration | Closest to this paper's setting, but it burns full generations and calibrates against only a single reference deployment |
| Single-token answer distributions this paper | one output token — no weights, no logits, no cooperation from the model owner | The trade-off: a single query proves nothing. You need dozens to hundreds of repeats before a distribution emerges |
LLMmap and its cousins obsess over what special prompt to send. This paper inverts that: the questions are as ordinary and harmless as possible, endlessly rephrasable, and what matters is how the model answers. Identity hides in the distribution.
Ask for a random number, and the spread of answers gives it away
Tomáš Bruckner at the Prague University of Economics and Business found a neat trick: ask an AI for a random number, and how it answers is enough to identify it.
The trick exploits a famously bad habit: models can't produce real randomness. Ask for a number between 1 and 100 and the same one or two keep coming back — and every model has its own pet numbers. GPT-4o leans hard on 42 (with 37 and 57 close behind), Claude Sonnet 5 says almost nothing but 47, Llama 3.3 locks onto 53, and Qwen3-Max answered 42 on all 30 samples. Everyone else has treated this as a defect to fix. This paper treats it as a fingerprint.
Ask for "a random number between 1 and 100," demand a one-word reply (16-token cap), turn off reasoning mode, set temperature to 1.0 — which just means let it sample from its own probabilities instead of always grabbing the safest answer — and repeat a few dozen times. Whether the answer comes back as "forty-two," "٤٢," or "42," it counts as 42. Tally how often each answer appears and you have a distribution.
That distribution is the fingerprint. Each query burns exactly one output token.
Here's what four of them look like:
The lopsidedness is measurable. Slice 165 models × 40 questions into cells; 6,572 cells had at least 10 valid answers. Across those, the median entropyhow hard the answer is to guess. About 1 bit means the answer is essentially bouncing between two options of the answers is just 1.00 bit, against the 6.64 bits true randomness would give (for the 1-to-100 question). In each cell the model's favorite answer — not only on number questions, but on random words, colors and cities too — typically takes about seven in ten replies (median share 0.71).
At 6.64 bits, every number from 1 to 100 is genuinely in play and you have no idea which one is coming. At 1.00 bit, the model is really just toggling between two numbers, and your odds of guessing right are close to even. It agreed to be random; what it delivered was its verbal tic.
One set of weights, several names in the catalog
Before any of this works, you have to be clear about what's being measured. In an aggregator's catalog, names map to weights many-to-one: the same weights sit there under a rolling -latest alias, a dated snapshot, a free tier, a thinking tier, a fast tier, a long-context tier.
So the paper distinguishes three levels. A checkpoint is one specific set of weights, and that's what the fingerprint tracks. An endpoint is a service path that claims to lead to some checkpoint. A family is a lineage of checkpoints descended from a common ancestor. Verification asks whether an endpoint serves the weights it claims; attribution asks where those weights came from. The name you bought guarantees neither.
Why one token carries identity at all
Four layers stack up inside that distribution, and each writes its own trace into it.
The same candidate answer breaks into different numbers of pieces, split at different points, in each vendor's vocabulary — and when the split changes, so do the odds between that candidate and its rivals. The paper names this layer (tokenization differences across candidate answers) without working through examples.
Two models with different vocabularies start from different lines, and this layer has nothing to do with capability.Why 42, 47, 53 specifically? Because humans aren't random either when told to "pick a number," and those preferences are written all over the web. The model absorbs them wholesale. The spikes in the chart above are reading this layer.
The paper doesn't attribute individual numbers; the four prior works it cites study exactly these pseudo-random preferences in humans and models.Why can two models with the same base and the same vocabulary still be told apart? Post-training. It shoves the whole answer distribution to one side.
Conversely, a documented Llama derivative later turns up in Qwen's neighborhood — same layer, working in reverse.Temperature 0 should be fully deterministic: same question, same token every time. Within a single provider, 90.4% of questions behaved that way. Pool across providers and it drops to 84.5%. Those missing 5.9 points are numerical implementation differences between data centers.
This layer belongs least to the model itself, and it's exactly why the same model's fingerprint shifts a little when you change providers.At this point you might ask: if temperature 0 is deterministic on 90.4% of questions within a provider, why not just compare temperature-0 answers and be done in three queries? Three reasons. Safe answers collide across vendors (if everyone says 42, nobody is distinguishable). Cross-provider determinism falls to 84.5%, so a single point is unstable on its own. And a full distribution carries far more information than one point. Hence the need to make it "random" and ask repeatedly.
Why quantization and distillation can't hide from this question
Quantization rounds weights to lower precision; distillation trains a small model with a big one as teacher. Take quantization first. On questions the model is confident about, that rounding error doesn't change which answer wins, which is why benchmarks barely register it. But when several candidates are neck and neck, the error is plenty to scramble their ordering.
And "give me a random number" is precisely that kind of question: several pet numbers are all defensible, no ranking among them is right or wrong, and the whole thing rides on a delicate split of probability. That split is what the fingerprint reads.
Benchmarks measure whether the answer is correct. Fingerprints measure how probability is divided among answers that are all fine. Compressing weights can't move the first and is bound to move the second.
The paper devotes one sentence to this: quantization and distillation perturb exactly the probability layer these questions sample from. The plain-language version above unpacks that sentence.
Turning "looks similar" into a number you can compare
One question isn't safe: two models could easily both love 42. So the battery is 10 questions, asked in 4 languages each — 40 in total.
Why ten questions, and why four languages
The paper gives one sentence of rationale for each of these three design choices; what follows unpacks them.
Closed and open questions do different jobs. A coin flip has two answers, 1-to-10 has ten, and every model is choosing from the same menu — what's compared is the fine-grained split. But two options can only differ so much; the ceiling is low. Open questions (random word, city, animal) have unbounded answer spaces, so two models might not overlap on a single answer and the distance pins to the maximum. One type teases apart close relatives; the other shoves unrelated models far apart.
"Random" and "favorite" are two different questions. Asking for a random number treats the model as a lottery machine; asking for its favorite number probes its persona, and persona is sculpted by post-training. Two models might collide on random numbers and diverge on favorites, so the pairing buys a free extra dimension.
Ask in another language and you tap a different pocket of memory. The common answer to "name a city" in Chinese-language data isn't the common answer in English. Four languages means four independent slices of signal. Turn that around: anyone trying to impersonate has to match all four sets of habits.
Collapsing two distributions into one distance
The gap between two distributions gets folded into a 0-to-1 number via Jensen-Shannon divergencea measure of how far apart two answer distributions are, from 0 to 1. Symmetric, and still well-defined when the two tables share no answers at all. There's a practical reason for that choice: even when two models name entirely non-overlapping sets of cities, it still yields a meaningful distance — exactly what open questions require. The distance between two models is then the average across questions where both have enough samples.
At the level of a single question, a model compared against itself scores 0.075, and two different models score 0.489. (Mind the units: those are per-question numbers, not directly comparable to the 40-question averages below.) Averaged, they become the scale.
Does the fingerprint survive a change of provider?
One make-or-break question comes first: does the fingerprint change when the provider does? If it does, you're measuring data centers, not models. OpenRouter supplied a natural experiment: of the 165 models, 31 were served by two or more providers with enough samples, yielding 34 directly comparable pairs with at least 15 shared questions each.
Verdict: the fingerprint largely survives a change of provider. Ten pairs didn't; the two most striking get their own treatment in "What the survey found."
What one identity check costs
Checking whether an endpoint is serving the real thing takes four steps.
Say you've wired a reseller's endpoint into your product, and you selected Llama 3.3 70B.
Scoring works like a fingerprint lock. "Genuine" trials compare two halves of the same model's samples; "impostor" trials compare half of model A against half of model B. Across 165 genuine and 27,060 impostor trials, the full 40-question battery gets AUC 0.971 and an equal error ratethe error rate at the threshold where false accusations and missed substitutions are equally common. 7.3% is roughly one wrong call in 14 of 7.3%.
How much accuracy you lose with fewer questions
| Questions used | 1 | 4 | 8 | 16 | 32 | 40 |
|---|---|---|---|---|---|---|
| Equal error rate | 23.3% | 13.2% | 10.6% | 9.5% | 8.4% | 7.3% |
| Spread | 14 to 40% | 9 to 18% | 8 to 14% | 8 to 12% | 7 to 10% | — |
Even one question beats coin-flipping (50%) by a wide margin. At 16 questions and 15 repeats each, an audit is 240 queries and roughly 16,000 input tokens — under a cent on ordinarily priced models, a few cents on flagships.
A single verification is wrong about one time in 14, so no one run settles anything. But at a few cents a run, you can check the same endpoint every day, over and over. What actually holds up is evidence accumulated over time; any single run is one cell in that table.
On cost there's a reference point too: at equivalent repeat counts, this approach runs about a thousand times cheaper than long-text attribution.
Expand: the full survey's bill, and how the 165 models were selected
The full survey collected 326,047 responses — 23.3 million input tokens, 1.16 million output tokens, $34.44 total, averaging $0.21 per model. Failed requests were retried with exponential backoff, and retries were excluded from the data. Overall response validity was 97.6%, with a per-model median of 99.6%; the worst model came in at 60.6% (it frequently answered in full sentences). Every response was classified as valid, invalid, refusal or empty — nothing was silently discarded. Refusal and validity rates carry a bit of identity signal themselves, but were deliberately kept out of the fingerprint so it stays robust to changes in safety policy.
Models were selected from a July 6, 2026 catalog snapshot of 342 entries, excluding: non-text-only chat models (multimodal output, embeddings, audio, image, video, moderation and guardrail models, non-instruction-tuned bases, anything with a context window under 2048 tokens); narrow domain specialists (code, math, medical, roleplay); entries that aren't a single stable checkpoint (rolling -latest aliases, shifting preview versions and deprecated endpoints, meta-routers, multi-agent or search-augmented pipelines, free-tier or thinking-tier duplicates of checkpoints already in the catalog); endpoints with a mandatory hidden reasoning stage; and free-tier-only endpoints, where account-level daily request caps made complete collection impossible. One manual exclusion is documented as well (a model priced at $150 per million input tokens and $600 per million output). The rule list is published alongside the data, with each excluded entry carrying its reason. That left 165 models spanning 19 family labels and 53 providers.
On sampling: each model got 30 samples per question at temperature 1.0 and 3 at temperature 0; flagships priced above $5 per million input tokens were cut to 15. Questions ran in a seeded shuffle order, so gaps from rate limiting spread roughly evenly across a model's questions rather than wiping out one question or one language wholesale. A pilot with 14 models — covering seven same-family large/small pairings — preceded the main run, locking in every design and analysis choice against four preregistered criteria: at least 80% validity per model, temperature-0 determinism covering at least 90% of questions within a provider, a statistically significant between-family versus within-family divergence gap (p=0.0008), and a cost extrapolation. Hypotheses and the analysis plan were preregistered before collection began, and pilot data was excluded from the main analysis.
The fingerprint can also hint at where a model came from
Same-model fingerprints cluster tightly — what about same-family ones? Compute all pairwise distances across the 165 models, let an algorithm group the close ones (clustering), and the answer is: also close, but less reliably so. This is the weaker set of results in the paper; its main value is as context for the cases in the next section.
The algorithm is leave-one-out: hide each model in turn, look at whose family its nearest neighbor belongs to, and guess that. Across the 163 models with at least one same-family sibling, it guesses right 59.5% of the time against an 18.4% random baseline — 3.2× better.
The weakness is right there too: ask the tree to split cleanly into 19 well-separated families and it can't. That's mostly not the fingerprint's fault. The labels include an "other" bucket holding 17 unrelated vendors' models, plus a pile of singleton families that can't cluster by construction — the paper says as much, and expects it. Nearest-neighbor lookup recovers lineage; global partitioning doesn't.
| Family | Models | Precision | Recall |
|---|---|---|---|
| glm | 12 | 1.00 | 0.83 |
| llama | 12 | 0.88 | 0.58 |
| mistral | 16 | 0.87 | 0.81 |
| gpt | 21 | 0.70 | 0.90 |
| claude | 12 | 0.54 | 0.58 |
| qwen | 30 | 0.50 | 0.73 |
| deepseek | 8 | 0.46 | 0.75 |
| gemini | 11 | 0.43 | 0.55 |
| other (unrelated vendors) | 17 | 0.20 | 0.06 |
Precision is "of those assigned to this family, how many really belong"; recall is "of this family's members, how many were found." GLM's precision of 1.00 means every GLM call was correct. The Llama row deserves a second look: precision 0.88 is respectable, but recall of just 0.58 means nearly half the family wasn't found on home turf. One of the missing shows up in the next section.
Also, 59.5% is a floor. The ground truth comes from published family labels, so when documentation is wrong the fingerprint loses points even if it found the right relative — and errors in the opposite direction can't happen. True performance is no worse than 59.5%.
What turned up when the scale met the real ecosystem
Put the ruler against the live ecosystem and several endpoints come back mismatched. To be clear up front: these are statistical mismatches, not accusations of fraud. Updated weights, licensed quantization and caching layers are all innocent explanations.
Some endpoints don't fingerprint like what they claim to be
writer/palmyra-x5 fingerprints just 0.141 away from the open-source qwen/qwen3-235b-a22b-2507, while the median distance between a model and itself is 0.140 (and 0.463 between two different models). In answer-distribution terms, it is indistinguishable from an open-source Qwen deployment. The endpoint is sold as "a proprietary in-house model from Writer."
Writer is an enterprise-focused AI company that markets the Palmyra series as its own model line; X5 leads on a 1-million-token context window and is available through Amazon Bedrock. (This product background comes from Writer's own launch materials, not the paper.)
Innocent explanations really do exist — training your own model on a Qwen base is entirely legitimate. There's a clean example right here.
deepcogito/cogito-v2.1-671b states plainly that it was trained from a DeepSeek V3 base, and its three nearest fingerprint neighbors are all DeepSeek checkpoints (0.268 to 0.308). Fingerprint and documented lineage agree. xiaomi/mimo-v2.5-pro and inclusionai/ling-2.6-1t likewise sit squarely in Qwen's neighborhood.
Put those two sets of numbers side by side and the distinction sharpens: a documented, legitimate derivative sits around 0.27 from its base — relative distance. Palmyra's 0.141 hugs the 0.140 noise floor — same-model distance. One is well clear of the floor; the other is flat on it. The paper declines to accuse anyone. The numbers are here; read them how you like.
There's also the case of erased lineage. nvidia/llama-3.3-nemotron-super-49b-v1.5 is documented as a Llama-3.3 derivative, yet its fingerprint sits closer to Qwen (0.303) than to any Llama. Post-training went deep enough to bury its origin. That's one source of the 0.58 Llama recall in the previous section, and the ceiling on fingerprint-based attribution.
Same model, two providers, farther apart than two different models
Of the 34 "same model, two providers" pairs, 10 (29%) had already fallen into the "two different models" range. The same model out of two data centers can look like a model swap.
| Endpoint | The two providers | Fingerprint distance |
|---|---|---|
meta-llama/llama-3.2-3b-instruct | Cloudflare vs Parasail | 0.716 |
openai/gpt-4 | Azure vs OpenAI first-party | 0.392 |
| Reference: median distance between two different models | 0.463 | |
| Reference: median distance of a model to itself | 0.140 | |
The second row is worth a beat on its own: one vendor, one model name, two paths that both count as official (Azure and OpenAI first-party), and the distance is closing in on the median for two different models. As for how the first row reaches 0.716, the paper draws no conclusion — though the aggregator has itself acknowledged that quantization levels vary across upstream providers.
Three other oddities turned up along the way
Some of this is invisible in the text of a reply and only shows up in the token-by-token ledger. These three aren't trivia; they directly determined which endpoints got dropped from the sample.
Some flagship chat endpoints burned roughly 40 to 60 output tokens to produce a one-word visible answer, exposing no reasoning trace at all. You pay per token, so that's dozens of times the price for something you never see.
2,486 of 326,047 responses ignored the reasoning-off flag and came back with reasoning traces attached, concentrated in 14 model–provider combinations. These were split into their own category and never enter the fingerprint.
One model's sole provider returned a server error for every numeric question while answering everything else normally.
The first became an exclusion criterion outright: since there's no way to prove those dozens of tokens aren't hidden reasoning, every such endpoint had to go. Judgments rest on measured behavior, not on an endpoint's self-description — self-descriptions have already been shown to be unreliable.
None of this went through coordinated disclosure. The author's reasoning: these aren't security holes awaiting a patch, and publishing them hands nobody a new attack. Accountability instead comes from releasing all the raw data — every request's timestamp, provider and generation ID is in there, so anyone named, and anyone watching, can re-check the work or push back on it.
What happens once providers start fighting back
What if providers wise up and start countering? Their options come in three tiers, and the method works differently against each.
Nobody inspects the traffic; the substitution is simply made. Fully effective here.
Recognize published audit questions and route them alone to the real model. This is the tier the design targets.
Reproduce the target's distribution on arbitrary low-entropy questions. Get that far and you're honestly running the model anyway.
The defense against T2 is that there's no fixed password in the battery. "Name a random color" and "name a random city" are categories of question, not fixed strings: infinitely rephrasable, infinitely translatable (four languages already, for a start), drawn at random at audit time, and mixable into ordinary traffic.
To filter audit traffic out, a provider would have to catch every single "just name something" question in a flood of normal messages and route it to the real model. Filter too tightly and audit traffic slips through and catches you anyway; filter too loosely and you're handing a big slice of everyday traffic to the real model, burning the savings. Both ends lose. The paper's phrasing is that this is "expensive to detect"; how expensive isn't measured. One gap remains open too: whether the fingerprint holds up when the same kind of question is rephrased was left to future work.
The T3 math is already on its card: mimicry that good is just honestly running the real model, so there's nothing left to save. This method therefore offers no mathematical proof; what it does is make "swap and get away with it" a losing trade — which pairs neatly with the hardware-attestation route (having the chip cryptographically vouch that the weights it ran are the ones claimed).
Does asking the same question repeatedly hit a cache and wreck the result?
Repeating one prompt is bound to hit cache: 13.4% of requests hit the prompt cache, covering 10.1% of input tokens. Does that corrupt the measurement? Depends which kind of cache.
Reuses intermediate results already computed for the text before this point. It saves time and money without changing how the model picks its answer. Repeat samples remain independent draws.
Replays a stored answer outright, artificially collapsing the distribution you observe at temperature 1.0. In an auditing context, that is itself a form of cheating.
So the author went looking for response caching, with two criteria: answers collapsed to a single value, plus abnormally low and unusually stable latency. There were 2,040 questions where temperature 1.0 produced only one answer (concentrated distributions are common enough on their own), and of those, only 14 also had latency below half the usual. All 14 remained within a normal sub-second range — more like provider load variation than the instant replay a real cache produces. This round turned up no response caching.
Six things this method can't do
| Limitation | What it means |
|---|---|
| Fingerprints drift | A model update changes its fingerprint, so references must be re-registered periodically. Short-term stability was tested; drift over months was not |
| Requires a trusted reference | The whole verification scheme presumes a reference deployment you can trust |
| Samples out of reach | Low-traffic providers yield too few samples each; 5 endpoints were never sampled at all during the collection window (1 delisted, 2 whose providers were down throughout, 2 "unknown model" placeholder entries), plus 1 model whose sole provider failed systematically |
| Noisy labels | Family labels for closed-source vendors depend on public documentation. Label noise can only depress the lineage results, never inflate them |
| One class of endpoint is untestable | Endpoints with mandatory hidden reasoning were excluded wholesale: an answer emitted after a reasoning stage samples a different generative process, and mixing it in makes models cluster by output format rather than by lineage |
| Only one aggregator tested | The survey covers OpenRouter alone. The method itself is aggregator-agnostic, but the ecosystem-level findings may not generalize |
One practical note to close on: none of this has to be rebuilt from scratch. The prompts themselves (config/prompts.json) and the raw responses with full service metadata are in the public data package, and the complete collection and analysis pipeline (Node.js and R) is archived separately. Both live behind the Zenodo links in the endnotes. Grab them and run the four steps from "The math" against whatever endpoint you're using.
Model identity leaks through the cheapest possible channel: the single token a model emits when asked a boring question. One Token Is Enough, conclusion
AI endpoints go from "trust the name" to "verify on the spot"
A researcher in Prague made 165 models say a random number hundreds of times each. Here's what he found, in one illustrated page.
↓ one page · one animated figure
When you buy AI through a reseller or an aggregator — a middleman putting hundreds of models behind one endpoint — you pick a name and pay that name's price. Which machine your request lands on, and what's running there, comes with no receipt.
✘ What doesn't: proving the thing that answered is the thing you picked
An aggregator and dozens of providers sit in between, and all that comes back is text with no proof of identity. Quietly swapping in a compressed build or a smaller model saves real money, and the odds of getting caught stay low. This isn't hypothetical: an earlier study probed 31 commercial endpoints serving Llama, and 11 didn't match the released weights.
AI has a famous bad habit: it can't produce real randomness. Ask it to pick between 1 and 100 and the same one or two keep coming back — and every model plays favorites differently. Everyone else treated that as a defect to fix. This paper treats it as a fingerprint.
Tally how often each answer appears and you have a distribution, and that distribution is the identity. But "looks similar" is still just a feeling. To put a threshold on it, you have to fold it into a number.
The paper collapses the gap between two distributions into a number from 0 to 1 (Jensen-Shannon divergence, whose virtue is that it still yields a distance when the two sides share no answers at all). Every judgment happens on that scale.
The full 40-question battery errs 7.3% of the time, roughly once in 14; even 8 questions gets you 10.6%. One run settles nothing, but it's cheap enough to re-run on the same endpoint daily. How cheap, measured against the same job:
But hey, top tier.
- × weights
- × scores
- × vendor help
that didn't match
every time
loves 42
42 all 30 times
its own favorites!
isn't evidence.
indistinguishable
for all 165 models
Members can copy or download the full Markdown, and let their AI subscribe and ask.
Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.
