Benchmarks & Comparisons8 min read

OpenJev vs an LLM Judge on 990 Planted Errors: Recall, Calibration, Cost

The same 990 support tickets with 495 deliberately wrong labels, judged two ways: OpenJev over /v1/classify and Qwen 3.8 27B as an LLM judge. Asked one pair at a time OpenJev catches 82.6% of the planted errors; asked to pick among all twelve intents it catches 98.2%, rejects the same 33 mislabelled 'complaint' rows the 27B judge rejected, and its probabilities are calibrated to within 3 points. Every number is exact because we planted the errors.

The Paralon capybara measuring three holographic bar columns with an emerald caliper, red cubes on the bench as the planted errors

Two judges, one dataset, exact answers. Eight days ago we measured an open 27B model as an LLM judge on 990 customer-support tickets where we had deliberately corrupted half the labels, so recall and false-alarm rate were facts rather than estimates. Yesterday OpenJev went live on /v1/classify, a Qwen3.5-4B natural language inference cross-encoder that answers with a label and probabilities instead of text. Same tickets, same planted errors, same seed, second judge.

The short version: how you ask matters more than which model you ask. OpenJev given one pair at a time is a mediocre judge. OpenJev asked to pick the best of twelve labels is within 1.4 points of the 27B on catching errors, at 12 pairs per verdict and 3 ms per pair, and its probabilities mean what they say.

The setup

  • Data. 990 tickets from the synthetic dataset guide, twelve intents, one label each. Rows at even positions keep their label (495 correct); rows at odd positions get a random wrong intent from the same taxonomy (495 planted errors). Seed 21, the same as the judge guide, so the planted set is identical.
  • The 27B judge. Numbers from the guide's rubric run on 13 September: qwen3.8-27b, a one-line definition per intent, "correct only if it is the single best fit", JSON verdict, temperature: 0.
  • OpenJev. openjev-4b over /v1/classify. The rubric becomes twelve hypotheses, one per intent, from the same definitions: premise {ticket}, hypothesis The customer asks where an order is or when it arrives, and so on. Two ways to turn that into a verdict:
    • single pair: score only the proposed label; correct if the argmax class is entailment;
    • rerank: score all twelve; correct if the proposed label has the highest entailment probability.

11,880 pairs, through the public API in 93 requests of 128 pairs, 2.2 s each. The worker that day was a single RTX 5060 Ti on a provider's Windows machine, the slowest card in the pool, which is worth knowing when you read the timing row.

Results

27B judge, with rubricOpenJev, single pairOpenJev, rerank 12
planted errors caught99.6% (491/493)82.6% (409/495)98.2% (486/495)
correct labels accepted88.3%89.3%80.2%
accuracy against the dataset93.9%86.0%89.2%
top-1 intent, all twelve80.3%
time per verdict980 ms17 ms207 ms (12 pairs)
tokens per verdict290 in / 52 out75 in / 0 out903 in / 0 out
list price per 1,000 verdicts$0.123$0.004$0.045

Two things jump out, and the second explains the first.

Single-pair OpenJev is not a good judge. 82.6% of planted errors caught, 86 accepted that should have been rejected. The misses cluster on vague hypotheses: seven cancel_order tickets labelled product_question, five refund_status as product_question, five order_status as product_question. "Asks about a product before or after buying, not a problem with it" is a definition written for a reader with the other eleven in front of them. Alone, a ticket about an order fits it well enough to entail.

Rerank fixes that. Given all twelve at once, the right intent usually scores higher than the wrong one, and the same tickets are caught. 98.2% recall, nine planted errors through. The nine are neighbours (complaint labelled return_request, complaint labelled damaged_item), the same boundary the 27B missed both of its errors on.

The cost of rerank is on the second row: OpenJev rejects 98 correct labels, the 27B rejected 58. Read on before you call that a loss.

The judges reject the same rows

Of the correct labels rejected by both the 27B (rubric) and OpenJev (rerank), 38 are common to both, and 33 of the 38 are complaint tickets. The judge guide already found that: 43 of its 58 rejections were tickets the generator had labelled complaint that describe a broken zipper or a flickering lamp, which the rubric files under damaged_item. OpenJev makes the same call without being told:

"This jacket is garbage. The zipper broke after one wear and the lining is peeling off."damaged_item 0.42, complaint 0.15

"…the zipper is already stuck and the lining is peeling off this is ridiculous I need a fix NOW"damaged_item 0.93, complaint 0.48

Top-1 accuracy for the complaint intent is 6%. Every other intent is between 57% and 100%. That is the taxonomy's problem, not the model's: an abstract intent next to eleven concrete ones loses on every ticket that names a concrete thing. Both judges are telling us to fix the generator prompt, one sentence, and 40 rows come back.

The 42 rejections that are OpenJev's alone are a different story, and a useful one: 12 discount_code tickets it reranked as product_question, 11 refund_status it reranked as order_status. Those are two hypotheses that need a better sentence. The hypothesis is the rubric; you write it, you can fix it. We left them as written so the numbers are the first attempt, not the tuned one.

