Repository navigation
RFC: judge identity, declared vs. observed (a metadata.openeval.judge convention)
#118
Replies: 1 comment
|
A real record from one tool that stores judge identity, answering question 1, with the caveat that I produced it (the AgentEval maintainer invited the package in AgentEval#203 but has not reviewed it), so it is not an independent implementer's fixture. Source. AgentEval 0.42.0-beta (.NET), read at source commit {
"type": "atomic-llm",
"judge_model": "canned-judge",
"prompt_id": "agenteval.judge.default-system.v1",
"prompt_hash": "ec5f9a4be9894eb7",
"estimated_cost": 0,
"cache_hit": false
}How its fields line up with the proposed keys.
What I take from it.
Not a run of a real judge: the chat client in the sample is canned, so |
Uh oh!
There was an error while loading. Please reload this page.
Comment period: 2026-10-03 to 2026-10-17 (a floor, not a trigger). Per the project's Governance section, a draft reference PR (spec text and a conformance fixture, not for merge) follows this post, and a fresh PR follows consensus.
The question
A suite declares which judge it wants: an
llm_judgegrader hasparams.modelandparams.prompt(required) andprovider,temperature,schema(optional). A ResultSet records what the judge said:GraderResult.score,passed,reason,metadata. Nothing typed records which judge actually answered. Declared and observed can differ: an alias that resolves to a different snapshot, a changed served model, an endpoint swap, a sampling default nobody set.Should EvalPort define a convention for a runner to self-report the judge identity it actually observed, as
metadata.openeval.judgeon theGraderResult, with no schema change and no new validator rule?Where this came from
@jonathanngiroux-star (maintainer of Proofspan, disclosed in his comment) raised it on langchain-ai/langsmith-sdk#3428: a Result that says PASS with score 0.9 is not comparable across tools if the consumer cannot tell which model produced it. @joslat, the AgentEval maintainer, made a related point (his third) on AgentEvalHQ/AgentEval#203: each result carries the judge model, the prompt or rubric identity and the evaluator version, so that two ResultSets can say whether they are comparable at all. I have not verified the papers cited in the first comment and am not relying on them. The argument below does not need them.
What exists
docs/judges.md) describe a working version: each judge is pinned as<model>@sha256:<hash>, where the hash is computed from the provider's model card (the exactGET /v1/models/<id>response body). Before any HTTP judge call the engine compares both the card'sidand the body hash with the pin, and refuses to grade on a mismatch. The verdict is persisted with the exact fingerprint used. Builtin deterministic judges use abuiltin:<id>@<version>fingerprint. The page itself is clear that this is a pin on the served model card, which catches silent re-serving under the same name. It is not a claim that verdicts are reproducible.gen_ai.request.model("the name of the GenAI model a request is being made to") andgen_ai.response.model("the name of the model that generated the response"). They have since moved to a separate semantic-conventions repository, so I am citing the split, not a stability level.metadata.openeval.judge_hardening(Discussion #11) is a runner self-report onGraderResult.metadatathat needed no schema change.Proposal (a convention only)
An optional object
metadata.openeval.judgeon aGraderResultwhose grader is anllm_judge. Every key optional; values are descriptive, not validated.modelparams.model(what was requested).providerfingerprintfingerprint_methodfingerprintwas computed, e.g. "sha256 of the provider model-card body". Without it a fingerprint is not interpretable by anyone else.temperaturetemperature_source"explicit"or"provider_default": whether the producer set it or inherited it.prompt_sha256prompt_basis.prompt_basis"template"or"rendered".observed_at{ "grader_id": "gr_faithfulness", "type": "llm_judge", "score": 0.9, "passed": true, "metadata": { "openeval": { "judge": { "model": "z-ai/glm-5.3", "provider": "integrate.api.nvidia.com", "fingerprint": "z-ai/glm-5.3@sha256:<hash>", "fingerprint_method": "sha256 of GET /v1/models/<id> response body", "temperature": 0, "temperature_source": "explicit", "observed_at": "2026-10-03T12:00:00Z" } } } }Landing it would add one Appendix B row, one Extension Mechanism section modeled on the
judge_hardeningone, and one conformance fixture. No schema, SDK or validator change.What this deliberately does not do
fingerprint_methodmatches. The portable keys aremodel,provider,temperatureandprompt_sha256.exact_matchand friends are deterministic; this is forllm_judge.Alternatives considered
GraderResult.judgefield. Rejected for now. The fingerprint method is the unsettled part, and a typed field would freeze a shape from one implementation. A convention can be promoted to a field later as a MINOR change if several producers converge. The reverse is a breaking change.One thing to settle first
The spec's prose and examples spell reserved keys in the dotted form (
"openeval.judge_hardening": ...,"openeval.aggregation": ...). The SDK converters and the conformance fixtures write them as a nested object ("openeval": { ... }). This proposal uses the nested form. If the dotted form is the intended one, the example above changes; if both are tolerated, the spec should say so. This affects every existingopeneval.*key, not only this one.Questions for commenters
fingerprintplusfingerprint_methodthe right pair, or should there be no fingerprint key at all until two tools agree on one?temperature_sourceexist? It records "the harness didn't set it and the provider default applied", which is the case the original comment cared about, but it asks producers to know it.Evidence status: the Proofspan description is from its published docs, not from a run of it. Nothing here has been implemented against a second tool. A fixture from a real record from any tool that stores judge identity would be the strongest input.
All reactions