I’ve had the luxury of working at a number of companies with strong engineering cultures. They were typically led by one or more bizarrely talented engineers, and had built frustrating but effective hiring processes that ensured a high quality (if slow growing) technology organization. The majority of candidates didn’t pass the interview, and while there were plenty of close calls and false negatives, we also talked to a surprising number of people who couldn’t even write FizzBuzz. I frequently wondered about these people, where they ended up, how they navigated their careers – and the uncomfortable fact that they seemed to be the norm.
If all you’ve ever heard is a high school orchestra, you might be forgiven for not recognizing a world-class violinist in the wild. And if you aren’t yourself an engineer, it’s easy to imagine that all engineers are the same, and that the main differentiator between one organization and another is headcount, seniority, and credentials (or, as one executive once told me, “I can hire as many PhDs as I need”). If, on the other hand, you’ve ever worked with a top team, then you know that they’re a completely different thing.
And let’s be fair. To a non-techie, engineering is a bit of a mysterious art. You have an individual (or team) who disappears into a cave, consumes a frankly disturbing amount of caffeine and junk food, and delivers a… thing… that magically does something you want. If, like most of humanity, you have no conception of how computers work, the entire process is a riddle, wrapped in a mystery, inside an enigma. If you are an engineer (which is pretty much the entire readership of this blog), then you have no idea why normies can’t understand this (obligatory xkcd). The idea that building software could be reduced to a non-technical process must be deeply appealing to someone who both needs the deliverable, and has no idea what it is or how to create it on their own.1
So, the majority of programmers are somewhere between mediocre and terrible at writing code.2 A non-technical leader has no way to differentiate, and so they guess. In the rare case that they guess well, their company gets +5 luck, all the time – one good engineer pulls in other good engineers, and engineering becomes a source of strength. In the vast majority of cases, bad early choices result in a weak engineering team that’s a constant drag on business success.
Quick sidebar: at a previous job, the two non-technical co-founders spent years building a company around contractors, with a primary hiring criterion of price. While there were some good ones sprinkled into the mix, these contractors created a massive pile of technical debt so bad that each business unit magnified the problem by hiring their own contractors to work around it, making business decisions based on their own interpretations of the data, none of which mattered because the data pipeline failed constantly. It took years to dig ourselves out of the hole, by which time it was way too late.
Which brings us to AI.3 If engineers were fungible, code quality was meaningless, software engineering principles were irrelevant, and the only thing that mattered was speed of delivery, then AI would be perfect for all use cases. Why wouldn’t you use it for everything?4 Building an infinitely-scalable, industry-standard team would just be going to the engineering store, picking up a couple six packs, and taking them back to the office to write code. Some chess players are demonstrably better than others, but if all you’re doing is playing tic-tac-toe, then anyone – including a machine – is as good as anyone else, and price and convenience become the primary criteria. This is the real conversation we’re having when we talk about replacing engineers with AI.
Someone out there is going to argue that actually the frontier models create high quality code.5 Or that human engineers also create bugs. Or that you can use automated tests or adversarial AI as guardrails to define functionality and drive quality. Or that the output is the only thing that matters. But as a software engineer, it’s important to remember why we care about software engineering principles. It isn’t just because they’re cute, or cool, or make us feel all snug and oogly inside. We care about the quality of the underlying code because we understand that code is an investment – good or bad, depending on how it was written. We wouldn’t replace one great engineer with ten terrible engineers, because we understand that the long-term cost would far outstrip any short-term gain.
The man who does not read has no advantage over the man who can’t.
– attributed to Mark Twain
The idea that AI is a replacement for software engineers is a category error. A bottom-quartile engineer isn’t in the same category as a top engineer, and agentic AI is in the first category, not the second. Likewise, it’s not enough to say that your team is made up of top engineers who use AI to gain productivity. As described previously, your engineers are getting worse at coding every time they use AI. They’re going from writing code, to reviewing code, to reviewing high level descriptions of code, to looking at the output of automated tests, to trusting the automations that look at the output of automated tests. You’re turning them into non-coders, reducing their skills to the level of the AI – and converting them from one category into the other.
- I feel this way about graphics and UX. Not using AI is a choice. ↩︎
- I understand that this sounds elitist. I refer you to Sturgeon’s Law. ↩︎
- You knew we were going to get here eventually, right? ↩︎
- Other than that it prevents learning, destroys expertise, removes intrinsic motivation, and accelerates the rolling disaster of climate change. But hey, you do you. ↩︎
- This is laughable, and can be immediately disproven by looking at the code for any vibe-coded app. If you’re looking for something more metrics driven, then I would direct you to the recent 1Password research on AI-driven security fixes. ↩︎