Skip to main content
TACAVAR
Build in Public

We Made Coding Agents Dumber on Purpose. Output Quality Doubled.

We cut context, tools, and model tier. Engineer-approved code went up 2x.

That sounds absurd until you watch a capable coding agent solve a one-line bug by introducing a repository-wide event bus. At Tacavar, we ran that experiment in public: we intentionally nerfed our coding agents on purpose. The Show HN post hit #1 on Hacker News, but the metric that mattered was internal. After constraining what our agents could see, touch, and run, the share of agent output engineers approved without major rewrite doubled. The smartest model in the stack had been the biggest source of ai agent over-engineering.

The Inverted-U Curve of Agent Capability

The industry default treats capability as monotonic. Bigger model, larger context, more tools, more agents, better outcomes. For demos, that holds. For production code, it inverts. Tacavar's coding agents followed an inverted-U curve. Up to a point, more capability reduced errors. Past that point, additional capability expanded the solution space faster than it improved judgment. The agent could see more, so it invented more. It could call more tools, so it chained more steps. It could choose a frontier model, so it optimized for impressive rather than correct. LLM reliability does not improve linearly with model size when the task is bounded. It degrades under optionality. A coding agent with infinite design choices has infinite ways to be wrong. The inverted-U is not a model failure. It is an objective failure. If you do not define the smallest acceptable change, the agent will define a larger one.

What We Cut: Context, Tools, Model Tier

At Tacavar, we reduced three inputs. First, context. Agents no longer received the entire repository or long chat histories. They received the task ticket, the relevant diff, the interface contracts, and the tests that had to pass. We bounded context windows by task, not by codebase. Second, tools. We removed web search, arbitrary package installation, unrestricted shell, and most filesystem access. Agents could read specific paths, write specific files, run the test command, and grep. Nothing else. Third, model tier. We routed routine edits to a smaller, faster model. We reserved the frontier model for planning and genuinely ambiguous changes, not for line-level implementation. These are classic coding agent constraints, and they felt like sabotage. The result was the opposite. With fewer tools, agents stopped building Rube Goldberg pipelines. With less context, they stopped hallucinating dependencies. With a simpler model, they stopped over-abstracting. Engineer-approved code went up 2x. Not because the agents became smarter. Because we removed the room to be clever.

Why Over-Capable Agents Add Phantom Abstractions

Over-capable agents do not just generate more code. They generate phantom abstractions. A single-use factory. An interface with one implementation. A configuration layer no operator will ever tune. A generic utility wrapper around a standard library call. A new state manager for a component with one piece of state. These choices look sophisticated in isolation. In a real codebase, they are liabilities. They increase review surface, obscure data flow, and create future bugs. The agent makes them because it can. It has enough context to see patterns everywhere, but not enough product judgment to ignore them. It also has a bias toward action that looks impressive. When the simple fix is one line, the agent sometimes avoids it because the simple fix does not signal capability. That is ai agent over-engineering in its purest form: the model solving for perceived intelligence instead of operational value. Nerfed coding agents do not have that luxury. When the toolset is small and the context is tight, the shortest correct path is also the most available path. Constraints become a bias against phantom complexity.

Measuring Output: Maintainable Code, Not Impressive Code

If you want to fix this, change what you measure. Tacavar stopped scoring agents on whether code compiled, whether tests passed, or whether the answer looked smart. We scored maintainability. Our review rubric asks: Is this the smallest correct change? Does it reuse existing patterns? Does it add any new abstraction? If so, is that abstraction required by at least three concrete call sites? Does it introduce a dependency or configuration surface? Can a new engineer understand the diff without a design doc? We tracked engineer-approved code rate, review cycle time, revert rate, diff size, new abstractions per pull request, and post-merge defect rate. The important metric was not acceptance. It was acceptance without major rewrite. That is where the 2x came from. We also measured llm reliability as a function of task constraint, not as a model leaderboard score. The same model can be unreliable in an open-ended task and reliable in a bounded one. The work is to bound the task. Maintainable code is not impressive code. It is code that disappears into the system.

A Constraint Checklist for Production Agent Stacks

You do not need to copy Tacavar's exact configuration. You need a constraint-first mindset. Use this checklist as a starting point for your own agent orchestration patterns.

  1. Bound context by task. Send only files, diffs, contracts, and tests required for the current change. Do not send the repository.

  2. Limit tools to one job per agent. If an agent writes code, it does not also browse, install, and deploy. Split those into separate constrained agents.

  3. Force the simplest model that passes evals. Use a frontier model for planning, ambiguity, and architecture review. Use smaller models for implementation.

  4. Set a diff budget. Cap files touched, lines changed, and new abstractions per task. If the agent exceeds the budget, it must stop and explain.

  5. Require a plan before edits. Keep it short: what will change, what will not change, what test will prove it. Reject plans with more than a few steps unless the task is genuinely cross-cutting.

  6. Gate on deterministic checks. Linters, type checks, and tests are not optional. They are the floor. The agent cannot negotiate with a failing test.

  7. Penalize new dependencies. A new package is a product decision, not an implementation detail. Require explicit approval.

  8. Measure over-engineering signals. Track new abstractions per PR, helper functions with one caller, and lines changed per issue. These expose the failure mode.

  9. Use bounded orchestration. Sequential and routing patterns beat swarms for production work. A planner, a constrained implementer, and a verifier is often enough.

  10. Keep humans on abstraction review. Engineers should review design choices, not just syntax. The agent can type; the human should decide what deserves to exist.

These rules are not anti-agent. They are pro-reliability. Coding agent constraints turn a probabilistic system into a production system.

When to Nerf and When to Upgrade

Nerfing is not a permanent religion. It is a control surface. At Tacavar, we nerf when the task is well-scoped, the codebase has established patterns, and the failure mode is over-engineering. We keep agents constrained for bug fixes, feature increments, refactors inside known boundaries, test generation, and migration work with clear inputs and outputs. We upgrade when the task is genuinely ambiguous, when the agent needs to explore an unknown system, when a change is cross-cutting, or when we need architectural options before we know the shape of the solution. The key is sequence. Start constrained. Let the agent fail. Read the failure. If it failed because it lacked context or could not express a necessary design, loosen one constraint. If it failed because it invented a phantom abstraction, tighten the constraint. Do not upgrade capability because the demo felt weak. Upgrade because the constrained agent hit a wall that only capability can remove. That is how you get the inverted-U working for you instead of against you. The smartest agent is not the one with the most tools. It is the one operating inside the tightest boundary that still solves the problem.

See Tacavar's constraint-first agent orchestration playbook at tacavar.com/agents.