There was a time when the difficult part of building software was writing the software.
Today, that is increasingly not true.
We have better frameworks, better libraries, better APIs, better cloud infrastructure, better developer tools, and now AI can generate a significant amount of the code for us.
Yet I keep seeing the same pattern:
We are getting better at building things, but not necessarily better at deciding what should be built.
And I think that is becoming one of the biggest engineering problems of our time.
Software Has Become Too Easy to Start
Think about what it takes to build an application today.
You can generate a frontend in minutes.
Connect an API.
Add authentication.
Add a database.
Deploy it.
Add an AI model.
Give the model access to tools.
Add an agent.
Add another service.
Add monitoring.
Add a queue.
Add a vector database.
Add an orchestration framework.
Before long, you have a surprisingly sophisticated architecture.
And sometimes you have solved a problem that didn't actually require any of it.
This is the paradox of modern software development:
The cheaper it becomes to build software, the easier it becomes to build unnecessary software.
AI Made This Problem Bigger
AI has changed the equation even further.
Previously, I might have spent several hours implementing a feature.
Today, I can describe the feature and have an AI coding assistant generate much of the implementation.
That is incredibly useful.
But it also removes an important friction.
When building something required significant effort, effort itself acted as a filter.
You naturally asked:
"Is this worth building?"
When implementation becomes cheap, that question becomes easier to ignore.
You can simply build it.
And then build another version.
And then add another feature.
And then add an agent because the agent framework looks interesting.
The cost of implementation falls.
But the cost of complexity does not disappear.
Every Feature Creates a Future Problem
A feature rarely costs only what it takes to build it.
It also creates:
- code to maintain
- bugs to investigate
- dependencies to update
- documentation to maintain
- edge cases to handle
- users to support
- security concerns
- performance considerations
- monitoring requirements
- decisions future developers need to understand
This is why a 30-minute feature can sometimes create a six-month maintenance problem.
The original implementation was cheap.
The system became expensive.
This is particularly dangerous with AI-generated code because the initial implementation can feel almost free.
You ask for a feature.
The code appears.
It works.
You move on.
Six months later, someone has to understand why seventeen components depend on it.
Complexity Is a Technical Debt You Can See Too Late
Developers are generally good at recognizing obvious technical debt.
Poor naming.
Duplicated code.
Missing tests.
Outdated dependencies.
Large functions.
But there is another type of technical debt that is harder to recognize:
unnecessary architecture.
You can have beautifully written code inside an unnecessarily complicated system.
You can have excellent abstractions that nobody needed.
You can have perfectly implemented microservices where a single application would have been enough.
You can have an impressive AI agent where a deterministic workflow would have been safer.
The individual components can all be technically correct.
The overall system can still be wrong.
I Am Increasingly Suspicious of "More"
More services.
More abstractions.
More tools.
More frameworks.
More automation.
More agents.
More integrations.
More dashboards.
More features.
More AI.
None of these things are inherently bad.
The problem starts when more becomes the default definition of progress.
Sometimes the best engineering decision is to remove something.
Remove a dependency.
Remove an abstraction.
Remove a service.
Remove an AI step.
Remove a feature.
Remove an entire workflow.
That can be harder than adding something.
Because adding demonstrates activity.
Removing requires judgment.
The Best Architecture Might Look Boring
There is something I have increasingly come to appreciate about good systems:
They can look surprisingly boring.
Imagine two solutions.
System A
User → API → Database → Response
System B
User → Gateway → Service A → Queue → Service B → Agent → Tool Router → Vector DB → External API → Validation Service → Event Bus → Service C → Database → Response
System B looks more sophisticated.
But sophistication isn't the same thing as quality.
If both systems solve the same problem reliably, System A may be dramatically better.
Not because it uses newer technology.
Because it has fewer things that can break.
This is why I increasingly believe that simplicity is not the absence of engineering.
It is the result of engineering judgment.
This Is Where AI Agents Fit Into the Conversation
This is also why I have become cautious about the current obsession with AI agents.
Agents are useful.
There are problems where dynamic decision-making, tool selection, iteration, and autonomy genuinely create value.
But if a deterministic workflow can solve the problem, an agent may simply introduce additional uncertainty.
The question shouldn't be:
"Can I turn this into an agent?"
The better question is:
"Does this problem actually require autonomous decision-making?"
That distinction matters.
I wrote about this in more detail in my article “Stop Building AI Agents. Start Building AI Systems.”
The broader principle is the same:
Don't optimize for technological sophistication. Optimize for the outcome.
We Need a New Engineering Question
For a long time, developers were encouraged to ask:
"How do I build this?"
Then we learned to ask:
"How do I build this well?"
I think there is another question we need to put before both:
"Should this exist at all?"
That question applies to much more than software.
Should this feature exist?
Should this service exist?
Should this automation exist?
Should this database exist?
Should this AI component exist?
Should this entire application exist?
Sometimes the answer will be yes.
But sometimes the answer will be:
No.
And that's not failure.
That's engineering.
AI Makes Judgment More Valuable, Not Less
This is perhaps the most interesting consequence of AI-assisted development.
If AI continues making implementation faster, then implementation itself becomes less differentiated.
The valuable skills move upward.
Understanding the problem.
Defining the right requirements.
Choosing the right architecture.
Recognizing unnecessary complexity.
Knowing when not to automate.
Knowing when not to use AI.
Understanding trade-offs.
Evaluating whether something actually works.
And, perhaps most importantly:
knowing what not to build.
AI can generate ten possible implementations before you've finished explaining the problem.
That makes judgment more important, not less.
Before You Build the Next Thing
I've started thinking about software decisions through a much simpler filter.
Before building something, ask:
- What problem does this solve?
If you cannot explain the problem clearly, stop.
- Who actually needs it?
"Someone might use this" is not a strong enough answer.
- What is the simplest solution?
Not the most impressive.
The simplest.
- What complexity will this introduce?
Think beyond today's implementation.
- Does this need automation?
Maybe a manual process is perfectly acceptable.
- Does this need AI?
Maybe a rule, query, function, or conventional application is better.
- What happens if we don't build it?
This is the question I think we ask far too rarely.
Sometimes nothing happens.
And that may be the best outcome.
The Builder's Paradox
We are entering an unusual period in software development.
Building is becoming incredibly easy.
But deciding what deserves to be built may become increasingly difficult.
That creates a strange paradox:
The better our tools become, the more important restraint becomes.
When writing code was expensive, we naturally avoided unnecessary code.
When infrastructure was difficult, we naturally avoided unnecessary infrastructure.
When software development becomes increasingly assisted by AI, we will need a different constraint.
Judgment.
Not everything that can be built deserves to exist.
Not every workflow needs automation.
Not every application needs AI.
Not every AI application needs an agent.
And not every technical problem needs a technical solution.
Maybe the next great developer skill isn't building faster.
Maybe it's learning to look at a problem and confidently say:
"We don't need to build this."
What do you think?
Are developers becoming better at building software or simply better at building more of it?
Note: Looking for deeper insights into the future of artificial intelligence? Head over to ReThynk AI to access our latest research, magazine articles, and developer resources. Click Here
Top comments (1)
Building has become easy but what to build has become a challenge.