Authoring a benchmark suite¶
A benchmark suite measures an extractor's correctness — given a
fixed source, did it produce the expected particles at high enough
confidence? Run via particles extractor benchmark <id> (single)
or particles extractor benchmark-compare --extractor-id A
--extractor-id B (multi).
File format¶
Suites live in tests/benchmark/suites/<suite-id>.yaml. The schema
is normative — field names match techspec §13.3 verbatim
(particles/benchmark/schema.py).
suite_id: numismatic-seed-001
name: Numismatic seed benchmark
version: 0.1.0
domain: numismatics
source_types: [NUMISTA_API_COIN]
cases:
- case_id: numista-coin-001
fixture: numista-coin-001 # reuses tests/conformance/fixtures/<id>/
expected:
- content: "The 5 Pfennigs coin from the GDR has aluminium composition."
confidence_min: 0.95
uncertainty_nature: EPISTEMIC
required: true
The fixture: form reuses a conformance fixture. Use inline
source_snapshot: + inline_content: for ad-hoc cases that don't
warrant a conformance fixture.
required: true vs required: false¶
required |
Affects |
|---|---|
true |
The case's recall denominator. A miss is a recall failure. |
false |
Contributes to precision if matched; absence is not penalised. |
Use required: true only for facts whose absence would mean the
extractor has lost its core value (e.g. "the structured-properties
summary line" for a coin extractor — not "the manufacturer's
historical anecdote").
confidence_min is a floor, not a target¶
An emitted particle that matches semantically but reports confidence
below confidence_min becomes an under_confidence partial match.
It counts for neither precision nor recall, but is separately
reported so you can see "the extractor got it right but stated it
too timidly."
Three normative metrics¶
precision, recall, calibration_error are mandated by techspec
§13.3 and the runner always reports them. calibration_error is not just a
score: it is the input an operator fits a temperature against, so a suite
authored here is what makes
extractor calibration
possible at all — and
benchmark + compare is how
they check a tuning change moved the needle. Domain-specific metrics
are opt-in extensions; see
particles/benchmark/ for the
extension hook.
What good fixtures look like¶
- Realistic content — a real API response, a real article, not a synthetic minimal example. ~10–50 KB is typical.
- High-signal expected list — 5–20 particles per case, covering the structured / descriptive / catalogue-reference axes the extractor is meant to populate.
- Calibrated
confidence_min— what the extractor currently emits, not a target. A future improvement that emits at higher confidence still passes; a regression that emits below the floor is caught as under-confidence.
The suite schema is normative and declared in
particles/benchmark/schema.py.