Agent Experience (AX): Codebases Agents Thrive In
DX has a twin now — and a codebase that's easy for an agent to navigate is what lets a cheaper model do better work for fewer tokens
DX has a twin, and its name is AX
Developer experience (DX) is an old question: how easy is this codebase for a human to work in — clear names, consistent patterns, a fast feedback loop. Agent experience (AX) is the same question asked of whoever is doing the typing now. When an agent opens your repo, does it need three tool calls to understand one concept, or thirty?
These two used to track together loosely — a readable codebase was usually a well-organized one, and nobody measured the difference closely. Agents make the correlation exact and expensive. Every bit of friction a patient human would shrug off — poking around, guessing at a convention, backtracking after a wrong assumption — shows up as an agent burning tool calls and tokens, at your cost, on every single task.
Time spent deepening a module or keeping an interface honest looks like overhead with no user-facing payoff. It isn't overhead — it's the mechanism that lets you point a cheaper, faster model at your codebase and still get frontier-quality results, on every future task, forever.
Depth: the property that makes code cheap to read
John Ousterhout's term for this is depth. A deep module has a small interface — the function signature, the docstring, the contract — hiding a lot of implementation behind it. A shallow module's interface is nearly as complicated as its insides, which means reading the interface teaches you almost nothing.
For a human this is a readability preference. For an agent it's direct token economics: a deep module means one read of its interface answers "what does this do and how do I call it," and the agent can act without ever opening the file. A shallow module — or a concept scattered thin across many small files — forces the agent to open several files, hold them all in context at once, and still risk guessing wrong.
// shallow
function saveOrder(order) {
return orderRepo.save(order)
}
// deep
function processOrder(order) {
// validate, price, reserve
// stock, charge payment,
// emit events — atomically
}
orderRepo to learn what actually happens — the wrapper added a file to read, not a concept to learn.Where agent experience quietly breaks
None of these look dramatic in a code review. Each one is a place an agent will spend extra tool calls figuring out something the codebase should have just told it.
Understanding a single feature means bouncing between five files to reconstruct the whole picture. Every bounce is a tool call.
A function or class that adds a name but no behavior. It costs an extra read and gives nothing back.
A comment or interface that describes behavior the code no longer has. Worse than no docs — it actively misleads.
Three different naming or error-handling styles in one codebase. The agent can't infer the pattern, so it has to ask or guess.
Nothing verifies a change is safe through the module's public contract, so the agent either skips verification or re-derives it by reading the implementation.
A sprawling file mixing unrelated responsibilities. Changing one concern drags the other four into context for no reason.
Auditing your codebase the way an agent would
You don't need a new toolchain for this. Four checks, borrowed straight from deep-module design, catch most of what hurts AX.
Imagine deleting the module. If its complexity vanishes, it was a pass-through — merge it away. If the complexity reappears at every caller instead, it was earning its keep — deepen it, don't delete it.
One implementation behind an interface is a hypothetical seam — extra surface for zero leverage, and one more thing an agent has to read through to find the actual logic. Two real implementations make it a real seam worth having.
A one-line docstring at the function an agent already opened beats a wiki page it has to go find. The interface should state invariants and error modes, not just the type signature.
A module that takes its dependencies as arguments and hands back a value, rather than reaching out and mutating state, can be exercised through its interface alone — by a test, or by an agent checking its own work, without reading the implementation to be sure.
None of this is agent-specific advice in disguise. It's Ousterhout's case for deep modules, applied to a reader that now costs you real money per file it has to open.
The real payoff: a cheaper model doing better work
Token cost scales with exploration, not with the size of the actual change. A deep, well-seamed, honestly-documented codebase cuts that exploration close to zero for a familiar task — the agent reads one interface and acts. A shallow, scattered codebase forces every agent, on every task, to re-derive the same understanding from scratch, and you pay for that rediscovery every time.
That's the practical test of good AX: it's what lets you route a routine change to a cheap model, or dispatch it unattended, because the codebase already tells the agent what to do — it doesn't need judgment to fill the gaps you left out.
You're not writing code for yourself anymore, and not even just for the next human who reads it. You're writing an interface for whichever agent — cheap or frontier — picks this codebase up next. Investing in that interface, ahead of time, is the leverage move now.
Agent experience check
Three situations. Decide what the codebase — not the model — should be doing differently.
A function validates input, retries on a transient failure, and logs a consistent error shape — used by six call sites. You imagine deleting it: all six callers would need to reimplement retries and validation themselves.
What does the deletion test tell you here?
You're about to wrap your one and only database client behind a generic DataStore interface, "in case we swap databases later." There's no second implementation, and none planned.
Good move for agent experience?
Two codebases need the same routine change. Codebase A: one deep module, an accurate docstring at the seam. Codebase B: the same logic spread across five small files, with a comment that no longer matches the code.
Which will let a cheaper model do the task well, and why?
Pick one module you'd hesitate to hand an agent unsupervised. Run the deletion test on it, check whether its seams are real or hypothetical, and make sure its interface says what the code actually does. That's the whole audit — and it pays off on every task an agent does in that codebase from here on.