<?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: Roy Levy</title>
    <description>The latest articles on DEV Community by Roy Levy (@roylevy).</description>
    <link>https://dev.to/roylevy</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%2F4232777%2Fc84c9daf-58a0-42c8-b4e8-47c00e8f37d2.jpeg</url>
      <title>DEV Community: Roy Levy</title>
      <link>https://dev.to/roylevy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/roylevy"/>
    <language>en</language>
    <item>
      <title>I Spent 8 PRs Fixing My AI Fact-Checker. Then I Deleted All 12,852 Lines.</title>
      <dc:creator>Roy Levy</dc:creator>
      <pubDate>Sat, 07 Nov 2026 20:42:59 +0000</pubDate>
      <link>https://dev.to/roylevy/i-spent-8-prs-fixing-my-ai-fact-checker-then-i-deleted-all-12852-lines-a1a</link>
      <guid>https://dev.to/roylevy/i-spent-8-prs-fixing-my-ai-fact-checker-then-i-deleted-all-12852-lines-a1a</guid>
      <description>&lt;p&gt;&lt;em&gt;I asked AI to check AI. It cost more, caught nothing, and broke good articles.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I run a few product sites where AI writes the articles. Power stations, gear, that kind of thing. The articles go straight into the site's Git repo as MDX.&lt;/p&gt;

&lt;p&gt;Product articles have one job. Get the specs right.&lt;/p&gt;

&lt;p&gt;Battery capacity. Number of ports. Charge time. One wrong number and the article is useless. Worse, it's confidently wrong, and readers notice.&lt;/p&gt;

&lt;p&gt;So I did the responsible thing. I added an AI fact check.&lt;/p&gt;

&lt;p&gt;Every article got researched on the web. Every claim got checked against the research. If something didn't match, the check blocked the article or tried to fix it.&lt;/p&gt;

&lt;p&gt;Sounds great, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  Eight PRs of whack-a-mole
&lt;/h2&gt;

&lt;p&gt;It kept blocking good articles.&lt;/p&gt;

&lt;p&gt;I patched it. It found a new way to be wrong. I patched that. It found another one.&lt;/p&gt;

&lt;p&gt;8 PRs in a row. Each one fixing the last false alarm.&lt;/p&gt;

&lt;p&gt;At some point I stopped patching and did what I should have done on day one. I replayed the check over everything I had saved. &lt;strong&gt;1,075 lines from real articles.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt; real errors caught&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8&lt;/strong&gt; false alarms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3&lt;/strong&gt; "auto-fixes" that turned a correct line into a wrong one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read that again. It caught nothing, and it broke more than it fixed.&lt;/p&gt;

&lt;p&gt;And the bill? &lt;strong&gt;61%&lt;/strong&gt; of what the check cost was the web research step. Most of what it found was data already sitting in the product catalog.&lt;/p&gt;

&lt;p&gt;So I was paying one LLM to go find numbers I already had, so a second LLM could compare them with numbers a third LLM had typed.&lt;/p&gt;

&lt;p&gt;That's not quality control.&lt;/p&gt;

&lt;p&gt;That's an expensive game of telephone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop letting the LLM type numbers
&lt;/h2&gt;

&lt;p&gt;The fix wasn't a better checker.&lt;/p&gt;

&lt;p&gt;The fix was taking the numbers away from the LLM.&lt;/p&gt;

&lt;p&gt;Before, the writer produced prose with the numbers baked in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The SOLIX C300 has a 288Wh battery, enough for a laptop and a few phones.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it writes a variable instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The SOLIX C300 has a &amp;lt;Spec item="power-stations/anker-solix-c300" field="specifications.capacityWh" /&amp;gt;Wh
battery, enough for a laptop and a few phones.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The real value gets filled in from the catalog on save, preview, export, and push. The &lt;code&gt;field&lt;/code&gt; is just a path into the item's JSON (every site's catalog looks different, so it has to be flexible).&lt;/p&gt;

&lt;p&gt;The rule is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The catalog is the source of truth. The LLM writes the sentence around it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a number is wrong, it's wrong in exactly one place. Fix it in the catalog, and every article is fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Okay, but what if I check the catalog instead?"
&lt;/h2&gt;

&lt;p&gt;Yes. I tried that too. Smaller scope, same idea: compare each catalog item with the manufacturer's page.&lt;/p&gt;

&lt;p&gt;First live run: 5 products, &lt;strong&gt;$0.85&lt;/strong&gt; (that's &lt;strong&gt;$0.17 per product&lt;/strong&gt;), 10 differences flagged.&lt;/p&gt;

&lt;p&gt;5 were real. I fixed them by hand.&lt;/p&gt;

&lt;p&gt;The other 5:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LFP&lt;/code&gt; vs &lt;code&gt;LiFePO4&lt;/code&gt;. Same battery chemistry, different name.&lt;/li&gt;
&lt;li&gt;A 0–80% fast-charge time compared with a full charge.&lt;/li&gt;
&lt;li&gt;A group of USB-C ports read as one port.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every one of those is fixable with a special case. And I already knew how that story ends. Every special case exposes the next edge case.&lt;/p&gt;

&lt;p&gt;Same trap. Smaller scale.&lt;/p&gt;

&lt;p&gt;I deleted that one too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where an AI check still makes sense
&lt;/h2&gt;

&lt;p&gt;To be fair, this isn't a "never let AI check anything" post.&lt;/p&gt;

&lt;p&gt;The catalog check did find 5 real mistakes. Catalogs that were written fast (especially by AI) are exactly where errors sneak in.&lt;/p&gt;

&lt;p&gt;So if I ever bring it back, it'll be a one-time check when a catalog is first imported. Run it once, show the differences, let a human decide. Not a robot that runs on every article and edits things on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do if you're building something similar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;If a fact exists as data, &lt;strong&gt;insert it&lt;/strong&gt;. Don't ask an LLM to restate it.&lt;/li&gt;
&lt;li&gt;Before you patch a check, &lt;strong&gt;replay it over all your saved data&lt;/strong&gt;. One live failure tells you nothing about the rate.&lt;/li&gt;
&lt;li&gt;Count the cost per catch, not just the cost per run.&lt;/li&gt;
&lt;li&gt;Make deleting a feature an option on the table, not a failure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So, was it worth it?
&lt;/h2&gt;

&lt;p&gt;Here's my honest answer.&lt;/p&gt;

&lt;p&gt;The check made the product &lt;em&gt;feel&lt;/em&gt; safer. The variables made it &lt;em&gt;actually&lt;/em&gt; safer.&lt;/p&gt;

&lt;p&gt;The final diff was &lt;strong&gt;+147 / −12,852&lt;/strong&gt; across 79 files. Less code, lower bills, and the articles got more accurate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't make the AI remember the facts. Make it impossible to get them wrong.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;(All of this happened while building &lt;a href="https://nichepressa.com" rel="noopener noreferrer"&gt;NichePressa&lt;/a&gt;, the engine that writes those articles and commits them to the repo. If you run a Git-based blog, that's what it's for.)&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Where do you draw the line between what the LLM writes and what has to come from data? I'd love to hear how you handle it. Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
