Skip to main content

judgeswap

Evaluation harness pieces for LLM generation pipelines, lifted from a product that spent five months measuring itself against a full-document oracle. No framework, no network: a model is any object with complete(prompt) -> str, and the only files written are in the artifact directory you name.

pip install judgeswap

What is in it

module what it does
judgeswap.judging Rubric (prompt templates plus validation), RubricJudge (score and prefer through your client), parse_judge_json (every axis an in-range int, true refused, malformed extras coerced), head_to_head (position-swapped preference).
judgeswap.parity run_parity: generate a candidate per section over a frozen context, score it against a reference, swap-judge it, write one JSONL row per section and a REPORT.md. ungrounded_citations counts footnotes no retrieved item carries, with your join rule.
judgeswap.structured extract_structured: bare, fenced or prose-wrapped JSON, <think> blocks stripped, optional KEY: VALUE fallback, an error envelope instead of an exception. mean_axes.
judgeswap.floors Model(runtime, name) and regression floors keyed on (model, task); a combination without a floor is soft, recorded and never failing.
judgeswap.setdiff diff_sets (matched / added / dropped, with dropped suppressed on a partial run) and normalize_ref.
judgeswap.report JSONL in, Markdown tables out: write_matrix_report, render_delta_table.
judgeswap.embeddings Offline embedding-model A/B: cosine_rank, recall_pass, domain_separation, run_ab (a failing backend is skipped, a short result is refused), a recommendation with a migration bar.

Sixty seconds

from judgeswap import Rubric, RubricJudge, Section, run_parity

class Client:                       # anything with complete(prompt) -> str
    def complete(self, prompt: str) -> str:
        return my_model(prompt)

judge = RubricJudge(Client(), Rubric())   # or Rubric(score_template=..., preference_template=...)

sections = {
    "risks": Section(context=frozen_context, reference=oracle_markdown,
                     structured_data=facts, retrieved_citations=cites),
}

def generate(section_id, section, overrides):
    prompt = render(section_id, section.context, override=overrides and overrides.get(section_id))
    return my_model(prompt), []       # (markdown, citations)

summary = run_parity(sections, generate=generate, judge=judge,
                     artifact_dir="out/", variants={"baseline": {}, "v2": {"risks": V2_TEMPLATE}})
# out/baseline.jsonl, out/v2.jsonl, out/REPORT.md
# summary["v2"] -> {"mean_total": 3.9, "wins": 1, "ties": 0, "losses": 0, "ceiling_flag_count": 4, ...}

The swap in one line:

from judgeswap import head_to_head
head_to_head(lambda a, b: "A", candidate, reference)   # -> "tie": a judge that always says A proves nothing

Why these pieces

  • Freeze the context. The reference was written with the whole document; the candidate sees what retrieval returned, captured once. Prompt changes are then attributable to the prompt, and the judge's ceiling_flags name the facts no prompt could have used.
  • Swap the positions. Judges prefer slot A. Judged in both slots, a candidate wins only when preferred in both, and a biased judge scores a tie.
  • Validate the judge. A true is not a 1. A flags list returned as a string is not a list of flags. A truncated JSON is an error row, not a zero.
  • Key floors on the runtime. The same weights behave differently per serving stack; a floor on a bare model name blames the wrong thing.
  • Count what prose cannot show. A citation to a footnote that nothing retrieved reads fine and grounds nothing.

The experiments that shaped these are written up in docs/: a retrieval branch that never ran, an embedding A/B that correctly returned "no", a hybrid-retrieval flag that only moves exact-term queries, and a regression guard whose first failure was in the grader.

Not in it

Model clients, storage, a database, a CLI, or anything that knows your domain. The default rubric is generic on purpose; pass your own templates.

Development

pip install -e '.[test]' black ruff
pytest

See CONTRIBUTING.md. Security reports: SECURITY.md. Apache-2.0.

Metadata

Release files for judgeswap 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 judgeswap 0.1.0
File Size Uploaded
judgeswap-0.1.0.tar.gz 27.3 kB Details

Built distribution (wheel)

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

Total release size: 50.0 kB

Release files / judgeswap-0.1.0.tar.gz

Download URL judgeswap-0.1.0.tar.gz
Size 27.3 kB
Tags Source
SHA-256 checksum
How to use checksums
582401ae7eb0c0cae14734db3b13b1d7b1ea008dff3d4d955b23813d1f0fce58
BLAKE2b-256 checksum
How to use checksums
23b5a7ed8748b66c22246262164966e3781933e47f43eaddcd072e2b240a55d0
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 Oct 16, 2026.

Transparency log

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

Download URL judgeswap-0.1.0-py3-none-any.whl
Size 22.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc4cd230846a61a82f4bddc531667bd5051fdcea2ea57029708f82189e036faf
BLAKE2b-256 checksum
How to use checksums
eb2aee6791d92b789d883da650c2fc45f23991cfccbfe515bc56db6325bdb01a
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 Oct 16, 2026.

Transparency log

Release history Release notifications | RSS feed

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