7 min read

Published Updated

I Stopped Prompting and Started Specifying: How I Work With Coding Agents

The practices that decide whether a coding agent helps or costs you time: context budgets, spec-first delegation, parallel runs, verification gates, and knowing when to stop prompting.

When I first wrote this in February 2025, it was a post about Cursor, and it promised 100x productivity. I had no measurement behind that number. I want to be blunt about it, because the post was doing the thing I now find least useful in writing about AI tooling: asserting a multiplier, describing which buttons to press, and calling the result a practice.

Almost every tool-specific detail in that version is now wrong. Features were renamed, replaced, or absorbed into something else, and the editor I was writing about is no longer the place most of my work happens. That is the actual argument for writing down habits instead of keyboard shortcuts.

So here is the rewrite. These are the practices I use daily to ship Go, Python, and TypeScript with agents doing most of the typing, and the honest accounting of what I can and cannot claim about them.

The one number I have, and what it does not prove

When I pulled eighteen months of my own commit history across fifteen production repositories, monthly commits went from between 50 and 90 up to roughly 300, and the inflection lines up with rebuilding my workflow around agents.

That is throughput. It is not value, it is not quality, and it is not a multiplier. I do not know my defect rate before versus after, and I am suspicious of anyone who says they do. What I can say is that the shape of my day changed: less typing, much more specifying and reviewing. Everything below is about making that trade come out in your favor.

Context is the input, not the prompt

The single biggest lever is what the model can see when it starts. Prompt wording matters far less than people think once the context is right, and no amount of prompt polish rescues a model that is guessing at your conventions.

Two things I do:

Keep a repo-level instruction file, and keep it short. Claude Code reads CLAUDE.md, and will read a repository's AGENTS.md too. AGENTS.md is the cross-tool version of the same idea, now stewarded under the Linux Foundation and, by its own count, in over 60,000 open-source repositories. Whichever filename your tools read, treat it as a budget, not a wiki. Build and test commands, the conventions that are not inferable from the code, the directories that are off limits, the two or three mistakes agents repeatedly make in this repo. A stale instruction file is worse than none, because it produces confidently wrong work that is also consistent with your written rules.

Point at files, not at the whole repo. Whole-codebase retrieval is a convenience for exploration and a liability for editing. When I know the three files that matter, naming them beats letting the agent go looking, every time. The failure mode of too much context is not slowness, it is that the agent anchors on an unrelated pattern it happened to find.

Spec first, and write the spec for a reader who will not ask questions

This is the practice that changed my output most, and it is not an AI practice. It is the same thing I argue about deciding what to build, just with a shorter feedback loop.

Before delegating anything non-trivial I write down the goal, the constraints, the files in scope, what is explicitly out of scope, and how I will know it worked. Usually a few hundred words. It takes ten minutes and it routinely saves an hour, because the gap it closes is the one a human colleague would have closed by asking a clarifying question. An agent does not ask. It picks.

The corollary is uncomfortable: a vague spec used to produce a stalled ticket, and now it produces a confidently wrong implementation at speed. Ambiguity got more expensive, not less.

I have also stopped treating "write the spec" as a chore to hurry through. If I cannot state the acceptance condition in one sentence, I do not understand the task yet, and delegating it is going to cost me more than doing it myself.

Parallel runs, with disjoint file surfaces

Running more than one agent at a time is genuinely useful and routinely oversold. What makes it work is not the number of agents, it is whether their work touches the same files.

Two tasks in unrelated directories, or a code change in one session and an investigation in another, parallelize cleanly. Two tasks in the same module produce two plausible diffs that conflict, and reconciling them costs more than doing them in sequence would have.

The other limit is me. Reviewing two diffs properly is not faster than reviewing one, and an agent finishing while my attention is elsewhere is how unreviewed code gets merged. I cap myself at what I can actually read.

Verification gates before the diff counts

My rule is simple: nothing lands on the strength of an agent's own report that it works.

The gates in order, cheapest first. Type check and lint, because they are free and catch a surprising share of hallucinated APIs. Tests, run by me rather than reported to me. Then actually running the thing, which for voice work means placing a real call and grading it, because a pipeline can pass every test and still leave two seconds of dead air on the phone. Those graded calls are the only verification that has ever caught the failures that matter in my domain.

The point of automating these is not rigor for its own sake. It is that an agent can run them itself and iterate before handing me anything, which moves the loop off my attention.

Read the diff, not the summary

An agent's summary of its own work is a claim, and the claims are usually accurate about what was attempted and unreliable about what was achieved.

Specific things I look for, because they have each bitten me:

  • Scope creep. A refactor nobody asked for, bundled into the fix. It is often an improvement, which is what makes it easy to wave through, and it is also why the diff is now three times bigger than the change it needed to be.
  • Tests that assert the implementation. A test written after the code, by the thing that wrote the code, frequently just restates it. It passes forever and protects nothing.
  • Silent fallbacks. Swallowed errors, default values where an unknown value should have been an explicit failure. In a provider-neutral pipeline this is the worst possible bug, because the system keeps working while doing the wrong thing.
  • Deleted safeguards. A guard clause or a validation that was in the way of making something pass.

Volume makes this harder, not easier. Three hundred commits a month is three hundred commits somebody has to have read. If the review is the thing you skip to get the speed, the speed is not real.

Know when to stop prompting

The failure mode I still fall into is correcting instead of restarting.

The agent gets it 80 percent right, I explain what is wrong, it fixes that and breaks something else, and I explain again. Two rounds of that and I am negotiating with a transcript instead of solving a problem. My rule now is two corrections. After that I either rewrite the spec and start a clean session, or I write the code myself. Almost always the original spec was the problem, and continuing the conversation just accumulates context that argues for the wrong approach.

There is also a category of work I have stopped delegating at all. Anything where the hard part is a judgment call I cannot articulate yet, and anything touching the parts of the system where I need the mental model in my own head, because losing that is a cost that shows up weeks later during an incident.

What I am still unsure about

Whether any of this nets out positive in value delivered rather than commits produced. Throughput I can count. Quality I mostly cannot, and the honest position is that I have a strong subjective sense and no instrumentation.

I also do not know how much of my current practice is durable and how much is compensating for this year's limitations. The verification discipline I expect to outlive every tool in my setup. The context choreography is probably temporary scaffolding that better models make unnecessary, and I would not be sad to lose it.

Written by

Software Engineer II at Spyne. I build production voice agents, telephony infrastructure, and developer tools, and contribute to the LiveKit Agents SDK.

Experience and open-source contributions →
Issue Tracking Is Dead. The Ticket Is Just a Receipt.I pulled 18 months of my own commit history to test whether tickets still do anything. Here is what the data shows, including the part that contradicts me.Aug 2026AI Made Building Faster. We Still Have to Decide What to Build.Small teams can ship more with AI. But unclear requirements still send us back to rebuild. My thoughts on planning, prototypes, and engineering judgment.Sep 2026Claude Code: The AI Coding Assistant That Lives in Your TerminalWhat Claude Code actually does in a terminal, how it differs from an editor plugin, and where an agent that reads and edits your repo earns its keep.Mar 2026
Continue exploringWriting indexAll writing.