Skip to main content

schemascore

CI PyPI

Field-level evals for structured LLM output.

"The extraction looks fine" isn't a metric. When you change a prompt or swap a model, you need to know which fields got worse. schemascore runs your extraction over labeled cases, validates every output against a Pydantic schema, and reports validity plus accuracy per field. Save the report, compare the next run against it, and fail CI when something regresses.

pip install schemascore

Python 3.10+. One dependency: Pydantic 2.

Quickstart

from pydantic import BaseModel
from schemascore import evaluate, fuzzy, numeric, Report

class Invoice(BaseModel):
    vendor: str
    total: float
    currency: str

cases = [
    {"id": "acme", "input": "INVOICE ... Acme Corp ... USD 1,250.00",
     "expected": {"vendor": "Acme Corp", "total": 1250.0, "currency": "USD"}},
    # ...
]

report = evaluate(
    Invoice,
    cases,
    extract,  # your function: input -> JSON string, dict, or Invoice
    comparators={"total": numeric(abs_tol=0.01), "vendor": fuzzy(0.85)},
    concurrency=8,
)
print(report.summary())
report.save("baseline.json")

# Later, after changing the prompt or model:
diff = report.compare(Report.load("baseline.json"), max_drop=0.02)
diff.ok           # False if any metric dropped more than 2 points
diff.regressions  # {"total": -0.25, "<overall>": -0.08}

extract can return a JSON string (```json fences are fine), a dict, or a model instance, and can be sync or async. Sync targets run on threads and async ones as asyncio tasks, concurrency at a time.

How scoring works

  • Expected and actual outputs are flattened to paths like items[0].price.
  • Only fields present in expected are scored, so partial labels work.
  • Accuracy is reported per field, with list indexes folded together: items[*].price.
  • A comparator is chosen by exact path, then wildcard path, then the default, exact().
  • If the output isn't valid JSON, fails the schema, or the target raises, the case is invalid and every labeled field counts as a miss. The eval never crashes because of the thing it's evaluating.
  • overall = correct fields ÷ labeled fields, across all cases. validity = valid cases ÷ cases.

Comparators

A comparator is any (expected, actual) -> bool.

Comparator Matches when
exact(normalize=True) equal; strings ignore case and extra whitespace, floats ignore rounding noise
numeric(abs_tol=0, rel_tol=0) numbers within tolerance; numeric strings like "1,250.00" are converted
fuzzy(threshold=0.85) text similarity (difflib ratio) is at least threshold
contains() the expected text appears in the actual text
one_of([...]) both values are in the same group of synonyms, e.g. ["USD", "US$", "$"]

In CI

schemascore run \
  --schema examples.invoice:Invoice \
  --target examples.invoice:extract \
  --cases examples/cases.jsonl \
  --comparators examples.invoice:COMPARATORS \
  --baseline baseline.json --max-drop 0.02 --min-overall 0.9 \
  --out latest.json

Exit code 1 if any metric (validity, overall, or a field) dropped more than --max-drop against the baseline, or overall is below --min-overall. Commit a baseline, and update it deliberately when a change is an improvement.

The bundled example scores a fake extractor with realistic mistakes over four invoices, one of which comes back as truncated JSON:

cases     4
valid      75.0%
overall    70.8%

Limits

  • List items are matched by position, not by content. If a model returns the right items in a different order, they score as misses.
  • One call per case. Model output varies between runs; before trusting a small difference, run more than once or use more cases.

Author

Built and maintained by Ananda Poudel (email@anandapoudel.com).

License

MIT © Ananda Poudel

Metadata

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

Built distribution (wheel)

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

Total release size: 24.1 kB

Release files / schemascore-0.1.0.tar.gz

Download URL schemascore-0.1.0.tar.gz
Size 12.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b71f6b2241246500c0290f398a562ee94105de3f2d29bbbcfbd7f3705f01427f
BLAKE2b-256 checksum
How to use checksums
c470c4cfa787ad5d1e61a93be79b9c70bcd11a509845f3ec035670fa854501e7
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 6, 2026.

Transparency log

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

Download URL schemascore-0.1.0-py3-none-any.whl
Size 11.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
022f24b2b144cfe4c75e0fc06d57d4c8912ccc83b2643c31254df9b997e7559c
BLAKE2b-256 checksum
How to use checksums
a520294a78df78cb875a8e3329207fd49ddf641b6559d5b65724a207ab918f16
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 6, 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