Last month I spent forty minutes on a call with a college student who had just finished a summer internship at Google. He was polite about it, but the question under all his questions was the one I’d ask in his position. The agents write the code. The platforms hide the infrastructure. The CI pipeline is something you copy from a template and never read. So what exactly is he supposed to get good at?
I gave him an answer on the call. It was mostly right and mostly unorganized, and I’ve been turning it over since.
Nobody Asks for You
Around the same time I fixed a bug in a small sync daemon I run on my homelab. It pulls things I’ve saved in various places into Readwise, and on every run it asks Readwise what it has already seen so it doesn’t save duplicates. The agent that wrote it did that the obvious way. It walked my whole Readwise library and built a set of URLs. What neither of us noticed for a while was that the walk included my RSS feed, and on a real account feed items outnumber the things you’ve deliberately saved by orders of magnitude. The daemon paged through 103,819 feed documents and never reached the end.
I caught it because I was reading the logs and knew what my account looked like. The agent wasn’t going to catch it. It had no idea what a normal Readwise library looks like, and nothing in the code was wrong in a way a test would find. Then I had to ask for the second fix too. The dedup set needed to be a cache on disk that warms incrementally, not something rebuilt from scratch every fifteen minutes. That’s a design decision, and the agent didn’t make it until I asked.
Both fixes took an afternoon. Neither would have happened without someone in the loop who knew to ask. I’ve been living the same thing at Vycari at a much larger scale.
What I Actually Do All Day
Chris and I have merged more than 2,600 pull requests across Vycari’s repositories so far, with two people. Two months of that work came to 1.1 million lines of new code. We have an army of agents doing most of the coding, and I wrote in The Backlog Was a Coping Mechanism about what that does to an issue tracker. What I haven’t written about is what it does to my job.
I write very little code and I’m busier than I’ve ever been. I’ve started calling what I do meta-programming, because the work has moved up a level. I write the plans, the rules, the guidelines, the checks, and the hooks that push everyone who touches the codebase, human or agent, toward the right decision. Chris makes changes all over the codebase, and he doesn’t need my sign-off to do it. He’ll check with me sometimes, especially on database changes, but nobody knows what they don’t know. The guardrails exist for that. Whoever picks up a change next, human or agent, needs enough context to get it right, and that context is mine to build. It never stops needing maintenance.
The second thing I do is think about the shape of the codebase over time. We started as one repository. As the product got more complicated I began splitting services out, each into its own repo with its own CI and its own rules. I wrote about why in The Test Suite Is the New Code Review. That makes iterating on any single service fast, and it forces a contract between services that has to be written down. Agents don’t do this on their own, not even the best or newest ones. They’ll add a new top-level directory next to the last one forever, and thirty days in I had a repository full of horizontal directories, repeated code, and no shared components. I refactored it from version zero to version one over a weekend, mostly from my phone while I was at a jazz festival.
The agents were excellent at the refactor once I’d decided what it should be. Mechanical moves, package relocations, extracting an interface and applying it across a dozen subpackages: I could hand those off and not watch. The biggest one moved more than a hundred thousand lines of code, not all of it mechanically, and I was reviewing it on a phone. I only slept because we require ninety-five percent test coverage, and because adversarial review agents were reading the diff alongside me. But the decision that the codebase needed reorganizing, and the decision about what the organization should be, came from me reading the code and recognizing a shape I’d seen go wrong before.
Proportional Scrutiny
The student asked how you get good at systems when the abstractions keep you from touching them. Part of my answer was that you have to read the code the agent writes, which is different from reviewing it.
The distinction matters to me because most code review I saw at Google was style review. Someone would tell you a line was too long, or a name didn’t match the convention, and both of you would feel like work had happened. I don’t do any of that anymore. We use Ruff for linting and formatting, it runs on every PR, and whatever it says is fine with me. I also don’t fight the agentisms. There are twenty-five line comment blocks in our codebase, and I leave them, because the next reader of that file is another agent and the comment might be useful context for it. A comment explaining how a for loop works is wasted tokens, but I’m not going to spend my afternoon hunting those down.
What I do instead is apply scrutiny in proportion to what the code is. If an agent rewrites a pile of CSS, I open the page in a browser, it looks fine, and I move on. I’m not a CSS expert and I have no plans to become one. When an agent touches our core agentic loop, I read every line and I make sure I understand why every line is there. That loop is one of the pieces of the product I’d call real intellectual property, and most of it was guided by me, decision by decision. The agent is the same in both cases. What changes is how much attention I give its work, and knowing where that attention belongs is most of the skill.
That’s proportional scrutiny, an idea I learned from Luiz Barroso. You watch the things that took a big investment, that have a large blast radius, that are consequential to the rest of the system, and you give everything else a lighter look. It applies to engineering management too. Luiz used it to let a few of us chase a long-shot project for a year while he ran an organization of fifteen hundred people.
What Breaks First
My favorite question to ask an agent, and the one I gave the student to take home, is what breaks first if usage goes up by three orders of magnitude.
A hundred queries a second to a hundred thousand. A thousand users to a million. The agent will give you a real answer, and the answer will teach you about the system you’re building faster than any textbook I know of. If you can get a project to the point where you’re confident it would survive that, you’ve done the distributed systems course. Very few systems actually run at that scale. Asking the question is still how you learn to think about scale.
I learned it the expensive way. I’ve taken large portions of Google down more than once in my career, and the lesson from those days was simple: you learn from the outage or you get fired. I once led a team that built a geographic photo search system, and it had to sit in the main search path, so every query to Google.com went through our code. The day we turned it on our baseline was over a million queries a second with a five millisecond budget at the ninety-ninth percentile. The naive implementation took a week. The version that could actually carry that traffic took two years. That gap, between the thing that works and the thing that survives, is what senior engineers carry around in their heads. It’s what the student was really asking how to acquire.
The Bargain We Used to Make
His question is harder now than it was for me. The industry used to run on a trade. A new grad could write syntactically correct code and not much else. We’d hire them, they’d write a lot of code, and a tech lead would sit alongside them and teach them how systems actually fit together. They gave us labor, we gave them judgment. It wasn’t efficient, but it worked, and it’s how every senior engineer I know got here.
Agents took the labor half of that bargain. A new grad’s first year of work, the part where you write a lot of code and learn by getting it wrong, is exactly the work agents do well and cheaply. What’s left is the judgment half, and that was always the part that was hard to teach and impossible to shortcut. I wrote in The Last Programmers that each rung on the abstraction ladder frees us to work on harder problems. I still believe that. But the ladder used to have a bottom rung you could stand on while you learned, and I’m not sure it does anymore.
I don’t think that’s hopeless. I think it means the apprenticeship has to be rebuilt on a different foundation, and so does the university curriculum. Whatever anyone thinks of AI, it isn’t going back in the bottle for coding. The new foundation is the same one the senior people are standing on: the questions.
The Most Patient Teacher You’ll Ever Have
The part of my answer I most want to be true is that agents are the best teachers most of us will ever get access to, if you treat them that way.
Don’t take the PR blindly. Ask why it did that. Ask what the trade-offs of that data structure are. Ask what the runtime implications of that table layout will be at ten times the rows. Ask it to explain the same thing three different ways until one of them lands. It will never get tired, never get impatient, and never make you feel stupid for asking the same question again. Some of the tools lean into this directly. Claude Code ships a Learning output style that explains its choices as it goes and leaves small pieces of the code for you to write yourself. That’s closer to what a good tech lead did for me than anything I got from a book.
I do a version of this constantly. I’ll point an agent at a subsystem and say I want to understand this deeply, walk me through the important files and the control flow. I’ll ask for a diagram of how a subsystem looks in main today and then interrogate the diagram. When I was a senior director that was exactly how engineering reviews worked: someone came in with block diagrams and sequence diagrams and we talked about the project at that level of abstraction. I wrote about coming back to the individual contributor side in Full Circle. One of the surprises has been how much of the director job I still do, just with an agent across the table instead of a team.
I’ve even considered running a full design review this way, asking an agent to build a presentation and walk me through its decisions the way a team would have. I haven’t taken it that far yet, but I may at some point.
That’s the rebuilt apprenticeship. You still have to write some code by hand, and you still need a couple of languages you’re truly fluent in. But the judgment you used to absorb from a tech lead over three years is now something you can pull out of an agent on purpose. You do it one question at a time, starting on your first day.
I don’t want to oversell this. Glyph Lefkowitz makes the strongest version of the opposing case in Programming Isn’t Special. Take away the mundane work and you take away the practice, because “the majority of true skill development happens on the job and always has.” He’s right about that part. Most of my own judgment came from getting things wrong in production, and asking an agent good questions doesn’t replace the experience of an outage you caused. What it can do is get you to your first real failures sooner, with a much better map of what you’re looking at when they happen.
There’s also something the agent can’t teach you, which is anything that happened after its training data ends. When a new language feature ships, the agent won’t reach for it unless you tell it to, because it has never seen it. Knowing when a change like that matters, and when to bring it up, takes judgment and experience of your own.
How We’ll Know
The student asked about hiring, and I gave him a split answer. Google and the other big companies will move slowly on this. The interview you get there in five years will look a lot like the one you’d get today: computer science fundamentals, system design, distributed systems. Those things aren’t going away, and the big companies are right to keep testing for them.
Startups will change faster, and I’m one of the people who gets to decide how. We’re not hiring at Vycari yet, but when we do I’m not going to put anyone in front of a whiteboard. I think that’s archaic now. What I might do is hand a candidate a coding challenge and an agent, and ask for the transcript instead of the code. How they worked with the agent will tell me more about how they’ll work with us than the code will. Did they read what came back? Did they ask why? Did they notice the thing that was going to break at scale, or did they ship the first thing that passed the tests?
I recently built a whole project in Swift, and I had never written a line of Swift before. I mention it because it shows how little the language matters now, and how much everything else does. The student was worried the abstractions were taking the important skills away from him. I think they’re taking the unimportant ones and leaving the important ones exposed, with nothing to hide behind. That makes the job harder. But the questions were always the job. We just used to let people spend a few years writing code before we told them.