AI coding tools generate two kinds of takes: they will replace engineers, or they are useless autocomplete. After a couple of years building both a full-time government platform and my own apps with these tools in the loop, I land somewhere more boring and more useful. They are a leverage multiplier on judgment I already have, and they are dead weight when I do not know what good looks like. Here is how I actually use them.
Where they earn their keep
Architectural exploration. Before I commit to a navigation approach or a state management pattern, I have the model argue several designs against each other for my specific constraints. It is faster than a whiteboard and it surfaces tradeoffs I would have discovered two days into the wrong path. I still make the call; the model just widens the set of options I am choosing from.
Test generation. This is the highest-return use for me. I write the interesting test, the one that encodes the behavior I actually care about, and then I let the tool fan it out across edge cases: empty inputs, boundary values, the concurrency race I keep forgetting. Coverage that used to feel like a chore becomes cheap enough that I stop skipping it.
Mechanical refactors. Extracting a shared Swift package across three apps, renaming a concept that leaked into forty files, migrating a callback API to async/await. The work is unambiguous and tedious, which is exactly the profile where an agentic tool shines and where a human is most likely to make a careless slip.
Where I deliberately hold back
I do not let a model design the security-critical path. On the hardening work I have written about elsewhere, every line is mine, because the failure mode of "looks plausible, subtly wrong" is unacceptable when the wrong version still compiles and still passes the happy-path test.
I also do not accept generated code I could not have written myself. The moment I am pasting something I do not understand, I have traded a short-term speedup for a long-term liability I will own at 2am during an incident. The tool's output is a draft I am responsible for, not an answer I get to stop thinking about.
The mental model that works for me
I treat the AI like a fast, tireless junior pair who has read everything and remembers nothing about my product. It is brilliant at the parts of the job that are pattern-heavy and context-light, and it needs me for the parts that are judgment-heavy and context-rich. My job did not disappear; it moved up the stack. I spend less time typing boilerplate and more time deciding what should exist and verifying that what got built is actually right.
That shift, from author of every line to director and reviewer of the work, is the real skill these tools demand. It is also, not coincidentally, the same skill that separates a senior engineer from a junior one.