Evaluation

Model scorecard

Rules decide; models read. Every appetite disposition in Astra Risk comes from a deterministic engine that applies the carrier's thresholds, so the same evidence always gives the same answer and every factor cites its source. Language models do the reading: they pull the construction year and the three-year loss count out of broker prose. This page measures each reader on the same 31 broker notes.

Invented values are the failure that matters most: a year or a loss count that the note never stated. Missed values cost a broker question; wrong values cost a wrong check.
This run hit API refusals, so the model rows understate what the model can read. The refusal counts sit under each reader; rerun npm run eval:scorecard once the quota resets.
ReaderAccuracyInventedMissedWrongp50p95Cost per 1,000 notes
Deterministic parserregex parser100%31 of 310000 ms1 ms$0
Gemini aloneno model call completed31 of 31 notes got no model result (31 × HTTP 429)0%0 of 310001.1 s1.2 s—
OpenAI aloneSkipped: OPENAI_API_KEY unset on the machine that ran this.
Models and parser, resolved by agreementno model call completed; the parser supplied every value0 of 31 notes got no model result (31 × HTTP 429)100%31 of 310001.1 s1.1 s—

Generated 9/20/2026, 5:14:12 AM with 1000 ms between model calls. Accuracy counts a note as correct only when both fields match what a careful underwriter would take from it. Cost uses published list prices per million tokens and the tokens each call reported; the parser runs in-process. Reproduce with npm run eval:scorecard; the cases live in evals/suites/extraction.ts.

What each reader got wrong

The appetite engine itself is pinned by 189 offline cases that run in npm test; see Models and rules.