On the death of intelligence: why software engineers need to reallocate their time and effort towards learning
Recently I've been seeing a lot of articles talking about how AI is making us dumber (1, 2, 3). As a software engineer, I can speak firsthand about how AI has automated a lot of the work I used to do, namely writing code by hand. However, just because I am not writing every line of code and dealing with every compiler error doesn't mean I'm not learning anything. After working on the Chromium codebase for ten months, I certainly know a lot more about it than I did before. I understand the multi-process architecture of Chromium, how Mojo IPC works and why it exists, how various device APIs work and how to build new ones, and the list goes on and on. Additionally, I've completed high-priority team projects and squashed dozens of bugs along the way.
Yet, it feels like I'm only scratching the surface when it comes to learning about the work I'm doing. In the same way a calculator removes the manual labor of doing mental or written arithmetic, using coding agents removes the trials and tribulations of writing code by hand. And in doing so, it also removes opportunities for my own failures. Now, I don't mean to say agents spit out 100% perfect code every single time; it's just that when things do go wrong, the agent failed, not me. Maybe the prompt led the agent down an incorrect path, or I didn't provide enough context to the agent to best prepare it for success. However, because I did not write the code, the learning signal is obscured by whatever harness I was using at the time. It's like trying to backpropagate an error signal through a black box. Sure, I can read back the code the agent wrote, which I encourage people to do anyways, but in doing so I am now trying to read and understand someone (or something) else's work. That in and of itself is typically much more challenging than understanding your own work, particularly when the problem or task posed to the coding agent is often one we haven't figured out for ourselves.
Back when ChatGPT first surfaced in 2022, I was in my senior year of college. Initially, these tools served as the best version of Stack Overflow I'd ever encountered. It was a way to narrow what used to be a Google search with dozens of results to a much more prompt-specific response that, like searching for something on the internet, still required validation and careful reading. Additionally, these tools had zero context on what I was working on: all of the context I could provide had to fit in whatever character-limited input box existed for that model. Furthermore, the accuracy of these early models was seriously lacking, especially for complex problem solving that required multiple steps. As such, what was going into the prompts were usually partially complete solutions to a problem I had a good idea of how to solve already. In the years that followed, as models improved and agents grew more capable, achieving a working solution required less and less prework. Agents went from being able to execute instructions for carrying out a solution to coming up with the solution on their own. Prompts no longer contained large codeblocks with small errors or half-baked solutions; they were shortened to imperative requests like "Create X feature". None of this is novel to software engineers, it's the reality we live in and the usage of coding agents has become an expectation and necessity to keep pace in today's world. But the reason I bring up this development is because it demonstrates that our role as engineers has shifted from problem solvers to prompters. Learning by doing is no longer the default mode (literally, "learning output style" is a separate configuration setting in Claude Code), and as a result, it has become very easy to be complacent with the current body of knowledge we have about our work and the codebases we operate in.
Now this post isn't an argument for getting rid of coding agents or going back to writing code by hand, even if it would mean we learn a lot more. Instead, it is a reflection on how coding agents have granted us as engineers a lot more time and unused effort that is now up to our discretion on how we want to spend it. To figure out the best way to spend these newfound resources, I think we need to ask ourselves "what is our goal?" when we start a task. If my goal is to solve a problem and learn while doing it, it's in my best interest to spend my time and effort learning about the problem and trying to solve it myself. In practice, this can look like writing a spec by hand, or having a thorough back-and-forth discussion with a coding agent about how to accomplish a task before asking it to "go do it". In other words, it would look like convincing myself that if I were tasked to go implement the solution by hand, I could do it. Now, I'm not claiming this is a one-size-fits-all solution to learning with coding agents. In fact, there are many tasks that I feel confident enough an agent could complete on its own and I'm happy reviewing and verifying its approach after the fact. In those cases, the goal is simply to complete the task, not necessarily to learn a lot along the way. Learning could also look very different depending on the goal. If my goal is to simply learn about the codebase that I'm working on, I can spend my time and effort reading code and talking with agents to deepen my understanding so that when I shift back to asking agents to "implement X", verifying the solution afterwards is that much easier. Regardless of what approach we take, learning is now something engineers need to do on purpose, rather than something we used to gain along the way.
Just like how calculators automated computation for mathematicians so they could learn how to tackle harder problems, agents give us the opportunity to automate away coding by hand so we can spend our time learning and improving as engineers.