Trefon.
← All notes 6 min

amber-bench: benchmarking the harness, not the model

A model leaderboard can't tell you whether your agent loop is broken. I built a benchmark that scores the harness and the model as a pair. The first thing it found was bugs in my own harness.

Jacek Trefon
  • harnesses
  • evals
  • C++
  • amber
Code ↗

Every agent result is a pair: a model and the harness driving it. The tool schemas, the system prompt, the loop control and the way tool output is parsed and fed back all change what the model does. Swap the harness and the same model scores differently. Leaderboards score the model alone, so they can’t tell you which half of the pair is failing.

amber is my C++17 agent runtime. amber-bench is the benchmark I built next to it, to measure the harness itself: every architecture change should show up as a number, not as a feeling after a good afternoon.

What it runs

There are 49 scenarios in 10 suites:

SuiteScenariosExamples
Coding5FizzBuzz, sorting, ring buffer, LCS, graph BFS
Prompt adherence5envelope format, refusing a banned tool, verify before claiming
Refactoring4extract method, polymorphism over switch, adapter, strategy
Terminal work6count files, grep a value, compile and run C++, pipelines
Tool selection6search vs grep, read vs cat, write vs rewrite
Agent failures6redundant calls, recovering from a mistake, mid-stream dropout, empty replies
Loop-live6plan design, plan adherence, repeat discipline, termination
Review8architecture, data structures, patterns, code quality
Repo2repository navigation and search
Delegate1sub-agent delegation

How it scores

Each scenario earns 0–100 from four sub-scores:

  • Correctness: did it reach the right result? Checked against the expected answer and a hidden test.
  • Efficiency: steps, wasted calls and redundant calls, compared with what the task needs.
  • Robustness: retries, recoveries and hard stops.
  • Adherence: prompt checks passed, minus any use of a forbidden tool.

Scenarios carry a difficulty weight from 1 to 5. The model score is the weighted aggregate, scaled to 1000.

The first thing it found was my bugs

I recorded harness baselines on the same model, Qwopus3.6-27B, as the engine changed:

BaselineScenariosScorePass
v2, first live calibration43769.139/43
v3, after fixes43821.641/43
v4, loop-live suite added49788.242/49

The +52.5 points between v2 and v3 didn’t come from a better model or a better prompt. They came from three harness defects that the v2 run surfaced:

  • Oracle: path normalisation in the oracle was wrong.
  • JSON extraction: extraction failed when a model answered with bare JSON.
  • SSE sink: the sink’s lifetime ended too early.

v4 adds six loop-discipline scenarios, so its score isn’t comparable with v3.

For scale: on the current 49-scenario set, the gap between the best and the worst of ten local models is 99.6 points. Harness bugs alone were worth about half of that.

Ten local models, one harness

Every model in my local swap registry runs the full 49 scenarios, serially, on one GPU slot:

ModelScorePassLoop-liveWastedRedundant
Qwen3.6-27B (dense)816.244/4989.014612
Qwopus3.6-27B-v2-MTP808.042/4976.214212
Gemma-4-31B806.238/4975.91088
Gemma-4-12B Q4780.037/4975.812017
Ornith-1.0-35B770.040/4975.619243
Qwen3.6-27B MTP768.841/4977.116617
Gemma-4-12B Q8756.837/4975.813528
Qwen3.6-35B-A3B (MoE)742.236/4965.918336
Qwen3.6-27B (pi-reasoning)723.336/4963.219736
Ornith-1.0-9B716.627/4980.0271122

The table above is a snapshot. The live leaderboard, updated with each run: trefon.com/benchmarks.

What I read from it:

  • Dense 27B leads. The two dense Qwen3.6-27B variants are the strongest local agentic models I have, at 816 and 808.
  • MoE and reasoning modes cost tool discipline. The 35B MoE (742) and the pi-reasoning variant (723) trail models smaller than them.
  • Pass rate and tool economy are different axes. Gemma-4-31B wastes the fewest calls (108 wasted, 8 redundant) but passes only 38 of 49.
  • Small models fall apart on loops. Ornith-1.0-9B makes 271 wasted and 122 redundant calls.

Running it without a model

There’s a hermetic mode with a fake LLM. It’s deterministic and needs no model and no GPU, so the harness half of the pair gets tested in CI on every change.

What I take from it

  1. Fix the harness before you pick the model. The cheapest 52 points I found were in my own code.
  2. Count waste, not just passes. Ornith-1.0-35B passes more scenarios than Gemma-4-31B (40 vs 38) with almost twice the wasted calls (192 vs 108). Wasted calls are what you pay for in tokens and latency.
  3. Measure loop discipline on its own. It fails differently from correctness, and it’s what turns a capable model into an agent that never stops.

The full tables, the scenario list and the method: jtrefon.github.io/amber/benchmarks. The code: github.com/jtrefon/amber.

Have a problem like this?

Describe your problem

30-minute technical call with the engineer who builds it. No sales team, no slides.