Guardrails for agentic coding: making AI write like your team
An agent can generate a thousand files before lunch. Left unsupervised, it will also generate a thousand small inconsistencies — three ways to handle errors, two naming conventions, a folder structure no human chose. The trick to coding with agents isn't getting more output. It's making the output conform to your patterns, automatically, every time.
When teams first turn an agent loose on real work, the demo is intoxicating: describe a feature, watch the files appear. Then they try to merge it, and the cracks show. The code works, but it doesn't look like their code. It reaches for a library they'd never approve. It invents a fourth pattern for something they'd already solved three times. Multiply that across a team and a few months, and you've traded a tech-debt problem you understood for an entropy problem you don't.
The fix isn't to slow the agent down. It's to give it a paved road — a clearly marked path where doing the right thing is the easy thing — and a feedback loop that catches it the moment it wanders off. Here's how I set that up.
Codify your patterns as reference, not folklore
Most teams' "standards" live in people's heads and in the muscle memory of code review. An agent can't read muscle memory. So the first move is to make your patterns explicit and machine-readable: a short, living document that says exactly how you build a controller, a service, a data-access layer, a test — with a real, canonical example of each.
This is the single highest-leverage artifact in the whole system. The agent is extraordinary at imitation and mediocre at invention. Give it one excellent example of "this is how we write a service in this codebase," feed that example into every relevant task, and it will produce the fourth, fortieth, and four-hundredth service to match. Skip it, and it improvises — beautifully, and differently, every time.
An agent doesn't follow your standards because you wrote them down. It follows them because you showed it what "right" looks like and made "wrong" impossible to miss.
Make your standards executable
A style guide a human reads is a suggestion. A style guide a machine enforces is a wall. The goal is to turn as much of your judgment as possible into checks the agent can run itself:
- Formatting and linting. A formatter and a strict linter config remove an entire category of "looks wrong" before a human ever sees it. Non-negotiable, zero-discussion, applied on every file.
- Architectural rules as code. Boundaries you care about — this layer may not import that one, these modules stay decoupled — can be expressed as automated checks that fail the build. The agent learns the boundary because it keeps bouncing off it.
- Project conventions encoded in config. Naming, file layout, allowed dependencies. The more of this lives in tooling rather than tribal knowledge, the less the agent can drift.
The point of all this isn't bureaucracy. It's that every rule you can make executable is a rule you never have to enforce by hand again — for a human or a machine.
Close the loop: generate, check, correct, repeat
This is the heart of structured agentic coding, and it's where most setups fall short. Don't run the agent open-loop — generate code and hope. Run it closed-loop: the agent writes a file, then immediately runs the formatter, the linter, the type checker, the architectural rules, and the tests, reads the output, and fixes what it broke before moving on.
That feedback cycle is what turns a plausible-looking draft into something that actually holds. The agent is good at reacting to a concrete error message — far better than it is at getting everything right on the first pass. So your job is less "review every line" and more "make sure the agent is being graded continuously, and that the grader is strict." When the loop is tight, the agent self-corrects toward your standards without you in the seat.
Use more than one model — and never let a model grade its own homework
A model reviewing its own output is a notoriously soft grader; it's primed to agree with what it just produced. The cure is cheap and effective: use a different model to review than the one that wrote the code. Cross-model review surfaces blind spots that a single model — however capable — will talk itself past.
In practice I run a small ensemble with distinct jobs:
- A builder generates the implementation against the pattern examples.
- A reviewer — a different model — critiques it cold: correctness, adherence to the standards, security, edge cases it ignored. It hasn't seen the "reasoning" that produced the code, so it's not invested in defending it.
- A tester focuses purely on adversarial test cases: the inputs the builder conveniently forgot, the failure paths, the boundary conditions.
Different models have different blind spots and different strengths. Playing them against each other gives you something closer to a real review culture than any single model can — and it scales to a volume of changes no human review team could keep up with.
Tests are the contract, not an afterthought
Generated code that compiles and passes a generated test is not the same as correct code — especially when the same model wrote both. So tests get extra scrutiny: I want the tester model writing characterization tests against intended behavior, I want a human signing off on the tests that define what "correct" even means, and I want the whole suite gating every change. The tests are the place where your intent becomes enforceable. Treat them as the most important artifact the agent produces, because they are.
Keep humans where judgment lives
None of this removes the human — it relocates them. You're no longer hand-writing the fortieth CRUD controller. You're doing the three things that actually require judgment: defining the patterns the agents imitate, setting the rules the loop enforces, and owning the merge — the final call that this change belongs in the system. The agents handle volume and consistency. You handle direction and the standard everything is held to.
Done well, this flips the usual fear about AI-generated code on its head. Instead of a flood of inconsistent output you have to police, you get a codebase that's more uniform than most human teams produce — because every file passed through the same paved road, the same strict grader, and the same cross-model review, without exception and without fatigue. That consistency is the real prize. The speed is just the bonus.