<?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: DeadY2J</title>
    <description>The latest articles on DEV Community by DeadY2J (@deady2j).</description>
    <link>https://dev.to/deady2j</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%2F4215577%2Fdb567b9d-4eff-4cd0-8dec-609a9f518a45.png</url>
      <title>DEV Community: DeadY2J</title>
      <link>https://dev.to/deady2j</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deady2j"/>
    <language>en</language>
    <item>
      <title>How I stopped an LLM from inventing facts in my daily YouTube Shorts</title>
      <dc:creator>DeadY2J</dc:creator>
      <pubDate>Thu, 29 Oct 2026 15:09:50 +0000</pubDate>
      <link>https://dev.to/deady2j/how-i-stopped-an-llm-from-inventing-facts-in-my-daily-youtube-shorts-28cg</link>
      <guid>https://dev.to/deady2j/how-i-stopped-an-llm-from-inventing-facts-in-my-daily-youtube-shorts-28cg</guid>
      <description>&lt;p&gt;I run a channel that publishes one Short every day, unattended. The first version let the LLM write the script from a topic. It worked until it didn't: it slipped in numbers that weren't in my notes and presented rumours as facts. On a channel about facts, that is the one thing you can't afford.&lt;/p&gt;

&lt;p&gt;So I flipped the design. &lt;strong&gt;I write the verified facts once (with sources). The AI only turns them into a script, and the script has to pass guards written in plain code.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The guards
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Number whitelist.&lt;/strong&gt; Every number in the script must appear in the facts (plus a few allowed ones, like a countdown). Anything else is rejected and the model retries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repetition check.&lt;/strong&gt; Repeated n-grams and repeated ideas across recent videos are rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rumour labelling.&lt;/strong&gt; Facts prefixed with &lt;code&gt;RUMOR:&lt;/code&gt; must be presented as rumours, or the script is rejected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A second pass at temperature 0&lt;/strong&gt; that lists claims not supported by the facts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A facts-only fallback.&lt;/strong&gt; If the model keeps failing, the video is built straight from the facts. It is less punchy, but it is always correct.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What a reader taught me
&lt;/h2&gt;

&lt;p&gt;After I shared it, a reader pointed out the weak spot: guard #4 is another LLM call, so it is the only check that code doesn't verify, and the number whitelist can't see sentences without numbers (which are exactly the ones models invent most).&lt;/p&gt;

&lt;p&gt;His suggestion, which I'm tracking as &lt;a href="https://github.com/DeadY2J/factreel/issues/11" rel="noopener noreferrer"&gt;an issue&lt;/a&gt;: make the model cite, for every sentence, the index of the fact it comes from, and check in code that the sentence's numbers appear in &lt;em&gt;that&lt;/em&gt; fact. The index says where to look; the numeric check proves the sentence agrees with it. Each guard reinforces the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallbacks everywhere
&lt;/h2&gt;

&lt;p&gt;Same philosophy for the rest of the pipeline: voice (Edge TTS, then ElevenLabs, Cloudflare, offline system voice) and images (Cloudflare FLUX, NVIDIA, your own generator, archive, procedural gradient) each have a chain, so one service being down never stops the channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / help
&lt;/h2&gt;

&lt;p&gt;It is open source (MIT, Python + FFmpeg), runs with zero API keys, and I built it with a lot of AI assistance, so design feedback is very welcome.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/DeadY2J/factreel" rel="noopener noreferrer"&gt;https://github.com/DeadY2J/factreel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install factreel&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Good first issues (new language packs, a JSON validator, local TTS): &lt;a href="https://github.com/DeadY2J/factreel/issues" rel="noopener noreferrer"&gt;https://github.com/DeadY2J/factreel/issues&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>opensource</category>
      <category>ffmpeg</category>
    </item>
  </channel>
</rss>
