Fallacies of GenAI Development #8: More AI Agents Means More Productivity
DEV Community Grade 9 7d ago

Fallacies of GenAI Development #8: More AI Agents Means More Productivity

This is the eighth and final post in a series on the false assumptions teams make when building with generative AI. The series began with the observation that the trough of disillusionment for AI-assisted development has arrived — not because AI is useless, but because eight false assumptions made the trough inevitable. This post covers the last assumption and closes the series. The Fallacy "If one AI agent gives us a 10x boost, ten agents will give us 100x." Why it's tempting The arithmetic feels irresistible. One agent generates code for the backend. Another generates the frontend. A third writes tests. A fourth handles database migrations. A fifth generates documentation. Each agent works in parallel. No meetings, waiting or coordination overhead. Pure throughput. Leadership sees the potential: a five-person team with fifty agents has the output of a fifty-person team at the cost of a five-person team plus API credits. The scaling is linear. The economics are transformational. And the early results confirm it. Each agent, working on its own, produces impressive output. The backend agent generates Go code. The frontend agent generates React components. The test agent generates test suites. Each agent, in isolation, looks like a 10x developer. Why it's wrong You've seen this problem before. It has a name. It's called distributed systems. A distributed system is a collection of independent actors that must coordinate to produce a coherent result. Each actor makes decisions locally. The system's correctness depends on those local decisions being compatible globally. When they aren't, you get inconsistency, conflicts, data corruption, and cascading failures. AI agents working on the same codebase are a distributed system. Each agent makes decisions — variable names, error handling strategies, retry policies, data formats, abstraction levels, dependency choices. Each decision is made locally, in the context of one prompt, one file, one task. No agent sees the full picture. No agent coordinates with the other agents. Each agent's decisions are invisible to the others. Distributed systems engineers spent 40 years learning that you can't scale a distributed system by adding more nodes. You can only scale it by adding protocols — consensus mechanisms, ordering guarantees, conflict resolution rules, interface contracts. Without protocols, more nodes means more conflicts, not more throughput. The same applies to AI agents. More agents without specifications means more invisible decisions, more inconsistency, more cognitive fragmentation — not more productivity. The boom Month 1-2: The parallel sprint. Five agents work simultaneously on different parts of the system. Each produces well-structured code. PRs flow in from every direction. The team merges them rapidly. The system takes shape faster than anyone expected. Month 3-4: The integration cracks. The backend agent chose camelCase for JSON field names. The frontend agent expected snake_case . The database migration agent used PascalCase for column names. None knew about the others' choices. Each was reasonable in isolation. The integration fails silently — data flows through but field mappings are wrong. The bug appears as "the UI shows the wrong value" and takes two days to trace to a naming mismatch across three layers. Month 5-6: The contradictory patterns. The backend agent implemented retries with exponential backoff and jitter. The API gateway agent implemented retries with a fixed 3-second delay. Both are valid retry strategies. Both were generated from different training data patterns. When a downstream service is slow, the backend retries with increasing delays while the gateway retries every 3 seconds — creating a thundering herd that overwhelms the already-slow service. The agents' patterns contradicted each other. Neither knew the other existed. Month 7-8: The architectural drift. Each agent, given different tasks over months, evolved different internal patterns. The backend agent started using result types for error handling. The frontend agent uses exceptions. The test agent mixes both depending on which prompt it received. The codebase has three error handling philosophies, each locally consistent, globally incoherent. A new developer opens the codebase and can't determine which pattern is correct because all three exist in production. Month 9-10: The edit war. Agent A refactors a shared utility function for performance. Agent B, in a separate task, refactors the same function for readability. Agent A's change merges first. Agent B's change overwrites A's optimization. Neither agent knows the other touched the file. The team pays for the token cost of both refactors and gets the result of neither. Adam Bender of Google has a name for this — in his talk Software Engineering at the Tipping Point , he calls it the agentic edit war: two agents refactoring the same file toward different goals, livelocking the system while the company pays for the tokens

