<?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: FX-LgLL</title>
    <description>The latest articles on DEV Community by FX-LgLL (@montydrief).</description>
    <link>https://dev.to/montydrief</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%2F4093945%2F96c0f467-7f7c-4f5c-a971-041ca4ade958.jpeg</url>
      <title>DEV Community: FX-LgLL</title>
      <link>https://dev.to/montydrief</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/montydrief"/>
    <language>en</language>
    <item>
      <title>Free Unlimited Web Search for AI Agents</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Wed, 02 Sep 2026 18:59:51 +0000</pubDate>
      <link>https://dev.to/montydrief/free-unlimited-web-search-for-ai-agents-1p56</link>
      <guid>https://dev.to/montydrief/free-unlimited-web-search-for-ai-agents-1p56</guid>
      <description>&lt;p&gt;AI agents need access to the web.&lt;/p&gt;

&lt;p&gt;The problem is that web search APIs can be expensive, limited, or complicated to integrate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SIMURG Search&lt;/strong&gt; gives AI agents a simple way to access web search for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SIMURG?
&lt;/h2&gt;

&lt;p&gt;SIMURG is an open-source protection layer for LLMs.&lt;/p&gt;

&lt;p&gt;It monitors model generation and detects when the output starts going wrong, such as repetition loops, language drift, garbage output, or other decoding failures. When corruption is detected, SIMURG can stop the generation and retry it before the bad output reaches the user.&lt;/p&gt;

&lt;p&gt;SIMURG also includes a web search layer that allows agents to retrieve real information from the internet and use it for grounding before answering.&lt;/p&gt;

&lt;h2&gt;
  
  
  SIMURG Search
&lt;/h2&gt;

&lt;p&gt;With SIMURG Search, your AI agent can search the web, retrieve sources, and use the results to verify information instead of relying only on the model's memory.&lt;/p&gt;

&lt;p&gt;It is designed to be simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;simurg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can use the built-in web search directly from your agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use it?
&lt;/h2&gt;

&lt;p&gt;Free web search for AI agents&lt;/p&gt;

&lt;p&gt;Open source&lt;/p&gt;

&lt;p&gt;Simple installation&lt;/p&gt;

&lt;p&gt;Real-time web information&lt;/p&gt;

&lt;p&gt;Useful for local, quantized and self-hosted models&lt;/p&gt;

&lt;p&gt;SIMURG combines generation protection with web grounding, giving AI agents a simple way to become more reliable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Started
&lt;/h2&gt;

&lt;p&gt;Install SIMURG:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;simurg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitHub repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your AI agent needs web access without adding another complicated infrastructure layer, give SIMURG Search a try.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>automation</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I found a completely free web search for AI agents.</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Sat, 29 Aug 2026 19:21:02 +0000</pubDate>
      <link>https://dev.to/montydrief/i-found-a-completely-free-web-search-for-ai-agents-5an4</link>
      <guid>https://dev.to/montydrief/i-found-a-completely-free-web-search-for-ai-agents-5an4</guid>
      <description>&lt;p&gt;A week ago my agent confidently described a treaty that does not exist. It even had a date.&lt;/p&gt;

&lt;p&gt;The fix is simple: before the model commits to an answer, make it check the web. &lt;br&gt;
I contributed this to SIMURG&lt;br&gt;
(&lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;) and it just shipped as v1.0.3.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free means free
&lt;/h2&gt;

&lt;p&gt;SIMURG web search is a web layer for AI agents powered by TinyFish. 30&lt;br&gt;
requests per minute, $0, no card, no wallet. The package ships a bundled free&lt;br&gt;
key, so it works out of the box:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install simurg
python3 -m simurg.websearch "when was the Y2K bug" --json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  The part I care about: ground()
&lt;/h2&gt;

&lt;p&gt;Search results are context. Verdicts are decisions:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from simurg import websearch
check = websearch.ground("Y2K bug")
# check["verdict"]: "attested" | "thin" | "no_record"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;attested: feed check["evidence"] into your model's context. thin: treat with&lt;br&gt;
caution. no_record: the subject is probably fabricated, abstain instead of&lt;br&gt;
asserting.&lt;/p&gt;

&lt;p&gt;One honest detail: "Zorbachian treaty of 1874" returns real 1874 treaties from&lt;br&gt;
any search engine. So ground() requires the subject itself to be echoed in the&lt;br&gt;
evidence, generic hits downgrade to thin.&lt;/p&gt;

