What I Stopped Doing After a Year of Coding With Agents
Suneet Malhotra
Apr 27, 2026
I have spent roughly a year writing the majority of my code with an AI coding agent in the loop. Not autocomplete on steroids. The kind where I describe a change, the agent edits the files, runs the tests, reads the failures, and iterates until the diff makes sense. The first six months I tried to use these tools the same way I used IDEs and search engines and Stack Overflow. That was wrong. Below are five habits I have actively stopped, and the specific reason for each.
1. I stopped writing inline comments that explain what code does
For years I wrote comments like "// validate that the bracket order has both stop and limit set" above the corresponding if-block. The reasoning was that future-me, reading the code six months later, would appreciate the hint.
What I noticed in the past year is that future-me does not read those comments. The agent does. And the agent is far better than me at reading the code itself. The comments rot anyway. They survive refactors that change the code but leave the comment claiming the old behavior. Then the next time I ask the agent to edit that section, the stale comment is the most authoritative-looking piece of input in the function. I have watched an agent "fix" code to match a comment that was wrong by twelve months more than once.
The new rule: a comment exists only if it explains a non-obvious why. A constraint. A workaround for a specific bug. An invariant that a reader could not infer from the code. Everything else is noise to me and misinformation to the agent.
2. I stopped pre-writing skeleton code for the agent to fill in
This was the biggest unlearning. Early on I would write the function signature, the docstring, a few pass statements, the import block, and then ask the agent to fill it in. I was treating the agent like a junior engineer who needed scaffolding.
The result was almost always worse than letting the agent write the file from scratch. My pre-written scaffold encoded assumptions the agent then could not relax. If I had picked the wrong abstraction in the signature, the agent would write fifty lines of code working around it rather than tell me the abstraction was wrong.
The new rule: I describe what I want, point at the file, and let the agent propose the structure. If the structure is wrong, that is now visible in one round of review instead of buried inside fifty lines of compliant-but-wrong code.
3. I stopped asking the agent to think about it
Modern agents have multi-step reasoning baked in. Asking them to slow down, work through a problem, or "think harder" used to be a useful prompt. It is no longer reliably useful, and at the long tail it produces longer responses without higher quality.
What works instead is constraining the output. "Show me the diff" is more productive than "think about the right approach." "Give me three options with tradeoffs" is better than "what is the best way." The instruction to constrain the output shape pulls the reasoning into the open, where I can audit it, instead of leaving it as a paragraph of preamble I have to read past.
This sounds like a prompt-engineering tip. It is actually a workflow tip. The shape of what I ask for determines what I have to verify, and verification is the slow step now.
4. I stopped reaching for the chat for one-line questions
If I want to know what a flag does or what a function returns, opening a chat is a four-second context switch. The agent is on. The IDE is on. There are five other panes open. The cost of the context switch is real, and the answer to a one-line question is usually three keystrokes away in the source file itself.
The rule I have now: chat is for changes. Reading is for reading. If I want to know something about the code, I read it. If I want to change something, I describe the change to the agent. Mixing the two turns the chat into a generic search box, and using a model as a search box is the most expensive way to search ever invented.
5. I stopped pretending I was going to read every line of agent-written code
This one was hard for me. I was raised on the discipline that you read every line you commit. With an agent writing roughly eighty percent of the code I ship, that discipline does not scale, and pretending it did was pushing me into one of two failure modes. Either I would skim a hundred-line diff, call it reviewed, and ship it. Or I would slow down to the agent's typing speed for no good reason, which defeats the entire point of the tool.
What I do now: I read agent-written code at the level I would review a teammate's PR. I follow the diff. I check the boundaries. I run the tests. I do not stare at every line of a hundred-line function in a language and a library I trust. The honest version of "I reviewed it" replaced the performative version, and bug rates have not gone up. They have gone down, because the time I used to spend skim-reading I now spend writing better tests around the boundaries the agent crosses.
The pattern
These five habits have one thing in common. They were all designed for a world where the bottleneck was my typing speed and the cost was my time staring at code. Both bottlenecks moved. The discipline that fits the new shape of work is to constrain and audit rather than to scaffold and read.
A year in, the engineering work I do feels less like writing code and more like designing the contract the code is allowed to live inside. Set the shape of the output. Verify the boundaries. Trust the middle until something breaks, and when it breaks, write the test that would have caught it. The five habits above are the ones that quietly go away the first time that shift is real for you.
Share this post
You Might Also Like
The Test That Cannot Name What It Expects
An LLM step is not a pure function, so no gate in this routine can assert what the post says. Every check I run is a property the output must obey, never a value it must equal.
AI & AutomationThe One Step I Never Hand to a Subagent
My content routine dispatches a fleet of subagents to gather, then hands none of them the draft. A fleet parallelizes retrieval. It cannot parallelize a voice.
Quantitative TradingA Retry Is Not a Trading Decision
A rejected order is a decision. Retrying it without preserving the reason can turn a risk control into a duplicate trade.
Agentic AIThe Log Is Part of the Agent's Interface
An agent that can act but cannot leave a useful decision record is not autonomous. It is an opaque process with write access.
Latest Blog Posts
A Retry Is Not a Trading Decision
A rejected order is a decision. Retrying it without preserving the reason can turn a risk control into a duplicate trade.
The Log Is Part of the Agent's Interface
An agent that can act but cannot leave a useful decision record is not autonomous. It is an opaque process with write access.
The Market Is Closed Is Not a Trading Rule
A backtest can know the exchange hours and still schedule a trade into a holiday, an early close, or a stale session. Calendar state is market data.
Related Tools & Demos
The QA Field Manual to Language Models
A free 24-chapter book. Start at “what is AI, really?” and finish with a small language model you built yourself — one that reads a failing Playwright test and proposes a fix you can run. Read it in your browser, or download the PDF or the Mac app.
View Source Code →Multi-Model LLM Harness
One interface to call any AI model — capability routing, fallback chains, budgets, circuit breakers, and a quality feedback loop. A practical architecture pattern write-up.
Automated Trading System
Multi-engine trading platform with real-time risk management, regime-based strategy selection, and automated order execution.
View Source Code →
Stay in the Loop
Get weekly insights on AI-driven QA, engineering leadership, and automation strategies.
No spam, ever. Unsubscribe anytime.