qalarc.com / projects / glm-word-filter
GLM Word-Filter Research & Anti-Scrape Toolkit
Our production classifier was silently failing on 31% of calls — rejected by an undocumented content filter on a Chinese LLM API, on exactly the content a moderation system needs to see. We reverse-engineered the filter with ~4,000 controlled probes, extracted a 560-term verified blocklist that exists nowhere publicly, and built both the fix (failures 31%→0%) and defensive tooling on top.
The problem
Our forum-analysis platform (chanalyse) classifies online discussion threads through a commercial Chinese LLM API. Roughly a third of calls on politically noisy boards were dying with HTTP 400 · code 1301 — "unsafe or sensitive content" — with zero documentation of what trips it. This is a fundamental trap for anyone building moderation tooling: the system that exists to analyze difficult content is precisely the system prevented from receiving it. We had three questions: what exactly triggers the filter, can the blocked calls be recovered, and is there anything useful in knowing the answer?
The investigation
We treated the filter as a black box and probed it scientifically over two days, ~4,000 controlled API calls on a dedicated key. Three techniques did the work: carrier-sentence probing (one candidate term at a time, appended to an innocent weather sentence — isolating what blocks by itself); bisection (taking genuinely blocked real prompts, splitting them into windows, recursively bisecting to the exact minimal substring, then proving causality by removing it); and combination controls (pairing individually-harmless terms to test whether the filter reasons about meaning rather than strings). Candidates came from a locally-hosted Zhipu-trained model recalling filter vocabulary across ~40 categories, from 20 public wordbanks, and from mechanical mining of our own blocked prompts.
What it showed
The filter is not what almost anyone would guess. It is a string list, not a meaning detector: remove one specific substring and an otherwise-identical blocked prompt sails through. It is narrowly political: 550+ English slurs, profanity, religious and sexual terms were all tested — zero blocked; every verified blocker sits in the China-political domain. Some entries are phrase-level only — the individual words pass, the exact three-word collocation blocks. And 71% of verified blockers turned out to be extensions of a shorter root (560 verified terms decompose into just 162 minimal roots) — the signature of raw substring matching. When we compared the verified set against every public Chinese filter wordlist we could find (~250K entries across 20 lists), their union covered 5.4%: 530 of our verified blockers appear in no public list anywhere.
Why it's interesting
First, the dataset itself is novel — the only publicly-available, empirically-verified window into what a commercial Chinese LLM provider actually blocks, measured rather than rumoured. Second, it corrects popular assumptions: the widely-circulated advice to embed profanity lists as "AI-repellent" is measurably useless against this class of provider, while the actual trigger vocabulary is completely different from what censorship-research lists (e.g. Citizen Lab's WeChat measurements) would predict — it behaves like a consumer-chat moderation bank, not a political censor. Third, the structure itself (roots + substring matching + drift over days) tells you how these systems are engineered: simple, brittle, and rotatable.
How it can help
- If you build against filtered APIs: the wire-swap technique (replace trigger strings with typed placeholders in-flight, storage stays raw) rescued our hardest blocked threads and took classifier failures from 31% to 0% — with a local unfiltered model as backstop for filter drift.
- If you own content being scraped: the verified vocabulary is poison text for non-consensual AI pipelines. Our companion dataset-tarpit serves a freshly-composed, dedup-defeating PDF of trigger-laden prose on every invalid lookup — plus hit-logging that tells you exactly who is ingesting you.
- If you research censorship or moderation: the full probe/bisect/verify toolchain is in the repo and reproduces this analysis against any provider in an afternoon.
Everything is open: github.com/qalarc/glm-word-filter (research, dataset, tooling) · github.com/qalarc/dataset-tarpit (defensive serving layer).
Capabilities
560 empirically verified filter triggers
162 minimal roots + 398 extensions decomposition
Bisection isolator for exact trigger substrings
Production swap map + local-GLM backstop
20 public wordlists compared (5.4% coverage)
Full reproduction toolchain
Unique poison PDF per request (dedup-proof)
Local-GLM paragraph bank across 12 genres
CJK-capable composer, subset per document
Hit logging for scraper analytics
nginx/Caddy 404-handler or Cloudflare Worker deploy
Bait-mode + catchall-mode
Tags
Status: live · First built: 2026-08-31 · Last updated: 2026-08-31