&lt;p&gt;Stdlib only, zero new dependencies, and it degrades instead of crashing. In&lt;br&gt;
our internal checks on factual prompts, hallucinations dropped to the 1-5%&lt;br&gt;
range.&lt;/p&gt;

&lt;p&gt;Code, examples and a 13 page paper: &lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your agent an internet. It costs nothing.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I almost killed all GLM 5.3 Flash 2 bit hallucinations, with SIMURG</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Fri, 28 Aug 2026 13:53:32 +0000</pubDate>
      <link>https://dev.to/montydrief/i-almost-killed-all-glm-53-flash-2-bit-hallucinations-with-simurg-c9m</link>
      <guid>https://dev.to/montydrief/i-almost-killed-all-glm-53-flash-2-bit-hallucinations-with-simurg-c9m</guid>
      <description>&lt;p&gt;I ran a little experiment tonight and I have to share it, because the result honestly surprised me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I connected our &lt;strong&gt;GLM 5.3 Flash in 2 bit&lt;/strong&gt; to SIMURG. If you have played with heavily quantized models you know the tradeoff. They are fast and cheap, but 2 bit hurts, and this one hallucinated a lot. Confident wrong dates, made up people, numbers that came out of nowhere. Exactly the kind of thing that looks perfectly fluent and is just false.&lt;/p&gt;

&lt;p&gt;So I plugged it into &lt;strong&gt;SIMURG Monolith&lt;/strong&gt; and started using it like a normal user.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happened
&lt;/h2&gt;

&lt;p&gt;Here is the fun part. I did not retrain anything offline. I just asked questions, and when the model made something up I hit dislike, and when it was right I hit like.&lt;/p&gt;

&lt;p&gt;SIMURG learns in real time. The serving loop is the training loop, so every thumbs up or thumbs down is one training step. After a fairly short session, the guard was already flagging the fabrications the model kept producing, and abstaining instead of letting them through.&lt;/p&gt;

&lt;p&gt;It was not magic and I am not going to claim 100 percent. But watching a 2 bit model go from hallucinating freely to almost silent on the bad answers, live, with nothing but my own feedback, was a genuinely cool thing to witness.&lt;/p&gt;

&lt;h2&gt;
  
  
  What SIMURG is, in short
&lt;/h2&gt;

&lt;p&gt;SIMURG is an LLM hallucination guard. It does a few things at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reads the model's own token probabilities to spot facts the model is unsure about&lt;/li&gt;
&lt;li&gt;grounds claims against real sources (Wikipedia and the web), so it catches both made up subjects and wrong details on real ones&lt;/li&gt;
&lt;li&gt;abstains instead of confidently lying when a claim cannot be trusted&lt;/li&gt;
&lt;li&gt;and the big one, it &lt;strong&gt;learns in real time&lt;/strong&gt; from your like and dislike feedback, so it adapts to your model and your traffic on the fly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is it for? You put it in front of any OpenAI compatible endpoint, wire your existing like and dislike buttons to it, and it starts catching your model's specific failure modes right away. No batch retraining, no separate judge model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;&lt;br&gt;
or&lt;br&gt;
pip install simurg&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>machinelearning</category>
      <category>api</category>
    </item>
    <item>
      <title>GLM-5.3-Flash is a total blast when you kill its hallucinations</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Thu, 27 Aug 2026 08:38:32 +0000</pubDate>
      <link>https://dev.to/montydrief/glm-53-flash-is-a-total-blast-when-you-kill-its-hallucinations-5a6</link>
      <guid>https://dev.to/montydrief/glm-53-flash-is-a-total-blast-when-you-kill-its-hallucinations-5a6</guid>
      <description>&lt;p&gt;So as you all know, GLM 5.3 Flash dropped yesterday and it is a super model. I am running it at 2 bit quant and it is really doing its thing. &lt;/p&gt;

&lt;p&gt;But as you know, quantization kills quality, and this one is extra fun because the model was pretrainsed mostly on Chinese, so it sometimes just starts writing code or chatting with me in Chinese out of nowhere. You are mid conversation and suddenly you get a sentence of Mandarin in the middle of your Python.&lt;/p&gt;

&lt;p&gt;Anyway, SIMURG came out the day before yesterday so I decided to give it a shot. The cool part is that I configured it for exactly the hallucination type I needed: the model switching to Chinese mid response. I hooked it up to my API through the layer and now I always get clean perfect output, no more random language switches. Honestly the model feels like it is on par with Fable 5 in my daily use once the hallucinations are gone.&lt;/p&gt;

