Setting up an agent to spend fewer tokens
This page is about the cost of an agent session, and what to put in CLAUDE.md or AGENTS.md
to lower it. Every figure on it comes from Claude Code sessions run by docspack’s benchmark,
1,100 of them, on Vite and on docspack’s own repository. The method and every result are in
docs/design/repo-index.md and docs/design/compact-output.md in the docspack repository.
What an agent session spends its tokens on
A session is a series of turns. Each turn sends the whole conversation to the model again: the
system prompt, the tool definitions, CLAUDE.md, and every message and tool result so far. So a
session costs roughly its number of turns times the size of its context.
| Task size | Turns | Share of input that is the same base, sent again |
|---|---|---|
| Find where something is | 3–4 | 95% |
| Change a behaviour | 7–8 | 88% |
| Build a small feature | 19–20 | 53% |
The base was about 18,000 tokens per turn, and about 16,000 of that is Claude Code’s own system prompt and tool definitions. What the agent writes was under 1% of all tokens, but output is priced at five times input, and the resent base is mostly read from the cache at a tenth of it. So the agent’s output was 12% of the cost of a short task and 25% of a long one. Most of that output is reasoning, commands and edits. The agent’s prose was about a tenth of it. Two things follow:
- Fewer turns save the most. Every turn pays for the whole base again, and fewer turns also meant less output: 3,800 tokens a feature session instead of 5,200.
- Every line of
CLAUDE.mdis paid for on every turn. A 2,200-tokenCLAUDE.mdcosts about 44,000 tokens over a 20-turn session.
The CLAUDE.md block for fewer tool calls
Paste this into CLAUDE.md or AGENTS.md. docspack agent install --recipe repo writes it for
you, inside its managed block:
## Working efficiently in this repository
Every tool call is a turn, and every turn resends the whole conversation. Use fewer, larger calls:
- Read several files, or several ranges of one file, in one shell command
(`sed -n '40,90p' a.ts; sed -n '1,60p' b.ts`) instead of one Read per file.
- Search once, with a pattern that covers everything you are looking for.
- Make related edits together, and run the tests once the change is complete.Keep the wording. It is the exact text that was measured, and the measurement below applies to it, not to a rewrite.
What the block saves, and where it saves nothing
Measured over 780 Claude Code sessions, 10 per task, against the same repositories with nothing
added to CLAUDE.md:
| Task | Tokens used | Cost | Turns | Tasks passed |
|---|---|---|---|---|
| Build a small feature (7 tasks) | 79% | 76% | 19.2 → 9.5 | 70/70 both |
| Change a behaviour (16 tasks) | 89% | 93% | 7.7 → 6.3 | 158/160 both |
| Find where something is (16 tasks) | 101% | 99% | 3.7 → 3.4 | 148/160 both |
The block is worth about a quarter of the cost of a long task, and almost nothing on a short one. A three-turn session has few turns to save. It never cost a task its pass. The agent did read and edit through the shell instead of the Read and Edit tools, so its edits arrive as scripts, which are harder to review than one Edit call at a time.
Keeping CLAUDE.md short
Everything in CLAUDE.md is sent on every turn, whether the task needs it or not. Reference
material, such as how the release works or what each package does, is better kept in the
repository’s docs. There it costs nothing until the agent asks for it:
docspack index --repo
docspack recall --name repo-docs "how does a release work"Keep in CLAUDE.md what applies to every task: the commands to build, test and lint, and the
rules the agent must not break. Move the rest into docs/, under headings in the words someone
would search for.
docspack agent check prints what each instruction file costs per turn. Over 1,000 tokens, it
also lists the three largest sections, which are where reference material usually sits:
CLAUDE.md ~1555 tokens, sent again on every turn: ~31100 over a 20-turn session
~573 ## Part 3 — TypeScript Monorepo
~455 ## Part 1 — Behavioral Guidelines
~453 ## Part 2 — General Coding QualityThe count is an estimate at four characters a token. Markdown that is mostly code and commands
tokenizes more densely: one CLAUDE.md estimated at about 1,500 tokens added 2,238 to every call.
A pointer line such as “read docs/schema.md only when working on migrations” also costs tokens
on every turn, one line per document. With the docs indexed, the agent can search them, and the
pointer lines are not needed.
Finding things without reading whole files
docspack index --repo builds two indexes of the repository: repo-docs, its Markdown, and
repo-code, a map of its code with one entry per declaration. A repo-code answer gives the
file:line, the signature and the doc comment. A three-entry answer is about 200 tokens.
docspack recall --name repo-code "where is the socket that pushes updates to the browser created" --limit 1## packages/vite/src/node/server/ws.ts:118 createWebSocketServer
export function createWebSocketServer(The index is for finding things. It does not lower a session’s cost on its own. With Claude
Code, an agent that searched with Grep and read ranges spent about the same as one that asked the
index, because Grep returns matching lines, not whole files. Use it when the question names
what the code does, not what it is called. When the name is known, grep -n is as good.
Answers about dependencies
docspack ask answers from the documentation of the versions in node_modules, at most 3,000
tokens per answer. That is cheaper than a web search, and the version is the one installed:
docspack ask "how do I verify a webhook signature"What does not save tokens
These were measured and found to save little or nothing in a coding session:
- Telling the agent to write tersely. Its prose is about a tenth of its output, which puts
it at 1–3% of a session’s cost. Widely shared rules for this (“NEVER output pleasantries”, “NO
hedging”, “Output ONLY the requested code”) were measured over 140 feature sessions: the agent
wrote 12% less prose, its output fell 2%, and the cost did not change. No task was lost either
way. If you like terse replies, put the rules in your own
~/.claude/CLAUDE.md, not the repository’s: they are a matter of taste, and every collaborator pays for them on every turn. - Re-indenting code, or other lossless reformatting. The tokenizer already encodes runs of spaces cheaply: 1,964 tokens became 1,961.
- A code index on its own. See the section above: it finds things, and Grep is about as cheap.
What did not lose information and did save: docspack’s own answers say each location once.
That made a recall answer about code 70% smaller, though it is a small part of a session.
Setting it up in a repository
pnpm add -D docspack # 1. a dev dependency: the hooks run this install
mkdir -p .claude # 2. with Claude Code: where skills and hooks go
npx docspack agent install --recipe repo # 3. the block, two skills, two SessionStart hooks
npx docspack sync # 4. dependency docs, for `ask`
npx docspack index --repo # 5. repo-docs and repo-code, for `recall`
npx docspack agent check # 6. in CI: fails when the wiring driftsStep 3 writes the block above and the recall and ask instructions into CLAUDE.md or
AGENTS.md. Without .claude/ it writes only that block. With it, it also writes the skills and
a SessionStart hook that runs steps 4 and 5 at the start of every session, so the indexes stay
current. Commit CLAUDE.md and .claude/. The index itself is in .docspack/, which is
gitignored for you.
Every command the block tells the agent to run starts with npx, because an agent’s shell does
not have node_modules/.bin on its PATH. That is also why docspack has to be a dev dependency:
npx then runs the project’s own version, and the hooks, which use npx --no-install, find it.
index --repo takes the files git ls-files lists, tracked or new, and skips what .gitignore
ignores. It also skips node_modules, tests, fixtures, type declarations and changelogs, which
nobody asks where something lives in.
To see whether it pays in your repository, try it on a task that takes the agent a dozen turns or more. That is where the measured saving was. On a quick lookup expect little difference.