Skip to content
All writing

Programming's Old Metaphor Is Failing: From Orchestration to Improvising

The old software system was a factory line. AI-native systems look more like setting up a stage.

Hongkai He 7 min read
  • #AI
  • #AI-native
  • #programming
  • #philosophy

Originally published March 10, 2026 on my WeChat newsletter, 问题儿童与端水大师的日常.

A companion to “Governance Is AI’s Hidden Thread — and We’re the Bottleneck” — that piece took the macro view; this one zooms in.

For the past few decades, our understanding of “programming” has been almost a default.

To write a program is to break a task into a sequence of deterministic steps and hand them to a machine. Every branch, every exception, every condition — defined and accounted for as far as possible, ahead of time.

You can even find the trace in the etymology. Programming literally means “pre-arranging.” The machine executes; the programmer’s job is to design the entire flow up front.

So classical software engineering carried a very explicit aesthetic:

  • The system as an assembly line
  • Modules as gears
  • Development as precision orchestration
  • The best program is the one that eliminates uncertainty

This paradigm was extraordinarily successful, and it shaped the whole industry’s sense of what “engineering” feels like.

Years ago, the broad adoption of neural networks quietly shook the premise. Today, the maturation of LLMs and Agents is shaking the foundation outright — when a system’s core capability comes from foundation models, agents, tool calls, context engineering, memory, and runtime inference, software is no longer just a machine that runs predetermined commands. It starts to look more like an actor with judgment.

And so, for the first time, developers feel a clear dissonance: we’re still writing software with the old assembly-line mindset — workflows, rules, state machines; even at the very start of a system, defining the database schema and API structure, trying to box in every possible future path the system might take.

And yet, at the same time, we know more and more clearly: these Agents can already make their own judgments. They pick tools based on context, try different paths, adjust their strategy on feedback. In other words, they have some degree of “Improvising.”

So a strange state shows up: we have systems that think and decide, and we still treat them like gears we’re cutting.

Assembly line vs. stage

If I had to put it in a metaphor — more and more I feel: the old software system is a factory line; an AI-native system is more like setting up a stage to put on a show.

On a factory line, everything is pre-defined. Each part handles a fixed motion; the whole system runs on the precision orchestration of determinism.

But on a stage, it’s different. You still need structure — you need stage, lighting, rhythm, edges, theme. You need to know what can happen and what can’t. But you don’t choreograph the whole dance dead. What you do is:

Build the stage
Cast the dancers
Define the roles and the story
Give them props and room to play
Then let them do the performance, live

AI-native systems increasingly look like this.

The deterministic, precision part hasn’t disappeared. It’s just receded — it’s become infrastructure. Determinism used to be the work itself, like the inside of a mechanical watch. Now it’s more like the stage, the lights, the props, and the rules. The thing actually creating value is the agent improvising in that space. They:

Judge
Try
Fail
Correct
Try again

Many behaviors aren’t fully written into the code — they take shape at runtime.

This is why people writing AI-native systems for the first time often feel off-balance. The intuition we’ve built up over the past few decades is: if a system’s behavior isn’t fully deterministic, the design must be wrong. But more and more systems are now, exactly, deliberately preserving some uncertainty. Not because they’re chaotic — because the system itself has judgment.

The programmer, more like a director

From this angle, the center of gravity in software engineering has quietly shifted.

A programmer’s core skill used to be: think of everything beforehand. You had to design every path before the system runs.

In an AI-native system, the developer is closer to a director or a choreographer. What you do becomes:

Define intent
Provide context
Open up capability
Design the edges
Build feedback

Then let the agents dance on the stage, and the system converges toward the goal at runtime.

So when people talk about writing AI applications today, they still tend to reach for “automation” as the frame. But that’s a little misleading. The real change isn’t that automation got more automated. It’s that systems are starting to have autonomous judgment.

And so the proposition of software design quietly changes. No longer just “how do we write the flow clearly,” but more like “how do we set up the stage, and how do we empower a system that can act.”

Schema is no longer the starting point

This shift shows up in what look like technical details too.

In traditional software engineering, we design the schema first, then start writing the system. We assume a system’s data structure can — or should — be fully defined at the moment of design.

In many AI-native systems, that’s changing. A lot of systems start by simply running. Through real running they generate data, behavior, and patterns; only afterward does a stable structure precipitate out. In other words:

We used to design schema, then write the system. Many future systems will run first, and the schema will surface from practice as it stabilizes.

Schema is no longer the system’s starting point — it’s more like the convergence point after the system has settled.

This isn’t engineering discipline disappearing; it’s engineering discipline moving to a different position.

To stay with the metaphor: the old software engineering was solving an assembly-line management problem. AI-native systems look more like an organization-and-coordination problem.

The question isn’t only:

How does each part run
Whether the system is airtight

It’s:

Whether the capabilities are complete
Whether the information is relevant
Whether the goal is clear
Whether the edges are reasonable
Whether the collaboration is smooth
Whether the feedback closes the loop

In other words, this is more a problem of empowerment, mobilization, and cohesion — not screws and gears.

Letting go is, paradoxically, a kind of completion

Once you actually accept this framing, an interesting thing happens. The programmer’s coding pressure drops noticeably. You no longer have to exhaust every path, preset every structure, design every contingency before the system runs. A lot of what used to require “design ahead” can be left for the system to form at runtime.

And often the system does better. Because the agent’s judgment finally has space to be released.

Some AI-native engineering practice already validates this. OpenClaw runs on an extremely lean kernel — only the most basic capability and edges — and what emerges in real running far exceeds expectations. Often the system feels clumsy not because the model is too weak, but because we’ve designed too much structure that didn’t need to exist.

In this sense: restraint is itself design; letting go is itself empowerment.

Maybe one day we’ll realize: the most profound shift in software development history isn’t a new language, a new framework, not even “AI can write code.” The real change is that we’re finally beginning to admit: software-driven systems are no longer just machines.

They are becoming actors — or assemblies of actors — that can be organized, empowered, guided. And a programmer’s real work is no longer to write each step dead. It’s:

Set up the stage. Grant capability. Give the theme. Then let the system perform.

Letting go, paradoxically, is a kind of completion.