Coding agents, defaults, and human judgment — RPC Coding agents, defaults, and human judgment<br>R Phillip Castagna · August 6, 2026 ·30 min read
When I worked at Google, some of the engineers who’d been around more of the industry than I had<br>would tell me the codebase was strange.
That didn’t make a ton of sense to me. I found it healthy and pretty intuitive to work in, and the<br>more experience I’ve picked up since, the more I’ve come to appreciate it — given both the size and<br>scale of the company and the scope of its products, google3 was in shockingly good shape.
At one point I asked my tech lead where this disconnect came from. What was so weird? His answer was<br>code generation.
Google used code generation extensively at a time when almost no one else did. Even if you were<br>totally sold on the benefits, it was still a new set of tooling to learn, and a different mode of<br>operating than what you might be used to after several years in the industry. If nothing else, you<br>had to rework your muscle memory a bit to reach into the codegen toolbox instead of jumping into<br>writing things by hand, and there was a new set of norms to internalize when tracing code execution<br>in order to find the right declaration sites.
I’d immediately loved the thing other people found frustrating,<br>I’m an unabashed compilers nerd. I like programs that write programs, and I like<br>working on the ones that do. so the speed bump<br>there only made sense to me when he pointed it out.
Before Google I’d been working a lot in Django — which, as frameworks go, isn’t a bad offender for<br>what I’m about to describe. It still bit me more than once. Django is heir to the metaprogramming<br>paradigms that were popular at the time it was built, a key selling point of Rails and everything<br>downstream of it. Extending certain key base classes or adding certain annotations tells the<br>framework to extend your code in various ways and gives you wonderful expressive power and APIs<br>without you having to write very much on your own at all. It’s an ergonomic developer experience, at<br>least 90% of the time.
When there’s a hiccup, though, it gets complicated fast. My experience here is almost certainly<br>outdated, and I’m sure Django specifically has gotten better, but it was formative for me. Something<br>in a model wouldn’t behave the way I expected, and finding out why meant climbing into<br>annotation-declaration code and tracing paths through the framework to work out what was actually<br>executing. I’d written a short declaration. The code doing the work was somewhere else, and getting<br>at the actual machine state meant jumping through file after file of library source, working out how<br>the declarations and overrides all fed into each other. The abstractions I relied on were easy to<br>ignore until they weren’t, and then I suddenly needed to understand all of them at once.
Google’s generators gave me the same experience on the way in — short, clear, declarative<br>annotations. What they gave me on the way out, though, was much easier to work with — often a<br>single file. When something misbehaved, I could read the generated code in a single place.
That distinction is nice, and it’s one I still use: declarative input, easily inspectable output.<br>Metaprogramming keeps the result in its head. Generation puts it on disk. The difference is<br>invisible while everything works; it decides your afternoon the moment something doesn’t.
Coding agents as code generators
I use coding agents in much the same spirit as I used to use code generators, and it really is the<br>same working mode. I sketch what I need at about the level of detail I’d have put in an annotation,<br>I get code back with the rest filled in, and the result is sitting flat in front of me where I can<br>check it against what I meant. I like that they write code for me. What I like more is that I can<br>open what they wrote, read it, change it, and steer the next pass toward what I actually wanted.
That’s a better answer to “how can you trust generated code” than most of what gets written on the<br>subject. You don’t trust it. You read it. And you can read it, because the output is a real<br>artifact sitting in your repo rather than a transformation happening somewhere you can’t get at.
The analogy breaks in one place, though, and the place it breaks is intrinsically tied up in what<br>makes coding agents powerful.
AutoValue exists because somebody sat down and wrote AutoValue. That was true of every generator<br>I used at Google. Each one covered a single pattern, somebody had built it deliberately, and the set<br>of things I could generate was exactly the set of generators that happened to exist. Everything<br>outside that set I wrote by hand, and most things were outside it.
An agent has no such boundary. Ask for a service skeleton, a migration, a retry wrapper, a test<br>harness for something nobody has built before, and you get a plausible version of it. Nobody wrote a<br>generator for that shape. The model already carries a view of what the shape looks...