Make grader response parsing robust to reasoning and echoed rubrics - #17
Open
dan-s-w wants to merge 1 commit into
Open
Make grader response parsing robust to reasoning and echoed rubrics#17dan-s-w wants to merge 1 commit into
dan-s-w wants to merge 1 commit into
Conversation
Every grader took the first regex match in the judge's response, which is only safe if the judge emits nothing but its verdict. SimpleQA matched an unanchored (A|B|C), so any capital A, B or C inside a word was read as the grade. A response opening "Based on the gold target..." scored B -- INCORRECT -- regardless of the actual verdict. FRAMES took the first TRUE|FALSE, but its prompt asks for an explanation before the decision, so a TRUE or FALSE anywhere in the reasoning won. A response with no match indexed a dict with None and raised KeyError, which surfaced as FAILED rather than as a parse problem. FinSearchComp took the first answer_score, and its prompt embeds worked examples that an echoing judge can reproduce. All four now read the last match, prefer an explicitly labelled decision where the prompt defines one, and log when they fall back to a default. Silent defaults were indistinguishable from genuine wrong answers. Graders are stubbed in tests, so no network or API keys are needed. Six of the thirteen fail against the previous implementation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
eddy-nassif
approved these changes
Sep 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every grader took the first regex match in the judge's response. That's only safe if the judge emits nothing but its verdict, and the prompts don't all guarantee that.
SimpleQA — the worst one
Unanchored, so it matches a capital A, B or C anywhere, including inside a word. A judge response opening
"Based on the gold target..."matches the B in "Based" and scores the answer INCORRECT — whatever the actual verdict was.The prompt does say "Just return the letters, with no text around it," so this needs a chatty judge to bite. But nothing enforces it, and the failure is silent and looks exactly like a wrong answer.
FRAMES — matched against its own prompt
The prompt asks for this shape:
Explanation first. So
re.search(r"(TRUE|FALSE)", ...)reads whichever appears in the reasoning, not the decision."It is FALSE to say these differ... Decision: TRUE"scored FALSE.A response with no match was worse:
which surfaced as a
FAILEDrow rather than a parse problem.FinSearchComp
Took the first
answer_score, and its prompt embeds worked examples an echoing judge can reproduce.Change
All four now read the last match, prefer an explicitly labelled decision where the prompt defines one (
Decision:for FRAMES,correct:for BrowseComp), and tolerate case and spacing. Falling back to a default now logs the unparsed response — previously a default was indistinguishable from a genuine wrong answer.Tests
tests/test_grader_parsing.py— the judge is stubbed, so no network or API keys. Covers each grader's happy path, the specific corruptions above, and the unparseable case.Six of the thirteen fail against the previous implementation:
Worth discussing
This changes grading, so scores can move — most likely on FRAMES, where the prompt actively invites reasoning before the verdict. If any published FRAMES number was affected by first-match parsing, it would have been biased downward. Might be worth a re-run on a sample to see whether the delta is material.
🤖 Generated with Claude Code