Skip to main content

Causal Judge Evaluation - Unbiased LLM evaluation framework

Project description

CJE Logo

CJE - Causal Judge Evaluation

Your LLM judge scores are noisy and nebulous. CJE calibrates them to what actually matters.

arXiv Dataset Open In Colab Docs Python Tests License PyPI Downloads

We ran 16,000+ tests on Chatbot Arena data. Without calibration, 95% confidence intervals captured the true value 0% of the time. With CJE: 99% ranking accuracy using just 5% oracle labels, at 14× lower cost.


Quick Start

pip install cje-eval
from cje import analyze_dataset

# Compare policies on the same evaluation prompts
# Structure: { policy_name: [samples] }
# Each sample needs: prompt_id, judge_score
# Optional: oracle_label (human ground truth) on 5-25% of samples

results = analyze_dataset(
    fresh_draws_data={
        "gpt-4o": [
            {"prompt_id": "eval_001", "judge_score": 0.85, "oracle_label": 0.9},
            {"prompt_id": "eval_002", "judge_score": 0.72, "oracle_label": 0.7},
            {"prompt_id": "eval_003", "judge_score": 0.68},
            {"prompt_id": "eval_004", "judge_score": 0.79},
        ],
        "claude-sonnet": [
            {"prompt_id": "eval_001", "judge_score": 0.78, "oracle_label": 0.82},
            {"prompt_id": "eval_002", "judge_score": 0.81, "oracle_label": 0.79},
            {"prompt_id": "eval_003", "judge_score": 0.75},
            {"prompt_id": "eval_004", "judge_score": 0.83},
        ],
    }
)

# Or from files: analyze_dataset(fresh_draws_dir="responses/")

results.plot_estimates(save_path="ranking.png")

CJE learns the judge→oracle mapping from the labeled samples and applies it everywhere.


Why You Need This

LLM-as-judge gives you rankings. CJE gives you certainty.

Without calibration, you know prompt A scored higher than B—but you don't know:

  • Is the difference real or noise?
  • How big is the improvement, actually?
  • Have I tested enough samples?
  • Will this hold next week?

CJE answers all of these. Label 5% of samples with your oracle (human raters, latest SOTA model or AI agent, downstream metric). CJE learns the calibration and applies it everywhere—giving you trustworthy magnitudes, valid confidence intervals, and drift detection.

The result: Make decisions faster, spend less on labeling, and defend your conclusions with real statistics.

Read the full explanation →


The Results

We tested on 5,000 Chatbot Arena prompts with GPT-5 as the oracle (ground truth) and GPT-4.1-nano as the cheap judge:

CJE achieves 99% ranking accuracy using only 5% oracle labels—matching full-oracle performance at 14× lower cost.

Label ~250 samples with your oracle (human raters, downstream KPIs, expensive model). CJE learns the judge→oracle mapping and applies it to everything else. Without calibration, error bars contained the true value 0% of the time. With CJE: ~95%.

Already using an expensive model for evals? Switch to a 10-30× cheaper judge + CJE calibration. Same accuracy, fraction of the inference cost.

CJE Output Example
Example output with simulated data (not real model benchmarks)

Read the full Arena Experiment →


Monitoring Calibration Over Time

Calibration can drift. Periodically verify it still holds with a small probe:

from cje import analyze_dataset
from cje.diagnostics import audit_transportability

# results.calibrator is automatically fitted during analysis
results = analyze_dataset(fresh_draws_dir="responses/")

# Check if calibration still works on this week's data (50+ oracle labels)
diag = audit_transportability(results.calibrator, this_week_samples)
print(diag.summary())
# Status: PASS | Samples: 48 | Mean error: +0.007 (CI: -0.05 to +0.06)
Temporal Monitoring

PASS means your calibration is still valid. FAIL means something changed — investigate or recalibrate.


Try It Now

Open the interactive tutorial in Google Colab →

Walk through a complete example: compare prompt variants, check if calibration transfers, inspect what's fooling the judge, and monitor drift over time. No setup required.


Documentation

Planning sample sizes? Once you have pilot data, CJE can optimize your oracle/surrogate budget allocation. The tutorial notebook walks through budget planning using Arena data as a reference.

Video Walkthroughs

Technical Guides

Examples & Data


Development

git clone https://github.com/cimo-labs/cje.git
cd cje && poetry install && make test

Support

Citation

If you use CJE in your research, please cite:

@misc{landesberg2025causaljudgeevaluationcalibrated,
  title={Causal Judge Evaluation: Calibrated Surrogate Metrics for LLM Systems},
  author={Eddie Landesberg},
  year={2025},
  eprint={2512.11150},
  archivePrefix={arXiv},
  primaryClass={stat.ME},
  url={https://arxiv.org/abs/2512.11150},
}

License

MIT — See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cje_eval-0.2.16.tar.gz (347.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cje_eval-0.2.16-py3-none-any.whl (405.7 kB view details)

Uploaded Python 3

File details

Details for the file cje_eval-0.2.16.tar.gz.

File metadata

  • Download URL: cje_eval-0.2.16.tar.gz
  • Upload date:
  • Size: 347.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cje_eval-0.2.16.tar.gz
Algorithm Hash digest
SHA256 d054361a721d75b6cb66ed1a36a869f72bb936bb42cea543ca44950a4fc000c0
MD5 81319c9571b4553a8db554670f3d9fef
BLAKE2b-256 641d4a9f6ee1d2a51a3354ebee2b50af34b20e4ac39613613248c3b5879996f2

See more details on using hashes here.

Provenance

The following attestation bundles were made for cje_eval-0.2.16.tar.gz:

Publisher: publish.yml on cimo-labs/cje

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cje_eval-0.2.16-py3-none-any.whl.

File metadata

  • Download URL: cje_eval-0.2.16-py3-none-any.whl
  • Upload date:
  • Size: 405.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cje_eval-0.2.16-py3-none-any.whl
Algorithm Hash digest
SHA256 b15bc511fd57dc77af62d01f3b6c88d46f45bcb5a76baea088adb1d19b21e0c9
MD5 af023552dd8e29035b5dd9ab6a309839
BLAKE2b-256 19011c90a8164b8ef3cd9805f1ae3a5b519e595746dbdcbd9888647dc10f2bb0

See more details on using hashes here.

Provenance

The following attestation bundles were made for cje_eval-0.2.16-py3-none-any.whl:

Publisher: publish.yml on cimo-labs/cje

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page