Evaluation Scoring Harness
Part of AI Engineering: Build and score a small evaluation set
Evaluation Scoring Harness
A policy assistant must either answer a supported question with the right fact or abstain when its source lacks the answer. An evaluation runs every case once and records at most one structured outcome per case. Write the harness that scores those outcomes.
Implement summarize(dataset, results).
Inputs
dataset: an array of cases{ id, slice, expected, fact }.expectedis"answer"or"abstain".factis the expected fact key for an answer case andnullfor an abstain case.results: aMapfrom case ID to the recorded outcome (adictin Python). An outcome is{ kind: "answer", fact },{ kind: "abstain" }, or{ kind: "error" }. A case with no entry inresultshas a missing output.
Scoring rules
A case passes when:
- it expects
"abstain"and its outcome is an abstention, or - it expects
"answer"and its outcome is an answer whosefactequals the case'sfact.
A missing output never passes. It is not an abstention and not an error.
Report
Return an object (a dict in Python) with exactly these keys:
| JavaScript key | Python key | Value |
|---|---|---|
total | total | Number of cases in dataset |
success | success | Passing cases |
answered | answered | Cases whose outcome is an answer, correct or not |
correctAnswers | correct_answers | Answered cases that pass |
errors | errors | Cases whose outcome is an error |
missing | missing | Cases with no recorded outcome |
taskSuccess | task_success | success / total |
answerCoverage | answer_coverage | answered / total |
answeredAccuracy | answered_accuracy | correctAnswers / answered |
slices | slices | For every slice name in dataset: { total, success } |
totalcounts every case, including errors and missing outputs, so a missing output stays in the denominator of task success and answer coverage.- A rate whose denominator is 0 is
null(Nonein Python), never0orNaN. - Every slice with at least one case appears in
slices, even when none of its cases pass.
Errors
Check before scoring:
- Two cases share an ID: throw an
Errorwhose message contains"Duplicate case ID". resultscontains an ID that is not indataset: throw anErrorwhose message contains"Unknown result ID".
In Python, raise ValueError with the same messages.
Fixture
| Case | Slice | Expected | Expected fact | Recorded outcome |
|---|---|---|---|---|
| E1 | standard | answer | return_window_30_days | answer return_window_30_days |
| E2 | exception | answer | custom_excluded | answer return_window_30_days |
| E3 | missing | abstain | none | abstain |
| E4 | missing | abstain | none | answer shipping_fee_10 |
| E5 | standard | answer | defect_window_7_days | error |
| E6 | exception | answer | custom_excluded | abstain |
The tests score this fixture, the same fixture plus a case with no recorded output, and the edge cases above.
Example
summarize(
[
{ id: 'A1', slice: 's', expected: 'answer', fact: 'f1' },
{ id: 'A2', slice: 's', expected: 'abstain', fact: null },
],
new Map([['A1', { kind: 'answer', fact: 'f1' }]]),
);
// {
// total: 2, success: 1, answered: 1, correctAnswers: 1, errors: 0, missing: 1,
// taskSuccess: 0.5, answerCoverage: 0.5, answeredAccuracy: 1,
// slices: { s: { total: 2, success: 1 } },
// }A2 has no recorded output, so it counts as missing and does not pass, even though it expected an abstention.
In Python, implement summarize(dataset, results) with lists and dicts, and use the Python keys from the table.
0 views
Solution
Hints
