Why Your AI Agent Still Writes GPT-2 Code (And Why It's Not Hallucinating)

I run a lot of agents. SENTRY, my incident responder, triages production alerts through MCP and stops at a human gate before any rollback. Every day I watch these agents generate code, and every day I see the same pattern: they reach for GPT-2-era snippets when there are six generations of better options sitting right there.
Ask any frontier coding agent — Claude Code, Cursor, Codex — to write you an ML training loop and you'll get this:
tokenizer = AutoTokenizer.from_pretrained("gpt2")
model = AutoModelForCausalLM.from_pretrained("gpt2")The first instinct is to blame hallucination. It's not. The model isn't making things up. It's doing exactly what it was trained to do — and that's what makes this so hard to fix.
The Core Problem: Frequency ≠ Correctness
Models don't learn what's correct or current. They learn what's statistically dominant in training data.
Between 2019 and 2023, the internet was drowning in GPT-2 and GPT-NeoX content. Every Colab notebook, every Hugging Face tutorial, every Stack Overflow answer, every Medium blog post — all demonstrating the same snippets. By raw token count, these patterns dominate every frontier model trained since.
ACM research backs this up: models trained on biased code favoring older methods actively neglect newer, more secure mechanisms. The model learned GPT-2 because GPT-2 was everywhere. The internet said "this is how you do it" a billion times, and the model listened.
Four years of GPT-2 tutorial token weight exceeds one year of Qwen3 tutorial token weight, even with a late-2025 cutoff. "Wait for the next model release" is not the fix. This is a data density problem, not a knowledge cutoff problem.
Five Ways This Bites You in Production
1. Ghost Dependencies
Agents generate pinned versions that are years old:
torch==2.2.0 # from January 2024
transformers==4.26.1 # from 2023Dependency files were copy-pasted across millions of repos, so the model reproduces them faithfully. Beginners install cleanly, then hit walls three layers deep when API signatures changed or CUDA wheels mismatch. The errors point nowhere near the real cause.
2. Wrong Device Placement
device = "cuda" if torch.cuda.is_available() else "cpu"Fine for a quick test script. Bad for anything production. This ignores Apple Silicon, Intel GPUs, and NPUs entirely. On a Mac Mini, it silently falls back to CPU. The modern fix is accelerate from Hugging Face, which handles device mapping across XPU/NPU/GPU, DDP/FSDP, offloading, and checkpointing — all in one call.
3. Decorative Code as "Clean Code"
Models scatter ASCII section banners (# =====, # ── TEXT ──) through generated code. They absorbed this from enterprise codebases and license headers and decided it means "organized." It doesn't. Real clean code comes from good naming, type annotations, small logical functions, and docstrings. A file needing section markers is a file that should be refactored into modules. In heavy scripts, you burn 15-20% of tokens on decorative text art.
4. Reflexive AdamW
Every generated training loop contains:
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.01)Three problems:
- Memory: two optimizer state tensors per parameter. For a 7B model in float32, that's roughly 56GB before gradients or activations.
- Not neutral: designed for transformer NLP specifically. Assumptions don't transfer to SSMs, CNNs, or novel architectures.
- Frontier has moved: production labs dropped it. Muon trains Moonlight (16B MoE) at ~52% of the training FLOPs of AdamW counterparts. Kimi K2 uses MuonClip. Alternatives like Adam-mini cut memory in half. GaLore uses low-rank gradient projection. Schedule-Free Adam eliminates the LR scheduler entirely.
Keller Jordan, Muon's creator, has a sharp observation: most "beats AdamW" papers fail due to badly tuned AdamW baselines. The real baseline nobody beats is a well-tuned one.
5. Overriding Your Explicit Instructions
This one is the scariest. You spell out an exact repo ID:
Qwen/Qwen3-VL-8B-InstructThe agent silently substitutes Qwen2.5 or adds a comment claiming the model doesn't exist yet. Ask for Llama 4, get Llama 3.1 IDs. A 2026 paper measured 25-38% deprecated API usage across eight Python libraries. Even when given correct info in the prompt, adoption was only ~75%. With full documentation, it rises to ~93% — but executable rates stay at ~66%.
This is parametric priors fighting provided evidence. The model's training data "knows" Qwen2.5 exists as a real, documented thing. Qwen3-VL-8B-Instruct is newer and hasn't accumulated the same token weight. So under generative pressure, the model falls back to what it's seen a billion times.
The silent swap is dangerous: the code looks structurally correct and runs, but you're training or inferring an entirely different model than you specified.
What to Do About It
Immediate: SKILL.md Files
The most practical defense right now is skill files. Put your modern baselines in a CLAUDE.md or AGENTS.md and force every agent session to read it. This pushes correct patterns into the system prompt and overrides the parametric prior. It's a patch, not a fix — but it works today.
Immediate: Verify Everything
Before trusting any from_pretrained() call from a vibe-coded ML project:
- Check the model ID on Hugging Face — especially for models released in the last 14 months, multimodal/reasoning variants, and version-number changes
- Pin your dependencies with current versions, not what the model suggests
- Use
device_map="auto"instead of manual CUDA/CPU checks - Replace AdamW with task-appropriate optimizers
Long-Term: Fix the Training Data
The self-reinforcing failure loop is real: someone gets bad AI code, doesn't catch it, publishes it, and the next model picks it up. The cycle repeats.
The fix isn't better prompts or bigger context windows. It's data quality at training time. Specifically, filling pre-training corpora with human reasoning about why patterns are wrong — not just correct answers. GitHub Issues, Reddit threads on r/LocalLLaMA, debugging Stack Overflow posts, analysis pieces that explain failure modes. Unresolved debugging threads teach models what problems exist, what triggers them, and what diagnosis looks like.
This builds anti-pattern recognition before generation, and compounds as a habit rather than an instruction.
The Modern Baseline
If your agent is still generating GPT-2-era code, here's what the minimum acceptable baseline looks like in 2026:
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_id = "Qwen/Qwen3-VL-8B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto"
)
messages = [{"role": "user", "content": "She has really beautiful eyes."}]
text = tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
inputs = tokenizer([text], return_tensors="pt").to(model.device)
with torch.no_grad():
output = model.generate(**inputs, max_new_tokens=256)
print(tokenizer.decode(output[0], skip_special_tokens=True))Current gold-standard families: Qwen2.5/Qwen3/Qwen3-VL, GLM, MiniMax, Kimi. The Qwen3 tokenizer alone has a 150K+ vocab, handles code, math, and non-English text far beyond GPT-2's first-generation BPE.
The Bottom Line
The code isn't hallucinated. It's inherited. That is what makes it scary.
Every time you let an agent generate ML code without verification, you're trusting patterns that dominated the internet between 2019 and 2023. Not patterns that are correct. Not patterns that are current. Patterns that were most common.
Fix this by verifying every dependency pin, device setup, optimizer choice, and repo ID in vibe-coded ML projects. And if you want to help future models: write clear public reasoning about why patterns fail. That teaches more than another correct-answer tutorial ever will.
Frequently asked questions
What is LLM frequency bias?
Frequency bias is when a language model defaults to patterns that were statistically dominant in its training data, even when those patterns are outdated or incorrect. Between 2019-2023, GPT-2 and GPT-NeoX tutorials flooded the internet, and every frontier model trained since inherited those patterns as defaults.
Why doesn't the model use the latest code patterns?
Models learn what's statistically dominant, not what's correct or current. Four years of GPT-2 tutorial token weight exceeds one year of Qwen3 tutorial token weight, even with a late-2025 knowledge cutoff. It's a data density problem, not a knowledge cutoff problem.
How do I fix outdated AI-generated code?
Verify every dependency pin, device setup, optimizer choice, and model ID in AI-generated ML code. Use SKILL.md or CLAUDE.md files to enforce modern baselines at inference time. Replace GPT-2 defaults with current gold-standard families like Qwen3, GLM, or Kimi.
Is AI-generated code hallucinated?
No — and that's what makes frequency bias dangerous. The code isn't made up. It's faithfully reproduced from patterns that dominated training data between 2019-2023. The model is doing exactly what it was trained to do, which happens to be wrong for modern use cases.