C_W
Contact

◄ NotesSoftware5 min read

AI makes software cheaper. Systems thinking becomes more valuable.

Writing code is getting cheap. Deciding what the system is, where it can fail and how its parts fit together is not, and that is where the work moves.

The cost of writing code is falling fast.

A function that took an afternoon now takes a prompt and a review. A prototype that took a week can exist by lunch. Boilerplate, migrations, test scaffolding, the fifth CRUD screen: models produce all of it quickly and mostly correctly.

It is tempting to conclude that software itself is getting cheap.

I don’t think that follows. Code is getting cheaper. Software isn’t, at least not at the same rate.

The difference is where the interesting work is moving.

Code was never the whole cost

Anyone who has run a software project for long knows that typing was rarely the bottleneck.

The expensive parts were elsewhere:

  • working out what the system should actually do,
  • deciding where one component ends and another begins,
  • integrating with systems you don’t control,
  • handling the cases nobody mentioned in the spec,
  • keeping it running, observable and correct once real people use it,
  • changing it later without breaking what depends on it.

Models help with some of this. They are good at reading unfamiliar code, proposing a design and spotting an obvious gap.

But most of that list is about decisions, not keystrokes. And decisions have consequences that outlive the session in which they were made.

When the cost of producing code drops, the relative cost of those decisions goes up.

Cheap code means more code

When something gets cheaper, we tend to use more of it.

That is already visible. More internal tools. More prototypes. More scripts that quietly become services. More integrations, because building one is now an evening instead of a sprint.

Each of those pieces may be simple. The system they form together is not.

Every new component brings interfaces, state, failure modes and an owner who may or may not remember it exists in six months. Cheap code lowers the cost of adding parts. It does nothing for the cost of understanding how the parts interact.

So the total amount of complexity in a company can grow faster than before, not slower.

That is not an argument against using AI to write software. I use it constantly. It is an argument for paying more attention to the shape of what we are building.

What systems thinking actually means here

“Systems thinking” can sound like a consultancy slide. I mean something quite practical.

It is the habit of asking questions like:

  • Where does state live, and who is allowed to change it?
  • What happens when this call fails halfway?
  • What does this component assume about the others, and what happens when that assumption stops being true?
  • Where are the feedback loops? How would we notice if this were quietly wrong?
  • What is the cost of being wrong here, and who pays it?

None of these questions gets easier because the code was generated.

Some of them get harder. Generated code is often locally reasonable and globally unaware. A model can write a perfectly sensible retry loop that, combined with 3 other perfectly sensible retry loops, produces a very efficient way of taking down a dependency.

Agents make it more obvious

Working with agents makes this especially visible.

An agent iterating on its own work has the same failure modes as a team without a clear definition of done. When I wrote a small skill for iterating on an artifact until it reaches a confidence threshold, the 2 problems I had to design against were exactly that:

  • Score inflation: every pass nudges the number up without evidence.
  • Scope padding: to reach 100%, the loop invents work the artifact doesn’t need.

The fix wasn’t a smarter model. It was structure: every re-score has to cite specific evidence, the loop stops when the same weakness appears twice, and trade-offs go back to a human instead of being guessed.

That is systems design. The model is one component. The loop around it determines whether the result is useful.

The same thing showed up in a trading experiment with a fast decision model. Changing the wording of the question moved the rate at which it wanted to trade from 3% to 70% of decisions on identical market states. The model hadn’t become braver. The system around it had changed, and nobody would have noticed without caching answers by prompt and comparing like with like.

Where the value moves

If code gets cheaper and systems don’t, a few things become relatively more valuable.

Knowing what not to build. When building is nearly free, the discipline is in saying no. Every feature you ship is something you operate.

Clear boundaries. Good interfaces were always valuable. They are more valuable when a lot of the code on either side of them is written quickly, by people and by models, and replaced often.

Cheap ways of being wrong early. Before spending money on model calls in that trading experiment, the useful first step was computing the cost floor: the minimum a strategy has to earn to pay its own fees. It said the idea was impossible at that horizon, and every later result agreed. A few lines of arithmetic did more than any amount of generated code.

Operating knowledge. Someone still has to know why the system is shaped the way it is. Some of that can live in documentation and, increasingly, in agent memory. But somebody has to decide what is worth remembering.

Taste. Not the aesthetic kind only. The judgment that a design is too clever, that a dependency isn’t worth it, that 2 services should really be one.

The open questions

I’m not sure how far this goes.

Models are getting better at the system level too. They can already read a whole codebase and point out that 3 services duplicate the same logic. It would be naive to assume that architecture is a permanently human activity.

I’m also not sure how people will learn systems thinking if they rarely write the code themselves. A lot of systems intuition comes from building things that broke and having to understand why. If a model writes the code and another model fixes it, where does that intuition come from?

And there is an organisational question. Many companies measure engineering by output. Cheap code makes output a worse measure than ever. What replaces it?

Where I’ve landed for now

For now, I treat generated code roughly the way I treat code from a fast, capable colleague I haven’t worked with for long.

Useful. Often right. Occasionally confidently wrong in ways that only show up at the boundaries.

The code is the cheap part. The system is the product.

Which, to be fair, was always true. It is just harder to ignore now.