Where AI Actually Helps in a Codebase
The gap between the demo and your Tuesday afternoon. What these tools are genuinely good at, and the categories where they reliably waste your time.
The demos show a blank file becoming a working app. Your job is mostly not that. Your job is a codebase somebody else started, with conventions that are half-documented, a test suite that takes eleven minutes, and a bug that only appears in staging.
AI coding tools are extremely useful in that environment — but not in the places the demos suggest. The developers who get real speed out of them are the ones who worked out the boundary early.
Where the gain is real
These share a shape: the problem is well-specified, the answer is verifiable in seconds, and being wrong is cheap.
- Translation — this SQL as an ORM query, this callback as async/await, this Python function in TypeScript
- Boilerplate with a known shape — a CRUD endpoint matching three existing endpoints, a form component, a migration
- Explaining unfamiliar code — a 300-line function you inherited, a regex, someone's clever one-liner
- First-draft tests for a pure function, especially the edge cases you would have skipped
- Shell, config and glob syntax you look up every single time and never retain
- Naming and API shape — 'give me six names for this function' is a genuinely good use of a language model
Where it reliably costs you time
- Architecture decisions in a system it cannot see. It will produce a confident, generic answer that ignores the constraint that actually matters
- Anything depending on a library version newer than its training data — it will invent a plausible API that does not exist
- Bugs whose cause is in a different file than the symptom. Without that file, it will 'fix' the symptom and hide the bug
- Performance work without measurements. It will optimise what looks slow rather than what is slow
- Security-critical code — auth, crypto, permissions. Not because it is always wrong, but because you cannot verify it as fast as it can produce it
Confident wrongness looks exactly like confident rightness
A junior developer who is unsure says so, or writes hesitant code you can spot. A model that is unsure produces the same fluent, well-formatted, correctly-indented output as when it is right. There is no tell in the style.
This matters most with library APIs. `client.messages.create()` and `client.message.send()` look equally real. The only defence is running it — which is why the sweet spot is code you can execute in seconds.
A working rule
Use AI for code you could have written but did not want to. Be careful with code you could not have written — not because using it is cheating, but because you cannot review what you do not understand, and unreviewed code is what you will be debugging at 11pm.
If you do accept code you do not fully follow, make understanding it the next task rather than the never task.
What to take from this chapter
- The gain is largest where the spec is clear, verification is seconds, and being wrong is cheap
- Avoid it for architecture in code it cannot see, unmeasured performance work, and security-critical logic
- Wrong output looks identical to right output — style carries no signal
- Never merge what you would not have approved in a colleague's pull request
Try it
Look back at your last five AI-assisted coding sessions. Sort them into 'saved time' and 'cost time'. The pattern that emerges is more useful than any general advice, because it reflects your codebase and your stack.