There's a common mental model for building a feature: you start at point A (the requirement) and walk a straight line to point B (the finished feature).
AI coding assistants seem to promise exactly that. Describe the feature, let it drive, arrive at B.
That's not how building software actually works, and treating it that way is where things go wrong.
It's a fork, not a line
Every feature is a sequence of decisions, not a path. You start, and almost immediately you hit a fork: approach A or approach B. You pick one and move forward, and a few steps later there's another fork: C or D. This continues, decision after decision, until you reach a point you can call "done."
Each fork is a real architectural choice: how to model the data, where a piece of logic lives, how two components talk to each other, what to make configurable and what to hardcode. None of these choices are forced. Each one has consequences that show up later, sometimes much later.
Consider a seemingly simple requirement: save a user's filter so they can use it again later.
One approach is to build a feature specifically for saving filters. Store the filter criteria, associate them with the user, and retrieve them when needed.
Another approach is to introduce a more general user-preference capability. Today, it stores filters. Tomorrow, it could accommodate other preferences without having to build a separate mechanism for each one.
Both approaches can work. The second might make future development easier, but it also introduces a broader abstraction before you know what those future preferences will look like. The first is simpler today, but it could become limiting if the requirements expand.
This is the architectural decision. Not which approach AI can implement faster, but which tradeoff makes sense for the product and the system.
This is why I don't let an AI assistant drive a complex feature end to end. It might produce working code quickly, but if I simply accept the path it takes, I haven't necessarily made the decisions that matter. I'd arrive at B, but not necessarily a B that I understood or would have chosen.
There's no ideal design, only less bad
Here's the part that took me longer to internalize: there is no ideal software architecture.
"Ideal" only exists on a whiteboard, in a world with no deadlines, no legacy constraints, and no business tradeoffs.
In practice, every design decision is a tradeoff. Your job at each fork isn't to find the perfect answer. It's to pick the option that leaves you with a less bad system than the alternative.
Less bad means being honest about what you know today and what you don't. It means admitting that today's choice might need revisiting, and making that choice in a way that doesn't turn a future change into a rewrite.
At each fork, I ask:
- Does this leave the system easier or harder to change later?
- Am I choosing this because it's right for the business right now, or just because it's familiar?
- If I have to come back and improve this in six months, will that be a reasonable amount of work, or a rewrite?
In the saved-filter example, I wouldn't introduce a general preference system just because there might be other preferences someday. I'd look at the product's direction, existing patterns, and the cost of expanding the feature later.
That mindset only works if you're actually present at each fork, thinking it through.
What AI actually speeds up
This is the distinction I want to make: AI can help you reason through a fork, but it shouldn't silently make consequential decisions on your behalf.
It can suggest alternatives, surface tradeoffs, and challenge your assumptions. What it doesn't automatically know is which tradeoffs matter most for your system, your team, and your business.
In my experience, this is where AI is genuinely useful:
- Fast failure. You pick approach A, let AI scaffold it quickly, and within minutes you can tell if A is a dead end. That used to take an hour of manual work; now it takes a few.
- Exploring a fork cheaply. You can ask AI to sketch both a filter-specific implementation and a general preference model, then compare the approaches concretely instead of reasoning about them in the abstract.
- Execution speed once the decision is made. Once you know the direction, AI can write the boilerplate, tests, and repetitive parts quickly.
For example, I could ask AI to outline both designs for the saved-filter feature. What data would each require? How would retrieval work? What changes if we add another kind of preference?
That gives me something concrete to evaluate. But I'd still need to decide whether the product's actual needs justify the generalization, or whether we're introducing complexity for a hypothetical future.
If I let AI make that call implicitly, by just letting it drive, I'm not skipping a step. I'm outsourcing the one step that actually matters.
The takeaway
Use AI to explore options and move faster between decisions, not to remove the decisions themselves.
Treat every fork in building a feature as a deliberate choice toward a less bad design, not a search for a perfect one.
AI can help you explore the forks quickly. It can even help you think through them. But you still own the choice of which ones are worth taking.
My Other Blogs:
- Code Review in the Age of AI: Is Manual Review Still Enough?
- The New Currency Is Tokens - How to Save AI Tokens
- Personal Agentic AI Assistant - Architecture
- Openclaw Personal AI Assistant Complete Series
- “Skills” in Claude Aren’t About Prompts — They’re About Context Design
- Practical Tips When Working with AI Coding Assistants
- Subagents: The Building Block of Agentic AI
Top comments (0)