Coding at a Higher Abstraction
There is no going back to the old way of writing code. Best to learn the new way properly.
Not too long ago, “using AI to code” just meant you had a really fast autocomplete. And by not too long ago, I mean just one year back.
You still used your editor (the hottest game in town was Cursor - it was an IDE). You still had the files open. You were still the one writing the code, emotionally and literally. The AI was basically just a smart buddy guessing your next few lines (and eventually, the entire body of a function).
We’re not in that world anymore.
It’s not only that models got smarter. The actual unit of work we hand off has shifted. We aren’t asking for the next line or function any more. We’re asking for the next feature, a bugfix, a database migration, or a whole pull request. The machine isn’t just suggesting text, it is reading your repo, editing files, running bash commands, fixing its own typos, and coming back with something that genuinely looks like finished work.
This is why debating “real programmers” vs “vibe coders” feels played out. GitHub’s 2023 survey already called AI tools mainstream. Fast forward to 2025, Stack Overflow’s survey shows almost everyone is using or planning to use them. The big players aren’t hiding it either—Google admitted over 25% of their new code is AI-generated, and YC is seeing startups with 95% AI-written codebases.
So yeah, I’m not here to argue if this shift is happening. It’s already here. The real question is: what actually happens to our day-to-day programming when we stop caring about individual lines and move one abstraction layer up?
1. The Cursor Left the Editor
A lot of people think AI coding is just the same old job but on fast-forward.
It really isn’t.
The old way of writing code was super intimate. Open a file, write a function, agonize over variable names, tweak the signature, spot a code smell, refactor, change your mind, and finally land on something that works. Most of the actual thinking didn’t happen before writing the code—it happened while you were typing it out.
The new ‘loop’ is radically different. You just drop into a terminal or a chat UI and say: “build this flow, wire up that endpoint, migrate this module, write the tests, and fix the build until it’s green.” And then you just watch it go. Or honestly, if your test suite is solid, you don’t even watch. You go grab a coffee and come back to see if it actually did it or if it completely hallucinated.
And this isn’t some futuristic hypothetical. Anthropic already pushes Claude Code as the “first stop” for eng tasks. GitHub is pushing agent-mode hard so the AI just loops until the job is done. Even Google’s Jules tool straight-up assumes developers just live in the terminal now.
When that shift happens, something weirdly subtle disappears: the file itself isn’t your main workspace anymore.
It sounds like a minor detail, but it changes your entire relationship with the codebase. You aren’t molding the code line by line anymore. Instead, you’re describing what you want, setting boundaries, and checking the results. Sure, sometimes you step in and fix things manually. But if you start micromanaging the AI—getting mad about camelCase vs under_scores, or where a private helper method sits—you completely lose the massive speed boost this whole workflow gives you.
This is why I think the term “vibe coding” is kind of funny but also misleading. Karpathy’s joke hit hard because we’ve all been there. But as Simon Willison pointed out, not all of this is just blindly riding the vibes. There’s a serious version of this workflow where you actually understand the system, you write tests, you jump in when needed, and you own the final outcome—even if you didn’t physically type every single character yourself.
Whatever we end up calling it—agentic coding, or just modern software engineering—this is where the industry is going.
2. Bringing an Excavator to a Shovel Fight
I keep hearing the “pair programming with a robot” analogy. That doesn’t sufficiently capture the change. To me it feels more like the difference between digging a ditch with a shovel versus operating an excavator.
Yes, at the end of the day, you get a hole in the ground either way.
But being amazing with a shovel doesn’t mean you know how to drive an excavator. And mastering the excavator doesn’t mean you’d win a manual digging contest in someone’s backyard. They’re related, but they’re fundamentally different skillsets.
I bring this up because a lot of devs still talk about AI like it’s somehow “cheating” at shovel work.
It’s not cheating. It’s just a completely different process.
I felt this hard when I was messing around with some side projects recently. One was a CLI tool to sync .env files across my laptops. I hacked together an ugly prototype in bash first, and then wrote a lot of end to end tests for it. All of it with lots of help from AI ‘generating’ the code, but I did it all from a proper IDE. Then I let the AI rewrite the whole thing in Go while I just kept the test suite green. I just wanted to see what a cross-language rewrite feels like when the machine does the heavy lifting. Another project was a 2FA app where, using agents, I shipped clients for web, CLI, desktop, iOS, Android, Apple Watch, and Wear OS in a fraction of the time it would normally take me to hand-code all those different platforms.
Now, before anyone gets defensive, let’s be real: this doesn’t mean your enterprise day job is suddenly 100x faster. METR did a great study on experienced devs working on open-source repos and found that on gnarly, mature codebases, AI can actually slow you down. Legacy code has weird edge cases, migration headaches, and a ton of review overhead. AI doesn’t magically make that baggage disappear.
But for zero-to-one work? Prototypes, side projects, new features where you aren’t fighting legacy tech debt? The speed difference is so insane that pretending it’s just “a bit faster” is basically lying.
It’s not just about raw output speed. It’s about where you actually spend your brainpower.
When coding by hand, my brain was locked into the micro-details. Function signatures. Variable naming. If I made a bad choice at the low level, I felt the pain immediately while typing the next few lines. Like you make a function signature like
function doSomething(param1, param2, param3...)
then when using it you soon realise the number of parameters will increase eventually, and instead passing it in form of an object will be less disruptive to frequently updating the callsites so you change it to
function doSomething({param1, param1, param2...})
With agents, you zoom way out. I’m no longer saying “write a function that takes these three args”. I’m saying “make service A talk to service B, send an ID and a description, and honestly I don’t care if you use an enum or a string union as long as the tests pass.” That’s how a manager talks, not a coder.
This is why so many senior devs feel this weird disconnect right now. You aren’t coding less, you’re just coding from 10,000 feet up.
You can see this shift everywhere. Addy Osmani’s workflow is all about spending time on specs and architecture. Les Orchard’s routine literally boils down to writing a spec.md, generating a plan.md, letting the agent loose, and then reviewing the PR. Simon Willison nailed it when he said it feels like managing a super fast but overconfident intern. You just have to tell them exactly what to do.
You trade fine-grained control for massive leverage. You can’t have both. You can’t operate the excavator and still try to sift through every grain of dirt with your hands.
3. ‘Guardrail’ engineering
When you level up your abstraction, some of the older, boring tools suddenly become your best friends.
Testing is the obvious one.
When you write code by hand, the act of typing is how you maintain control. Your types, your function signatures, your if-statements—that’s where your discipline lives.
But when an agent is writing a whole feature for you, you can’t just dump a vague prompt and hope for the best.
If I tell an agent, “add cookie auth to this app,” I’m asking for a mess. It might invent a hybrid monster of JWTs, session tokens, local storage, and weird refresh logic. And if I just ask another AI to review it, we’re still just arguing over whether the code vibes correctly.
That just doesn’t cut it.
But if I write tests first—asserting the cookie is HttpOnly, the expiry works, cross-origin requests behave correctly—I suddenly have a hard boundary. I’m controlling the exact outcome instead of micromanaging the syntax.
Honestly, this makes Test-Driven Development (TDD) way more relevant now. Not because the old TDD evangelists were right all along, but because automated tests are literally the only way to steer an AI that writes code unpredictably. Anthropic spells this out—evals are just tests for AI. OpenAI’s docs say the exact same thing. We don’t care if the code looks pretty; we care if the system does what it’s supposed to do.
So the tools haven’t really changed. Tests, linters, CI/CD, type checkers—they were always good ideas. But now, they aren’t just the boring chores you do after writing the code. They are the steering wheel.
You can see the whole industry pivoting this way. GitHub’s agent docs and their product updates are entirely focused on isolated sandboxes, automated checks, and PR reviews. Hamel Husain has been shouting about “evals over vibes” for ages. Even Martin Fowler’s take on GenAI patterns hits the same point: when the AI is non-deterministic, “vibes” aren’t enough. You need hard checks.
When we wrote code by hand, control lived inside the syntax.
Now, that control has to live around the code.
4. Errors Now Hide One Layer Up
The wildest part about all this is that AI doesn’t just change how we write code, it also changes where the bugs hide.
When I typed everything manually, the slow, boring grunt work gave me time to think. While I was translating an idea into syntax, my brain was running a background check on the logic. I’d notice if a variable was redundant, if a security check was dumb, or if I was over-engineering a simple helper function.
When you abstract away the typing, you lose that built-in thinking time.
Here’s a real example.
I was building that .env sync tool I mentioned earlier. The idea, fairly simple: sync secrets across my Mac, Windows, and Linux boxes over my local network without hitting a cloud server. I told the agent the core requirements: LAN peer discovery, conflict resolution, use existing SSH keys.
The AI crushed it. It nailed the service discovery, the sync logic, the tests, the docs, and even wrote that overly eager README copy AI loves to generate.
But buried in all that great code was a totally useless security feature.
The AI decided to use AGE-based encryption at rest for the secrets. It sounded awesome in the docs. The README was flexing about how secure it was.
But it made zero sense for my setup.
These were all my personal machines. They already had SSH access to each other. If my laptop can SSH into my desktop to grab the encrypted files, it can just as easily grab the decryption keys too. The encryption was just security theater.
If I had coded this by hand, there was no question of me having made something like this. I would have considered a bunch of alternatives for the transport - say a custom Https/TLS server, or piggybacking over SSH/SCP. The moment I would have picked the later, it would simply never even be a consideration to then encrypt the secrets at rest with AGE. Because if I am already assuming the devices can read files from each other, including any ssh priv keys, what would the at-rest encryption even achieve?
If I had written encryption boilerplate first anyway before the transport, I would have stopped when implementing the SCP part and thought, “Wait, what threat model was I actually defending against here with that AGE encryption?”
But because the agent wrote it, the code just materialized. I only caught the flaw later when I was reviewing the system architecture and realized the AI had brilliantly solved a problem I didn’t actually have.
Now, if I was building this for untrusted devices, then yeah, I’d need actual transport security, pairing protocols, and encryption.
But that’s the whole point.
The AI didn’t write bad code. It just solved the wrong problem and confidently sold it to me as a feature.
This is a totally new class of bug.
This is exactly what Addy Osmani means by the “70% problem”. That first 70% feels like magic. But the last 30% is where the real engineering, edge cases, and architecture happen. It’s also why GitClear’s report on AI code quality is kind of scary—AI is great at churning out code, but terrible at refactoring and reflection. And Thoughtworks was right to warn us: AI can definitely help you build the wrong thing much faster.
In the old days, you’d catch these logic errors while sweating over the details.
Now, you have to actively hunt for them from a higher altitude.
5. Changing our priors
If this was just about individual devs typing faster, it wouldn’t be a big deal.
But it matters because our entire industry is built on assumptions about how we divide work, review PRs, mentor juniors, and track velocity.
And all of those assumptions were built for a world where writing the code was the bottleneck.
Take sprint planning and ticket sizing. We usually know exactly what kind of ticket goes to a junior, what subsystem a senior owns, and what architecture a staff engineer handles. That structure exists because we know how much complexity a single human can juggle.
Throw an AI agent into the mix, and suddenly a single dev can tackle a massive chunk of work. Anthropic’s internal research showed that AI isn’t just speeding up work—it’s empowering devs to take on massive refactors they wouldn’t have even bothered attempting before. The scope of “what’s worth doing” is expanding.
That doesn’t mean we just 3x the size of everyone’s Jira tickets. That’s a terrible idea (again, see METR’s study). It just means we need to recalibrate how we map seniority, task size, and review time.
Concepts like pair programming or mobbing are going for a toss too. The old model was one person driving, one person navigating. But if an AI is spitting out code so fast that two humans can barely read it, “watch me prompt” isn’t a great collaboration model. I bet live pairing is going to shift toward writing specs together, breaking down tasks, and designing tests, rather than watching a diff grow line by line. Let’s agree on the end goal before we let the AI loose.
And then there’s the code review. The sacred ritual.
We love to pretend that code quality is guaranteed because another human reads your PR. Honestly, reading code is harder than writing it, so that was always a stretch. But now? With AI generating massive PRs for free? The old review ritual is dead.
Sure, AIs are already doing code reviews. GitHub says Copilot has done tens of millions of them. Having an AI do a first-pass review is super helpful. But the real shift isn’t just using AI to read more lines of code. It’s about humans reviewing different things entirely.
Instead of nitpicking syntax, reviews need to focus on:
What exactly changed?
Why was this the right approach?
Are the tests actually proving the behavior?
What are the hidden assumptions here?
What breaks if the AI hallucinated the requirements?
Those are system-design questions, not code-golf questions.
Seniority starts looking completely different in this world. You still need deep system knowledge, good taste, and the ability to dive into the weeds when things break. But your daily leverage comes from writing killer specs, breaking down problems, validating outcomes, and having the gut instinct to know when the AI is confidently solving the wrong problem. It’s like LeadDev said—engineers are becoming editors just as much as authors.
So yeah, we really are moving toward coding at a higher abstraction. I don’t mean that in a buzzwordy startup pitch kind of way. I mean it literally. The baseline level of how we interact with code has fundamentally shifted upward.
You can still write code by hand. Sometimes you should. Sometimes you just want to feel the code beneath your fingers.
But industrial construction isn’t going back to shovels.
At work, where large companies pay thousands of engineers money by the order hundreds of dollars per hour, there is no doubt, the demands of velocity and productivity will dictate that most code is generated via agents than written by hand. This new reality is here, and it is to stay. Love it or hate it, this is the way most code in 2026 or beyond will be brought into existence.

