An LLM extracts invoices into dicts like {"vendor": ..., "total": ..., "date": ...}. Whole-record exact match is too harsh: score each field.
Implement field_scores(predictions, gold, fields) for parallel lists of dicts:
"1,234.50") compare as floats within 1e-6. None and missing keys mean "not extracted".{field: {"precision", "recall", "f1"}}, using 0.0 when a denominator is 0, plus a key "_record_exact_match": the fraction of records where every field matches (two missing values match).