<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[NiriZan Engineering]]></title><description><![CDATA[Technical deep dives into production AI evaluation, judge drift detection, RAG pipeline metrics, and continuous LLM testing by Redwan Rahman.]]></description><link>https://nirizan.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Thu, 22 Oct 2026 17:54:46 GMT</lastBuildDate><atom:link href="https://nirizan.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[The Ruler Can Change Too: Navigating Judge Drift in Production AI Evaluation]]></title><description><![CDATA[Learn how judge drift can cause false AI regressions and how NiriZan uses fixed anchors and statistical gating to identify the real source.]]></description><link>https://nirizan.hashnode.dev/the-ruler-can-change-too-navigating-judge-drift-in-production-ai-evaluation</link><guid isPermaLink="true">https://nirizan.hashnode.dev/the-ruler-can-change-too-navigating-judge-drift-in-production-ai-evaluation</guid><category><![CDATA[ai-evaluation]]></category><category><![CDATA[llm evaluation]]></category><category><![CDATA[LLM as a Judge]]></category><category><![CDATA[RAG triad]]></category><category><![CDATA[Judge Drift]]></category><category><![CDATA[AI reliability]]></category><category><![CDATA[rag-evaluation]]></category><category><![CDATA[RAG ]]></category><category><![CDATA[Retrieval-Augmented Generation]]></category><category><![CDATA[ai-observability]]></category><category><![CDATA[AI infrastructure]]></category><category><![CDATA[Statistical Testing]]></category><category><![CDATA[Machine Learning]]></category><category><![CDATA[NiriZan]]></category><category><![CDATA[llm]]></category><category><![CDATA[Artificial Intelligence]]></category><category><![CDATA[large language models]]></category><category><![CDATA[AI]]></category><category><![CDATA[mlops]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Redwan Rahman]]></dc:creator><pubDate>Mon, 10 Aug 2026 17:52:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a79fe0d217c4d6a590f595a/d0da3152-0cde-4422-b6f1-1964787b3fcf.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2>The Monday Morning Regression</h2>
<p>It is Monday morning. You arrive at your desk to find that production monitoring has flagged a sudden, severe degradation in your core Retrieval-Augmented Generation (RAG) pipeline. The dashboard reports a 15% drop in "Answer Relevance" and "Groundedness" scores, concentrated over the last six hours.</p>
<p>A standard engineering post-mortem begins. You check the deployment logs: no code was pushed over the weekend. You verify the prompts: they are identical to the previous version. You inspect the retrieval corpus: it remains static, with no new documents ingested. From an infrastructure perspective, the system is a bit-for-bit match of the one that was passing all quality gates on Friday.</p>
<p>This creates a crisis of attribution. If the code, the prompts, and the data remain unchanged, why did the scores move?</p>
<p>This is the fundamental challenge of modern AI reliability: <strong>if the system didn't change, did the ruler itself move?</strong></p>
<hr />
<h2>Defining the Silent Variable: Judge Drift</h2>
<p>In current AI infrastructure, we rely heavily on "LLM-as-a-Judge," using high-parameter models to evaluate the outputs of production systems. While scalable, this introduces a secondary source of stochastic uncertainty. The evaluator is not a fixed, deterministic metric like Mean Squared Error. It is a probabilistic model subject to its own internal variance and calibration shifts.</p>
<p>This phenomenon is known as <strong>Judge Drift</strong>. Research by <em>Zheng et al. (2023)</em> documents several biases that can trigger false regressions:</p>
<ul>
<li><p><strong>Position Bias</strong>: The tendency to favor whichever response is presented first in a comparison.</p>
</li>
<li><p><strong>Verbosity Bias</strong>: A systemic preference for longer responses, regardless of their actual factual density.</p>
</li>
<li><p><strong>Self-Enhancement Bias</strong>: The inclination of a model to favor outputs that mirror its own stylistic patterns.</p>
</li>
</ul>
<p>Beyond these inherent biases, we face the <strong>"Third-Party Update" problem</strong>. Most production judges are hosted APIs like GPT-4o, Claude, and Gemini. When a provider silently updates the underlying model or changes internal system prompts, the judge's calibration can shift without announcement.</p>
<p>This is not hypothetical. In April 2025, OpenAI pushed an update to GPT-4o that made it "more proactive and better at guiding conversations." Within days, users reported the model had become overly agreeable, a phenomenon later labeled "sycophancy." OpenAI reverted the update. But for teams using GPT-4o as a judge during that window, their evaluation scores shifted without any change to their own systems. The ruler had changed, and their dashboards couldn't tell them.</p>
<p>As noted by <em>Li (2026)</em> in recent work on <em>anytime-valid inference</em>, these silent updates can render historical score comparisons invalid, turning a stable monitoring system into a source of noise. A rolling Z-test at α = 0.05 can also produce severe false-alarm rates when repeatedly applied to drift-free streams.</p>
<hr />
<h2>Why Existing Tools Fall Short</h2>
<p>Frameworks like DeepEval, RAGAS, and TruLens provide excellent metric computation and baseline comparison. Their recommended approach to judge drift is <strong>preventive</strong>: pin the judge model to a specific version and manually recalibrate when upgrading.</p>
<p>But this doesn't help when a provider <strong>silently updates</strong> the judge behind the API or when you need to know, in real time, whether a regression alert is caused by your system or your ruler.</p>
<hr />
<h2>The Solution: Fixed Anchors + Attribution</h2>
<h3>Fixed Evaluation Anchors</h3>
<p>To solve the attribution problem, I designed NiriZan around <strong>Fixed Evaluation Anchors</strong>. The idea is to decouple system performance from judge behavior using a small, immutable reference set.</p>
<p>While production monitoring typically relies on "reference-free" evaluation, NiriZan supports continuous "reference-based" rescoring. The system maintains an <strong>Anchor Set</strong>, a small, immutable, human-labeled collection of queries paired with "gold" responses.</p>
<p>By continuously re-evaluating the same static data alongside production traffic, NiriZan can observe the "movement" of the judge itself. If the judge begins scoring the immutable Anchor Set differently, NiriZan has a signal that the ruler has changed. This makes it possible to separate measurement error from an actual system regression.</p>
<h3>Introducing NiriZan</h3>
<p><strong>NiriZan</strong> is an open-source framework I built to solve this attribution problem. The name is a fusion of two roots: the Bangla word <em>Nirikkha</em> (নিরীক্ষা), meaning inspection or audit, and the Arabic word <em>Mīzān</em> (ميزان), meaning scale or balance. Together, they represent "Inspection through Measurement."</p>
<p>I built NiriZan on a strict <strong>8-Layer Unidirectional Architecture</strong>. By enforcing a one-way import chain from Layer 1 (Instrumentation) to Layer 8 (Reporting), NiriZan keeps telemetry collection latency-neutral and non-blocking, while isolating the complex statistical work in the upper layers.</p>
<h3>The Core Logic: The Trust &amp; Attribution Layer</h3>
<p>The heart of NiriZan is the <code>AttributionEngine</code>. It simultaneously calculates:</p>
<ul>
<li><p><code>judge_delta</code>: The shift in scores on the fixed Anchor Set</p>
</li>
<li><p><code>system_delta</code>: The shift in production metrics</p>
</li>
</ul>
<p>Critically, NiriZan evaluates <strong>Judge Drift first</strong>. If the judge's scoring criteria have moved past a significance threshold, the engine flags it immediately because a drifting judge makes all subsequent system scores unreliable.</p>
<p>The engine produces an <code>AttributionVerdict</code> based on three-state logic:</p>
<pre><code class="language-json">{
  "NONE": "No significant shift detected in judge or system.",
  "JUDGE_DRIFT": "The evaluator's scoring criteria changed (judge_delta &gt; threshold). Checked first to ensure measurement reliability.",
  "SYSTEM_DRIFT": "The judge is stable, but system performance shifted negatively (system_delta &gt; threshold)."
}
</code></pre>
<p>By isolating these variables, NiriZan prevents teams from wasting engineering cycles "fixing" a RAG pipeline when the actual issue is a silent update to the evaluation model.</p>
<hr />
<h2>Statistical Rigor: Beyond Point-in-Time Averages</h2>
<p>Traditional evaluation tools often rely on naive rolling Z-tests, which can lead to high false-alarm rates when repeatedly applied to streaming data. NiriZan rejects this approach in favor of methods suited for the bounded, non-parametric nature of AI metric scores.</p>
<h3>Mann-Whitney U Test</h3>
<p>Because metric scores are rank-ordered and frequently bimodal, clustering at 0.0 or 1.0, NiriZan uses this non-parametric test to determine if a candidate run is stochastically smaller than a baseline.</p>
<h3>Holm-Bonferroni Correction</h3>
<p>Testing multiple metrics simultaneously inflates family-wise error rates. NiriZan applies this step-down procedure to manage multiple comparisons, ensuring significance thresholds are adjusted for the number of metrics being tested.</p>
<p>I ran NiriZan's statistical gate against synthetic data designed to be as difficult as possible, including tiny batches (just 10 traces per comparison) and noisy scores. Even under those conditions, it kept false alarms to 3.3%, comfortably below the 5% operational constraint, while detecting real regressions 58% of the time.</p>
<p>These numbers come from my open ablation study (<a href="https://github.com/Red1-Rahman/NiriZan/blob/main/experiments/07_evaluation_ablation_and_benchmarking.ipynb">experiments/07</a>), you can rerun the exact same experiment and get the exact same results.</p>
<p>Under a more realistic workload of 30 traces per comparison, which is the workload I use to represent a practical evaluation setting, detection power reached 100% while false alarms remained below 5%.</p>
<hr />
<h2>The Composite Signal: System Health Scoring</h2>
<p>For infrastructure dashboards, NiriZan consolidates these signals into a unified <strong>SystemHealthScore</strong> (0–100). This score is not a raw average; it is a trust-weighted reflection of the pipeline's health.</p>
<p><strong>NiriZan's health score computation</strong> applies specific penalty multipliers based on the attribution verdict:</p>
<ul>
<li><p><strong>JUDGE_DRIFT (0.90 multiplier)</strong>: This is a "trust-tax." The system may be performing adequately, but because the measurement tool itself has become unreliable, the reported quality scores carry less weight. A perfect 100 becomes 90.</p>
</li>
<li><p><strong>SYSTEM_DRIFT (0.80 multiplier)</strong>: This is a genuine regression. It represents a drop in actual system performance and requires immediate engineering intervention. A perfect 100 becomes 80.</p>
</li>
</ul>
<p>This gives AI infrastructure teams a clear, dashboard-ready snapshot that distinguishes between a broken system and a broken ruler.</p>
<hr />
<h2>Conclusion: Moving Toward the Engineering Quality Layer</h2>
<p>I built NiriZan around a simple engineering principle: continuous evaluation is only trustworthy if engineers can distinguish a genuine regression from a change in the ruler.</p>
<p>NiriZan combines immutable anchor sets with statistical gating to provide an attribution layer for production AI systems. The goal is not simply to produce another evaluation score. It is to help engineers understand whether a change in that score reflects a change in the system or a change in the measurement process.</p>
<p>If your team is building production AI systems, you need to know whether your dashboards are measuring your product or your ruler.</p>
<p><strong>NiriZan is open-source and available today:</strong></p>
<ul>
<li><p><strong>Install</strong>: <code>pip install nirizan</code></p>
</li>
<li><p><strong>Star the repo</strong>: <a href="https://github.com/Red1-Rahman/NiriZan">github.com/Red1-Rahman/NiriZan</a></p>
</li>
<li><p><strong>Read the architecture</strong>: <a href="https://github.com/Red1-Rahman/NiriZan/blob/main/docs/architecture.md">docs/architecture.md</a></p>
</li>
<li><p><strong>Try the experiment notebooks</strong>: <a href="https://github.com/Red1-Rahman/NiriZan/tree/main/experiments">experiments/</a></p>
</li>
</ul>
<p>Judge drift isn't a hypothetical edge case. It's a property of the tools you're already using. The question is whether your evaluation infrastructure can detect it before your next Monday morning regression.</p>
<hr />
<h2>References</h2>
<ol>
<li><p>L. Zheng et al., "Judging LLM-as-a-judge with MT-bench and Chatbot Arena," in <em>Advances in Neural Information Processing Systems</em>, vol. 36, pp. 46595–46623, 2023. <a href="https://arxiv.org/abs/2306.05685">arXiv:2306.05685</a></p>
</li>
<li><p>Y. Li, "Who drifted: the system or the judge? Anytime-valid attribution in LLM evaluation pipelines," <em>arXiv preprint</em> arXiv:2606.15474, 2026. <a href="https://arxiv.org/abs/2606.15474">Read the paper →</a></p>
</li>
<li><p>H. B. Mann and D. R. Whitney, "On a test of whether one of two random variables is stochastically larger than the other," <em>Annals of Mathematical Statistics</em>, vol. 18, pp. 50–60, 1947.</p>
</li>
<li><p>S. Holm, "A simple sequentially rejective multiple test procedure," <em>Scandinavian Journal of Statistics</em>, vol. 6, no. 2, pp. 65–70, 1979.</p>
</li>
</ol>
]]></content:encoded></item></channel></rss>