<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Wibo</title>
    <description>The latest articles on DEV Community by Wibo (@aiarch_wibo).</description>
    <link>https://dev.to/aiarch_wibo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4057989%2F4963ffce-f5b2-4832-adc3-ad80d73eede6.png</url>
      <title>DEV Community: Wibo</title>
      <link>https://dev.to/aiarch_wibo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aiarch_wibo"/>
    <language>en</language>
    <item>
      <title>How to evaluate an LLM agent: evals, golden sets, and LLM-as-judge</title>
      <dc:creator>Wibo</dc:creator>
      <pubDate>Sat, 01 Aug 2026 13:59:25 +0000</pubDate>
      <link>https://dev.to/aiarch_wibo/how-to-evaluate-an-llm-agent-evals-golden-sets-and-llm-as-judge-1e2g</link>
      <guid>https://dev.to/aiarch_wibo/how-to-evaluate-an-llm-agent-evals-golden-sets-and-llm-as-judge-1e2g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Short answer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can't unit-test an LLM to correctness, because the same input can take a different path on the next run.&lt;/strong&gt; Evals are the test suite for probabilistic systems: a scored, repeatable check of whether the system reached an acceptable outcome across runs, not whether it returned one exact string once.&lt;/p&gt;

&lt;p&gt;The core toolkit is small: a curated golden set of input-to-expected-outcome examples, an offline run of that set in CI plus online checks against live traffic, and the right scorer for each task — assertion, golden set, LLM-as-judge, or human review. Wire it into CI as a regression gate and a quality drop fails the build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why evals, not unit tests
&lt;/h2&gt;

&lt;p&gt;A unit test asserts that a deterministic function returns one exact value. An LLM is not deterministic: temperature, model updates, and the model's own sampling mean the same prompt can produce different — and differently worded — outputs across runs. Pinning to a single expected string makes a test that either flakes or asserts nothing useful.&lt;/p&gt;

&lt;p&gt;Evals replace that assertion with a different question: did the system reach an acceptable outcome, across multiple runs, at an acceptable rate? That reframes testing as a measurement problem. You score outputs against a target, aggregate over a set, and track the score over time. It is closer to an SLO with an error budget than to a pass/fail unit test, and it is the discipline that lets you change a prompt or swap a model without flying blind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Golden sets
&lt;/h2&gt;

&lt;p&gt;A golden set (also called a reference or eval set) is a curated collection of input-to-expected-outcome examples. Each row pairs an input the system will actually see with the outcome you consider correct or acceptable — sometimes an exact answer, more often a rubric or a set of properties the answer must satisfy.&lt;/p&gt;

&lt;p&gt;The most valuable golden sets are not invented up front; they are grown from real failures. Every production bug, every escaped edge case, every "the model did something weird here" becomes a new row. Over time the set encodes the actual shape of your traffic and your hardest cases, so a passing eval run means something concrete. Keep the set version-controlled, keep it representative rather than merely large, and treat adding a case after an incident as part of the fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Offline vs online
&lt;/h2&gt;

&lt;p&gt;Offline evaluation runs your system against a fixed golden set, usually in CI, before anything ships. It is repeatable, comparable across changes, and cheap to run on every commit. Its limit is that it only measures the cases you thought to include.&lt;/p&gt;

&lt;p&gt;Online evaluation measures behavior against live traffic and real outcomes after release — sampling production runs, scoring them, and watching real signals such as task completion, user corrections, or downstream success. It catches the distribution shift and the inputs your golden set never anticipated. Offline tells you a change is safe to ship; online tells you it actually worked. You need both, and online failures are the best source of new offline cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  LLM-as-judge (and its pitfalls)
&lt;/h2&gt;

&lt;p&gt;For subjective qualities — is this summary faithful, is this tone right, did the answer address the question — there is often no exact string to match against. LLM-as-judge uses a model to score the output against a rubric. It scales grading that would otherwise need a human on every row, and for many tasks it correlates well enough with human judgment to be useful.&lt;/p&gt;

&lt;p&gt;It is also a component with real failure modes, and you should treat the judge as something you must itself evaluate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Position bias:&lt;/strong&gt; in pairwise comparisons the judge can favor whichever answer it sees first, regardless of quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verbosity bias:&lt;/strong&gt; longer, more confident-sounding answers tend to score higher even when they are not better.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inconsistency:&lt;/strong&gt; the judge is itself probabilistic, so the same pair can score differently across runs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gameable:&lt;/strong&gt; outputs can be optimized to please the judge rather than the user, and a self-judging model can flatter its own style.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The mitigation is to validate the judge against a sample of human-labeled data before you trust it, measure how well its scores agree with those labels, and re-check that agreement when you change the judge model or its rubric. A judge you have not validated is an unscored assumption, not a measurement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evals as regression gates
&lt;/h2&gt;

&lt;p&gt;An eval suite earns its keep when it runs automatically. Wire the offline golden-set run into CI so a change that regresses quality below a threshold fails the build, the same way a failing unit test or a dropped coverage number blocks a merge. That turns "we think this prompt change is better" into a measured claim, and it stops silent quality regressions from shipping when someone edits a prompt, upgrades a model, or refactors the harness.&lt;/p&gt;

