Agentic coding tools: a year-one review
A year ago, AI in the editor mostly meant autocomplete. Now we have tools that edit across files, run commands, and work through a task while you watch. After a year of using them in real work, here's an honest review: what they're genuinely good at, where they fall down, and how they change the job.
A year ago, AI in the editor mostly meant autocomplete — Copilot suggesting the rest of a line or a function as you typed, which you accepted or ignored. Useful, but bounded: it was a faster way to type code you were already going to write. Over the past year that’s changed shape entirely. The tools now in daily use are agentic: you describe a task, and the tool edits across multiple files, runs commands, reads output, and works through the change while you supervise — autocomplete grew up into something that does multi-step work, not just completes a line. I’ve spent the year using these in real production work, and this is an honest year-one review: where they genuinely shine, where they fall down, and — most importantly — how they change what the job of programming actually is.
What changed: from autocomplete to agent
The shift is worth naming precisely, because it’s a difference in kind, not degree. Autocomplete operated at the level of the line or the block: it predicted what you were about to type next, in the file you were in. An agentic tool operates at the level of a task: “add a column and wire it through the form and the API,” “find why this test is flaky and fix it,” “refactor this class to extract the payment logic.” It reads the relevant files itself, makes coordinated edits across several of them, runs the tests or the build, sees the result, and iterates. That’s the agent loop I wrote about for LLMs in general — model decides an action, observes the result, decides the next — applied to your codebase with your editor and shell as the tools. The same pattern, pointed at programming.
Where they genuinely shine
After a year, the strengths are clear and, in some cases, genuinely impressive. The tools are strongest where the work is well-specified and pattern-heavy:
- Boilerplate and mechanical changes. Wiring a new field through model, migration, form, controller, and view; adding a standard endpoint; generating tests that follow an existing pattern. This is work that’s tedious but unambiguous, and the tools do it fast and mostly correctly. The drudgery-removal is real.
- Working in unfamiliar territory. Dropping into a language, framework, or codebase you don’t know well, the tool’s ability to read the surrounding code and produce something idiomatic is a real accelerant. It compresses the “how do they do things here?” ramp-up.
- Mechanical refactors across many files. Renaming a concept everywhere, extracting a method, applying a consistent change across a codebase — the kind of repetitive, spread-out edit that’s error-prone by hand and well-suited to a tool that can make the same change in twenty places consistently.
- Exploration and explanation. “How does this part work?” “Where is X handled?” The tools are excellent at reading a codebase and explaining it, which is genuinely useful for onboarding and navigation independent of writing any code.
In these areas the productivity gain is not hype — it’s a real, daily speedup on a meaningful fraction of the work, and it’s why these tools have stuck.
Where they fall down
Equally clear after a year are the failure modes, and they’re the mirror image of the strengths. The tools are weakest where the work requires judgment, deep context, or genuine novelty:
- Subtle, system-wide design decisions. Asked to make an architectural choice with trade-offs that depend on context the tool can’t fully see — performance characteristics, future direction, business constraints — it produces something plausible that may be subtly wrong in ways you only catch if you know the system. It doesn’t have the judgment; it has the appearance of judgment, which is more dangerous.
- Confident wrongness. The single most important thing to internalize: the tools are often confidently wrong. They produce code that looks right, runs, even passes a shallow test, but is incorrect in a way that requires real understanding to spot. The fluency is decoupled from the correctness, exactly as with every LLM output I’ve written about.
- Anything genuinely novel. Where the task isn’t pattern-matchable to things seen before — a truly new algorithm, an unusual constraint, a clever optimization — the tools struggle, because their strength is recombining patterns, not inventing them.
- Large, vague tasks. Hand an agent a big, underspecified goal and it tends to wander, make sweeping changes, and produce a mess. They work far better on bounded, well-specified tasks — the same lesson as agents in general.
The common thread is that the tools are pattern-matchers of extraordinary fluency, and they fail exactly where fluency isn’t enough — where you need understanding, judgment, or novelty.
How the job changes
The most significant thing isn’t the speedup; it’s how the role shifts. Using these tools well, you spend less time writing code and more time specifying, directing, and reviewing it. The model writes; you decide what to ask for, and you scrutinize what comes back. This has real consequences:
- Review becomes the core skill. Because the tools are confidently wrong, the discipline that matters most is reading generated code critically — understanding it, not just running it. A developer who accepts generated code they don’t understand is accumulating a codebase nobody understands, which is a slow catastrophe. The seatbelt is the same as for any LLM output: never trust it because it looks right; verify it because you understand it.
- Specifying clearly is leverage. The clearer and more bounded your request, the better the result — which makes the ability to decompose a task and specify it precisely a more valuable skill than ever. It’s prompt engineering applied to your own work.
- Understanding still can’t be outsourced. The tool can write the code, but you remain responsible for it. You can’t review what you don’t understand, so the tools don’t remove the need to understand the system — if anything they raise it, because you’re now responsible for code you didn’t write line-by-line.
This is not the “AI replaces programmers” story, and after a year I’m confident it isn’t that. It’s a change in what programming is: less typing, more directing and reviewing; less time producing code, more time deciding what code should exist and verifying that what was produced is correct. The skill shifts toward judgment, and judgment is exactly what the tools don’t have.
Verdict
A year in, agentic coding tools have moved from autocomplete to something genuinely different: tools that take a task, edit across files, run commands, and iterate — the LLM agent loop pointed at your codebase. The review after a year of real use is neither hype nor dismissal. They genuinely shine on well-specified, pattern-heavy work — boilerplate, mechanical refactors, unfamiliar territory, exploration — where the daily speedup is real and is why they’ve stuck. They fall down exactly where fluency isn’t enough: subtle system-wide design, genuine novelty, large vague tasks, and above all confident wrongness, producing code that looks right and isn’t. The deepest change isn’t the speed; it’s that the job shifts from writing to directing and reviewing — which makes critically reading generated code the core skill, clear specification a form of leverage, and understanding the system something you still can’t outsource, because you can’t review what you don’t understand. Used with that discipline — bounded tasks, critical review, ownership of the result — these tools are a real and lasting improvement to how the work gets done. Used carelessly — accepting confident code you don’t understand — they’re a fast way to build a codebase nobody can maintain. The tools changed; the responsibility didn’t.