feat: 6-dimension rubric with deterministic checks for workflow evals - #1204
Draft
RobertCrupa wants to merge 1 commit into
Draft
feat: 6-dimension rubric with deterministic checks for workflow evals#1204RobertCrupa wants to merge 1 commit into
RobertCrupa wants to merge 1 commit into
Conversation
Replaces the single PASS/FAIL judge verdict in evals/workflows with a fixed 6-dimension rubric (toolSelection, argumentCorrectness, resultUtilization, taskCompletion, errorRecovery, planEfficiency), so a reviewer can see which capability regressed instead of one opaque verdict. Two checks are computed in code, not by the LLM: - toolSelection: exact set-match against a new expectedTools field on the test case, overriding the judge's own verdict when set. Ported from the toolsExactMatch evaluator in evals/run_evaluation.ts. - schemaValidity: every tool call's arguments validated with AJV against that tool's declared inputSchema. Reported separately from argumentCorrectness. The judge now also sees tool results (truncated to 2000 chars per result, errors shown as errors) — resultUtilization and errorRecovery are unjudgeable without them. overallVerdict = taskCompletion, purely informational. Exit-code behavior is unchanged and nothing here is gated in CI. results.json keeps verdict/reason as mirrors of taskCompletion so existing readers don't break, and gains rubric, toolSelectionCheck and schemaValidityCheck. Baseline comparison prints per-dimension pass-rate deltas alongside the byte/token ones. expectedTools backfilled on 25 of the 30 test cases; left unset on the 5 where multiple tool paths are genuinely valid. Assisted-by: Claude Code Claude-Session: https://claude.ai/code/session_0136aUA25ZgcWmM7RMDq3iar
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.
Why
Closes #1203.
evals/workflows/judged every multi-turn conversation with one binary PASS/FAIL from an LLM judge that only saw tool calls, arguments and agent text. A red verdict didn't say which capability regressed, and nothing in the harness was ground truth — tool selection and schema validity have knowable answers that don't need an LLM.What changed
The judge now scores six independent dimensions (
toolSelection,argumentCorrectness,resultUtilization,taskCompletion,errorRecovery,planEfficiency), same six for every test case.overallVerdictis just thetaskCompletionverdict — there's no aggregation rule, and the exit code is unchanged, so none of this gates anything.Two checks are computed in code and reported separately from the LLM's answers:
expectedToolsfield onWorkflowTestCase. When it's set, the deterministic verdict overrides the judge's and the judge's own answer is discarded; when unset the judge's verdict stands. The compare logic is ported from the existingtoolsExactMatchevaluator inevals/run_evaluation.tsrather than re-derived.inputSchema. Deliberately not folded intoargumentCorrectness: schema-valid arguments can still be semantically wrong. Validators are cached per tool name because tool schemas carry a$idand AJV rejects a second compile of one. Calls naming a tool that isn't in the final tool list, and tools whose schema won't compile, are skipped rather than flagged — neither is an agent mistake.The judge also now sees tool results, truncated to 2000 chars each, with failed calls rendered as errors rather than omitted.
resultUtilizationanderrorRecoveryaren't answerable without them.expectedToolsis backfilled on 25 of the 30 test cases. The 5 left unset are the ones where more than one tool path is genuinely correct: the three "which is the best scraper" searches, where fetching Actor details on top of searching is legitimate, plus the two reachable either via a dedicated Actor orapify/rag-web-browser.results.jsonkeepsverdictandreasonas mirrors oftaskCompletionso anything reading the old field names still works, and gainsrubric,toolSelectionCheckandschemaValidityCheckas optional fields. Baseline comparison prints per-dimension pass-rate deltas next to the existing byte/token ones, with the arrow polarity flipped since more passes is better here.Notes for reviewers (human-written)
Proof it works
Not yet proven end-to-end — this is why the PR is a draft. The eval harness needs
APIFY_TOKENandOPENROUTER_API_KEY; neither was available in the environment this was written in, so no live run happened. Still outstanding from the spec's acceptance list:pnpm run evals:workflow -- --id <a few ids across categories> --output --verbose— eyeball all six dimensions in verbose output, and spot-check that a deliberately wrongexpectedToolsvalue flipstoolSelectionregardless of what the judge said.failToolscase, confirming the synthetic error result isn't false-flagged as a schema violation.--outputrun to write the first rubric-bearing baseline, then a second run to confirm the per-dimension deltas print as= baseline. No committed record carries arubricfield yet, so the first run shows no dimension deltas by design.What is covered: unit tests for the deterministic override flipping
toolSelectionwhile the judge says PASS, afailTools-shaped error result not being schema-flagged, and unchanged pass counts rendering as= baseline— i.e. the three behaviors steps 1–3 exist to catch, exercised without live credentials. The table, verbose output and record JSON were also smoke-rendered from synthetic data, and the CLI entry point loads and exits cleanly at the credential gate.One thing to check on the reviewer's side: the spec mentioned pinning the judge to
deepseek/deepseek-v4-flash-0423, but design decision #9 says the judge model is unchanged, soMODELS.judgeis left atdeepseek/deepseek-v4-flash. I couldn't confirm whether-0423is a distinct OpenRouter variant — the sandbox's proxy blocksopenrouter.ai. Nothing new was hardcoded, so this only matters if the dated variant was actually intended.AI-assisted: written with Claude Code. https://claude.ai/code/session_0136aUA25ZgcWmM7RMDq3iar