This is the eighth and final post in a series on the false assumptions teams make when building with generative AI. The series began with the observation that the trough of disillusionment for AI-assisted development has arrived — not because AI is useless, but because eight false assumptions made the trough inevitable. This post covers the last assumption and closes the series. The Fallacy "If one AI agent gives us a 10x boost, ten agents will give us 100x." Why it's tempting The arithmetic feels irresistible. One agent generates code for the backend. Another generates the frontend. A third writes tests. A fourth handles database migrations. A fifth generates documentation. Each agent works in parallel. No meetings, waiting or coordination overhead. Pure throughput. Leadership sees the potential: a five-person team with fifty agents has the output of a fifty-person team at the cost of a five-person team plus API credits. The scaling is linear. The economics are transformational. And the early results confirm it. Each agent, working on its own, produces impressive output. The backend agent generates Go code. The frontend agent generates React components. The test agent generates test suites. Each agent, in isolation, looks like a 10x developer. Why it's wrong You've seen this problem before. It has a name. It's called distributed systems. A distributed system is a collection of independent actors that must coordinate to produce a coherent result. Each actor makes decisions locally. The system's correctness depends on those local decisions being compatible globally. When they aren't, you get inconsistency, conflicts, data corruption, and cascading failures. AI agents working on the same codebase are a distributed system. Each agent makes decisions — variable names, error handling strategies, retry policies, data formats, abstraction levels, dependency choices. Each decision is made locally, in the context of one prompt, one file, one task. No agent sees the full picture. No agent coordinates with the other agents. Each agent's decisions are invisible to the others. Distributed systems engineers spent 40 years learning that you can't scale a distributed system by adding more nodes. You can only scale it by adding protocols — consensus mechanisms, ordering guarantees, conflict resolution rules, interface contracts. Without protocols, more nodes means more conflicts, not more throughput. The same applies to AI agents. More agents without specifications means more invisible decisions, more inconsistency, more cognitive fragmentation — not more productivity. The boom Month 1-2: The parallel sprint. Five agents work simultaneously on different parts of the system. Each produces well-structured code. PRs flow in from every direction. The team merges them rapidly. The system takes shape faster than anyone expected. Month 3-4: The integration cracks. The backend agent chose camelCase for JSON field names. The frontend agent expected snake_case . The database migration agent used PascalCase for column names. None knew about the others' choices. Each was reasonable in isolation. The integration fails silently — data flows through but field mappings are wrong. The bug appears as "the UI shows the wrong value" and takes two days to trace to a naming mismatch across three layers. Month 5-6: The contradictory patterns. The backend agent implemented retries with exponential backoff and jitter. The API gateway agent implemented retries with a fixed 3-second delay. Both are valid retry strategies. Both were generated from different training data patterns. When a downstream service is slow, the backend retries with increasing delays while the gateway retries every 3 seconds — creating a thundering herd that overwhelms the already-slow service. The agents' patterns contradicted each other. Neither knew the other existed. Month 7-8: The architectural drift. Each agent, given different tasks over months, evolved different internal patterns. The backend agent started using result types for error handling. The frontend agent uses exceptions. The test agent mixes both depending on which prompt it received. The codebase has three error handling philosophies, each locally consistent, globally incoherent. A new developer opens the codebase and can't determine which pattern is correct because all three exist in production. Month 9-10: The edit war. Agent A refactors a shared utility function for performance. Agent B, in a separate task, refactors the same function for readability. Agent A's change merges first. Agent B's change overwrites A's optimization. Neither agent knows the other touched the file. The team pays for the token cost of both refactors and gets the result of neither. Adam Bender of Google has a name for this — in his talk Software Engineering at the Tipping Point, he calls it the agentic edit war: two agents refactoring the same file toward different goals, livelocking the system while the company pays for the tokens on both sides. Worse, without a pattern specification, the cycle repeats. Agent A sees the unoptimized code and refactors it again for performance. Agent B sees the unreadable code and refactors it again for readability. The agents consume tokens infinitely, bouncing the code back and forth between two valid-but-contradictory goals. In distributed systems, this is called livelock — the system is active but making no progress. In AI development, it's called your API bill. Month 11-12: The coordination collapse. The team needs to make an architectural change — migrate from REST to gRPC. Each agent needs to be told individually. Each interprets the migration prompt differently. The backend agent generates gRPC server code. The frontend agent keeps generating REST client calls because its prompt wasn't updated. The test agent generates tests for both protocols because it sees both in the codebase. The migration that should take a week takes two months because every agent is working against the others. The team discovers they've been managing a distributed system without the protocols that distributed systems require. Each agent is a node. Each node is making decisions. Nobody built the consensus layer. What distributed systems already solved Hold up the two systems side by side: Distributed Computing (1990s): Distributed AI Development (2020s): ─────────────────────────── ────────────────────────────────── Multiple processes on multiple nodes Multiple agents on one codebase Each makes local decisions Each makes local decisions No shared state by default No shared context by default Inconsistency is the default outcome Inconsistency is the default outcome Distributed computing solved this with protocols: Protocol What it solves AI equivalent ──────────────────── ──────────────────── ────────────────────── Consensus (Paxos, Raft) Agreement on shared state Shared specification repo Ordering (vector clocks) Event sequencing Architectural priority rules Conflict resolution Concurrent modifications Specification gate on merge Interface contracts (IDL) Cross-service compatibility API contracts + contract tests Schema evolution Backward compatibility Migration specifications Circuit breakers Cascading failure prevention Dependency scope limits Every protocol in the left column has an AI development equivalent in the right column. The solutions exist. They're called specifications, contracts, and enforcement gates. They're the same coordination mechanisms — applied to agents instead of processes. The five coordination failures and their fixes 1. Naming inconsistency → Convention specification Problem: Each agent chooses its own naming conventions. Fix: A convention specification fed to every agent as context. "JSON fields: camelCase. Database columns: snake_case. Go structs: PascalCase. Environment variables: UPPER_SNAKE." Four lines. Every agent reads them. Every change is checked against them by a linter. Inconsistency becomes mechanically impossible. Critical: the specification must be immutable for the duration of concurrent agent tasks. In distributed systems, "split brain" happens when nodes have different versions of the truth. If Agent A has the old naming convention and Agent B has the new one, the codebase gets both. Version the specification. Update it between task batches, not during them. 2. Pattern contradictions → Architectural decision records Problem: Each agent implements different patterns for the same concern. Fix: One ADR per cross-cutting concern. "ADR-007: Retry strategy is exponential backoff with jitter, base 100ms, max 5 attempts, across ALL services." The specification is the protocol. The CI check is the enforcement. Any agent that generates fixed-delay retries fails the build. 3. Edit conflicts → Ownership boundaries Problem: Two agents modify the same file with contradictory goals. Fix: CODEOWNERS + module boundaries. Each module has one owner (human or agent). Cross-module changes require the interface contract to be satisfied. Agents can't modify modules outside their scope. Same principle as microservice boundaries — but for agents. 4. Error handling divergence → Interface contracts Problem: Three error handling philosophies coexist in the codebase. Fix: One interface contract: "All public functions return (result, error). No exceptions. No panics. No sentinel values." Enforced by the compiler (Go) or by a linter rule (TypeScript). The contract is the specification. The tool is the enforcement. 5. Migration incoherence → Change specifications Problem: An architectural migration is interpreted differently by each agent. Fix: A migration specification: "Phase 1: Add gRPC endpoints alongside REST. Phase 2: Migrate clients to gRPC. Phase 3: Remove REST. Current phase: 1. Agents must not remove REST endpoints." Each agent reads the current phase. The specification prevents agents from jumping ahead or falling behind. Each fix is small. Each is a few lines of text. Each is fed to agents as cont

Comments

No comments yet. Start the discussion.