&lt;p&gt;If you are running GLM at low bit rates, this one is worth it.&lt;br&gt;
repo: &lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;&lt;br&gt;
pypi: &lt;a href="https://pypi.org/project/simurg/" rel="noopener noreferrer"&gt;https://pypi.org/project/simurg/&lt;/a&gt;&lt;br&gt;
install: pip install simurg&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>llm</category>
    </item>
    <item>
      <title>I just killed hallucinations on my 2 bit Qwen3.8 27B</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Wed, 26 Aug 2026 13:41:00 +0000</pubDate>
      <link>https://dev.to/montydrief/i-just-killed-hallucinations-on-my-2-bit-qwen38-27b-1hj1</link>
      <guid>https://dev.to/montydrief/i-just-killed-hallucinations-on-my-2-bit-qwen38-27b-1hj1</guid>
      <description>&lt;p&gt;Yesterday tried out a small tool called SIMURG. It sits in front of an OpenAI-compatible endpoint and monitors the generation. If it detects that the model is going off the rails, it stops the request and retries it. Hallucinations mostly, and right now i have really consumer GPU RTX 3060&lt;/p&gt;

&lt;p&gt;I tested it with Qwen3.8 27B running a 2-bit quant on an RTX 3060. The model is surprisingly capable for its size, but at 2-bit I was getting quite a few hallucinations and made-up facts and actually bad, i mean not bad, and not so good due to hallucinations because of Chinese symbols and so on.&lt;/p&gt;

&lt;p&gt;So just used SIMURG, the responses have been noticeably more consistent so far. It's still early and I'm testing how well it holds up across different prompts, but the difference is pretty noticeable on this particular setup and actually not bad i trained this tool on my type of hallucination when model starts to do shitty tool calls and leaks its own tool call style so yep and simurg just aborting it and end user never sees hallucination and btw this is machine learning model that contains 15 parameters.&lt;/p&gt;

&lt;p&gt;You can install it if you want:&lt;/p&gt;

&lt;p&gt;pip install simurg&lt;br&gt;
Or link it's open-sourced: &lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>news</category>
      <category>programming</category>
    </item>
    <item>
      <title>Five detectors, one bad merge: why our LLM corruption guard flagged 43% of healthy output</title>
      <dc:creator>FX-LgLL</dc:creator>
      <pubDate>Tue, 25 Aug 2026 10:31:54 +0000</pubDate>
      <link>https://dev.to/montydrief/five-detectors-one-bad-merge-why-our-llm-corruption-guard-flagged-43-of-healthy-output-59ph</link>
      <guid>https://dev.to/montydrief/five-detectors-one-bad-merge-why-our-llm-corruption-guard-flagged-43-of-healthy-output-59ph</guid>
      <description>&lt;p&gt;We run a self-hosted ~300B reasoning model in production. It writes macroeconomic desk reports in Azerbaijani and English.&lt;/p&gt;

&lt;p&gt;Every so often, it stops.&lt;/p&gt;

&lt;p&gt;Not crashes. Not refuses. Mid-sentence, a competent economic analysis turns into a fabricated Chinese news article. Or a software README, complete with &lt;code&gt;pip install&lt;/code&gt; instructions. Or a Persian name, repeated seven times. Or a wall of spreadsheet cells starting with &lt;code&gt;#REF!&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The user is watching this happen, token by token.&lt;/p&gt;

&lt;p&gt;We call this decoding corruption*, and it is not hallucination. Hallucination is the model being wrong about the world. This is the model no longer producing an answer at all. There is a large literature on detecting the first one. There is almost nothing on the second, which is strange, because anyone who operates a self-hosted model has seen it.&lt;/p&gt;

&lt;p&gt;This post is about what we learned building a detector for it. The headline lesson is not the one I expected going in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why post-hoc detection is useless here
&lt;/h2&gt;

&lt;p&gt;Most hallucination detectors run after generation completes. For factuality that is fine. For this, it is not.&lt;/p&gt;

&lt;p&gt;Two reasons. First, streaming: the user already watched the model derail. A verdict that arrives after the fact has failed. Second, cost: on a reasoning model, one corrupt generation burns minutes of GPU time. We measured a 13,200-character table echo that took 269 seconds to generate to completion. Every one of those seconds was wasted.&lt;/p&gt;

