
For the past six months I’ve been generating code through Claude Code 6–8 hours a day. Not as an experiment — as my primary work tool. I run 7 custom sub-agents, MCP servers, hooks, persistent memory. I’m not some theorist who read a couple of blog posts and decided to have opinions.
And that’s exactly why I’m saying this: most AI-generated code is technical debt that starts rotting the moment it’s committed.
Not because the models are bad. Because people use them wrong.
”It Works” Is Not Quality
The main trap: you describe a task, get 200 lines of code, run it — works. Tests are green (if you even asked for any). PR gets merged. Everyone’s happy.
Three weeks later you open that file, and you have more questions than answers:
- Why are there three layers of abstraction for writing to a single table?
- Why does the service know about HTTP headers?
- Where did this
catch (Exception $e)come from that silently swallows errors? - Why does the DTO mirror the Entity structure 1:1, and why does it even exist?
The model doesn’t write bad code on purpose. It writes plausible code. Code that statistically resembles what it saw in training data. And the training data is Stack Overflow, GitHub repos with 2 stars, junior-level tutorials, and legacy projects on PHP 5.6.
Plausible ≠ correct. Plausible ≠ maintainable.
Concrete Patterns of Decay
I’m not going to theorize. Here’s what I see in real projects every single week:
1. Phantom Abstractions
The model loves creating interfaces with a single implementation, factories for objects instantiated in one place, and service layers that just proxy repository calls. It does this because “that’s how it’s done” in the code it trained on. But abstraction without reason isn’t architecture — it’s noise.
In a PHP/Symfony project with 15 entities, I counted 47 AI-generated interfaces. The actual need for polymorphism existed in 3 cases.
2. Copy-Paste via Prompt
Humans copy-paste by hand. AI does the same thing, but at scale. You ask for “a similar endpoint for orders,” and you get a full copy of the users endpoint with swapped names. No reuse. No generalization. Just a clone with different variable names.
Six months later you have 30 controllers with identical error handling, validation, and pagination structures — all slightly different. Because each one was generated as an independent request.
3. Silent Degradation
The model really doesn’t like returning errors. It would rather wrap everything in try-catch, log it, and return an empty array. Or null. Or a default value.
In Go it looks even worse: if err != nil { return nil } — and you find out about the problem three call layers deep, when data has already been written to the wrong place.
This isn’t a bug. It’s a pattern: the model optimizes for “code compiles and doesn’t crash,” not for “code correctly reports problems.”
4. Context Amnesia
AI doesn’t remember what it wrote 40 prompts ago. Every new request is a blank slate. You can end up with two services that do the same thing, conflicting validation approaches in different parts of the application, three different ways of handling dates in one project.
In a monolith, a human at least sees the neighboring file. AI only sees what you showed it. And builds in a vacuum.
5. Decorative Tests
Ask AI to write tests — you’ll get tests. Beautiful, well-structured, with mocks and assertions. The problem: they test implementation, not behavior. They’re brittle. They break on any refactor. And they create an illusion of coverage.
I’ve seen a test suite with 94% coverage that didn’t catch a single real business logic error. Every test verified that a method calls another method with the right arguments. In other words, they tested that the code is written the way it’s written. Thanks, very useful.
Why This Is Worse Than Regular Tech Debt
Regular technical debt is taken on consciously. “Let’s do it quick now, we’ll refactor later.” You know exactly where you cut corners. You know what will break.
AI tech debt is hidden. The code looks clean. Naming is fine. Folder structure is textbook. No code reviewer will find fault. But underneath:
- There’s no unified architectural decision — just a collection of locally-optimal fragments
- There’s no understanding of business constraints — only formal correctness
- There’s no trade-off analysis — just “first plausible option”
It’s like a house where every room was designed by a different architect who never talked to the others. Each room is fine. The house as a whole is unlivable.
So, Don’t Use AI?
No. I use Claude Code every day, and my velocity has increased dramatically. But I treat AI code as a draft, not a final result.
My workflow:
- Architectural decisions are mine. I define the structure, the layers, the contracts between modules. AI gets specific, bounded tasks within decisions already made.
- Review every generation. Not “skimmed it” — an actual review. Why this interface? Why three dependencies here? What happens if this service goes down?
- Context is my job. I maintain
CLAUDE.mdfiles with architectural rules for each project. Naming conventions, error handling approaches, banned patterns. Without this, every generation is a lottery. - Refactor immediately. Not “later.” Right after generation — strip unnecessary abstractions, unify with the rest of the codebase, check edge cases.
- AI doesn’t write business logic from scratch. It implements what I’ve already thought through. The difference is between “draw me a house” and “build from this blueprint.”
The Bottom Line
AI code generation is not a silver bullet, and it’s not the end of the profession. It’s a powerful tool that in an engineer’s hands accelerates work, and in a prompt operator’s hands generates technical debt at a speed that was previously physically impossible.
The difference between “I use AI for development” and “AI develops for me” is the difference between a tool and a crutch.
If you can’t explain why every line in the generated code exists — you’re not programming. You’re accumulating debt that someone will have to pay off. Possibly you. In three months. With interest.
15+ years in production. PHP/Symfony, Go, Vue/Nuxt, PostgreSQL. Writing about real-world experience with AI tools in day-to-day development.