Pin and persist LLM judge models - #788
Conversation
Co-authored-by: haoranpb <27280733+haoranpb@users.noreply.github.com>
Co-authored-by: haoranpb <27280733+haoranpb@users.noreply.github.com>
Co-authored-by: haoranpb <27280733+haoranpb@users.noreply.github.com>
Co-authored-by: haoranpb <27280733+haoranpb@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Pins LLM judge models centrally and preserves judge provenance through evaluation exports, summaries, and leaderboard aggregation.
Changes:
- Adds shared judge-model configuration and workflow propagation.
- Persists judge models in results, summaries, and aggregates.
- Separates leaderboard runs by judge model and adds coverage.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
tests/test_type_exhaustiveness.py |
Tests category judge mapping. |
tests/test_result_writer.py |
Tests export metadata. |
tests/test_result_hierarchy.py |
Updates judge summary fixture. |
tests/test_evaluation_summary.py |
Tests judge-aware aggregation. |
tests/test_evaluation_factories.py |
Tests provenance propagation. |
tests/test_codereview.py |
Updates result fixture. |
tests/test_category_command.py |
Tests workflow outputs. |
src/bcbench/types.py |
Maps categories to judges. |
src/bcbench/results/summary.py |
Adds summary provenance. |
src/bcbench/results/leaderboard.py |
Adds aggregate provenance. |
src/bcbench/results/codereview.py |
Marks reviews judge-scored. |
src/bcbench/results/bceval_export.py |
Exports provenance metadata. |
src/bcbench/results/base.py |
Defines judge-scored results. |
src/bcbench/config.py |
Loads judge configuration. |
src/bcbench/commands/result.py |
Groups by judge-aware identity. |
src/bcbench/commands/category.py |
Emits judge workflow output. |
src/bcbench/agent/shared/config.yaml |
Pins judge models. |
docs/_data/test-generation.json |
Refreshes leaderboard data. |
docs/_data/code-review.json |
Adds historical provenance fields. |
.github/workflows/summarize-results.yml |
Passes JUDGE_MODEL to bc-eval. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ilot/bc-bench-review-ai-models
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.
Suppressed comments (1)
src/bcbench/results/summary.py:196
- This silently labels the whole summary with the first result's judge even when the input artifacts contain different
judge_modelvalues. The resulting leaderboard then treats all instances as one judge run, defeating the provenance guarantee. Reject non-judge results or any judge-model mismatch before constructing the summary.
first_result = results[0]
assert isinstance(first_result, JudgeScoredEvaluationResult)
return {**super()._base_fields(results, run_id), "judge_model": first_result.judge_model}
There was a problem hiding this comment.
Only one thing I'd actually ask for: JUDGE_MODEL is emitted for code-review (which has no lm_checklist evaluator) and as an empty string for the unjudged categories. See the two comments on summarize-results.yml and category.py — same fix covers both.
The rest are a nit and a question. I retracted my comment on test-generation.json, it was wrong.
Extending combination_key with judge_model is the best part of this PR — runs judged by different models won't get silently merged anymore.
Wenjie Fan (gggdttt)
left a comment
There was a problem hiding this comment.
One more question, on the docs side.
BC-Bench relied on separate implicit model defaults for code-review matching and LMChecklist scoring, without recording judge provenance. This could mix results produced by different judge models.
Configuration
Evaluation
bc-evalthroughJUDGE_MODEL.Provenance
judge_modelin evaluation results, bc-eval metadata, summaries, and leaderboard aggregates.judge_modelin aggregation identity to prevent combining runs judged by different models.Original prompt
Implement. Add anything unclear or concerns in the comments or PR description
[Chronological Review: 1. User asked: “In BC-Bench, we are using LLM as judge 2 places at least. 1. for code review agent 2. for LMChecklist. Review how are we pinning the AI model used there, and if there are better ways.” 2. BC-Bench inspection found: - Code-review comment matching uses a fixed Copilot CLI model. - LMChecklist scoring is delegated to the external `bc-eval` package. 3. Initial `bc-eval --help` commands hung. The user supplied authoritative source at `C:\depot\BC-LanguageModelTools`, which was then inspected directly. 4. `bc-eval` source confirmed LMChecklist defaults to `gpt-41`, which CAPI resolves to `gpt-41-2025-04-14`. 5. Result schemas were inspected and found not to persist judge-model provenance. 6. Initial recommendation included replacing the code-review subprocess. User explicitly rejected that: “Leave teh code-review Copilot agent subprocess, it is only used for comment matching, should be fine.” 7. User proposed pinning judge models in results and shared `config.yaml`. The shared configuration and result/summary schemas were inspected. 8. An initial richer judge-profile design was proposed. User simplified it: “Not sure if we need properties like profile-version, isn't a model enough? Backend is also not really needed.” 9. Final design converged on a model-only configuration and `judge_model` result field. No implementation has been performed.][Intent Mapping:
[Technical Inventory:
gpt-5.3-codex.@github/copilot@1.0.75.bc-evalscorer usingautoevals.OpenAIScorer.bc-eval[capi]==0.3.14in workflows.gpt-41.gpt-41-2025-04-14.nl2alextensibility-request-implementextensibility-request-triagesrc/bcbench/agent/shared/config.yamlresult.model.judge_modelcurrently exists.dataset/judge_calibration.jsonl.BCBENCH_RUN_JUDGE_CALIBRATION.[Code Archaeology:
src/bcbench/config.pyJudgeConfigcurrently containscode_review_model.JudgeConfig.default()hardcodescode_review_model="gpt-5.3-codex".src/bcbench/evaluate/codereview_judge.py_build_judge_prompt()builds semantic matching prompt._parse_judge_results()parses verdict JSON.judge_expected_and_ignored()combines expected and ignored pairs in one call.judge_verdicts()invokes Copilot CLI withf"--model={model}".src/bcbench/evaluate/codereview.pyjudge_expected_and_ignored(), then buildsCodeReviewResult.src/bcbench/evaluate/codereview_judge_calibration.pysrc/bcbench/commands/evaluate.pyjudge-calibration; its model defaults to_config.judge.code_review_model.src/bcbench/cli_options.pyCopilotModelliteral includesgpt-5.3-codex..github/actions/install-eval-clis/action.yml@github/copilot@1.0.75..github/workflows/copilot-evaluation.yml.github/workflows/claude-evaluation.yml.github/workflows/summarize-results.ymlbc-eval[capi]==0.3.14.bceval metrics calculate --use-capi.JUDGE_MODEL.Created from Copilot CLI via the copilot delegate command.