I was trained, like every software engineer, on a single deep assumption: the machine does exactly what the code says. Bugs were my failures of specification. The computer was innocent. Determinism was the ground you stood on.
Then I started building agents, and the ground moved.
From instructions to intentions
A traditional program is a script of instructions. An agent is closer to a delegation: here is the goal, here are the tools, go. The system decomposes the goal, picks actions, reacts to results. Differently on Tuesday than on Monday, because the context shifted or because the model simply sampled another path.
The first time you watch an agent take a route you didn't anticipate and succeed, something in your engineering brain rewires. You realize you are no longer writing behavior. You are shaping it. The unit of design is not the instruction anymore; it is the intention, the constraint, the affordance.
This is a different profession. It looks like software engineering the way a garden looks like a building.
What actually transfers
The surprise is which old skills matter more, not less:
- Interfaces beat implementations. An agent is only as good as its tools, and a tool is only as good as its description. Writing a tool definition is API design where the consumer is a mind that reads English. Ambiguity you would have gotten away with before now costs you at runtime.
- Testing becomes evaluation. You cannot assert
output == expectedwhen output is a distribution. You need evals: datasets, rubrics, regression suites over behavior. In every production system I shipped, the eval pipeline was the difference between a demo and a product. Whoever measures, ships. - Failure design is the job. Deterministic software fails loudly at the broken line. Agents fail plausibly: a confident wrong answer, a loop that almost terminates. So you build the way good ops teams build: observability, guardrails, escalation paths. You assume failure and make it cheap.
The deeper shift
Here is what I did not expect. Working with non-deterministic systems made me better at deciding what should be deterministic.
There is a boundary in every agentic system: on one side, the model's judgment; on the other, hard code. Validation, permissions, money, anything irreversible. Drawing that boundary is now the central architectural act. Too much determinism and you have built an expensive workflow engine. Too little and you have built a liability.
I think of it as a budget of trust. Each capability the agent gets is spent trust; each guardrail earns some back. The systems that work in production are not the smartest ones. They are the ones whose trust budget is spent deliberately.
Gardens, not buildings
Software used to be architecture: you designed a structure and the structure stood. Agentic software is horticulture: you prepare the soil, plant, prune, and the system grows behavior you then observe and correct. Less control, more leverage.
Plenty of engineers hate this. I understand. We were promised determinism, and determinism was beautiful. But the machines that only did what they were told could only do what we could specify. The interesting problems were always the ones we couldn't fully specify.
That is what changed for me. I stopped asking "how do I make the machine do X" and started asking "how do I make a system in which X reliably emerges." It is a harder question, and a much bigger one.