Running AI coding agents in an existing codebase
The practices that decide whether an AI coding agent speeds a team up or quietly generates a month of debugging. Mostly about the repository.
Most teams adopting AI coding agents start with prompting and are disappointed. The leverage is not there. It is in how the repository is set up, how work is scoped, and what counts as evidence that something is done — and those are engineering decisions, not phrasing.
This is the standard we hold our own delivery to, written for an engineering lead introducing agents into a codebase that already exists and already has users.
Start from an accurate mental model
An AI coding agent is fast, literal, widely read, and systematically overconfident. It is not a junior engineer — a junior asks when lost, forgets less, and learns permanently. Treating it as one is the root of most bad outcomes, because it invites exactly the kind of trust the tool cannot support.
Three consequences follow, and everything else in this guide is downstream of them.
- Fluency is not competence. A wrong answer arrives in the same tone as a right one, with the same formatting and the same air of authority. “It sounded sure” is not evidence.
- Context is the product. Output quality is dominated by what the agent can see, not by how well the request is phrased. An agent that has read the calling code, the tests and the configuration produces a different class of work.
- Verification cannot be delegated to the thing being verified. An agent asked whether it did the job correctly will usually say yes. The check has to come from outside its own judgement.
And the goal is not speed. An agent can generate a week of code in an hour and a month of debugging alongside it. What matters is throughput of work that ships and stays shipped.
Most of the work is preparing the repository
A repository set up well makes every future session better. One set up badly makes every session start from zero. This is where the time goes, and it is a one-off cost against a permanent gain.
- Keep a single agent instruction file, checked in. Versioned, reviewed, shared — one file, one source of truth. It holds the exact build and test commands, a one-line directory map only where the structure is non-obvious, conventions a reader could not infer from the code, and the hard prohibitions: protected branches, files never to touch, actions that require a human.
- Write instructions as testable imperatives. “Write clean code” is unenforceable. “Run the test command before reporting done, and paste the output” is enforceable. A rule that cannot be checked will not be followed — by people either.
- Encode conventions in tooling rather than prose. A linter, formatter, type checker or CI gate teaches through immediate feedback. A paragraph in a document does not, and it drifts until it is actively misleading.
- Make the fast feedback loop genuinely fast. Agents iterate against whatever signal exists, so a forty-minute test suite means the agent guesses instead of checking. Build a subset that runs in seconds and say so in the instruction file.
- Keep secrets out of reach. Assume anything in the working tree may end up in a prompt, a log, or a support ticket.
- Give the agent a scratch directory, ignored by version control. Without one, exploratory scripts and intermediate files land in your source tree and then in your diff.
What to leave out of the instruction file matters as much: anything the code already states clearly, aspirational standards nobody follows, and long prose. Every token spent describing the repository is a token not spent on the task.
Scope deliberately, because agents expand scope by default
Left alone, an agent tidies adjacent code, renames things, and improves whatever it passes. Naming the boundary in advance is far cheaper than reviewing the overreach afterwards.
- One task, one deliverable. “Fix the bug, refactor the module and add caching” yields three mediocre attempts.
- Separate diagnosis from implementation. Ask why first, read the answer, then decide whether and how to fix. An agent that diagnoses and fixes in one motion has already committed to its first theory.
- State acceptance criteria up front — what must be true, which tests must pass, what must not change. Without them the agent invents its own definition of done, and it is more generous than yours.
- Say what is out of scope, explicitly.
- Distinguish blocking from non-blocking unknowns. Blocking means proceeding on any assumption would be unsafe or would waste the work if wrong. Everything else: state the assumption and continue.
Match the tool to the task
Agents are well suited to boilerplate, test scaffolding, mechanical refactors, exploring an unfamiliar API, searching a large codebase, first-draft documentation, and reading logs and stack traces.
They are poorly suited to novel architecture, decisions with irreversible consequences, and anything where the right answer depends on context that lives in someone's head or in a meeting rather than in the repository. Knowing which side of that line a task sits on is most of the skill.
The working loop
A predictable cycle. Skipping stages is what produces the “it wrote a thousand lines of garbage” experience that puts teams off entirely.
- Explore before planning. Have the agent read the relevant code and report what it found, with file and line references, before proposing anything. Misunderstandings surface while they are still cheap.
- Get the plan in writing, and actually read it. This is where a wrong approach costs one paragraph instead of one pull request. Skimming the plan and then carefully reviewing six hundred lines is the expensive order to do it in.
- Confirm the intent before implementation begins.
- Implement in reviewable steps rather than one long run.
- Verify from outside the agent — a test that runs, a type check, output someone reads.
The pattern underneath is that every stage produces something a human can inspect before the next stage multiplies it.
Evidence, not assurances
“Done” should mean a command was run and its output is visible, not that the agent believes the work is complete. This single rule removes most of the failure modes people attribute to the model.
The same applies to review. Code from an agent is reviewed as code, by a person who is accountable for it. Volume is not a reason to review less carefully; it is the reason review matters more. Nobody gets to say the agent wrote it.
The anti-patterns worth naming
- Accepting a diff nobody has read, because the tests passed.
- Asking the agent whether its own work is correct, and treating the answer as verification.
- Prompting harder instead of fixing the repository — rewording a request that fails because the agent cannot see the relevant code.
- Letting one session run for hours without an inspectable checkpoint.
- Measuring adoption in lines generated rather than in work that shipped and stayed shipped.
How to adopt it
Start with the repository, not the tooling. Get the instruction file, the fast test subset and the scratch directory in place, then use agents on well-bounded, low-risk work — tests, boilerplate, mechanical refactors — while the team builds a feel for where the tool is reliable.
Expand scope as the verification story gets stronger, never ahead of it. A team that can prove what an agent did is a team that can safely let it do more.
AI & Automation
Smarter business systems through practical AI and automation.
Start a conversation
Let's find where value is leaking in your ecosystem.
Bring us the workflow, the channel, or the half-built thing that's stuck. In 30 minutes we'll tell you plainly which parts should connect, where intelligence pays back — and what it takes to ship.