Add cross_model_verifier scorer (grader must differ from the model under evaluation)#4477
Open
blewis-maker wants to merge 1 commit into
Open
Conversation
…der evaluation) model_graded_qa falls back to the model under evaluation when no grader role is bound, so a model can grade its own output. cross_model_verifier enforces actor != verifier: it resolves the verifier with the same precedence as model_graded_qa, then raises (by default) if the verifier resolves to the same model as the actor. Records actor_model / verifier_model / actor_verifier_distinct in score metadata. Reuses _model.py grading/parsing/hardening unchanged. Signed-off-by: Brandan Lewis <lewisgeospatial@gmail.com>
blewis-maker
marked this pull request as ready for review
July 12, 2026 01:53
dragonstyle
requested changes
Jul 15, 2026
dragonstyle
left a comment
Collaborator
There was a problem hiding this comment.
It seems to me that a better way to approach the issue is to require that the user provide the role rather than that the roles be distinct. We have this available in get_model(required=True), but the model graders we have built in don't expose this. I think it would be better to expose this behavior in the existing graders and allow tasks using those graders to require specific roles be defined, if they like. Perhaps model_role_required could be added to the graders and make its way down to the get_model call.
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.
Draft PR
Title: Add
cross_model_verifierscorer (grader must differ from the model under evaluation)Summary
This adds a small model-graded scorer,
cross_model_verifier, that behaves likemodel_graded_qabut guarantees the grader (the verifier) is a different modelfrom the one that produced the answer (the actor). If the two resolve to the
same model it raises by default, so a model never silently grades its own output.
Motivation
model_graded_qa/model_graded_factdefault tomodel_role="grader", but whenno grader role is bound they fall back to the model under evaluation. That makes it
easy to accidentally have a model grade its own output, which tends to be
self-favouring. For governed or third-party evaluations it's often a hard
requirement that the answering model and the grading model are not the same.
Rather than everyone re-implementing that check around
model_graded_qa, this makesactor≠verifier a first-class, enforced property with an audit trail in the score
metadata. (The idea comes from governed multi-agent evaluation, where the actor and
verifier are deliberately kept separate.)
What it does
model_graded_qa(
model>model_role> model under evaluation).state.model).on_same_modelcontrols the same-model case:"error"(default) raises aValueError,"warn"logs and grades anyway,"allow"grades silently.actor_model,verifier_model, andactor_verifier_distinctin thescore metadata so the separation is visible in the eval log.
hardening from
_model.pyunchanged — no forked logic.Usage
Tests
tests/scorer/test_cross_model.pycovers distinct-model grading, thesame-model error / warn paths, the default-role fallback, a bound grader role,
and grade-parse-failure being unscored. All pass locally;
ruffandmypyareclean.
Open question for maintainers
Would you prefer this as a standalone scorer, or as an option on
model_graded_qa(e.g.require_distinct_grader=...)? Happy to refactor towhichever fits the codebase better. I can also add a docs entry if you point me
at the right file.