10 Nov 2026

Subagents considered harmful?

If you’ve ever watched an agent forget something important right after it compacted its context, you know how lossy a summary can be. Something that’s talked about a bit less often is that subagents actually suffer from the same problem! The main agent writes a few paragraphs about what it thinks the job is, the subagent begins from that summary, and never sees the conversation that produced it. In exchange, the main agent’s context stays small and focused. I used to think that was a great deal because it lets you parallelize work. These days I think it’s usually a bad one.

It turns out there are a few different approaches to delegating to subagents, and they fail in different ways. This post covers what they are, why teaching an agent to choose between them was the hard part, and a new approach I’m testing that might give you the best of both. I’ll start with how the usual one fails.

I’d asked an agent whether a tool I’d built duplicated something Anthropic and OpenAI already ship, and to have a subagent look into it. The summary it wrote told the subagent to go investigate my tool and somehow completely failed to mention Anthropic or OpenAI anywhere. The subagent dutifully came back with a thorough report about all the details of my own code, and no mention of OpenAI or Anthropic’s features anywhere 🤦‍♂️. The agent had had my entire request in front of it and still managed to drop the half that mattered. Worse, the subagent had no way to know, because as far as it could tell the summary it received was complete, so it diligently proceeded to do a bunch of useless work.

Alexander Yue recently posted a thread calling subagents “the biggest cause of AI failures” for exactly this reason, with numbers. On a 137k-token session with Opus 5.5, letting the main agent do a task itself took 67 seconds and cost $0.38. Handing the same task to a subagent via a summary took 123 seconds and cost $0.57. So the usual way of spawning subagents was slower, more expensive and less informed, all at once.

Summaries versus forks

The usual solution to this issue is to use a forked subagent. Instead of a summary, the subagent gets a copy of the whole conversation plus a note saying which part of the work is its job. Both Codex and Claude Code support forked subagents now, and in both harnesses the model itself picks whether to start a fresh subagent or a fork. This is a real tradeoff: a fresh subagent with a tight summary is cheaper and sharper (since it isn’t wading through a long and often irrelevant history on every turn), but it’s much more likely to be missing critical context and make bad judgment calls. A fork costs more tokens, but it knows exactly what’s been asked for, what’s been corrected and which approaches have already been thrown out.

Forks have their own quirks though. The first time I tried one, the new agent read the last message in its inherited history, which was a request to start a fork, mistook it as an instruction to itself, and started another subfork within the first fork. It also saw the parent’s to-do list and started working through that. So now my fork implementation inserts a note telling each child that it is the fork, that the request to create it has been handled, and which piece of the work is its job. Easy to fix in my own setup, maybe worth knowing if you’re relying on someone else’s or rolling your own.

Teaching an agent when to fork

Getting forking to work was the easy part. The hard part was getting the agent to make the fork-or-summary call the same way I would, without having to have me in the loop every time.

The tradeoff itself is simple: if the worker will have to make judgment calls that depend on the conversation, fork it. If it’s carrying out decisions that were already made, then use a summary. Easy enough, right? And yet when I wrote that down in the agent’s instructions, it almost never forked.

When I pushed it to fork more often, it managed to make a worst-of-all-worlds decision: it handed the entire project to a fresh subagent, and then asked that subagent to delegate the forks. A coordinator’s whole job is to hold the big picture, and the big picture lives in the conversation, which this new coordinator had none of. And since a coordinator doesn’t do any of the work itself, nothing was gained in focus or parallelism either. The agent had basically passed the work to a less informed version of itself and told it to be the boss.

The moment that the real problem clicked for me was when I watched an agent send three planning jobs off to fresh subagents, describing them as “narrow code inspections”. And yes, each job only touched a few files. But the jobs were to plan new work, and a plan is mostly decisions: which of the approaches we’d discussed to take, which ones I’d already ruled out, what the feature was actually for. None of that lives in the code. A subagent with a summary can inspect files all day and still not know about any of the things that actually matter. The agent had looked at these jobs, seen “a few files”, and filed them under mechanical work. Without noticing, it had turned “judgment calls need a fork” into “small jobs get a summary”, because job size is easy to see and judgment isn’t.

