
Over the past few months, I have had several conversations about how artificial intelligence is changing the way we develop software.
Most of them ended up taking us somewhere that had little to do with which model writes better code or which agent is more sophisticated.
The important question was a different one:
Are we using AI to do better engineering, or are we simply learning to produce software faster?
Because those are not the same thing.
And the more capable we become at generating code, the more important it will be to tell them apart.
The arrival of agents that can explore repositories, implement features, write tests, refactor, or spin up entire applications has radically changed the economics of producing software. What used to take several days can now be done in hours, and in some contexts, work that once required a team can be done by a single person.
That opens up countless possibilities, but it also creates a temptation: to assume that writing code was always our main limitation as developers.
Perhaps it never was.
Developers are not paid to write code
For years, we have simplified our work by calling ourselves programmers: we write code, implement tickets, close stories.
That description has always been incomplete. Writing code is an important part of the job, but we are usually trying to solve something that exists beyond the code: a problem that goes beyond conditionals, loops, zeroes, and ones. We are trying to solve problems ingeniously.
Sometimes the solution will be to write code, and sometimes to delete it. At times, changing a process, connecting two existing systems, or automating a task will be enough. The right decision may even be to build nothing at all.
That possibility becomes especially relevant now that producing software is becoming extremely cheap.
When producing code was expensive, there was natural friction. We had to justify what we built reasonably well because it came at a considerable cost. Now we can generate applications, services, or integrations in a matter of hours, and some of that friction disappears.
A different risk emerges:
Building software in search of a problem.
A solution without a real problem can look like innovation for the first five minutes. After that, it can become inventory: something to deploy, secure, understand, and maintain for years.
And even if it took very little time to generate, someone will still have to take responsibility for it.
AI does not make XP obsolete. It makes XP uncomfortably relevant again
It is curious that while we talk about agents, enormous specifications, and completely new processes, many of the questions we are trying to answer were already with us decades ago.
Extreme Programming emerged precisely in response to environments where requirements change, knowledge is incomplete, and learning early is more valuable than trying to predict everything.
Its values—communication, simplicity, feedback, courage, and respect—remain current challenges. The same is true of practices such as incremental design, test-first development, continuous integration, refactoring, and a sustainable pace.
None of this stops being valid just because a machine can now write much of the implementation.
What does change is the cost of getting things wrong.
An agent can propagate a bad decision across many more files, tests, and layers before anyone notices that we started from a mistaken assumption. That is why increasing our generation speed without also improving our ability to learn and verify does not guarantee a better development system.
Speed amplifies good decisions and bad ones alike.
The danger of turning SDD into waterfall on steroids
One current response to the uncertainty introduced by AI is Spec-Driven Development.
The idea makes a lot of sense: before asking an agent to implement something, we explain more precisely what we want to build.
Tools such as GitHub Spec Kit formalize workflows along the lines of:
Specify → Plan → Tasks → Implement → Converge.
Separating intent from implementation can be extremely useful when working with agents.
The problem appears when we confuse providing context with trying to eliminate all uncertainty before we start. Then we risk returning to the place we tried to escape years ago: a huge requirements document, followed by an architecture document, then a task list with hundreds of decisions made in advance, and finally an AI capable of turning all of it into code at spectacular speed.
That may look tremendously sophisticated, but it preserves a fundamental problem:
we can specify something with enormous precision and still not know whether it is right.
The Agile Manifesto put working software above comprehensive documentation and responding to change above following a plan. Documentation and planning still have value. The limit appears when we treat those artifacts as if they could contain knowledge we have not acquired yet.
I am not sure exactly where that boundary lies. It probably depends a great deal on the context, the system, and the risk we are taking on.
I find it more useful to think of a specification as enough context to get started, rather than an attempt to describe the system’s entire future in advance.
Learning should remain our unit of work
Here, I think XP offers a rather interesting middle ground.
We can delegate a considerable amount of work without turning that delegation into a leap of faith.
One way to do this is to work in small units of behavior: define what we want to achieve, provide a few relevant examples, set the constraints that must not be broken, and let the agent work within that space.
Within that small cycle, the agent can write an initial implementation, run the tests, inspect what failed, revise its solution, and try again several times before returning a result.
That changes our relationship with implementation quite a bit.
We do not need to supervise every internal move an agent makes. Our checkpoint can sit one level higher: in the expected behavior, the constraints, and the evidence we will use to decide whether the result is acceptable.
This is where I think small batches still make a lot of sense.
DevOps Research and Assessment (DORA) continues to explicitly recommend working in small changes, and this discipline becomes especially relevant when we use AI. Models let us generate enormous modifications with very little effort, but reviewing, understanding, and integrating those changes still costs time.
Our responsibility begins to shift toward another question:
What are we delegating, and what evidence will we use to accept the result?
A Software Factory should not be a code factory
I find it interesting to think of development teams as a kind of Software Factory.
The problem is that the image of a factory easily encourages us to measure what is most visible: how much we produce.
We could end up describing an organization like this:
We have agents working constantly, generate dozens of pull requests a day, and ship features at a speed we have never seen before.
That sounds impressive, but it says nothing about whether we are creating value.
The industrial analogy has its limits, but it is useful here: increasing production is only an advantage when we are producing something worth producing.
A mature Software Factory should care less about gross output and more about the outcomes it achieves.
Lines of code, pull requests, or even token consumption can be useful operational metrics, but on their own they say little about the ultimate goal.
I am much more interested in how much we can compress this cycle:
problem → hypothesis → solution → evidence → learning.
AI can radically reduce the time needed to move through it.
That is where I see one of its greatest strengths: exploring an idea sooner, getting evidence sooner, and discovering sooner that we were wrong.
The challenge is not to spend all the time we save filling the system with more bureaucracy, more features, and more code.
Building faster is an extraordinary capability.
The question remains: what do we do with it?