Calibration: 0.9 means 90%

The question on Hacker News the week Jev launched was whether a classifier's probabilities are probabilities at all. On the proposed pair's entailment probability, over all 990 verdicts:

entailment probabilityverdictsactually correct
0.0–0.13394.7%
0.1–0.25121.6%
0.2–0.33026.7%
0.3–0.42941.4%
0.4–0.55552.7%
0.5–0.66852.9%
0.6–0.74673.9%
0.7–0.84575.6%
0.8–0.96794.0%
0.9–1.026096.9%

Expected calibration error 0.028. Sixty percent of verdicts land in the two outer bins, where the model is right 95% and wrong 95% of the time respectively. The middle is thin and honest: at 0.5 it is a coin flip and it says so. That is what lets you set a threshold and know what it buys:

single pair, accept if entailment ≥planted errors caughtcorrect labels accepted
0.377.8%92.9%
0.586.5%84.6%
0.795.4%70.5%
0.998.4%50.9%

And for rerank, accept if the proposed label is within a margin of the top score:

marginplanted errors caughtcorrect labels accepted
0.00 (strict top-1)98.2%80.4%
0.1096.4%85.7%
0.2093.3%89.5%

Pick the row that matches what a miss costs you. A dataset QA pipeline wants the first; a router that must not bounce customers wants the last. The 27B judge offers no such dial: it returns a word.

Time and money

27B judgeOpenJev rerank (12 pairs)
verdicts per hour14,320 (14 in flight)17,400 (one 5060 Ti, sequential batches)
tokens per verdict290 in / 52 out903 in / 0 out
cost, 990 verdicts$0.122$0.045

The OpenJev number is the slow-card, one-request-at-a-time number: 93 batches of 128 pairs, 2.2 s each, through the tunnel to a provider's 5060 Ti in Canada. On the 4090 that served the model the day before, the same batch ran in about 0.8 s, and nothing stops a client from keeping several batches in flight. The point is not the exact ratio. It is that a verdict costs twelve short prefills and no generation, so the ceiling is the card, not the token budget.

What to take from it

  1. Ask "which", not "is this right". A judge that sees only the proposed label misses what the other labels would have told it. Rerank across the taxonomy, or at least across the neighbours.
  2. The hypothesis is the rubric. Two badly worded definitions cost 23 false rejects. Write them the way you would explain the category to a person who has not seen the others.
  3. Trust the probabilities, after you check them once. ECE 0.028 here; measure it on 200 rows of your own before you set a threshold in production. The script prints the table.
  4. Keep the LLM judge for the reason. The 27B gives a one-line explanation per verdict, and that is what made the 58-row review queue a ten-minute job in the guide. OpenJev gives you a number. For quality control at scale, run OpenJev first and send the disagreements to the 27B.

Reproduce it

The dataset and the 27B judge script are from the judge guide. The OpenJev script plants the same errors with seed 21, sends 11,880 pairs to /v1/classify in batches, and prints both verdict rules, the miss table and the calibration bins. It takes a JSONL of {customer_message, intent} rows; edit DEFS for your taxonomy. A free key's trial covers the run.

Keep reading

Related Articles

The Paralon capybara at a glowing emerald lever switch under holographic panels: one decision, no text
News & Updates
8 min

OpenJev Is Live on an OpenAI-Compatible API: an Open Jev Alternative You Can Call Today

TypeSafe's Jev is hosted-only and behind a waitlist. OpenJev, the open NLI cross-encoder built on Qwen3.5, is now served on ParalonCloud behind POST /v1/classify: a label and calibrated probabilities per input, 3 ms per item in a batch, no generated text. Measured against a 27B LLM judge on the same pairs, with the vLLM recipe so you can run it yourself.

announcementinference APIOpenJev
The Paralon capybara seated as a judge with a glowing gavel, weighing two floating sheets on a holographic balance
Guides & Tutorials
13 min

LLM-as-a-Judge with an Open Model: 990 Planted Errors, 99.6% Caught, and What the Rubric Changes

We used Qwen 3.8 27B over an OpenAI-compatible API as a judge of dataset labels, and scored it against errors we planted ourselves so every number is exact. With a written rubric the judge caught 491 of 493 wrong labels and also rejected 58 labels the dataset called correct, 43 of them the same systematic mistake in the generator. Without the rubric it agreed with the dataset more and missed 20 planted errors. The rubric is not a tuning knob; it decides what the judge measures.

LLM-as-a-judgeevaluationdata quality
The Paralon capybara pulling a glowing ribbon of index cards out of a server cube and stacking them into tall piles
Guides & Tutorials
11 min

Synthetic Dataset Generation with an Open LLM: 8,600 Labeled Examples an Hour on an OpenAI-Compatible API

We generated 990 labeled customer-support examples with Qwen 3.8 27B through a plain OpenAI-compatible endpoint, schema-enforced with a forced tool call. Here is the script, the throughput and latency we measured, the token cost per thousand examples at list price, what the model got right, and the two ways it quietly repeats itself.

synthetic datadataset generationfine-tuning