← all posts

Your agent harness is an efficiency decision, not a quality decision

Hold the model fixed, one local DeepSeek V4 Flash (High), and change everything around it. Three harnesses, Pi, OpenCode and Claude Code, wrapped the same model, each bringing its own tool set and system prompt, the levers people believe make a coding model better. Handed the same tasks and graded the same way, the work came out the same across every setup. What changed, by multiples, was the time and tokens each one spent getting there.

19 July 2026 · same model, four harnesses · updated 27 Jul

Four harnesses. Three off-the-shelf, lightest to heaviest: Pi, a bare 4-tool harness; OpenCode, a mid-weight framework; and Claude Code, a heavy one that does not speak the local server's API, so it reaches DeepSeek V4 Flash through a small proxy (CLIProxyAPI). Plus a fourth, Nanocoder, a community, local-first harness added later. The same model sits underneath all of them, served the same way throughout, the same set of real bug fixes, the same grading, and only the wrapper moves.

The grades come out the same

Across the tasks no grade difference held up, and whether it was Pi, OpenCode or Claude Code the scored work landed in the same overlapping place, because the run-to-run noise is wide enough to swallow the gaps between them whole.

On the hardest tasks the same harness scores a basic attempt on one run and a solid fix on the next, a full grade apart, with nothing changed between them but the random seed.

The run-to-run swing is that wide, so with only 2 or 3 runs the noise decides which harness looks best, and a ranking that changes every time you rerun it is no ranking at all. The chart below puts the four harnesses on one axis, and they land in a single overlapping band.

Quality: grade per run
failbasicsolidfullPi2.34OpenCode2.07Claude Code2.42Nanocoder2.25
Each dot is one run — 24 apiece for Pi, OpenCode and Claude Code (three per task), 64 for Nanocoder (eight per task) — with the mean and 95% confidence interval. Every interval overlaps every other: even at these sample sizes, nothing separates cleanly from the noise.

The difference is time and tokens

What separates the harnesses is efficiency, and the heavy end is Claude Code and Nanocoder, several times the tokens and the wall-clock of either lean harness to reach the same fix. The cost is all on the output side, in what the model generates and the tools it runs. They read very differently too, Claude Code and Nanocoder exploring far more, but on this model that barely registers, because DeepSeek V4 Flash reads input at nearly the same speed at 10K tokens or 200K, so heavy context is close to free here and would only bite as billed input on a metered API. What costs is generation, and since the same model decodes at the same rate for all three, more output and more tool-running is simply more time. The two lean harnesses come out close on output, and where OpenCode takes longer than Pi it is the tool-running, not the word count.

Efficiency: wall-clock per run
0m2m4m6m8m10mPi2.1mOpenCode3.1mClaude Code8.0mNanocoder5.2m
Zoomed to 10 minutes by default; toggle to Full to see every run at its true spot. Each dot is one run, the marker its task-weighted average. Claude Code is the slowest, Nanocoder the next-heaviest, while Pi and OpenCode finish in a fraction of the time.
Efficiency: output tokens per run
020K40K60K80K100KPi14,775OpenCode17,463Claude Code58,370Nanocoder55,844
Zoomed to 100K by default; toggle to Full for the whole axis. Claude Code and Nanocoder generate several times more than either lean harness; Pi and OpenCode land close once OpenCode's subagents are counted in.

Pi reasons, OpenCode delegates

The two lean harnesses generate about the same amount, they just spend the clock differently. Pi does the whole task in one context, verifying by thinking, so almost all of its tokens are reasoning in one long stream. OpenCode hands chunks of the work to subagents instead, each a separate sub-run that generates on its own, and those tokens never surface in the main stream, which is what made a plain count read OpenCode as the leanest of the three at around 11,000. Count the subagents back in and it lands near 17,000, right alongside Pi's 15,000, not below it, so neither out-writes the other by much. What separates them is pace, the same model decodes at one rate for both, but Pi spends its clock generating in long bursts while OpenCode spends more of its shuttling work out to subagents and waiting on the hand-offs, so it takes longer to reach a similar word count. And none of it moves the grade, because the 8 bugs are subtle logic bugs, a guard testing the wrong condition, a state change firing a step too early, that a subagent catches no better than a careful line of reasoning, and a capable model lands either way.

Claude Code and Nanocoder explore most, and edit only when certain