&lt;p&gt;One discipline matters more than the rest: pick the metric that reflects task success or outcome correctness, not just string similarity. Two answers can be worded completely differently and both be right; an exact-match score would fail a correct answer and a similarity score can pass a fluent wrong one. Score what you actually care about — did it do the job — and let the gate enforce that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing an eval approach
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Eval approach&lt;/th&gt;
&lt;th&gt;What it measures&lt;/th&gt;
&lt;th&gt;Use when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Assertion / code checks&lt;/td&gt;
&lt;td&gt;Hard, objective properties: valid JSON, required fields present, value in range, no banned content&lt;/td&gt;
&lt;td&gt;The output has a checkable structure or invariant; cheapest and most reliable, so reach for it first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Golden set&lt;/td&gt;
&lt;td&gt;Outcome correctness against curated input-to-expected examples, aggregated across the set&lt;/td&gt;
&lt;td&gt;You have known-good answers or rubrics and want a repeatable score you can gate CI on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LLM-as-judge&lt;/td&gt;
&lt;td&gt;Subjective quality — faithfulness, tone, relevance — scored by a model against a rubric&lt;/td&gt;
&lt;td&gt;There is no exact answer to match and you need to scale grading; only after validating the judge against human labels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human review&lt;/td&gt;
&lt;td&gt;Ground truth and nuanced judgment; the reference everything else is calibrated against&lt;/td&gt;
&lt;td&gt;Stakes are high, the task is ambiguous, or you are validating a judge or building the golden set&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Evals before scale&lt;/strong&gt; &lt;br&gt;
 Build the eval harness before you scale usage, not after. Without it you have no way to tell whether a prompt change, a model upgrade, or a new tool made things better or worse — you are shipping on vibes. The team that can answer "did quality go up or down, and by how much" is the team that can iterate safely; the one that can't will eventually regress in production and not know why. Eval design is also the single strongest signal in hiring that a person has actually shipped with LLMs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  As-built: how we evaluate the coach on aiarch.dev
&lt;/h2&gt;

&lt;p&gt;This page has just recommended wiring evals into CI and validating your judge against human labels. We do neither. Here is what actually gates a coach change on aiarch.dev, including both places it falls short of the advice above.&lt;/p&gt;

&lt;p&gt;Two tiers. &lt;code&gt;npm run eval&lt;/code&gt; scores the golden set against a mocked model — cheap, local, run on every coach change. Above it sits a live gate: real calls, scored for the behaviours that matter here (fading hints instead of revealing answers, naming the misconception, escalating after two stalled turns), and it has to clear 80% before a coach prompt or a deploy ships. It runs up to three times and takes the majority, exiting early once two runs pass. The coach is probabilistic even where the scoring isn't, so a verdict read off a single sample is noise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is no CI.&lt;/strong&gt; No &lt;code&gt;.github/workflows/&lt;/code&gt; in the repo, and &lt;code&gt;git push&lt;/code&gt; deploys nothing — shipping is a deliberate &lt;code&gt;wrangler deploy&lt;/code&gt;, with the gates as commands a human runs first. That is a gap, not a design choice. It is also why the offline tier has to stay fast: a gate you run beats a gate you describe.&lt;/p&gt;

&lt;p&gt;The second gap is sharper. The live gate scores every reply against a rubric. &lt;strong&gt;No model reads it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The scoring is deterministic assertions — eleven regexes over the coach's text, four that check which tools the turn actually called (did it fetch the lesson context, did it grade something the learner never attempted), two length floors, a &lt;code&gt;stop_reason&lt;/code&gt; check. The harness is candid about the limits of that in its own comments: two of the checks are annotated as "necessary-but-not-sufficient evidence", naming a human or an LLM judge as the thing that &lt;em&gt;would&lt;/em&gt; confirm real tutoring quality. So 80% measures observable adherence, against a threshold we chose rather than one calibrated against human labels. It catches regressions. It does not certify quality, and reading it as though it did is the mistake the section above warns about. See &lt;a href="https://aiarch.dev/patterns/eval-harness-gate" rel="noopener noreferrer"&gt;the eval-gate pattern&lt;/a&gt; for how it slots into the release pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources &amp;amp; provenance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Course material: aiArch Track B (eval design) — golden sets, offline vs online, judges, and CI gates.&lt;/li&gt;
&lt;li&gt;Eval design guidance: Anthropic's docs on &lt;a href="https://platform.claude.com/docs/en/agents-and-tools/tool-use/overview" rel="noopener noreferrer"&gt;building and evaluating tool-using agents&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Anthropic — platform docs on evaluation (designing and running evals).&lt;/li&gt;
&lt;li&gt;The limitations of LLM-as-judge (position bias, verbosity bias, inconsistency, gameability, and the need to validate against human labels) are widely documented in the evaluation literature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a conceptual overview; no specific benchmarks or figures are claimed, and API shapes change — verify against current provider docs before implementing. Corrections: &lt;a href="mailto:hello@aiarch.dev"&gt;hello@aiarch.dev&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://aiarch.dev/llm-evaluation-guide" rel="noopener noreferrer"&gt;aiarch.dev/llm-evaluation-guide&lt;/a&gt;, where it is kept up to date.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Want the skeleton instead of the essay? &lt;a href="https://github.com/sofus-nl/aiarch-templates" rel="noopener noreferrer"&gt;&lt;code&gt;aiarch-templates&lt;/code&gt;&lt;/a&gt; has the &lt;code&gt;src/lib/&lt;/code&gt; seams, a threshold-gated eval stub and a cost-model skeleton. It is deliberately empty — it fixes the shape and you write the implementation. Apache-2.0.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
      <category>llm</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
