Skip to main content

any-to-bench

Convert any exam materials — photos of exam papers, exam PDFs, solution PDFs/photos, official answer keys, scoring rubrics — into a machine-gradable benchmark.

Give it everything you have for one exam; it produces an exam bundle: the structured exam, a strict answer-sheet JSON Schema for any LLM harness, and a grading spec. Fixed-answer questions grade deterministically; open-ended questions are graded by multimodal LLM judges with rubrics extracted from your materials. All common paper-exam question types are supported, including nested sub-questions, figures, tables, and LaTeX math.

Install

Requires Python ≥ 3.12.

uv tool install any-to-bench   # or: pip install any-to-bench
a2b --help

Set the API keys for the providers you use as environment variables (or in a .env file in your working directory): OPENAI_API_KEY, GOOGLE_API_KEY, HF_TOKEN, ...

For development, clone the repo and:

uv sync
cp .env.example .env   # fill in the API keys for the providers you use

Usage

# 1. Ingest: any mix of PDFs and photos for ONE exam -> a bundle
a2b ingest exam.pdf answer-key.jpg rubric.pdf -o out/bundle --model openai:gpt-5.6-sol

# 2. Check the bundle
a2b validate out/bundle

# 3. Have an LLM take the exam (any provider — this is the benchmark part)
a2b solve out/bundle --model google:gemini-3.7-flash -o out/answers.json

# 4. Grade the answer sheet
a2b grade out/bundle out/answers.json -o out/report.json
# override judge model(s): --judge-model openai:gpt-5.6-sol --judge-model codex:gpt-5.6-sol

# Or benchmark several models at once: solve + grade each, compare in one table
a2b bench out/bundle -o out/bench \
    --model openai:gpt-5.6-terra --model google:gemini-3.7-flash

# Share bundles via Hugging Face datasets (viewer-friendly, byte-faithful round trip)
a2b upload out/bundle user/my-exams --name matha
a2b download user/my-exams --name matha -o local/bundle

a2b is a shorthand alias for any-to-bench — every command works with both. In a cloned repo without installing, prefix commands with uv run (e.g. uv run a2b ...).

Ingest, solve, and judge models are independent. Use a codex: or claude: model string (e.g. codex:gpt-5.6-sol, claude:opus) to run a phase agentically via that CLI instead of direct LLM calls — same commands, same outputs. All commands accept --effort and report token usage.

Design principles

The three phases have deliberately asymmetric goals:

  • Ingest: spend freely, be exact. A bundle is a dataset — built once, reused by everyone who ever benchmarks against it. Extraction accuracy is worth almost any model cost and wall time; this is why ingestion supports the expensive agentic mode, gap-repair rounds, and validate-and-fix loops. Intelligence spent here is amortized across every future run.
  • Solve: no constraints. The taker is the thing being measured — anything from a cheap LLM call to a full agent belongs here.
  • Grade: require as little intelligence as possible. The same answer sheet must earn the same score every time. Fixed-answer questions grade as pure scripts — zero model calls, bit-for-bit reproducible. Where an LLM judge is unavoidable (open-ended questions), it is constrained, not creative: precise rubrics with defined point levels, reference answers, and level snapping mean the judge follows the rubric mechanically instead of improvising — so even a non-frontier judge model grades accurately and consistently.

Put differently: ingest converts intelligence into structure (keys, rubrics, schemas) exactly once, so that grading needs almost none, forever.

Documentation

Development

uv run pytest -q        # fully offline — model requests are forbidden in tests
uv run ruff check .
uv run ruff format .    # CI enforces this with --check

The test suite fakes the LLM layer (any_to_bench.llm.build_agent) and the agentic subprocess layer (any_to_bench.agentic.runner.run_codex / run_claude), so the entire ingest → solve → grade pipeline runs end-to-end in every mode without network access or either CLI binary installed.

Download files

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

Source Distribution

any_to_bench-0.1.1.tar.gz (69.3 kB view details)

Uploaded Source

Built Distribution

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

any_to_bench-0.1.1-py3-none-any.whl (89.4 kB view details)

Uploaded Python 3

File details

Details for the file any_to_bench-0.1.1.tar.gz.

File metadata

  • Download URL: any_to_bench-0.1.1.tar.gz
  • Upload date:
  • Size: 69.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for any_to_bench-0.1.1.tar.gz
Algorithm Hash digest
SHA256 da2a888247c25a16e69c312c337d0bb1d7166525084b7e4fb20ee32843a1a1d3
MD5 ed0de0133198ac3b37a3f77b88bf3aaa
BLAKE2b-256 70c41413866baafa5faf3c4c824093a95f5f052e1df24c8c87858a6318d43093

See more details on using hashes here.

Provenance

The following attestation bundles were made for any_to_bench-0.1.1.tar.gz:

Publisher: release.yml on JacobLinCool/any-to-bench

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

File details

Details for the file any_to_bench-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: any_to_bench-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 89.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for any_to_bench-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 926ada578dfdd24760639f637ec75b0a4d288bd3cd2245c994ac683ebf902629
MD5 de45c30c6314697c11d8a01ce1697c65
BLAKE2b-256 8e048416a3b3a0e92fb4f914179f52ca2f6714d3961b6d199dff5fd2b0e60c98

See more details on using hashes here.

Provenance

The following attestation bundles were made for any_to_bench-0.1.1-py3-none-any.whl:

Publisher: release.yml on JacobLinCool/any-to-bench

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

Release history Release notifications | RSS feed

0.1.2

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

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