So I attempted to let it hill-climb its way out of this mess, and the agent did what agents do: it patched the case in front of it until we’d accumulated a pile of confusing and overfit edge case directives. Fork more. Don’t fork everything. Planning counts as judgment.

Each patch was reasonable on its own, but together they made things worse. The guidance ended up spread across several files and contradicted itself often enough that the agent could justify whatever choice it made by quoting one of them. For a while it overcorrected and forked everything, which meant even trivial mechanical jobs were lugging around the whole conversation. What none of the patches addressed was the real problem: the agent didn’t understand what a summary loses.

In the end I just deleted the whole pile and replaced it with one paragraph:

Work needing a holistic view of our intent, decisions, corrections, and how the pieces fit together usually benefits from a fork. Small, mechanical, well-structured work that does not need that broader context benefits from a fresh Task’s context savings and focus. Give substantial weight to what a selected brief could lose: a narrow assignment or a tidy summary does not establish that the worker has enough context.

The last sentence does most of the work. Every one of the bad calls above started with the agent writing a tidy summary and treating that as proof the worker had what it needed. A summary always looks complete to the agent that wrote it, because the things it forgot aren’t in there to be noticed. The rule the agent had to learn is that the tidiness is not evidence.

Smart forks

So forking beats a summary in a lot of cases, but a full fork has the opposite problem. It inherits everything, including the failed commands, the raw logs and the side discussions about other topics entirely. And the cost of that isn’t mainly tokens. Models get worse as their context grows. A fork wading through a hundred thousand tokens of mostly irrelevant history is a less focused, less sharp worker than one that only has what it needs.

Which got me thinking: what if we could have the best of both worlds? A fork that keeps the parts of the conversation it needs and drops the rest. Something like compaction, but less lossy: drop the irrelevant parts instead of trying to summarize them.

Compaction and LLM summarization is lossy and slow, but it’s been the default because LLMs were the tools we had available. In this case we don’t actually need to rewrite anything though, we just need to decide which parts of the context are relevant, and for that there’s a new tool. Jev and its relatives are the new “System One” models that answer typed questions (eg yes or no, pick one of these) instead of writing text. They’re cheap, fast, and embarrassingly parallelizable. Deciding whether a fork needs a given piece of history is exactly the kind of question they’re good at, and a long conversation is just a few hundred of those questions, all be asked at once.

Other people are poking at this idea too. For pruning an existing session rather than selecting a fork’s context, there are extensions for the pi coding agent like pi-jev-compaction and pi-fast-jev-compaction. The closest thing to a smart fork I’ve found is Oskar Austegard’s delegating-with-context skill for Claude Code, which appends Jev-picked chunks of the parent transcript to a fresh subagent’s prompt instead of filtering a fork. His eval is encouraging for the whole approach: the selected chunks carried 99 of 105 needed facts against 102 for the full transcript, at about a quarter of the tokens, while a written summary managed 82.

Here’s how my experiment works. Before the fork starts, every piece of the history gets a keep-or-drop decision from a decision model, anything the model is unsure about stays, and the fork starts from whatever survived, in its original wording. Nothing gets rewritten, so there’s no summary to get wrong. I’m using Cloudflare’s Clef through Ollama Cloud for the decisions, but any good Jev-like System One style model should work. It’s a small oh-my-pi extension, and I’m happy to open source it if there’s interest. So far it looks promising and seems to help, but the jury is still out on whether it’s better long term. Ask me in a month!

So should you still use subagents?

Probably not. At least, not the kind that start from a summary. A model decides what matters, leaves out the part that did, and nobody finds out until the work comes back wrong. Forks fix that by handing over the actual conversation, but a fork only helps if the agent knows when to use one, and teaching it that took far more work than anything in the harness. Smart forks are the next step I’m betting on. Keep the real conversation, drop the junk, and never ask a model to write a summary at all.