Skip to main content

pairsort

Rank anything with AI judges: reliably, cheaply, and with honest confidence.

tests Summary Showdown license: MIT

Ask a model to score 100 things from 1 to 10 and you get noise on a drifting scale. Ask it "which of these two is better?" and you get its best judgment. pairsort asks many of those small questions, cancels the model's biases, and couples the answers into one ranking with probabilities, using the pairwise-coupling rule of Price, Knerr, Personnaz & Dreyfus (NeurIPS 1994).

  • More reliable than any single judgment. Coupling many pairwise answers fixes the contradictions a judge makes (A > B > C > A) and averages out its noise and position bias. Measured against explicit ground truth in eight evals.
  • Cheap: not all-vs-all. An active schedule asks only the informative pairs and stops when the ranking settles; 100 items were ranked from 8% of the possible pairs. With Jev as the judge, 4,800 comparisons cost $0.11.
  • Probabilities, not vibes. Every item gets a posterior, every pair a calibrated P(A beats B), and pairsort abstains when the top two are too close to call.
  • Any judge. TypeSafe's Jev via OpenRouter (default), any OpenRouter LLM via token logprobs, open Jev models, or your own: judges.
  • Auditable. Every judgment, in both orders, lands in a JSON audit log.

Try it in 60 seconds

pip install pairsort                       # PyPI name; you `import pairsort` and run `pairsort` (or `pairsort`)
uvx pairsort demo                          # or run the CLI without installing anything
export OPENROUTER_API_KEY=sk-or-...        # or skip it and bring your own judge function
import pairsort

ideas = ["A CLI that turns any CSV into a chart", "A to-do app on a blockchain", "A tool that ranks PRs by urgency"]

result = pairsort.sort(ideas, "Which side project would developers find most useful?")
result.best        # 'A tool that ranks PRs by urgency'   (your own objects back, best first)
result.top(2)      # the two best
result.scores      # {id: probability of being the best}

pairsort.sort(ideas, {"useful": "Which is more useful?", "easy": "Which is easier to build?"})   # blend questions
pairsort.compare("draft A", "draft B", "Which is clearer?")                                    # -> P(A is better)
pairsort.sort(ideas, "Which is shorter?", judge=lambda q, a, b: len(a) < len(b))               # any function is a judge
pairsort sort ideas.txt "Which idea has more impact?"          # from a file (`uvx pairsort sort ...` works too)
cat ideas.txt | pairsort sort - "Which is funnier?" --top 3     # from stdin
pairsort compare "draft A" "draft B" "Which is clearer?"

Nothing is hidden behind the easy path: budgets, active/referee schedules, meta-judges, calibration profiles and any backend are all keywords on pairsort.sort or steps on the builder (pairsort.sorter().by(...).budget(60).meta()). Quickstart (runs in ~5 s: python examples/quickstart.py) · Usage & CLI

Summary Showdown

100 of OpenRouter's most-used models each summarized the 1994 paper this library implements. pairsort ranked them on six questions from 400 of 4,950 possible pairs (8%) with a jury of 4 AI judges. Current top 3: GPT-6 Astra, Claude Opus 5, Nemotron 3 Ultra.

Summary Showdown

Ground truth: none — nobody can say which summary is truly best. The ranking is the AI jury's opinion; we check it against a separate LLM grader (Claude Sonnet 5 + a key-fact rubric), which the verifiable eval shows is itself accurate on exact counts. Humans can vote on the site.

Judge the summaries yourself → · full results + method · leaderboard

Does it work?

Eight evals, each with its ground truth stated up front:

eval what gets ranked ground truth result details
Verifiable 72 summaries of 6 fictional documents exact counts of injected false statements and of facts mentioned, fixed by construction and recountable by a script Jev: 96% of pairs right on accuracy, 94% on completeness (τ 0.82 / 0.89) for $0.02; weakest judge τ 0.42 verifiable
Market 80 + 101 stocks over 2 sessions, judged only on their pre-open SEC filings realized next-day returns (Mon 09-21 and Tue 09-22), which didn't exist before those days Monday: Jev τ +0.14 (p = 0.035). Tuesday: no judge beat guessing (best p = 0.12). Weak evidence so far market
Degradation ladder 60 copies of 6 real summaries, damaged one logged step at a time rung number (each rung = previous + one planted error / deleted / swapped sentence) Jev: 94% of pairs right, ECE 0.033 ladder
Code runtime 25 correct implementations of a new function measured wall-clock time in a sandbox Jev picks the faster one 97% of the time runtime
Cross-lingual the same summaries in EN/ES/DE/JA exact counts, identical in every language by construction Jev gives the same answer in all 4 languages 96% of the time cross-lingual
Weather 35 cities, ranked the day before airport observations of the next day's high and rain; predictions committed first first round resolves 2026-09-25 weather
Paper sorting 16 fictional abstracts on 3 questions 1–5 levels assigned by construction by the dataset author (not expert ratings) Jev: fused AUC 0.994, Kendall τ 0.86 evaluation
Synthetic simulated items, flawed simulated judge known latent order; calibration labels sampled from it coupling + both orders + temperature: ECE 0.158 → 0.013 evaluation

Verifiable eval

Ground truth in this figure: exact counts built into fictional documents; recount them with python examples/verifiable_eval.py verify.

Learn more

MIT licensed. Contributions welcome.

Release files for pairsort 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pairsort 0.1.0
File Size Uploaded
pairsort-0.1.0.tar.gz 74.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pairsort 0.1.0
File Interpreter ABI Platform
pairsort-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 153.7 kB

Release files / pairsort-0.1.0.tar.gz

Download URL pairsort-0.1.0.tar.gz
Size 74.6 kB
Tags Source
SHA-256 checksum
How to use checksums
9a89d5aada43285de02c9edcae0984256ac13fae50e88a24d291f5a4c5445cbc
BLAKE2b-256 checksum
How to use checksums
8257b1cde3ca299a617d6555a6caa21e3eb0c0e001bbd426133f611c5b6e5c73
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pairsort-0.1.0-py3-none-any.whl

Download URL pairsort-0.1.0-py3-none-any.whl
Size 79.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1a128a56a83187460e676c78e53c1c1b9b757db753e917c86f6d4ad6309ba3c
BLAKE2b-256 checksum
How to use checksums
b66a0d6f7e652b0716746e05159b70281ee87ad4003887b06e5dc1d9bd37426e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page