<?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: jamil fayad</title>
    <description>The latest articles on DEV Community by jamil fayad (@jamil_fayad).</description>
    <link>https://dev.to/jamil_fayad</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%2F4179340%2F9e7f4016-8e46-47a2-8960-8a02d23552a5.jpeg</url>
      <title>DEV Community: jamil fayad</title>
      <link>https://dev.to/jamil_fayad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jamil_fayad"/>
    <language>en</language>
    <item>
      <title>I built a prompt pipeline that grades itself with an independent AI judge, not its own output</title>
      <dc:creator>jamil fayad</dc:creator>
      <pubDate>Mon, 12 Oct 2026 12:45:04 +0000</pubDate>
      <link>https://dev.to/jamil_fayad/i-built-a-prompt-pipeline-that-grades-itself-with-an-independent-ai-judge-not-its-own-output-3chn</link>
      <guid>https://dev.to/jamil_fayad/i-built-a-prompt-pipeline-that-grades-itself-with-an-independent-ai-judge-not-its-own-output-3chn</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Most prompt-engineering setups either hope the model complies with formatting/compliance requirements, or let the same model that generated the output also score it. Both fail quietly. I wanted a pipeline that catches that before a human ever sees the result.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Two failure modes show up constantly in LLM-generated content: the model "forgets" to include a required section (compliance language, a caveat, a citation), and when you ask the same model to grade its own output, it's a biased judge of its own work — it rates its own mistakes more charitably than an independent reviewer would.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;A sequential pipeline: &lt;strong&gt;user input → MCP-grounded research → DSPy reasoning/generation → deterministic validation → independent evaluation → optional closed-loop verification.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MCP Research Module&lt;/strong&gt; — injects live domain knowledge into context before generation starts, instead of relying on the model's frozen training data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DSPy.ai&lt;/strong&gt; for the actual reasoning/generation step — declarative, optimizable prompt pipelines instead of hand-tuned prompt strings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic QA Linter&lt;/strong&gt; — a rule-based hard gate (zero LLM calls) that catches placeholder gaps, duplicated sections, contradictions, and fabricated citations before anything reaches evaluation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independent Evaluation&lt;/strong&gt; via DeepEval/G-Eval — an external judge model scores the output, specifically to avoid the model grading its own work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterative Enhancer&lt;/strong&gt; — generate → critique → refine, with a bounded iteration budget and early-stopping once quality targets are hit, so it doesn't loop forever chasing marginal gains&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-provider routing&lt;/strong&gt; across OpenAI, Anthropic, Mistral, Qwen, Cerebras, OpenRouter, Groq, and Gemini with priority-fallback, so a single provider outage doesn't take the pipeline down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;215 offline tests run with zero API keys required, and the whole thing ships through GitLab CI/CD with SAST, secret detection, bandit, and pip-audit scanning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key design decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Deterministic gate before the AI judge, not instead of it:&lt;/strong&gt; cheap, fast, zero-cost checks (duplication, placeholders, missing required sections) get caught by a linter before spending an API call on evaluation. The expensive independent-judge step only runs on output that already passed the free checks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External judge over self-scoring:&lt;/strong&gt; explicitly rejected having the generator model rate its own output — avoids the obvious bias problem, at the cost of an extra model call per evaluation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bounded iteration, not infinite refinement:&lt;/strong&gt; the critique→refine loop has a hard budget and early-stopping. Early versions without this would occasionally chase diminishing returns on borderline outputs.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;Expanding the enterprise-safeguard sections (the linter currently enforces Security &amp;amp; Compliance, Scalability &amp;amp; Observability, and Governance &amp;amp; Audit blocks on production-bound prompts) and tightening the closed-loop verification trigger conditions.&lt;/p&gt;

&lt;p&gt;Portfolio: &lt;a href="https://jamilfayad.com" rel="noopener noreferrer"&gt;jamilfayad.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>mcp</category>
      <category>agents</category>
    </item>
  </channel>
</rss>
