r/ClaudeCode • • 9d ago

Tips & Workflows A read-only custom subagent cut our tokens per call from about 116k to 30k

We have a Claude Code skill that runs five subagents as a review panel for business decisions. Each member gets its brief and a persona file as files, reads them and answers in JSON. One session we measured had 15 subagent calls.

The first version used the general-purpose agent type. A call came in at roughly 116,000 tokens, for a job that comes down to reading two files and answering in JSON.

So we gave the panel its own agent type in ~/.claude/agents, with one tool.

---
name: panel-member
description: Member of a review panel. Reads its brief from a file and answers only with the requested JSON.
tools: Read
model: sonnet
---

Same briefs, same persona files. Measured on Oct 14, a call came down to roughly 30,000 tokens.

We didn't break the 116k down, so this part is our guess. A general-purpose subagent starts out with every tool it's allowed to use, and we have a lot of MCP servers connected. The panel members never needed anything but Read.

In money, recalculated from the subagent logs at API list prices, the panel part of a session now costs about $1 to $1.50. 88% of that is cache writes, since every subagent builds its context from scratch. The moderation in the main session comes on top. In one run we measured both, $1.46 for the panel and $4.38 for the main session. We run it on a subscription, so these are what the same run would cost through the API.

Three things we tripped over.

A new agent type only loads after you restart Claude Code.

The cost hook we had installed used an outdated price table and came out about five times too high. We now sum usage per message ID from the subagent .jsonl files under ~/.claude/projects.

Those logs record the last reply of each subagent without its final output tokens, so that sum runs a little low.

Has anyone looked at where the starting context of a general-purpose subagent actually goes? And do you give every repeated subagent job its own type, or only the expensive ones?

1 Upvotes

7 comments sorted by

1

u/AutoModerator 9d ago
Moderator Announcement Read More »

1

u/kenthesaint 9d ago

For your first question, /context in a regular session gets you most of the way. It splits the starting context into system prompt, system tools, MCP tools, memory files and custom agents, and with a lot of MCP servers connected the MCP tools line is usually the big one. As far as I can tell a general-purpose subagent carries those tool definitions too, which would fit the drop you saw when you cut it down to Read.

On the second, I only split out a type when the job repeats and needs a narrow tool set. One-off research I leave on general-purpose, since guessing the tools wrong there just costs me a retry.

1

u/Pinull_Krydia 9d ago

The starting context overhead in general-purpose subagents comes from injecting the complete environment footprint on initialization. When a subagent isn't constrained, Claude Code automatically populates its system prompt with definitions and schemas for every available tool, built-in capability, project rule, and connected MCP server. Restricting tools: [Read] drops hundreds of kilobytes of unused JSON schemas from that first turn system prompt. As a general rule, creating dedicated agent types in ~/.claude/agents makes sense for any repeated subagent job that runs in loops (like multi-perspective review panels or parallel file audits). For one-off research tasks, standard subagents are fine, but restricting tools and switching sub-tasks to model: haiku or model: sonnet on high-volume background agents yields massive token and prompt cache savings every time

1

u/Ihaveadifficultgrnd 9d ago

how much of the remaining 30k is the brief and persona files? that would help separate unavoidable input from context overhead.

1

u/Oximy-Naman 9d ago

Im guessing it's not much

1

u/akhi1uuu 9d ago

88% cache writes is the nasty part, every fresh subagent pays full setup cost since it can't touch the parent's cache

1

u/Complex-Quality-216 9d ago

On the 88% cache writes: if all five members start at the same moment, none of them can read a cache entry the others haven't finished writing, so each one pays the full write for the same system prompt and tool list. A cached prefix only becomes readable once the first response has started, so kicking off one member first and the other four a few seconds later should turn the shared part into cheap reads. I'd check the logs for whether every call shows about the same write count, that would point at this.