惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tor Project blog
V
Visual Studio Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
Jina AI
Jina AI
人人都是产品经理
人人都是产品经理
博客园 - 司徒正美
小众软件
小众软件
I
InfoQ
雷峰网
雷峰网
Recorded Future
Recorded Future
美团技术团队
博客园 - 【当耐特】
C
Check Point Blog
S
Securelist
Stack Overflow Blog
Stack Overflow Blog
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
T
The Exploit Database - CXSecurity.com
宝玉的分享
宝玉的分享
Cyberwarzone
Cyberwarzone
Apple Machine Learning Research
Apple Machine Learning Research
Recent Announcements
Recent Announcements
NISL@THU
NISL@THU
博客园 - 三生石上(FineUI控件)
B
Blog
T
Threat Research - Cisco Blogs
博客园 - 聂微东
www.infosecurity-magazine.com
www.infosecurity-magazine.com
K
Kaspersky official blog
Security Latest
Security Latest
Google DeepMind News
Google DeepMind News
有赞技术团队
有赞技术团队
The Hacker News
The Hacker News
V
V2EX
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Cisco Blogs
IT之家
IT之家
爱范儿
爱范儿
Scott Helme
Scott Helme
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
量子位
The GitHub Blog
The GitHub Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
大猫的无限游戏
大猫的无限游戏
T
Tailwind CSS Blog
T
Tenable Blog
Hugging Face - Blog
Hugging Face - Blog
The Cloudflare Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything BFF模式详解:构建前后端协同的中间层 I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Why We Banned 'Within the Realm of...' From Our AI Game Descriptions
doodoolove · 2026-04-29 · via DEV Community

A small portal's accidental brush with Google's scaled-content-abuse algorithm — and the 11-rule prompt change that fixed it.


TL;DR

We run a 6,800-game HTML5 portal where every game description is generated by GPT-4.1-mini using a prompt that tries to sound editorial. Last week we caught the prompt mid-disaster: 56% of descriptions across our entire corpus opened with the same six words ("What separates casual from committed play..."), 38% used the same skill-tier framing ("Veterans of [genre] recognize..."), and 86% violated our internal jargon budget by stuffing four or more of hitbox, frame-pacing, tick rate, RNG floor into a single page.

A wedding-dress-up game on our site discussed tick-rate. Dress-up games don't have a tick-rate. That's when we knew we'd built a textbook scaled-doorway pattern straight into the GPT prompt — exactly what Google's March 2024 spam-policy update explicitly called out:

"Scaled content abuse is when many pages are generated for the primary purpose of manipulating search rankings... It does not matter if you use generative AI, manual means, or a mix to produce this scaled content."

Our indexing rate was 18.6%. The pattern was both the cause and the diagnostic.

This post is what we found, what we changed, and the verification script we now run in CI to prevent regression.


How a "neutral expert" prompt becomes a doorway pattern

The original prompt was good-faith. We wanted descriptions that read like a reviewer wrote them, not like a marketer. To anchor the model away from generic Adventure-of-a-lifetime copy, we provided positive examples of "neutral-expert voice patterns" the model could draw from. Six of them, including:

  • "Veterans of [X] recognize..."
  • "Serious players of the genre find..."
  • "What separates casual from committed play is..."
  • "A commonly overlooked mechanic..."
  • "The game rewards a counter-intuitive approach..."

We also asked for a tail line Expert Tip: ..., a counter-intuitive truth, and "genre jargon used unapologetically" with examples of hitbox, tick rate, frame-pacing, metagame, RNG floor.

What happened: the model picked the path of least resistance. Each of the six voice patterns is high-quality on its own. But across 6,800 generations, the model converged on a tiny subset. It's the LLM equivalent of giving a student six sample answers and being surprised they only ever quote the first three.

We discovered the problem when we wrote a homogeneity check (more on that below) and learned that 3,797 of our 6,728 entries opened with the same eleven-word sentence. We had effectively templated 56% of our content corpus.


What this looks like to Google

