5 min read

Designing for Low-Context Engineering

NextJS feature list

Lately, it feels like every new open-source repository promises the exact same thing: an autonomous “swarm” of AI agents that will write your entire application for you. The pitch is very appealing to many. You give a single natural language prompt, and a collection of virtual developers, product managers, and QA testers chat with each other in the background to build your features.

But if you actually try running these setups on a non-trivial codebase, the magic disappears. You watch terminal logs loop indefinitely, burn through token budgets, and ultimately receive a massive, sweeping pull request that breaks three unrelated modules.

When we build software, our most important asset is our own mental model of the existing system. Every layer of abstraction we introduce between our intent and the code creates cognitive debt. When an autonomous tool changes ten files simultaneously across different layers of your stack, it hides the underlying complexity. You are forced to pay that debt back with interest the moment something breaks and you have no idea why.

We do not need every coding tool to become a self-running agent. For most day-to-day engineering work, we need smaller, bounded tools that expose their changes clearly.

We need to design for low-context engineering.

Why High-Context Swarms May Fail

Many AI products focus on making users experience the magic in a demo. It looks incredible in a demo video to see 3 or 5 agents arguing about architectural patterns in real-time. But in practice, multi-agent systems can spend more time coordinating than doing useful work.

When agents talk to other agents, errors can compound quickly, especially when no human is controlling the boundaries of the task. This approach assumes that the solution to complex engineering tasks is to throw a larger context window and more tokens at the problem. We feed an entire repository into a prompt, hoping the model will magically understand the correct relationships.

Instead, this high-context approach introduces structural noise:

  • A small feature request results in tiny, scattered modifications across a dozen files. Git histories would be interesting to look at :P.
  • If the orchestrator agent misunderstands the task, the other subagents can end up building the wrong solution.
  • As the volume of output grows, engineers stop reviewing every change closely. Small changes often pass without being questioned.

Limiting the problem space

Low-context engineering, as I define here, is the intentional practice of designing systems with clear boundaries that allow contributors to make safe changes with limited context.

When applied to AI tooling, this means constructing strict boundaries around what the model is allowed to see and modify. If you want to update an API endpoint, the tool should only know about that specific route handler and its direct interface. It should have no concept of your broader deployment pipeline, your global state management, or your database layout.

AUTONOMOUS AGENT                 MINIMALIST TOOL
─────────────────                ───────────────

Intent                           Intent
  ↓                                ↓
Agent Manager                    Isolated Target
  ↓                                ↓
Context Loop                     Predictable process
  ↓                                ↓
Sweeping Diff                    Single File Diff
  ↓                                ↓
High Noise                       Low Noise

The less context AI has to reason about, the more predictable it becomes. Give it a specific change, not a broad objective.

Rules for the Minimalist Tool

If we want to build an elite engineering culture that safely utilizes AI without losing control of our codebases, our internal tooling should follow a strict, Unix-like philosophy.

  1. Execute via explicit command lines, not conversational chat

    Conversational interfaces encourage vague, open-ended requests. Command-line interfaces force clarity. A minimalist agent should be invoked with explicit inputs and a defined target.

    # Too broad
    # agent-tool --prompt "build user authentication"
    
    # Explicit boundaries for predictable outputs
    # agent-tool --action add-validation --file ./src/routes/auth.ts --schema loginSchema
  2. Optimize for readability and maintainability, not volume

    Every developer knows that the value of an AI tool is not measured by how many lines of code it generates, but by how little code it requires to solve the problem. If a tool suggests adding a new library when a small utility function or an existing helper would suffice, it fails the minimalist standard.

  3. Architectural direction should be in our control

    The model should handle the boilerplate and repetitive work, and we need to stay in charge of the vision for the system. Do not let an agent make an architectural change that you cannot explain to your peer in two sentences.

Stay in control of the vision for the system

A Better Way Forward

The best developer tools do not try to do all the thinking for us. They protect our focus, eliminate repetitive syntax mechanics, and keep our heads clear so we can reason about the hard problems.

Agent Swarms are flashy, but narrow, deterministic workflows are what actually allow us to ship clean and reliable production software over time. This is a reminder to step back from over-automation, avoid unnecessary urgency in our code, and focus on building simple, useful tools that help us move forward with purpose.


🎉 Interested in Frontend or Indie-hacking?

I talk about the latest in frontend, along with my experience in building various (Indie) side-projects