&lt;p&gt;So the detector has to run inside the stream, cheap enough to be invisible next to decoding.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design
&lt;/h2&gt;

&lt;p&gt;One pass over the character stream. A single state object ingests one character at a time and incrementally maintains every statistic anything downstream will need. Detectors are stateless reads over that shared state, evaluated only at checkpoints.&lt;/p&gt;

&lt;p&gt;That constraint matters more than it sounds. It means adding a sixth detector costs zero additional passes. Everything is O(1) amortized per character with bounded memory, so a runaway generation is processed in constant space.&lt;/p&gt;

&lt;p&gt;Five detectors sit on top:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rules.&lt;/strong&gt; Deterministic thresholds on the snapshot. Digit fraction, symbol density, longest identical-character run. Ships day-one protection with zero training, and every alarm carries a human-readable reason like &lt;code&gt;numeric dump digit_frac=0.57&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Character n-gram surprise.&lt;/strong&gt; An online n-gram model trained on the stream's own clean prefix, scoring each incoming character's surprise before observing it. No pretraining, no access to the generator's logits. The stream explains itself. The signature is nice: repetition loops collapse surprise toward zero, while drift and regurgitation spike it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Count-Min Sketch repetition.&lt;/strong&gt; Character shingles counted in a 4×2048 sketch. Constant memory regardless of stream length. Reads the repeat rate, because a real loop hammers many shingles, not one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rolling SimHash.&lt;/strong&gt; A 64-bit fingerprint over a sliding word window, compared against the fingerprint frozen at the end of the clean prefix. This is the one that catches the hardest class: fluent, same-script regurgitation that is invisible to character statistics but lands ~0.5 normalized Hamming away in fingerprint space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Character entropy.&lt;/strong&gt; Table dumps and degenerate loops flatten the distribution.&lt;/p&gt;

&lt;p&gt;All five read from one state. Throughput is ~50,000 characters per second on a single CPU core, two to three orders of magnitude faster than the model produces text. No GPU anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I got wrong
&lt;/h2&gt;

&lt;p&gt;Detection was never the bottleneck. Every configuration I tried caught every corrupt stream. TPR 1.000, immediately, without effort.&lt;/p&gt;

&lt;p&gt;The entire difficulty was in &lt;strong&gt;not&lt;/strong&gt; flagging clean text.&lt;/p&gt;

&lt;p&gt;Our clean text is economic prose dense with figures, percentages, variable codes and markdown tables. It is, statistically, the most corruption-looking legitimate text you could ask for.&lt;/p&gt;

&lt;p&gt;I started with noisy-OR fusion. It is the textbook rule for combining independent evidence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p = 1 - Π(1 - sᵢ)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It produced a &lt;strong&gt;42.9% false positive rate on clean production text.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think about what that means operationally. Four out of every ten healthy desk reports killed and regenerated. Completely unusable.&lt;/p&gt;

&lt;p&gt;Here is why it happens. Legitimate prose mildly excites several detectors at once. A digit-dense sentence nudges the rules tier. A formulaic passage nudges compressibility. A section header nudges the sketch. None of them is alarmed. But noisy-OR multiplies survival probabilities, so five detectors at 0.3 each produce a confident 0.83.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real corruption does not look like five weak signals. It looks like one or two saturated signals.&lt;/strong&gt; A cross-lingual drift does not gently raise five statistics; it slams the foreign-script fraction to the ceiling while the others barely move.&lt;/p&gt;