Google's structured-content classifier doesn't need to "understand" voice patterns — n-gram fingerprinting is enough. When 56% of pages on a domain share an opener of >40 characters, that domain pattern-matches with the documented "scaled content" spam category from the March 2024 update. The algorithmic response is documented and predictable:

  1. Google still crawls each page (the URLs are in our sitemap).
  2. Google evaluates the content quality signal at the domain level.
  3. Pages that fingerprint as "templated content" land in "Crawled — currently not indexed" in Search Console.

The 16-million-page IndexCheckr study puts the cross-web indexing average at 37%. We were at 18.6%. GSQI's December 2024 spam-update case studies include a directory site with 140k programmatic URLs at 12% effective indexing rate — same shape, larger scale.

The diagnostic is unambiguous: when Crawled, not indexed dominates your index report and your domain-wide content shares a structural fingerprint, the algorithm has evaluated and rejected your content, not failed to find it.


The 11-rule v3 prompt

We rewrote the system prompt with anti-doorway constraints as first-class. Here's the structure (full prompt is in our open-source repo):

Hard constraints (kept from v2):

  1. No first-person pronouns — write as a critic, not a player.
  2. No em-dashes (we sanitize these but reject if they leak past).
  3. No marketing filler ("amazing", "unbelievable adventure", "dive into", "embark on").
  4. No AI connector words ("In summary", "Furthermore", "It is worth noting").
  5. No invented numbers or personal events ("scored 4,500", "on level 7").
  6. Game name appears max 3 times in 180 words.

Anti-doorway diversity (new in v3):

  1. BANNED OPENING TEMPLATES — the description must NOT begin with: "Within the realm of...", "Within the crowded field of...", "Within the niche of...", "Across the field of...", "Among browser-based...", "In the world of...", or any near-paraphrase of "[Prep] the [realm/field/niche/world] of [genre]".

  2. BANNED VOICE PATTERNS — do NOT use anywhere: "Veterans of [X] recognize...", "Veterans of the genre...", "Serious players of the genre find...", "What separates casual from committed play...", "Players of [X] often discover...". The same ideas may be expressed, but rephrased every time using the game's specific mechanics.

  3. JARGON BUDGET — across the entire description, use AT MOST 2 of: hitbox, tick rate, frame-pacing, metagame, RNG floor, input lag. Default to 0–1. Pick only what is actually visible in the game.

  4. OPENING ANCHOR — the first sentence anchors on something CONCRETE and game-specific (not generic genre framing). Pick one of six modes: (a) Concrete action/mechanic, (b) Visual/scene specifics, (c) Input/control feel, (d) Design-choice observation, (e) Physics/numerical constraint, (f) Contrast/contradiction.

  5. NAME ANCHORING — the game name must appear in the first 80 characters.

Server-side rejection: after generation, we regex-test the output against the banned openings/voices and the jargon-count budget. Any violation is rejected and the generation retried.


What v3 actually produces

A handful of side-by-side examples (real games, real outputs):

Game: urban-echo (parkour runner)

  • v2: "Within the realm of stylized urban runner-platformers, this title positions itself as a deceptively straightforward exercise in rooftop momentum. Veterans of the genre recognize that what separates casual from committed play..."
  • v3: "Sliding under a low-hanging pipe in Urban Echo requires split-second timing that often outweighs raw speed. This browser-based parkour game challenges players to navigate a series of urban rooftops..."

Game: bazooka-survivors (bullet-hell arena)

  • v2: "Among browser-based bullet hell shooters, this title stands out by combining relentless enemy waves with surprisingly deliberate pacing..."
  • v3: "Swarms of enemies press relentlessly in Bazooka Survivors, forcing rapid decisions amid chaotic bullet patterns. This arcade shooter demands not only quick reflexes but also strategic positioning..."

Game: granny-the-game (stealth horror)

  • v2: "Within the claustrophobic confines of a decrepit house, players face a tense stealth challenge that hinges on sound as much as sight..."
  • v3: "Granny: 5-day stealth horror in a creepy house. Find the keys, avoid Granny's hearing radius, escape before sundown. Browser play, no download required."

The v3 outputs share no opening fingerprint across pages of different genres. They mention specific game mechanics (low-hanging pipe, hearing radius, 5-day timer) that the model could only emit by actually engaging with the prompt's reference to the source material.


