AI for Developers: How AI Is Changing Software Engineering
The developer's job is shifting from writing code to defining tasks and checking the output. Here's what's actually changed in engineering work: from code review and testing to hiring and technical debt.
How AI is changing the developer's role: from coder to architect
Three years ago, a developer was accountable for every line they personally typed. Today, more and more of the code in a given project is written by an agent under that developer's direction, not by hand, and the job is shifting toward defining tasks, reviewing output, and making architectural calls.
That doesn't mean writing code by hand is obsolete. It means the share of time that used to go into typing now goes into articulating exactly what needs to be done, and into checking that it was done correctly. A developer who can't clearly frame a task and can't carefully review someone else's code (including AI-generated code) loses more productivity than one who simply types slowly.
It's worth separating two claims early, since debates about this shift constantly blur them together. First: the share of routine typing in a developer's job is shrinking. That's just an observable fact, backed up by the experience of any team that's adopted agentic tools. Second, and far more contested: the value of the profession itself is shrinking along with that share. That doesn't follow automatically from the first claim, and the rest of this piece is about exactly why these two claims diverge more than they appear to at first glance.
A telling detail: the set of skills that used to separate a good developer from a mediocre one has partly shifted. Being able to instantly recall the syntax of a rarely used standard-library method has lost almost all its value, because that's exactly the kind of task any current model handles instantly and without errors. Meanwhile, being able to break a vaguely stated requirement down into concrete, verifiable steps has become noticeably more valuable, because that's the skill that determines whether an AI tool produces something useful or just fast, confidently wrong code.
The rest of this piece covers what's actually changed in engineering work: how to pick tools, how to test and refactor with AI, what happens to onboarding, technical debt, and hiring, and where the profession itself is heading. The specifics of working with Claude Code (setup, CLAUDE.md, reviewing agent-written code) get their own separate breakdown in AI coding assistants in practice. This piece takes the wider view: the whole discipline, not one specific tool.
The landscape of AI development tools
The market for AI development tools has split into several categories, and most of the confusion comes from comparing tools across categories that are actually solving different problems.
Next-line autocomplete, like classic GitHub Copilot in its original form, speeds up typing but doesn't take on task definition. Agentic tools, like Claude Code, Cursor in agent mode, or Windsurf, take an entire task in natural language and decide for themselves which files to change. Specialized assistants for individual tasks (test generation, code review, migrations) are usually more precise in their narrow niche, but require stitching together several tools instead of one general-purpose one.
Picking a tool for a team usually comes down to three questions. How much is the team willing to trust autonomous edits without line-by-line review. What stack and internal conventions does it need to respect. And how costly is a mistake in this specific project: the bar is lower for an internal tool than for a payments service. There's no universally correct answer here. A team working with sensitive data reasonably picks a more cautious, less autonomous setup than a startup where speed matters more than perfect predictability.
Another practical criterion that's easy to underrate: how well the tool fits into the team's existing workflow, instead of requiring the workflow to bend around the tool. An agent that works beautifully in isolation but integrates poorly with version control, the issue tracker, or CI creates a steady stream of extra context switches that, over time, eat away at whatever speed was gained from the code generation itself. It's worth explicitly testing this during a trial period before rolling a tool out to the whole team, rather than trusting marketing copy about its capabilities.
Different roles on a team also benefit from AI unequally. A backend developer working against a clearly specified API often gets more autonomy from an agentic tool than a frontend developer who constantly has to check against a visual result and needs tighter, shorter-iteration feedback. That's not a reason to skip the tool for one role. It's a reason to tune the working mode (how much autonomy, how long the iterations) separately for each kind of task, instead of applying the same setup across the whole team.
DevOps and infrastructure work deserve a separate note precisely because of how expensive mistakes get there. An autonomous edit to a production cluster's config or a deploy script carries a completely different level of risk than an autonomous edit to an internal utility, even though both formally fall under "infrastructure code." A noticeably more conservative autonomy setting is justified here than the team average, regardless of how well the agent handles similar tasks in less critical parts of the system.
Prompt engineering for developers: patterns that actually work
Framing a task for an AI tool is its own skill, and it doesn't transfer cleanly from writing specs for humans, because a model doesn't fill in unstated context with common sense the way an experienced colleague does.
A few patterns that hold up consistently:
- Context before the task, not after. A model processes information sequentially: giving it context first (which file, which part of the system, what constraints exist) and the actual task second produces a more accurate result than the reverse order.
- Explicit statements of what not to do. "Don't touch the config files," "don't change the public API" head off the most common unwanted side effects of an autonomous edit.
- Ask for a plan before execution on anything above trivial difficulty. A few seconds spent reading a plan saves far more time than untangling a task that got done wrong.
- A concrete definition of done. "Done when all tests pass and the linter is clean" works better than an open-ended "make it good."
The principle tying all four together: the less a model has to guess, the more predictable the result. That's not specific to any one tool. It's just how working with language models goes in general.
A fifth pattern, less obvious but noticeably worth it on harder tasks: state the format you want the response in before the work starts, not just the content of the task. "Show me a diff before applying changes" or "list the files you're planning to touch before you start" turn the agent from a black box that just hands back a finished result into a process with intermediate checkpoints, where it's easier to catch a wrong direction before it's baked into the entire set of changes.
An example of what this looks like in practice, a weak and a strong version of the same task:
Weak: fix the auth bug.
Strong: in auth/middleware.rs, users with an expired token get a 500
error instead of the expected 401. Reproduce: log in, wait for the
token to expire (or manually set an expired date in the database), hit
any protected endpoint. Expected behavior: the middleware should return
401 with the body {"error": "token_expired"} before the request reaches
the handler. Don't touch the handler's own logic, the problem is in the
middleware.
The difference between these two isn't politeness or length for its own sake. It's how many assumptions the agent has to make on its own. In the weak version, the agent has to find the file itself, invent its own definition of "fix," and decide for itself what counts as done. In the strong version, every one of those decisions has already been made by a human, and the agent is left with exactly what it's actually good at: making a precise change quickly.
Solo development with AI: how one engineer does a team's job
The most visible structural shift of the last few years: a small team, or a single developer working alone, can now cover a volume of work that used to require a team of several people.
Why Small Teams Outpace Large Ones already covers the reasons a small team outperforms a large one even without AI in the picture: lower communication overhead, faster decisions, simpler architecture. AI amplifies exactly those advantages instead of creating new ones. An agent effectively absorbs the chunk of routine work that a larger team would have split across several junior developers, freeing the senior engineer up for architecture and review.
An important caveat: this works for tasks where the bottleneck is the volume of routine code, not the number of parallel workstreams. Wherever a project genuinely needs different people with different specializations at the same time (sales, customer support, a specialized domain), AI doesn't replace the team. It only replaces part of the engineering routine inside a single role.
A practical rule of thumb for estimating in advance how compressible a given piece of work is: how much of the total effort behind a product is actually code, versus client conversations, sales, legal, and financial work that an agent can't take on at all. A product where the engineering piece dominates everything else compresses the most. A product where engineering is just one of several equally weighted pieces compresses noticeably less, and inflated expectations here are usually what leads people to get disillusioned with solo development as an idea, rather than any real failure of the method itself.
There's a less obvious downside to solo development with AI: it removes the built-in check that a team provides just by having other people around. On a three-person team, a strange architectural decision usually gets caught on a call or in a pull request before it settles into the codebase. A solo developer working with an agent can spend months moving in a direction the team would've stopped in the first week, simply because there's no one around to say "hold on, why are we even doing it this way." You can compensate for this deliberately: showing your code to someone outside the project periodically, keeping a public blog about your technical decisions (which is disciplining in itself, see the piece on second brains and digital gardens), or at minimum, saying your architectural decisions out loud to the agent and explicitly asking it to poke holes in them instead of just approving them.
AI and legacy code: refactoring with language models
Working with old, poorly documented code is one of the areas where AI delivers the most noticeable win, because that's traditionally where the most time went into understanding what's happening rather than into making the actual change.
A working approach to refactoring legacy code with AI:
- Explanation first, changes second. Ask the model to explain what a specific piece of code does and why before touching anything. It often turns out the code doesn't do what its function name implies.
- Tests for current behavior before refactoring. If there are no tests, the agent's first job is writing them for what the code actually does right now, not what it's supposed to do in theory. That establishes a baseline you can safely work from.
- Small steps with a check at each one. Legacy code often rests on implicit dependencies, and a big refactor all at once sharply raises the risk of breaking something invisible. A step-by-step refactor with a test run after each step catches that kind of breakage earlier.
- An explicit list of what not to touch. Legacy code often contains deliberate, if odd-looking, decisions (workarounds for third-party bugs, specific hacks). It's worth explicitly asking whether the existing code has comments or patterns pointing to cases like that before "improving" them.
A separate category of legacy work: code with zero tests and not a single person left at the company who wrote it. The same logic applies here as with research sources that have no metadata: first ask AI to map out the dependencies and figure out which parts of the system are actually used and which are dead code left over from earlier iterations of the product. Removing unused code often cuts more risk than refactoring what remains, because it eliminates the surface area where something could quietly break in the first place.
A separate practical difficulty with AI-assisted legacy refactoring: an agent that doesn't know the project's full history sometimes proposes an "improvement" that actually reintroduces a decision that was already reverted in the past. If the codebase has code deliberately written in a non-obvious way to work around a bug in a specific library version, and there's no comment explaining it, the agent can very well "fix" that workaround and bring the bug right back. A useful safeguard: before a major legacy refactor, explicitly check the git history for similar changes that were made and later reverted, and why.
Testing with AI: generating unit tests and coverage
Test generation is one of the tasks where you can extend the agent's autonomy faster than average, because the cost of a mistake is lower here: a bad test usually just fails on its own instead of quietly breaking production.
A useful practice: ask for tests covering specific categories of cases, not just a generic "write tests." Happy path, edge cases, bad input, behavior when an external dependency is unavailable. Without an explicit request, a model most often covers only the happy path, because that's the most obvious case, and the edge and error scenarios are usually exactly where the real bugs live.
It's also worth watching the quality of the tests themselves, not just the coverage percentage. A test that checks that a function was called, rather than that it returned the correct result, technically bumps up coverage but doesn't guard against regressions. A quick check: comment out the meaningful part of the function under test, and the test should fail. If it still passes, it's not a test. It's the illusion of one.
Another practice that pays off: ask the agent to generate not just tests for what the code should do, but tests specifically aimed at breaking the code (fuzzing-style edge values, unexpected data types, concurrent access where relevant). Models explicitly told to "try to break this function" produce noticeably sharper test cases than a neutral "write tests" prompt, because shifting the role from "checker" to "attacker" changes which scenarios the model even considers.
It's also useful to sort tests by how expensive they are to maintain, not just by what they check. A model left to its own devices readily generates an excess of small implementation-detail tests, ones that break on any harmless refactor and need constant upkeep without any real benefit to system reliability. Explicitly asking it to focus on behavior visible from outside the function or module, rather than internal implementation details, cuts down on this bloat of brittle, low-value tests.
AI for code documentation: automating technical writing
Documentation traditionally goes stale faster than the code itself, because writing it isn't fun and it's the first thing to get dropped under time pressure. AI changes the economics of that task, but it doesn't remove the need for it.
What actually works: generating a first draft of documentation from already-written code (function comments, API descriptions, a README for a new module), followed by a human editing pass. What works worse: fully automated documentation with no review, because a model sometimes documents what it believes the code is supposed to do based on its own understanding, rather than what it actually does, especially when there's a hidden bug or non-obvious behavior involved.
A practical rule: AI-generated documentation needs the same level of scrutiny as code does. It's not exempt from mistakes just because it's "only text."
One specific case is especially dangerous: documentation that describes the code's intent rather than its actual behavior. If a function is called validateEmail but a bug lets some invalid addresses through, a model documenting from the name and the surrounding structure will most likely describe correct validation, because that's what the function is supposed to do based on its name and the code around it. The resulting documentation will be clean, convincing, and wrong at the same time, which is exactly why documentation for critical parts of a system should be checked not just against the code, but against actual behavior on test data, not just what the code visually appears to do.
A case that works well: generating a changelog and release notes from commit history. The risk here is lower (it's descriptive text about something that already happened, not an instruction someone's going to execute), and the tedium is correspondingly high, since manually turning dozens of commits into a coherent list of user-facing changes is one of the least-loved recurring tasks on any team. The one condition for this to work well: commit messages themselves need to be meaningful (see the git-practices section in the piece on AI assistants), or AI just automates generating meaningless text from meaningless input.
How AI changes onboarding on new projects
Getting a new person up to speed (or getting yourself back up to speed on a project after a long break) traditionally took weeks of figuring out the structure, conventions, and non-obvious decisions. AI cuts this phase down more noticeably than any other part of development.
A working approach: instead of reading code line by line, ask an AI assistant with repo access to explain the overall architecture, find the entry point for a specific piece of functionality, and show where the logic for whatever you're interested in actually lives. This doesn't fully replace reading the code, but it sharply cuts the time that used to go into just getting oriented in an unfamiliar structure.
There's a risk hiding here too: getting too fast a surface-level familiarity with a project through AI explanations creates an illusion of understanding, similar to what's described in the piece on learning with AI. The gap between "AI explained the architecture to me" and "I understand the architecture" is the same gap as between reading someone else's notes and actually understanding the material yourself. It's worth deliberately checking yourself during the first weeks on a new project: could I explain this part of the system without the model's help.
A practical first-week plan that combines the speed of AI explanations with actual understanding. Day one: ask for a general architecture overview and write it down in your own words, without copying the model's phrasing. Day two and three: pick one small, isolated task and work through it with AI, but explain to yourself at every step why the solution is built the way it is. By the end of the week: try to explain the project's architecture to a colleague, or at least out loud to yourself, with no open AI chat in front of you. If it comes easily, the onboarding stuck. If you find yourself peeking, it's worth setting aside a bit more time for reading the code on your own instead of relying only on the model's summary.
AI in code review: what's worth automating
Automating code review with AI deserves its own deep dive: tools, metrics, where automation genuinely catches problems and where it just adds noise. AI Code Review: How to Automate Reviewing Code covers this in detail.
Briefly, here's where code review sits in the bigger picture of engineering with AI: it's the one step you can't skip, even with high autonomy for the agent elsewhere. Writing code and checking it require different kinds of attention, and delegating both steps to the same agent with no independent check means losing the one real defense against the model's own systematic blind spots.
A telling principle worth remembering now, before getting into the details in the dedicated piece: a model that wrote the code tends not to notice problems in it when reviewing within the same conversation, because it's already "bought into" its own solution. A fresh context (a new conversation, or better yet a different model) gives a noticeably sharper, more useful review than asking "now check your own work" in the same window.
The risks of AI development: technical debt from AI-written code
AI doesn't just speed up development. It also creates a new kind of technical debt that's easy to miss, because the code formally works.
Three specific sources of this debt. Duplicate patterns: an agent that doesn't know about an already-existing similar solution elsewhere in the codebase often writes something new from scratch instead of reusing it, and over time the project accumulates similar-but-slightly-different implementations of the same logic. Excess abstraction, or a lack of it: models default toward one of these two extremes depending on their settings, and without review, it builds up unnoticed. And code written "correctly" by general best practices but a poor fit for this specific project: a universally good pattern sometimes clashes with a specific architecture if the agent didn't know the full system context.
A fourth source, less obvious than the first three: excessive error checks that never actually trigger. Models trained to write "safe" code tend to add error handling for cases that physically can't happen in this specific system, just because that kind of check looks like good practice in the general case. Bloated code with dozens of impossible error branches is no less dangerous than code with no error handling at all: it hides the real logic under a layer of defensive code that will never be needed but still has to be read and maintained with every nearby change.
The prevention is the same as for any other kind of technical debt: regular review specifically aimed at duplication and consistency, not just correctness of an individual task, plus explicit project conventions written into the agent's instructions rather than relying on the model to guess the right style on its own.
A useful periodic practice that catches this kind of debt before it piles up critically: every few weeks, ask an AI agent with access to the whole repo to find duplicate or near-duplicate chunks of logic on its own. It's a task that would take a human manually paging through the entire project, while a model can pass over it all in a single request. Not every duplicate found needs immediate fixing, but the list of candidates for consolidation is already a useful signal about where the project's architecture is drifting without explicit oversight.
AI pair programming: working effectively alongside a language model
Pair programming with AI differs from pair programming with a human in one key respect: the partner never gets tired, never gets annoyed at being asked the same thing twice, but also doesn't have the intuition of a live colleague, the kind that often catches a problem before it can even be put into words.
A format that works: hold the role of "navigator," continuously checking and steering, rather than a passive observer of what the model does. Ask questions as you go ("why did you pick this approach," "what happens if condition X changes") instead of just accepting or rejecting the finished result after the fact. This doesn't just guard against mistakes. It also preserves the actual understanding of the code that's easy to lose in a fully passive mode.
A useful technique borrowed from classic human pair programming: deliberately swap roles now and then. First the agent writes the code while the developer steers and checks. Then the task flips: the developer writes it themselves, and the agent is only asked to comment out loud, the way a real partner would, flagging potential problems without rewriting the code for the human. The second mode gets used less often, but it's the one that best trains the ability to spot those same problems on your own, without leaning on the model to fix them for you.
The right balance between the two modes depends on how new the task is for the developer personally. On familiar ground, where intuition is already well calibrated, the first mode (agent writes, human checks) gives maximum speed with almost no quality loss. On unfamiliar ground, where your own intuition hasn't formed yet, it's usually better to write it yourself with the agent as commentator, because it's the act of writing that builds the understanding that later makes working with an agent on that same territory faster and more reliable.
AI tools for debugging: finding bugs faster
Debugging with AI works best when the model gets specific symptoms, not a generic "something's broken." The technique for framing this is covered in detail in the piece on working with AI assistants in development.
A real example from this exact project: the CMS's slug generator was mistransliterating Cyrillic article titles, and it wasn't just getting them slightly wrong, it was dropping two specific letters exactly where they shouldn't be dropped: the "hard sign" and "soft sign," letters that modify pronunciation and have no Latin equivalent. The cause turned out to be a single line: the code looked up each letter's translation in a transliteration table, and when the lookup returned an empty string (the deliberately correct value for both of those two letters), it fell back to the original Cyrillic character instead of keeping the empty string, because JavaScript treats an empty string as falsy. Without a specific broken slug to point to, AI would've hunted for the problem for a while. With a concrete input and expected output, it found the cause in a single pass.
This illustrates a general rule: the more precise the reproducible example, the faster and more accurate the diagnosis, and that holds for both AI and humans. It's just that for AI, the gap in diagnostic speed between a vague report and a precise one tends to be more dramatic.
There's a category where AI is especially strong: bugs that only show up in a specific combination of conditions scattered across several files. A human has a hard time holding the entire data path through a system in their head at once, while a model with access to the right files can walk that entire path in a single request. A practical technique: instead of trying to trace the logic yourself through five files, ask the agent to build the full call chain for a specific scenario, from the entry point to where the bug shows up, noting what happens to the data at each step. That turns the task from "find the bug" into "show me the full picture," and finding the bug itself in a picture that's already been laid out step by step is almost always easier than finding it in the original fog.
Comparing AI models for code: Claude, GPT, Gemini
Models differ noticeably on coding tasks, and the difference doesn't collapse into a single "which model is best" ranking. It depends on the specific type of task.
| Model | Strong for code | Weaker at |
|---|---|---|
| Claude | Long context with no degradation, careful on multi-step agentic tasks, less likely to invent a nonexistent API | Sometimes more conservative with suggestions where a bold refactor is actually what's needed |
| GPT | Broad coverage of languages and frameworks, good at fast, targeted edits | Can lose context in long, multi-file sessions more than its competitors |
| Gemini | Strong with multimodal content (UI screenshots, architecture diagrams) alongside code | Agentic capabilities historically developed later than its direct competitors' |
Practical takeaway: for long agentic sessions with lots of files and steps, the gap in favor of models with better context retention is noticeable in practice, not just in benchmarks. For one-off, targeted tasks, the gap between the top models is usually smaller than the gap created by how precisely the request is phrased.
A practice that helps you compare models objectively on your own work, instead of trusting someone else's benchmarks: keep a small set of three to five real tasks from your own project at varying difficulty, and periodically run them through different models, comparing not just the final result but how many rounds of clarification it took to get to a correct solution. General benchmarks measure a model's average ability to solve someone else's tasks. For your specific stack and conventions, the result can look noticeably different from the general ranking.
Worth keeping in mind: this kind of model ranking goes stale faster than most technical decisions in development. Models update on a cycle of a few months, and the relative strengths that are accurate today can easily flip by the time any of the major providers ships its next big release. A sensible strategy is not to lock into one model out of loyalty, but to keep switching between them cheap: a single, model-agnostic format for prompts and instructions makes that switch easier whenever it's needed.
How AI is changing hiring and evaluating developers
Interviews built around writing algorithms on a whiteboard with no access to tools are increasingly disconnected from how developers actually work day to day. That creates a gap between what gets tested in an interview and what actually determines productivity on the job.
What matters more when hiring in the age of AI assistants: the ability to clearly frame a task, the ability to review someone else's code (including generated code) quickly and carefully, and architectural understanding deep enough to judge whether a proposed solution actually fits a specific system. What's become less telling: the speed of typing syntactically correct code with no assistance, since nearly everyone leans on that to some degree now.
Some teams are experimenting with a "solve this problem together with an AI assistant, like you would on the job" format instead of banning tools during interviews. That reflects the working reality more accurately, though it also requires rethinking the evaluation criteria: what matters isn't whether the candidate solved the problem, which is almost always possible with a good agent, but how they steered the process and whether they caught mistakes in the result.
This same shift in criteria applies to evaluating people already on staff, not just hiring. Performance reviews built around metrics like lines of code or tickets closed lose their meaning even faster than before, because those metrics now mostly measure how aggressively someone delegates work to an agent, not the quality of their engineering decisions. Companies that keep using metrics like these out of habit should explicitly reconsider what they actually want to reward.
A specific format that gives more signal than a classic algorithm question: hand the candidate a real (simplified but not artificial) piece of code with a deliberately planted problem, and an agent on hand, then watch how they frame the task, verify the proposed solution, and react if the agent's first attempt doesn't fully solve it. This surfaces exactly the skills that determine real-world productivity: not memorized syntax, but the ability to drive a problem from start to finish using the tools available, without losing control of the outcome.
AI-driven development: where a team should start
Moving a team to agentic development takes more organizational groundwork than it looks like at first, because it touches more than just tooling. It touches review processes, how responsibility is distributed, and the structure of the repo itself. Architecture for AI-Driven Development covers the architectural side of this transition in detail.
A practical starting minimum: repo-level instructions for the agent, not personal settings each developer configures individually. Explicit rules about which kinds of changes need extra scrutiny during review (see the technical debt section above). And a gradual expansion of scope, starting with low-cost-of-error tasks (tests, documentation, small refactors) rather than jumping straight to critical business logic.
An organizational trap a lot of teams fall into at the start: rolling out agentic tools top-down, as one decision for the whole team at once, with no pilot period on a single small team or project. Tools that work beautifully in one context (a small service with good test coverage) can behave completely differently in another (a decade-old monolith with almost no tests). A pilot on one team gives you the chance to work out real conventions, not hypothetical ones, before rolling them out to the whole organization.
Ethics and AI code: not losing your engineering skills
The growing reliance on AI agents raises a fair question: do your own skills atrophy if a significant chunk of the code isn't written by you personally.
The answer depends on how AI actually gets used. Passively accepting output with no understanding genuinely does lead to skill atrophy, the same pattern described in the piece on learning with AI, applied here to engineering. Actively using AI as an amplifier, with constant review, "why this way" questions, and periodic unassisted practice, can, on the other hand, deepen understanding faster than working alone, because the model keeps surfacing alternative approaches a developer might not have thought of themselves.
A practical recommendation: periodically solve problems entirely without AI, not because it's more efficient (usually it isn't), but as a way to honestly check that your base skills are still there. It's the same closed-book-test principle that applies to learning in general.
There's a less-discussed side to this same topic: accountability for code that a human didn't technically "write." If an agent generates a vulnerability or a bug that leads to an incident, the developer who accepted and shipped the result is accountable for it, not the tool. This is a direct continuation of a principle that's existed for a long time, not a new ethical standard: an engineer is responsible for the code they ship to production, regardless of where that code came from, whether it was copied from Stack Overflow, generated by autocomplete, or written by an agent. Changing the tool doesn't change who's accountable.
AI for migrations and stack upgrades
Migrations (a major framework version bump, moving to a new library, switching languages for part of a system) have traditionally ranked among the least-loved tasks in development: lots of mechanical work, high risk of quietly breaking something, and a result that looks to the business like "the same thing, but it took longer."
AI changes the economics specifically of the mechanical part: automated discovery of every place a deprecated API is used, pattern-based generation of the replacement, running tests after every step. What AI doesn't remove: the need to understand why a specific migration is necessary in the first place, and the judgment calls in ambiguous cases where a mechanical, one-for-one replacement doesn't fit. Migrating a large project still needs a human who holds the big picture and resolves the edge cases, but the volume of grunt work that used to be done by hand, line by line, shrinks dramatically.
A working sequence for a major migration: first ask the agent to compile a complete list of every place affected by the change, before touching a single line. This gives a realistic estimate of the scope of work before it starts, not after, when it's too late to change the plan. From there, split the migration into batches by logical grouping (one module, one feature), not by arbitrary file order, so a full test run after each batch confirms the system stays working throughout the migration, not just at the very end.
A specific practical risk of AI-accelerated migrations: the speed at which an agent can apply the same replacement pattern across an entire codebase also raises the scale of any potential mistake if the pattern doesn't fit some of the cases. A replacement that's correct for ninety percent of the matched spots and quietly breaks the remaining ten would, in a manual migration, have surfaced gradually, one case at a time. In an automated migration, it gets applied everywhere at once, and if test coverage is incomplete, that ten percent of errors stays invisible until it's in production. That's exactly why a full test run after every batch, not just at the end of the whole migration, is the only real defense against this scenario here, not a box-checking formality.
Common mistakes when adopting AI in development
- Trusting the output with no review because "the code works." Working code and correct code aren't the same thing. Code can pass every test and still contain a logic error the tests don't cover, or quietly violate the project's conventions.
- Giving vague tasks and being surprised by vague results. The less context and specificity in the framing, the more the final result diverges from what was actually intended.
- Using the same conversation for dozens of unrelated tasks in a row. The context gets cluttered the same way it does in learning scenarios, and the agent starts confusing which part of the system is actually being discussed.
- Ignoring the buildup of technical debt from AI-written code, because each individual task looks fine on its own. Duplication and stylistic inconsistency only become visible when you look at the whole project, not a single pull request.
- Not giving the agent project instructions, relying on the model to guess conventions from the surrounding code. Sometimes it guesses right, sometimes it doesn't, and the quality gap between explicit and implicit instructions is usually large.
- Rolling out agentic tools across the entire team at once with no pilot on a smaller group, so configuration mistakes and settings that don't fit this specific project get scaled to everyone at once, instead of being caught and fixed on a small group first.
- Completely stopping writing code by hand. Periodic unassisted practice remains the only reliable way to check that base skills haven't quietly atrophied.
Economics: when AI development is genuinely faster
The speedup from AI tools isn't universal, and an honest assessment requires admitting where it's real and where it's more of a feeling than a measurable fact.
AI delivers the biggest speedup on tasks with a high ratio of routine to unique complexity: generating tests for logic that's already well understood, migrations following a clear pattern, documentation, boilerplate for a new module modeled on an existing one. The multiple-times gains here are real and easy to confirm in practice.
AI delivers a modest speedup, or none at all, on tasks where the bottleneck isn't writing code but making a decision: an architectural choice with long-term consequences, diagnosing a problem with a non-obvious cause, aligning on requirements with a client. Here, an agent can help work through options faster, but a human still makes the actual decision, and that's where most of the time goes.
A practical takeaway for measuring ROI at the team level: don't measure the effect of AI tools as an average across every task at once. Split tasks by type and look at the speedup separately for routine categories and decision-heavy ones. A team expecting the same multiplier across the board is likely to end up disappointed, even if the real gain on well-suited tasks is substantial.
The future of the developer profession in the age of AI
The question "will AI replace developers" isn't quite the right one. The more precise question is: which part of a developer's current work stays valuable, and which part turns into a routine, interchangeable service available to anyone who can clearly frame a task.
A detailed look at this topic, with forecasts and no hype in either direction, is in AI and the Future of the Engineering Profession. Briefly, here: writing code as such is getting cheaper, and will keep getting cheaper. The ability to understand what actually needs to be built, how it should behave in the context of a real system, and how to verify the result is genuinely correct isn't getting cheaper, because that's exactly what remains the bottleneck even with perfectly capable AI tools.
A useful historical parallel: the profession has already gone through a similar transition more than once, just at different levels of abstraction. The move from assembly to high-level languages didn't eliminate the programming profession. It eliminated the need to keep processor registers in your head and freed up attention for higher-level work. The move from writing your own data structures to using standard libraries didn't eliminate the profession either. It shifted the value from being able to write a good search tree to being able to correctly pick an existing structure for the job. AI agents continue that same trajectory at the next level: they remove the need to keep syntax and routine patterns in your head, but they don't remove the actual task of understanding what's being built and why.
The difference from previous transitions is in speed, not direction. The move from assembly to high-level languages took years for the industry to adapt to. The move to agentic development is happening within one or two years, in plain view, and that speed is exactly what's fueling the sense of anxiety in parts of the industry, even though the shift itself is structurally similar to the ones that already happened.
Where to go from here
Everything covered here is the big picture of how AI is changing engineering work. The specifics of working with Claude Code (setup, agent instructions, review, autonomy boundaries) are covered in a separate piece on AI coding assistants in practice.
If you're specifically interested in automating code quality checks, AI Code Review: How to Automate Reviewing Code covers that separately and in detail. If the question is how to restructure your architecture and repo layout for effective work with AI agents, not just processes, Architecture for AI-Driven Development continues this topic at the technical level. And if you're curious where the profession as a whole is headed, beyond any specific set of tools, AI and the Future of the Engineering Profession covers that without tying itself to today's particular stack.
Takeaways
- The developer's role is shifting from writing code to defining tasks, reviewing output, and making architectural decisions. That doesn't remove the need to understand code. It changes where deep understanding actually needs to happen.
- AI delivers its biggest win exactly where the most routine time used to go: legacy code, testing, documentation, onboarding, migrations.
- A new kind of technical debt (duplication, stylistic inconsistency, code written with no awareness of the wider system) needs the same deliberate management as any other kind of technical debt.
- Your own skills don't automatically atrophy from using AI, but they don't stay sharp on their own either. It depends on whether you work with the model actively, with constant review and questions, or passively accept the output without looking closely.
- The AI speedup is uneven: large on routine, clearly specified tasks, modest where the bottleneck is the decision itself rather than writing the code. Measure the effect by task category, not as an average across all work.
- The profession is going through a transition structurally similar to the move from assembly to high-level languages: the routine at one level of abstraction gets removed, but the value of understanding what's being built and why doesn't.
Comments
No comments yet. Be the first.