Skip to main content
A run fingerprint identifies the setup — model, prompt, tools, evaluators — an evaluation was scored under, so two scores are never put side by side when the thing being scored has moved.

Quick Start

1

Automatic (recommended)

Run an EvalSuite — the fingerprint is stamped onto the result. Compare two suite results with assert_comparable.
2

Manual

Compute a fingerprint yourself when you are not using EvalSuite.
3

Diagnose a mismatch

Use fingerprint_parts to see exactly what changed.

How It Works

EvalSuite.run() reads model, prompt, and tools from each evaluator’s agent and stamps the fingerprint onto the result at the start of the run. Reading is best-effort — anything unreadable is left out rather than raised, so the fingerprint is never the reason an evaluation fails to run. If nothing can be read, fingerprint is "".

What Goes Into a Fingerprint

Each input is reduced to a stable shape before hashing.

Deliberately excluded

  • Timestamps, run ids, sample order, latency. Anything that varies run to run without changing what a score means is left out. A fingerprint that changed every run would refuse every comparison and be switched off.
  • Tool order. A reordered tool list is the same setup. A guard that changed on reordering would refuse valid comparisons.
  • The prompt text itself. Hashed, never stored, so fingerprints can safely land in shared result files.

Public API

Missing fingerprints are unknown, not equal. compare_fingerprints("", "") returns False, and assert_comparable("", "") raises FingerprintMismatch. Assuming legacy unstamped runs are equal would let every old baseline silently pass the check — the guard refuses instead.
Prompts are hashed, never stored. A fingerprint is written to result files and shared, so the full prompt text is never included.

Common Patterns

Gate CI on a stable baseline

Save result.fingerprint alongside the score, then guard before comparing numbers on the next run.

Persist fingerprints with results

result.summary already includes the fingerprint — write it to disk with the score.

Compare setups on purpose

When A/B’ing prompts, skip assert_comparable and record both fingerprints so the difference is visible in the graph.

Best Practices

A silent side-by-side of two different setups is the failure this guards against. Guard first, then subtract scores.
Old fingerprints will not compare equal to new ones after a bump — that is intentional, so scores from a changed recipe are never treated as comparable to older runs.
Temperature, seed, retrieval index name — pass them through extra= so they become part of the fingerprint.
The fingerprint code already fails silently at compute time (best-effort). Failing loud at compare time is deliberate — if two runs are not comparable, that is real.

Evaluation Suite

Run every evaluator as one CI gate

Harness Evaluator

Score test-harness traces

Loop Evaluator

Score loop health and convergence

EvalPort Adapter

Export and import suites in the EvalPort open spec