The verification script (run this in CI)

We open-sourced the homogeneity check. It does five things:

  1. Counts banned-opening hits across the corpus
  2. Counts banned-voice phrase occurrences
  3. Builds a normalized 50-character prefix per entry (strips game name + digits) and reports duplicates
  4. Counts jargon-term overuse per entry (>2 = budget exceeded)
  5. Optional --strict mode that exits 1 if any threshold fails — perfect for CI gates

Sample output on our v2 corpus before the fix:

[1] Banned opening frequency (target: each < 5% of corpus)
  FAIL Within the realm of: 1576 / 6728 (23.42%)
  FAIL Within the crowded field of: 428 / 6728 (6.36%)

[2] Banned voice phrase frequency (target: each < 5%)
  FAIL Veterans of [X] recognize: 2571 (38.21%)
  FAIL What separates casual from committed play: 3804 (56.54%)

[3] Top 12 normalized prefixes:
  (70x | 1.04%) "within the realm of browser puzzle games this titl"
  (56x | 0.83%) "within the realm of browser based games this title"

Enter fullscreen mode Exit fullscreen mode

Same script on the v3 entries we've migrated:

--strict: PASSED

Enter fullscreen mode Exit fullscreen mode

There's a subtle lesson in step 3 of that script. When we first wrote it, the prefix-uniqueness test fired a false positive on small samples — every prefix in an 11-entry test set hit 1/11 = 9.09%, which our naïve threshold flagged as failure. The fix is to require actual duplication (count >= 2) before any percentage threshold matters. Single occurrence is unique by definition. We learned this on a real CI failure that wasted ~$2 of API calls — not catastrophic, but a nice reminder that homogeneity checks need to distinguish "same prefix" from "small sample size".


What this hasn't fixed yet (honesty section)

The v3 prompt is correct. But only a small fraction of our 6,820-entry corpus has been migrated as of writing. We're running batched migration via GitHub Actions (~$0.30 per 100-slug batch). At our current cadence we'll hit 50% v3 coverage in about three weeks.

Why not all-at-once? Two reasons:

  • Cost: ~$30 to redo the whole corpus + es/pt/fr translations. Manageable, but not casual.
  • Risk: a single all-at-once rewrite means a single deploy where the entire site's content changes. If the v3 prompt has any latent issue we haven't found, it would ship to all 6,820 pages simultaneously. Batched migration gives us four daily checkpoints to verify the v3 corpus's homogeneity score before committing to the next batch.

We're also not naïvely expecting a linear recovery. Google's domain-level quality assessment is built from the pages it has crawled. To shift the assessment, we need to change enough of the corpus that the next time Google re-evaluates the domain, the n-gram fingerprint has measurably moved. The literature suggests 4–8 weeks after the corpus reaches >50% v3 before the indexing rate visibly responds.


What we'd do differently

Bake banned patterns into the prompt from day one, not as positive examples. The mistake we made was thinking "giving the model six varied voice patterns will produce variety". The model doesn't pick uniformly from six options across 6,800 generations — it picks the easiest one. The fix is to prevent high-frequency openers, not to suggest alternatives.

Treat the homogeneity check as a CI gate, not a post-hoc audit. If we'd had this in place at v2, we would have caught the 56% same-opener rate after generation #500, not after #6,728. Cheap dollars vs expensive ones.

Don't trust LLM "creativity" claims. The v2 prompt was 480 words long and produced a 56%-identical opener. The v3 prompt is 730 words long, with 11 explicit constraints. Most of those constraints are negative ("don't do X"). LLMs need negative space defined; positive examples are not enough.


Read more

If your portal or content site uses an LLM-driven descriptions pipeline, run a homogeneity check on your corpus today. Three minutes. If it passes, great. If it fails the way ours did, you have a working diagnosis before the next core update.

The site this lesson came from: DooDoo.Love — a free HTML5 browser games portal with 6,800+ titles.


About the author: Steuber Alberto is the editor at DooDoo.Love. Reach me at support@doodoo.love.