Complexity Without Comprehension
“Vibe coding” allows engineers to build impressive cathedrals in the wrong location with unprecedented speed.
AI helps developers build complex systems without forcing them to understand the problem domain deeply first. Traditional development’s slow pace was a forcing function for understanding. You’d hit walls, get frustrated, simplify. AI lets you bulldoze past those walls without learning why they existed.
Humans can learn plenty fast about a problem domain when forced to. The problem is AI removes the forcing function to learn entirely.
The Missing Filter
Traditional development had unavoidable chokepoints:
Hitting a complexity wall forced you to understand the problem better.
Inability to implement a feature forced you to question its necessity.
Unmaintainable code forced you to simplify the architecture.
Degrading performance forced you to understand resource constraints.
These weren’t just slowdowns; they were filters that killed bad ideas before they became real code. You literally couldn’t proceed without either understanding the problem deeply or abandoning the approach. AI removes the natural selection pressure that kept bad code from your codebase.
Balancing Speed and Understanding
How can we have our cake and eat it too?
Use AI for the parts you already understand deeply, not for exploration. When you are exploring, the friction is the teacher. Remove it, and you learn nothing.
The challenge lies in distinguishing between what you understand deeply and what requires exploration—a skill many lack. The Dunning-Kruger effect exists precisely because people struggle to accurately assess their own understanding.
The Concrete Test
Before using AI on any component, force yourself to:
Explain the problem to someone non-technical.
Predict what will break.
Describe the failure modes.
If you cannot do these things before the code exists, you are exploring, not implementing. Use different tools for exploration.
Effective exploration looks like:
Paper prototypes
Throwaway spike solutions (truly throwaway, not “we’ll refactor later”)
Building the “dumbest” possible version (no vibe coding)
Talking to users before writing any code
These create friction that generates understanding. AI is an accelerant. Accelerants applied to exploration create expensive mistakes faster.
Force Multiplier vs. Knowledge Substitute
The AI development framework that works for me is simple: use AI as a force multiplier, not a knowledge substitute.
Force Multiplier: “I understand OAuth flows and have implemented them manually before. AI helps me generate the boilerplate faster.”
Knowledge Substitute: “I need authentication, so I’ll let AI figure out what pattern to use.”
Learn first, then build. AI makes the building trivial, but it doesn’t make the learning optional. Skip the learning, and you’ll wake up maintaining an impressive cathedral that nobody needed, built on land you don’t own, solving problems that don’t exist.
