Writing

The Best Use of AI Coding Agents Isn't Writing Code

·7 min read·1416 words

I code with AI agents every day. Most people assume that means I'm letting autocomplete do the typing. In reality, I spend most of that time arguing with the models about architecture.

That's where the actual leverage is.

The common story about AI coding agents is that they make you faster at writing code. That's true as far as it goes, but software was never really about typing speed. The hard part has always been deciding what to build, how to structure it, and which trade-offs to accept.

You can have the most performant implementation in the world and still have wasted your time if you optimized for the wrong thing in the first place.

The question worth asking is how much of our time goes toward low-leverage execution versus high-leverage reasoning. AI keeps getting better at the execution side. That frees us up (if we let it) to spend more energy on the decisions.

There's a technique I landed on (thanks Ryan!) that reshaped how I work in that second category. It's straightforward: I get two AI models to critique each other's thinking, and use those two differing perspectives to help me make a decision.

This isn't about two AIs being smarter than one. You can't outsource decision-making to the models.

What you can do is use LLMs to make high-quality disagreement nearly free.

One engineer proposes an architecture --> Another engineer finds the holes --> Someone notices a constraint nobody considered --> The design improves.

AI just makes that loop easier, faster, and more accessible.


The Process

When my coding agent generates a design or implementation plan, I don't take it at face value. I copy the proposal, open a separate AI conversation, and ask for a second opinion.

Something like:

Think like a senior engineer reviewing this architecture. What assumptions are being made? What trade-offs are missing? What would you challenge if this came through a design review?

The second model has no conversational history. It didn't see the hour of exploration that led to the proposal. It just sees the output.

That gap matters. Conversations build momentum. Once an agent has spent time going down one path, both you and the model find it easier to keep optimizing along that same path rather than stepping back to ask whether the path itself makes sense.

A fresh perspective is far more likely to pause and ask, "Wait, why are we solving it this way?" And that question can surface a bug, a bad abstraction, or sometimes an entirely different framing of the problem.


A Real Example

I was building a feature that needed authentication. My coding agent laid out three options: full email/password, magic links, or optional auth where users could stay local but optionally create an account.

All reasonable choices. The agent had a lean, but it was careful about the trade-offs.

I pasted the proposal into ChatGPT and asked it to review the architecture. Within a paragraph, it pushed back hard on optional auth. The problem wasn't the idea itself — it was the hidden complexity. If users can have local state and cloud state, you now need to solve conflicts, merging, ordering, offline behavior, recovery flows, and edge cases.

That's not an auth feature. That's an entire product.

OAuth with Google was suddenly the obvious answer. The flow is familiar, users already understand it, and the complexity largely disappears.

That's exactly the kind of decision that's hard to make when you're deep inside a conversation with one model that's already committed time to exploring a direction. Fresh eyes help, even artificial ones.


The Ping-Pong Loop

Once I have the second opinion, I bring it back to the coding agent. I literally say something like, "I sent this to another engineer for feedback. Here's their analysis. Thoughts?"

The agent doesn't just accept it. It pushes back on parts, agrees with others, and flags where the second analysis might be missing context. That's exactly what I want.

Most people accidentally train their AI to be agreeable. They ask questions in ways that produce the answers they already expect. I have anti-sycophancy rules in my agent.md precisely because a model that always says "great idea" is useless. The point is better decisions, not compliance.

During one of these loops, my agent challenged my preference for a particular database design. It made a strong case for a different approach. After going back and forth, I changed my mind. That's the outcome worth optimizing for — an AI that actually improves your thinking, one that treats your ideas as hypotheses to test rather than instructions to follow.


Grilling

This is where the idea of grilling enters the picture (thanks Matt Pocock). Grilling goes beyond asking an AI questions or telling it what to build. It's a continuous process of trying to break the current idea.

The aim isn't consensus. It's surviving criticism. A good architecture isn't the first design that works. It's the one that still holds up after someone sharp has spent time looking for what's wrong with it.

I'll bring the coding agent's questions into ChatGPT, or ChatGPT will raise something I hadn't considered and I'll bring that back. The whole thing starts to feel less like using a tool and more like having two senior engineers available whenever you need them.


The Human in the Middle

This is the part that makes the entire process work. I'm not shuttling text between two models. I'm deciding what matters.

On one project, I realized simulations needed to keep running asynchronously in the background even after the user closed their browser. Neither AI suggested that, because it wasn't an engineering question — it was a product question. The models can reason about the architecture once that constraint exists, but they don't know what experience I'm trying to create.

The best results come when I bring the models my uncertainty, not just conclusions. I don't say, "Move storage to the use case." I say something like, "I'm worried this server action is doing too much. It's running on Netlify, there are function limits, and I'm not sure this is the right boundary."

Now the agent can engage with my reasoning, challenge the premise, look at the architecture docs, and say, "Actually, yeah — the use case should be the orchestrator here."

I've also found that speaking my reasoning out loud helps (I'll often transcribe my voice using Parakeet v3 with TypeWhisper for complicated decisions). Explaining the uncertainty forces me to actually articulate the problem, which means the agent can critique the reasoning instead of just reacting to a conclusion.


Where the Time Goes

I spend most of my time in this phase — no exaggeration. If I have an hour for a feature, I might use 50 minutes on thinking, debating, and changing my mind. The implementation tends to be the easy part. Once the architecture is solid, writing the code is almost mechanical.

The real work happened upstream. For small features I skip most of this. If the change is obvious, I let the agent handle it. Anything substantial (database changes, new systems, architecture shifts) gets the full treatment, because catching a bad decision when it's a paragraph in a design doc is infinitely cheaper than catching it after you've shipped.


The Setup

You don't need anything complicated. You need three things.

An agent with principles. Not formatting instructions or syntax preferences — engineering principles. Mine includes things like making the smallest coherent change, understanding before changing, making trade-offs explicit, and not being afraid to disagree. Those ideas matter more than the language or framework.

A second perspective. It doesn't have to be a specific model. The important part is that it isn't trapped in the same conversation and can challenge the assumptions behind the first answer.

Your own reasoning. Don't just tell the AI what you want. Explain why you're uncertain, what feels wrong, what you're worried about. The model can't read your mind, but if you expose your thinking, it can engage with the actual decision.


The Point

People think AI makes software faster because it writes code. That's part of it, sure. But the bigger shift is that AI makes criticism cheap, and criticism is what keeps you from making bad decisions.

The advantage isn't an AI that generates the most code. It's a process that produces better decisions before the code exists.