Min(Input) → Max(Output): The Agentic Equation
On this page 12 sections
I build AI agents for a living, and I spend most of my day either building them or working inside them. So I keep trying to bring agentic coding — or any agentic use case — back to first principles. The more I look at it, the more it feels like one equation:
Min(Input) → Max(Output)
That sounds obvious, but it hides the whole history of agentic systems: every layer we added around the model, every feedback loop we tightened, and every optimization we’re now making to control cost and context.
This is a mental model, not a law. And by input I don’t just mean tokens. I mean three things: how much the human has to explain and supervise, how much irrelevant context reaches the model on a single call, and how much work the system does behind the scenes.
The system may do more work so the human can do less.
At first, the model was the whole system
Start at the beginning. The LLM was a black box: tokens in, tokens out. No tools, no memory, no history.
For software, that was mind-blowing: we were generating code from plain English. And let’s be honest — the code was terrible. It looked right, it read well, and it broke the moment you ran it.
Take a failing test, the kind of task we now hand to agents without thinking. Back then you pasted the function, pasted the error, asked for a fix, copied the answer back, ran it, and pasted the new error. You were the agent. The model was just the autocomplete in the middle.
There are two ways to fix that:
- Improve the model itself.
- Improve the input reaching the model.
To be clear, the first path still wins. A smarter base model is the highest-leverage variable in this whole equation. Reasoning models already do in one shot what used to take elaborate loops and tool use. Every model jump deletes some of the scaffolding we built around the previous one.
But most of us don’t train models. We work on the second path.
The second path started manually. We called it prompt engineering: few-shot examples, chain-of-thought, system prompts that steered the model before the user typed a word. A human hand-picking context for every single prompt. It worked, but it didn’t scale.
Everything we now call an agent harness — the system around the model that supplies context, tools, memory, feedback, and stopping rules — is that same job, automated. Every layer of it answers the same question: what does the model need to see, right now, to do this well?
Every layer changed where context came from
A conceptual ordering, not a timeline — several of these layers emerged in parallel.
Turns made the human part of the loop
The first fix was almost embarrassingly simple: let the model see the whole conversation instead of one message at a time.
That created a small feedback loop. The user could correct the output, add missing information, or change direction. For that failing test, the model now remembered which fixes it had already tried and what error each one produced.
The model was still usually stateless between calls. The application carried the state forward. But from the user’s point of view, the black box could finally listen.
Tool calls brought in the environment
Listening was progress, but the model still saw only what someone typed at it.
Our first fix was to push context in from the outside: RAG. Embed your documents, store them in a vector database, retrieve the nearest chunks, and staple them to the prompt. It helped, but the model was a passenger. Relevance was whatever cosine similarity said it was.
Tool calls flipped that. Instead of us pushing context to the model, the model started pulling it. The first time I watched an agent run the failing test itself, read the stack trace, and fix its own code without me pasting a single line into the chat was the moment this stopped feeling like autocomplete to me. I wasn’t the agent anymore.
Now the model could decide which tool might provide the context it was missing: search the codebase, read a file, run a test, query an API, inspect a compiler error. A tool result isn’t automatically feedback, but it becomes feedback when the model uses that observation to revise what it does next.
The pattern had started:
Less context typed by the user. More context acquired by the system.
Skills made instructions reusable
I used to re-explain the same things at the start of every session: how I want commit messages written, which checks have to pass before a deploy, how posts on this site are structured. Around the fifth time, it stops feeling like collaboration and starts feeling like data entry.
Skills exist because that got old. Now you keep an archive of how situations should be handled, and the agent loads it only when it’s relevant.
Skills aren’t a feedback loop by themselves. They’re reusable procedural context. But they can contain the result of many previous feedback loops: all the times you explained the same preference, corrected the same mistake, or discovered the ideal way to do something.
The boundary between a skill and procedural memory is mostly architectural. Both stop useful knowledge from dying inside one conversation.
We move from instruction on every turn toward persistent intent plus exception handling. You don’t tell the agent your default answer every time. It knows where to find it.
Subagents became context compressors
Then we stopped relying only on humans and tools to produce context. We started using other LLMs.
A subagent can explore one bounded question inside an isolated context window, then return a compressed result to the main agent. The main agent doesn’t need every file read, every failed search, or every intermediate thought. It needs the useful result.
This can reduce pressure on the main agent’s context, but it does not necessarily reduce total tokens. When Anthropic wrote about their multi-agent research system, they found multi-agent setups used around 15× more tokens than a regular chat. That matches what I see in practice: subagents trade compute for parallel exploration, isolation, and a cleaner coordinator context.
Honestly, we’re still figuring out when that trade is worth it. The hard part is the handoff: compressing a subagent’s work without losing the one detail that mattered. A lot of multi-agent setups look amazing in demos and fall apart on coordination overhead in real work.
Memory stopped us from repeating ourselves
At some point I caught myself telling an agent to use pnpm instead of npm for the third time in a week. Same project, same correction, three different sessions. That’s the problem memory exists to solve.
I want the agent to remember stable preferences, relevant facts, previous decisions, and the state of long-running tasks.
Memory is like offloading part of your brain, but it’s more than a bag of facts. A useful memory system has to decide what to write, what to update, what to forget, and what to retrieve for the current situation.
When it works, future agents get a better starting point. When it fails, stale or irrelevant memories become another form of bad context. I’ve had an agent confidently follow a decision I’d reversed weeks earlier, just because the note was still sitting there.
Loops turned feedback into a system
Fast-forward, and now we have loops.
We can put a goal at the end, let the agent choose actions, observe the results, update its state, and iterate until the goal is satisfied — or until it hits a stop condition: budget, timeout, safety boundary.
That failing test from the beginning? These days I leave an agent alone with it: run the suite, read the failure, patch, rerun, ping me when it’s green. Sometimes I come back to a finished task. Sometimes I come back to an agent that spent twenty minutes confidently telling itself its answer looked correct.
The loop matters only if the feedback is good. Tests, type checks, execution environments, measurements, citations, and human review are stronger signals than the agent’s own confidence. The Claude Code team’s guide to loops lands on the same rule: deterministic exit criteria, like a passing test suite, beat the model grading its own work.
I’d go further: feedback quality is the most underrated variable in agentic systems right now. The strongest setups I’ve seen aren’t the ones with the fanciest context management. They’re the ones with the most grounded feedback. Weak feedback doesn’t just slow the loop down. It turns the loop into an expensive random walk.
A conceptual model, not a benchmark
The model stayed in the middle. The harness learned what to bring it.
Watch the two context bars above. Reachable context keeps growing, while Active context stays much smaller and drops again when selection gets smarter. That gap is the rest of this post.
We didn’t make context bigger. We made it reachable.
So far this looks like a race to give the model more context. The full conversation. Every tool. Every skill. Every memory. More agents. And to be fair, the raw capacity really did explode: context windows grew from 4K tokens to a million-plus in a few years.
But that’s not what improved the output.
What improved the output was better relevance, timing, structure, and feedback. We expanded the universe of context the system could access, then taught the harness around the model how to select from it. The discipline now has a name: context engineering.
The model is still in the middle. The agent harness around it decides what instructions to load, what history to keep, which tools to expose, what data to retrieve, when to delegate, what results to clear, and whether the goal has actually been reached.
So the first half of the equation isn’t:
Give the model as much context as possible.
It’s:
Make as much useful context reachable as possible, then deliver the minimum sufficient context for this step.
Then the equation seems to reverse
Once we made all that context reachable, another question appeared: do we actually need all of it at once?
This is where token cutting, compaction, prompt caching, subagents, multiple sessions, and dynamic tool and skill discovery come in. After years of teaching systems to acquire more context, we turned around and started building systems to aggressively remove or avoid it.
Why doesn’t more context always mean better output?
Because context has a cost, and irrelevant context actively makes the result worse. Models get measurably worse at using information buried in the middle of a long context. Old tool results can distract the model. A stale memory can override the user’s current intent. A giant list of tool definitions can make it harder to choose the right one.
There are also three different inputs that are easy to mix together:
| Input | What we’re trying to reduce |
|---|---|
| Human input | Repeated explanation, correction, and supervision |
| Active model context | Irrelevant or low-value tokens in the current inference |
| Total system work | Compute, latency, retrieval, tool execution, and tokens across every call |
An agentic system can reduce the first two while increasing the third.
That’s why subagents aren’t free, caching isn’t the same as context reduction, and compaction isn’t the same as forgetting:
- Dynamic discovery avoids loading every tool or skill before it’s needed.
- Retrieval and progressive disclosure keep information outside the active window until the current step needs it.
- Compaction compresses older state, saving context at the risk of losing a detail that matters later.
- Subagents and multiple sessions create clean context windows, but require good handoffs and may use more tokens overall.
- Prompt caching can reduce latency and price for repeated prefixes, but those tokens are still logically part of the model’s context.
Each of these has bitten me at least once. Compaction especially: I’ve watched a session summarize away the exact constraint I’d spelled out an hour earlier, then cheerfully violate it.
You’re not optimizing for the fewest tokens. You’re optimizing for the highest useful signal per token while keeping quality above the bar.
Optimization only happens where there is scarcity
We only optimize what’s scarce.
Right now that’s cost, latency, power, and availability. We add tool search, skill discovery, compaction, caching, and context isolation because sending everything everywhere is too expensive and too noisy.
As models improve, some of that scarcity may flip:
- If output quality becomes abundant, we may care less about perfect input because even a rough prompt reliably produces a good result, and parts of today’s harness disappear into the model.
- If availability and cost become abundant, we may care less about how much total machine work happens behind the scenes.
But I don’t think context selection disappears completely. Even with cheap tokens, attention, latency, energy, privacy, security, and verification remain scarce. More context also doesn’t guarantee better reasoning.
And one scarcity I don’t expect to go away: the human. Your attention, judgment, and taste don’t scale the way compute does. The winning agentic systems won’t be the ones that remove the person from the loop. They’ll be the ones that multiply what one person’s judgment can reach. The goal was never zero human input. It was maximum leverage per unit of it.
The implementation may change. The equation survives.
A mental model for every new agentic idea
When I see a new agentic approach or a new piece of terminology, I ask where it fits:
- What new context does it make reachable?
- How does it select what the model actually sees?
- What feedback helps the next attempt improve?
- Which input does it reduce: human effort, active context, or total system work?
- What does it cost in tokens, latency, coordination, privacy, or control?
Tools acquire context. Skills package procedures. Subagents explore and compress. Memory preserves useful state. Retrieval and compaction decide what stays in view, while evaluators close the loop. The harness coordinates all of it around the same black box we started with.
A more precise version of the equation:
minimize human effort + irrelevant context + cost + latency
subject to output quality ≥ the result we actually need But I still prefer the original:
Min(Input) → Max(Output)
It’s not mathematically complete. It’s a lens.
The black box never changed: tokens in, tokens out. Everything else — the whole story above — is us getting better at deciding which tokens deserve to go in, so the human can say less and still get the result they had in mind.
When the next “new” agentic pattern appears, ask what context it changes and what loop it closes. Most of the time, that’s the whole idea.
If you’re building agents and see the equation differently, I’d love to hear it — hit me up on X or LinkedIn.