Adversarial Coding

Saying that building software with AI agents resembles management more than coding is already a bit of a cliché, even if it happens to be true.
I noticed the shift properly while working on Alvia, my tool for running interviews at the scale of a survey. Early on, I had a decent handle on the architecture, how the components talked to each other, and where the edge cases hid. Moving Alvia into public testing brought a much knottier class of problem: noisy rooms, dropped connections, and dodgy WiFi. These are pure engineering headaches rather than feature requests; the exact point where product managers and leadership suddenly discover urgent business elsewhere.
Once the bugs outgrew my own technical depth, I had to change how I worked. Rather than trusting a single model to both plan and build, I started pitting models against each other. One writes the plan, another builds it, and I ask the builder to tear the plan apart. Then they swap roles, planning, critiquing, and replanning. If something still smells slightly off, I bring in a third agent, and occasionally a fourth.
The setup feels familiar from my time around contact centres, where we relied heavily on the Champ:Challenger model. You run a control process alongside a challenger, measure the results, and let the data pick the winner. It stops teams getting cosy and forces them to keep testing limits. The same logic holds here: structured friction gets you better work.
For an AI equivalent, look at Generative Adversarial Networks. A GAN pairs a generator that produces outputs with a discriminator that judges them. The generator tries to fool the discriminator, while the discriminator gets better at spotting fakes. Each side sharpens the other.
Obviously, I don't have gradients flowing between models or a shared loss surface, so my workflow isn't a literal GAN. Still, the dynamic does a similar job. Separating creation from judgement means one agent proposes while another looks for weaknesses. Each pass puts the design under pressure, and flimsy ideas are far less likely to survive a sceptical reviewer.
Keeping those roles distinct is the whole point. If you ask a single model to invent an approach and then mark its own homework, it will happily talk itself into its own blind spots. Setting a second system on the first breaks that complacency. The generator cannot just stumble on one plausible answer and coast; it has to come up with something that holds up to scrutiny.
Plenty of the multi-agent world is heading down this track. Gartner reported a 1,445% increase in enquiries about multi-agent systems between Q1 2024 and Q2 2025. Microsoft built its AutoGen framework around agents working through problems via structured conversation, while MetaGPT mimics a human software team with separate agents acting as product manager, developer, and QA. People are adopting the pattern because it delivers.
Working this way also changes how I relate to the build. I manage the agents much like a team of specialists, staying in my lane while they sort out the implementation details. The difference is how hard I can push them. Firing off my sixth "You're wrong!" of the evening to a human developer would rightly earn me a snapped, "well why don't you ask Claude to do it, he seems to be your favourite right now!". With people, that level of confrontation is draining. With agents, it is just Tuesday night.
The approach has its limits. My critics still share much of their training data, stylistic habits, and blind spots. They sometimes agree for the wrong reasons, or miss the exact same flaw in stereo. That leaves a clear job for me as the final discriminator, the one actually tethered to reality, budgets, deadlines, and users.
Working with agents blends collaboration with deliberate friction. You end up dealing with artificial colleagues that never get tired and never sulk when you tell them plainly that their work isn't good enough, which is already a step up on most organisations.