Part 2 of 4 in the Local AI Code Review series
The first article in this series introduced vet, a command-line tool that uses AI to generate code review issues and then validates each one against a six-question rubric before surfacing it to a developer [1]. That validation step represents a design pattern that appears across a growing range of AI systems. Understanding the pattern is what makes the model selection challenge in Parts 3 and 4 more than a benchmark exercise.
This article covers how the pattern works, why yes-bias is the most common and least obvious failure mode, and what properties to verify before trusting a candidate model.
The Concept Defined
A standard language model interaction is generative: a prompt goes in and the model produces a response. An LLM judge works differently. It receives a structured input comprising two elements, the artifact to evaluate and the criteria by which to evaluate the artifact, and returns a verdict. The output is not speculation, it is a judgment.
The judge is not generating new content. It is discriminating: valid or not, pass or fail, accurate or inaccurate. The distinction matters because the properties that make a model good at generation (fluency, creativity, coherent long-form reasoning) are not the same properties that make it reliable at judgment (consistency, rubric adherence, appropriate skepticism).
The judge can evaluate outputs from a larger model, a smaller model, or the same model class. The size relationship between the generator and the judge is not the relevant variable. What matters is whether the judge’s verdicts are reliable. In vet’s case, the generated code issue is the artifact, the six-question rubric from Part 1 is the criteria, and the verdict is a pass or fail. The pattern is the same regardless of the implementation.
How It Works in Practice
A judge call has three core components: the artifact, the rubric, and the verdict format.
The artifact is whatever is being evaluated. In a code review context, that is a generated issue alongside the diff that prompted it. In other contexts it might be a customer support response, a generated summary, or a piece of information extracted from a document.
The rubric is the set of explicit criteria that define what “valid” means for this particular task. In vet’s case, the rubric includes questions such as: “Is the issue grounded in specific code, rather than in the absence of something?” and “Is the flagged code actually being removed by this diff?” Each criteria targets a concrete failure mode rather than leaving the model to form a general response. A rubric written this way is auditable; any case where the judge returns the wrong answer can be traced back to specific criteria that was misapplied or misunderstood. This pattern of decomposing evaluation into fine-grained per-criterion binary decisions is well-established in LLM judge research, appearing independently in systems such as G-Eval and HD-Eval [2].
The verdict is the judge’s structured output: a boolean per criterion, a score, or a final pass/fail. The key word is structured. A judge that returns free-form language about quality is difficult to integrate into an automated pipeline. A judge that returns a predictable, machine-readable verdict can be wired directly into the system. In a minimal implementation, the output might be as simple as {"valid": true, "criteria": [true, true, false, true, true, false]}, one boolean per rubric question. That structure is what allows a downstream pipeline to act on the verdict without parsing natural language.
It is worth noting that rubric design is a form of engineering in its own right. A vague rubric produces vague, unreliable judgments. A rubric that can be tested against a labeled dataset, where the correct verdict is known in advance, is considerably more trustworthy than one built on intuition about what the model will do.
Why It Matters: Scale and Consistency
The appeal of an LLM judge is scale. Human review of every AI-generated output is impractical when generation runs on every commit, every query, or every customer interaction. A judge enables quality filtering to run automatically at the same speed as generation, without requiring human attention on each individual case.
A judge also applies the rubric consistently. A human reviewer working under time pressure may weight criteria differently from one review to the next. The judge applies exactly the same rubric to every artifact it sees.
Two failure modes carry equal weight. A judge that lets invalid outputs through, producing false positives, erodes trust in the overall system. With enough noise, users stop paying attention to the results. A judge that filters valid outputs, producing false negatives, reduces coverage and undermines the system’s purpose. Both matter, and a well-calibrated judge minimizes both.
It is also worth stating the appropriate scope: a judge is a filter, not a replacement for human judgment at decision points that carry real consequences.
The Yes-Bias Problem
The most common judge failure mode is not inaccuracy on a specific criterion. It is a pervasive tendency to return “pass” regardless of what the model receives. This is called yes-bias, and understanding why it happens is important before evaluating any candidate model.
Language models are trained through a process called reinforcement learning from human feedback (RLHF), which optimizes for outputs that human raters find agreeable and helpful. Research on LLM evaluators identifies this as the root cause of what the field calls self-enhancement bias: a structural tendency to return favorable verdicts regardless of whether the input merits them [2]. A judge role requires the opposite: selective rejection, skepticism toward plausible-looking artifacts, willingness to return “fail” even when the input seems reasonable at first glance. These behaviors run contrary to what RLHF training reinforces.
A yes-biased judge can appear, superficially, to be performing well. If most artifacts it receives happen to be valid, a model that says “pass” to everything will show a high accuracy score. The problem becomes visible only when the dataset is balanced, with roughly equal valid and invalid cases. On a balanced dataset, a yes-biased model scores approximately 50%, identical to random guessing [2]. That is the test that exposes the problem before it enters production.
Yes-bias is also not detectable from general benchmark scores. A model that performs well on reasoning tasks or code generation can still be yes-biased in a judge role on a specific rubric. The only reliable way to check is to run the model against labeled scenarios where the correct answer is “fail,” and observe whether it returns “fail.” In practice, a yes-biased model looks deceptively functional at first: the response format is correct, there are no errors, and verdicts appear considered. The problem only surfaces when the expected answers are checked against the actual output.
The practical implication is direct: checking for yes-bias should be the first step when evaluating a judge candidate, before prompt tuning or system message work. A model that cannot return “fail” on clear negative cases cannot be tuned into a reliable judge. It is worth noting that the opposite failure exists as well: a model that rejects nearly everything regardless of the input. That variant scores equally poorly on a balanced dataset and fails in the same way, just in the other direction. The goal is calibration, not skepticism for its own sake.
What Makes a Reliable Judge
With yes-bias in mind, the properties that distinguish a reliable judge become concrete.
Determinism. At a fixed temperature setting, the same input should produce the same verdict on every call. A judge that returns different answers on identical scenarios introduces noise rather than removing it. Thus, benchmarking becomes unreliable and production behavior becomes unpredictable [2].
Rubric adherence. The model should evaluate against the stated criteria, not drift toward a general impression of quality. A judge that ignores a specific criterion in favor of a holistic “this seems fine” response is not applying the rubric [2].
Appropriate skepticism. The model should return “fail” when criteria are not met, even when the artifact looks plausible. This is the counterweight to yes-bias; a well-calibrated judge neither agrees with everything nor rejects everything.
Bias resistance beyond yes-bias. Yes-bias is the most common failure mode, but research on LLM judge systems identifies several others that are directly relevant to a code review context: length bias, where a model favors verbose issue descriptions regardless of validity; concreteness bias, where specific line numbers or technical terminology cause an issue to pass even when the underlying claim is wrong; and position bias, where verdicts shift based on where content appears within the prompt [2]. A rubric-based judge is partially protected by its structured criteria, but these biases are worth verifying on a sample of known-verdict cases before a candidate is promoted for use.
Context capacity. The judge receives the artifact plus the rubric and supporting context. On long inputs, a small context window risks truncation, which is particularly problematic because it is often silent: the model produces a verdict anyway, based on incomplete information. The practical countermeasures are straightforward; prefer models with a context window sized to the largest expected input, and keep the rubric concise so it does not consume a disproportionate share of available tokens.
All five of these properties are directly testable before deployment, and that is worth emphasizing. A small labeled evaluation dataset, even ten to fifteen representative scenarios with known correct verdicts, provides more reliable signal about judge performance than a general benchmark. Scores on standard capability benchmarks measure abilities that may not correspond to performance on a specific structured rubric in a specific domain. This is the practical entry point for evaluating a judge candidate: build the dataset first, run the candidate against it, and let the results guide every decision that follows.
Testing these properties fits well with my scenario. I have a structured rubric from vet to build a dataset with known answers. The judge candidate can then be validated against the artifact it generates, plus the rubric, and the dataset.
What Comes Next
The LLM judge is a pattern for systematic, scalable quality filtering of AI-generated output. Its reliability depends on a clear and testable rubric, determinism in the model’s responses, and resistance to known pitfalls. Those are the properties that separate a reliable judge from one that merely appears reliable. Understanding them concretely is what makes the model comparison ahead more than a ranking exercise; it shows which properties actually matter when the pattern has to work under real conditions.
Vet’s framework has these properties. The cost described in Part 1 [1], comes in the form of session token limits that make consistent coverage difficult on an active codebase. The question is whether a small, locally-run model can meet the same reliability bar without the per-call token spend.
Part 3 of this series examines the model landscape: what small language models are, why they are a reasonable fit for the judge role, and what properties to look for in the candidates selected for testing.
Stay tuned for the next article: SLMs vs LLMs: Choosing a Model for Judgment Tasks

