Journal — № 002
Your model shouldn’t see your entire toolbox.
Eighty tools is prompt bloat wearing a new coat. Keep the top level boring, and let the rest of the toolbox wait for its cue.
In the last post I argued that your agent doesn’t need a better prompt, it needs a thicker harness. Keep the system prompt small. Give the model just enough to make its next decision, and let the harness carry everything else.
Since then, nearly every conversation about it has ended at the same question.
“Okay. If it isn’t in the prompt… where does it go?”
And the answer sounds easy. It goes into the harness. Into tools the model can call. Into guides it can load. Schemas. Runbooks. Recovery instructions.
So you do exactly that. You spend a week moving everything out of the prompt.
The prompt looks beautiful now. Six lines.
And your agent wakes up staring at eighty tools.
Congratulations. You moved the problem.
Go on. You’re the model now, and the user is waiting. Pick a tool.
48 tools · 48 schemas in context · every single turn
Every tool is a question.
There’s a belief hiding in most agent codebases I’ve been asked to look at. Nobody writes it down anywhere, but you can read it straight off the tool registry:
“More tools will make the model more capable.”
Sometimes that’s even true. But every tool you register asks the model a question it now has to answer on every single turn.
Should I use this one?
Or that one?
Do I read the guide first?
Search? Retrieve? Query? Plan?
Before the model gets to solve your user’s problem, it has to solve your toolbox. That’s real work. It burns context and attention on every turn, whether or not those tools ever get called. A frontier model pays for it in reliability. A small model pays for it in everything.
Three doors, not fifty.
One principle has changed how I lay out agents more than anything else I’ve picked up building them:
Keep the top level boring.
When my agent wakes up, I don’t want it staring at fifty tools. I want it looking at three or four meaningful choices. That’s the whole trick.
Nothing gets hidden from it. Functionality just has to earn a seat in the context window before it shows up.
Think about how you read documentation. You never sit down and read the entire docs site before writing your first line of code. You open one page. You solve the problem in front of you. When you get stuck, you open the next page.
Agents deserve the same courtesy.
what the agent sees on turn one
waiting in the harness, out of context
- search guide
- aggregation guide
- recovery guides × 6
- index schemas × 12
- runbooks × 9
- retry playbook
- on-call roster
- escalation policy
- report templates
Hover a choice. Nothing gets deleted. The whole library is still there, and it waits in the harness until the story needs it.
Watch one question travel through.
Enough theory. Let me walk you through a real run, the same shape as the fleet-monitoring agents we build. A user asks:
“Which five regions had the most failed devices this week?”
The agent doesn’t need everything to answer this.
It doesn’t need every query guide.
It doesn’t need every recovery playbook.
It doesn’t need schemas for indices it will never touch.
It needs to answer one question. What’s my next step?
in front of the model
- the question
- search
- act
- escalate
- answer
choices right now: 4
step 1 · the question lands
The agent wakes up to the task and four doors. No guides, no schemas, no recovery playbooks anywhere in context. Counting failed things by group reads like a search problem.
Step through that and count the options in front of the model at every stop. It picks search, so the harness hands it the search guide. The guide points top-N questions at the aggregation guide, so it loads that page and writes the query.
Then the query fails. This is my favourite part of the whole pattern.
400 search_phase_execution_exception
"Fielddata is disabled on text fields by default.
Use region.keyword instead."
harness: looks like an aggregation error
→ recovery guide available
The harness doesn’t fix the query. It doesn’t need to. It recognises the error class and
attaches one line to the tool result: this looks like an aggregation error, and a recovery
guide exists. The model takes the door, swaps region for
region.keyword, retries, and the buckets come back.
That recovery guide was not sitting in the prompt all along, paying rent. It appeared at the exact moment it became useful, and not a turn earlier.
Ask a different question.
The real shift here is a question swap.
I used to plan agents by asking, “what should the model know?” That question has no bottom. The honest answer is always “everything, probably”, and that answer is how prompts hit eight thousand tokens and toolboxes hit eighty entries.
Now I ask a smaller question.
“What decision is the model making right now?”
Only the information that serves that decision belongs in front of it. Everything else waits backstage for its cue.
The strange part is that agents built this way come out more capable, not less. The model spends less of its attention decoding your architecture, and more of it on the user’s actual problem.
The next bottleneck.
Follow this idea far enough and you run into something uncomfortable.
Your agent’s context is clean now. Its job description is not.
It still plans.
It still searches.
It still writes queries.
It still recovers from errors.
It still checks results, and then writes the final answer.
One worker, every role in the company. Progressive disclosure means it only sees one job’s paperwork at a time, but it is still the one doing every job.
one model
- plans
- searches
- writes queries
- recovers
- verifies
- writes the answer
The context is finally small. The job list is not. Six different jobs, one pair of hands, and no amount of context discipline changes that.
Eventually, that becomes the thing that caps your agent, no matter how disciplined the context is. And that’s when I stopped asking “how do I make this agent smarter?” and started asking a much better question.
“Should this even be one agent?”
That’s the next post.