Skip to content
All writing
Note Technical

A Slop Filter for Your Own Voice: The Anti-AI-Cliché Linter I Run on Every Auto-Post

AI-written text has tells, so I keep a blocklist of the worst clichés and reject any auto-post that contains one before it can leave in my name.


AI-written text has a smell. Once you’ve read enough of it, you can spot a generated paragraph before you’ve finished the first sentence. It reaches for the same handful of phrases every time: “game-changer,” “delve into,” “in today’s fast-paced world,” “a testament to.” None of those phrases are wrong, exactly. They’re just what a model says when it has nothing to say and has to fill the space anyway. They’re the linguistic equivalent of a stock photo.

That’s a real problem the moment you let a machine post on your behalf. I built a pipeline that announces my writing to social networks without me in the loop — it sizes the caption, picks the time, and sends. The whole point is that I don’t babysit it. But the one thing I can’t allow an unsupervised system to do is quietly start talking like a press release with my name on it. It can schedule. It can size. It does not get to choose the words and have them sound like nobody.

So before any caption is sent, it runs through a filter that rejects the tells of machine-written text. The clichés live on a blocklist, and a caption containing one fails the check instead of going out. The check is exactly as blunt as it sounds:

const SLOP = ['game-changer', 'delve into', "in today's fast-paced world", 'a testament to'];
if (SLOP.some((phrase) => caption.toLowerCase().includes(phrase))) reject(caption);

That’s the entire idea. Lowercase the caption, scan it for any phrase on the list, and refuse to ship if you find one. The same pass catches the other ways an automated caption goes wrong — empty strings, leftover placeholder text, anything over a network’s character limit — but the slop list is the part I care about most, because it’s the only one defending the voice rather than the format.

It’s a blunt instrument, and that’s the feature, not a flaw. A blocklist doesn’t understand tone. It can’t tell good writing from bad. What it can do is catch the specific, repeatable failure mode of generated text, which is that it converges on the same dead phrases over and over. You don’t need a model to police a model here. You need a list and a substring match. If a caption reads like it could’ve been generated by ten thousand other accounts, I’d rather it never leave the building.

A few things I’d tell anyone building their own version. Keep the list short and personal — it should be the phrases that make you wince, not a generic SEO list, because the goal is your voice, not everyone’s. Match on lowercase so casing can’t sneak a phrase past you. Treat a failed check as a hard stop, not a warning, or you’ll learn to ignore it. And grow the list the honest way: every time you catch a clunker in something you almost shipped, add it. The blocklist is a record of your own taste, written down so a script can enforce it at 2 a.m. when you’re asleep.

The deeper point is about where you draw the line with automation. The machine is allowed to do the tedious, easy-to-get-wrong work. It is not allowed to choose the words and make them sound like no one. A blocklist is a cheap, dumb, reliable way to hold that line.

This filter is one small guardrail inside a larger system. If you want the whole thing — how a post publishes and promotes itself on a schedule, in my voice, without me lifting a finger — read how this blog publishes itself.

Share LinkedInXBlueskyReddit