These two are the heavy explorers, each burning several times the tokens of a lean harness to reach the same fix and each holding off on edits until late in the run. Claude Code runs the most tool calls of the four by a wide margin, around 70 to a task where Pi needs 40 and OpenCode just 22, and its first edit lands about 80% of the way through; Nanocoder makes fewer calls but re-reads the same files more than anything else, and commits nearer 70%. Nearly all of that front-loaded work is looking rather than touching, reading files and searching the tree, and the edit each finally makes is the same handful of lines the lean harnesses landed long before. The diligence has no ceiling and no reward: on the hardest bug Claude Code was still reading when the run hit its time limit, and everywhere they finished the grade came out level with the lean pair. They are the most thorough readers of the codebase, and on fixes this size thoroughness is just time.

How each harness works a task: tool calls in order
Pibashbashbashbashreadbashbashreadreadreadreadbashreadreadreadreadreadeditreadreadeditreadreadeditreadbashreadeditreadreadreadreadreadeditbashbashreadread38OpenCodereaddelegatereadreadsearchsearchreadsearchreadreadeditreadeditreadreadbashbash17Claude Codereaddelegateotherbashbashbashreadreadreadreadreadreadbashbashbashbashreadreadbashbashreadbashbashreadreadbashreadbashreadbashbashreadreadreadreadreadreadreadbashbashreadreadreadreadbashreadreadeditediteditbashreadreadreadeditreadbashreadread59Nanocoderreadreaddelegatesearchsearchsearchsearchsearchsearchsearchsearchreadreadreadreadsearchreadsearchsearchreadsearchreadreadreadreadsearchreadplanreadeditbashbashbashreadplan35
readsearchbasheditdelegateplan
One representative run per harness, each tool call a cell in the order it happened. Strip length is the call count (Pi 38, OpenCode 17, Claude Code 59, Nanocoder 35), edits in red. OpenCode is short and decisive; Claude Code and Nanocoder are long stretches of reading and searching with their edits clustered near the end.

The four, and how each runs

All four drive the same local model; what differs is the machinery each wraps around it, and that is what the numbers reflect.

Pi (0.80.10), the bare harness, carries almost nothing, a short prompt and a handful of tools, so it stays the leanest on overhead by a wide margin.

OpenCode (1.17.10), the mid-weight framework, leans on compound shell commands, packing several operations into one call, but hands larger pieces of the work off to subagents, which do their own generating, bringing its true output up near Pi's, while the round-trips to and from those subagents are what cost it the extra clock.

Claude Code (2.1.186), the heavy harness, brings 27 tools, most of them orchestration plumbing a bug fix never touches, and it works through them in the most steps of the three, generating several times the output and running the most tools, which is where its tokens and its wall-clock go, with no grade to show for the extra.

Nanocoder (1.29.0), the community harness, is local-first and lean where it counts, its fixed prompt about 6K tokens, nearer OpenCode than Claude Code. But it explores the hardest of the four, read- and search-heavy, planning and delegating to subagents, and re-reading the same files more than any other harness. That exploration is all generation, so it spends like Claude Code, around 56K output tokens and five minutes a task, for the same graded result. Local-first does not mean lean.

PiOpenCodeClaude CodeNanocoder
Tools
4
10
27
15
Fixed overhead / turn
1,340
7,197
23,132
6,121
Avg. steps
28.0
16.6
37.9
37.4
Avg. output tokens
14,775
17,463
58,370
55,844
Avg. wall time
2.1m
3.1m
8.0m
5.2m
Avg. graded quality (0 to 3)
2.34
2.07
2.42
2.25
Claude Code costs the most on every row above the grade, with Nanocoder close behind on tokens and time. On the grade itself the four cannot be told apart, the point estimates jitter but the intervals overlap completely, so no harness is measurably better. Tools and fixed overhead are set per harness; the four rows below them are task-weighted averages across the runs.

Which one to reach for

This is DeepSeek V4 Flash on eight focused bug fixes, so read it scoped. For a capable model the harness is an efficiency choice and not a quality one, at least in my agentic workloads in a large codebase. And the next time a post claims that some harness, some prompt, or some clever context file made a coding model measurably better, the first thing to ask is how many times they ran it, because under about 10 runs a condition there is a good chance they mostly measured the weather.

Update, 27 July 2026 — after the r/LocalLLaMA thread I went and added a fourth harness, Nanocoder, the community local-first one. Same story: it sits right in the quality band with the others, and it spends about as much as Claude Code on tokens and time, so nothing really moved, the picture just gained a fourth harness saying the same thing.