&lt;p&gt;So we replaced the combination rule with strongest-signal dominance plus a small corroboration bonus when two or more detectors independently cross 0.5:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;p = min(1, max(max(sᵢ), w·ℓ) + b·[#{i : sᵢ ≥ 0.5} ≥ 2])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same five detectors. Same data. Same protocol.&lt;/p&gt;

&lt;p&gt;FPR dropped from 0.429 to 0.024.&lt;/p&gt;

&lt;p&gt;Then per-detector fixes took it to 0.000:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SimHash was firing on legitimate subtopic wandering&lt;/strong&gt; in long reports. Fix: cap its contribution at 0.60, below the abort threshold. It can accuse, but never convict alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The surprise model's low-surprise fraction was firing on fluent formulaic prose.&lt;/strong&gt; Fix: gate it behind the repetition tracker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The sketch's max-count was firing on a recurring section header.&lt;/strong&gt; Fix: score on rate, not max count.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The lesson generalizes past our system: if you are building a multi-signal guard over stylistically varied text, your combination rule is probably a bigger deal than your detector roster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things that only production teaches you
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Thresholds obvious in the abstract were wrong.&lt;/strong&gt; I set the hard digit-fraction rule at 0.18, which felt generous. Real quantitative answers sustain digit fractions near 0.3. Moved it to 0.28. Separately, a markdown horizontal rule is twenty-plus identical characters, which tripped the run detector on every document with a &lt;code&gt;---&lt;/code&gt; in it. Separator characters are now excluded.&lt;/p&gt;

&lt;p&gt;Both fixes came from replaying the guard over the real corpus. I would argue that step is non-optional for any detector you intend to deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aborting is an integration hazard.&lt;/strong&gt; We implement abort as an exception raised from inside the token sink. The first version tripped the HTTP circuit breaker, because the transport layer read an abort as an upstream failure. Three catches would have taken the entire assistant offline. The transport has to treat it as caller-side cancellation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zero leak
&lt;/h2&gt;

&lt;p&gt;The protocol has three phases. During &lt;strong&gt;hold&lt;/strong&gt;, the first 350 characters are buffered and inspected, and nothing is forwarded. A corrupt verdict here kills the request with zero characters leaked. This matters because corrupt-from-the-start is the dominant production mode. On a clean verdict, the buffer flushes, the self-calibrated baselines freeze, and the stream goes live with rechecks every 400 characters and two-hit hysteresis before aborting.&lt;/p&gt;

&lt;p&gt;The cost is a one-time ~350-character delay before the first visible token, roughly a second at typical decode speeds. That is the trade: one second of latency against never showing a user a corrupted answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Calibrating the threshold instead of guessing it
&lt;/h2&gt;

&lt;p&gt;Setting the abort threshold by hand felt wrong, so we use split-conformal calibration. Take the final fused scores of n held-out clean streams, and set τ to the ⌈(1−α)(n+1)⌉-th smallest. That guarantees &lt;code&gt;Pr[flag | clean] ≤ α&lt;/code&gt; in finite samples under exchangeability.&lt;/p&gt;

&lt;p&gt;The practical payoff: the operator's false-alarm budget α becomes the only meaningful knob in the system. You say "I will tolerate 2% false aborts" and the threshold follows.&lt;/p&gt;

&lt;h2&gt;
  
  
  An unplanned finding
&lt;/h2&gt;

&lt;p&gt;We ran the finished guard backwards over 121 historical messages in the deployment's database, expecting a clean sweep as a sanity check.&lt;/p&gt;

&lt;p&gt;It raised exactly two flags. Both were real corruptions that had shipped to users months earlier and nobody noticed: one desk report written entirely in Chinese, and one English answer that derailed into Chinese plus Python code and stopped mid-fragment.&lt;/p&gt;

&lt;p&gt;Zero false alarms on the other 119.&lt;/p&gt;

&lt;p&gt;So it is also an audit tool, which was not the plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;p&gt;Corruption that stays fluent, same-script, same-topic and statistically unremarkable is invisible to this. Subtly wrong but well-formed analysis needs grounding or factuality methods, and we handle that separately upstream.&lt;/p&gt;

&lt;p&gt;Our positives are synthetic, generated by injecting the four corruption classes into clean text at controlled onsets. They are modeled on real derails and they catch every real historical case we have, but production traffic at scale may hold surface forms we have not modeled.&lt;/p&gt;

&lt;p&gt;And the perfect scores are a statement about class separation, not difficulty. The observed corruption classes sit far from the clean manifold. I fully expect adversarially subtle corruption, like a slow drift below checkpoint resolution, to erode those margins.&lt;/p&gt;

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

&lt;p&gt;The detector, the benchmark generator and the trained weights are open source: &lt;strong&gt;&lt;a href="https://github.com/doofzoff/SIMURG" rel="noopener noreferrer"&gt;https://github.com/doofzoff/SIMURG&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The detector registry takes a three-line protocol — a name, an &lt;code&gt;evaluate(state)&lt;/code&gt; that returns a score, and a set of reasons. You can add a detector without touching the sentinel, and the fusion layer picks up whatever is registered. If you are running a non-Latin-script deployment, the expected-script priors need flipping and I would genuinely like help with that.&lt;/p&gt;

&lt;p&gt;If you self-host a model and have watched it derail: what did yours do? I am collecting failure modes, and the taxonomy has four classes right now but I do not believe that is the complete list.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
