claude-opus-5 at effort=low is the only model that has ever displaced gemini-3.1-pro
as top challenger — and it has run on 1 of 10 splits. That is enough coverage to make
the headline uncomfortable and not enough to change it.
Why this one matters more than the other coverage gaps
On annapolis, the only split where both ran:
| model |
P |
R |
F1 |
| rampnet |
0.973 |
0.738 |
0.839 |
| claude-opus-5 (effort low) |
0.572 |
0.605 |
0.588 |
| gemini-3.1-pro-preview |
0.613 |
0.527 |
0.567 |
| claude-opus-5 (effort high) |
0.430 |
0.656 |
0.520 |
| claude-sonnet-5 (effort low) |
0.589 |
0.381 |
0.463 |
| claude-sonnet-5 (effort high) |
0.506 |
0.415 |
0.456 |
docs/scoreboard.md reports RampNet's lead as +0.221 F1 over the best challenger, and
that best challenger is gemini-3.1-pro at a pooled 0.606. The model that beat it on the
one split where both ran is not in the pool. If the +0.021 annapolis edge held, Claude would
take the row and the lead would read ≈0.20.
That extrapolation is exactly what this issue exists to test, not to assume. annapolis is
one split, and it is the survey-grade Trimble MX7 city — the least representative rig in the
benchmark. Opus could just as easily regress on Mapillary 360s. Either answer is worth having:
a confirmed challenger changes the headline row, and a regression is a real result about what
annapolis's imagery flatters.
Scope
Run claude:claude-opus-5 --claude-effort low on the nine splits it has not seen:
richmond, bend, clovis, morgantown, paterson, gainesville, budapest_district5, sao_paulo,
manual_gold. 1,984 panoramas.
Deliberately not in scope:
effort=high on anything. It is a measured negative: Opus 0.588 → 0.520 and Sonnet
0.463 → 0.456, while spending ~127k extra thinking tokens on 125 panoramas. Effort moves
the operating point (recall up, precision down); it does not raise the ceiling. Running it
comprehensively would roughly double the bill to re-measure a result we have.
claude-sonnet-5 low. At 0.463 it is mid-field, so it adds a row rather than a result.
Worth completing later for the registry's sake; it is not what would change a headline.
Cost
From the measurement already in docs/model_comparison.md — claude-sonnet-5 at
effort=low bills 2,229 input / 39 output tokens per call, 0 thinking, six calls per
panorama — and the verified rates in scripts/model_comparison/pricing.py:
| leg |
rate (per MTok) |
nine splits |
batched (50%) |
claude-sonnet-5 low |
$2 / $10 |
~$57 |
~$29 |
claude-opus-5 low |
$5 / $25 |
~$143 |
~$71 |
Opus is 2.5× Sonnet per token; token counts are assumed comparable, which is the one
soft number here. Sonnet's promotional rate ends 2026-08-31 ($3/$15 after, +50%); Opus
is not promotional so its estimate is stable.
Batching halves it and there is no reason not to — this is an offline benchmark leg with
no latency requirement.
Running it
Credentials are the same Vertex ADC the Gemini legs use — no Anthropic key, no new secret.
Two constraints are already documented in docs/model_comparison.md § "Claude on Vertex" and
neither needs re-discovering: structured_outputs is blocked by org policy so the tool must
stay un-strict, and forcing tool_choice suppresses thinking (harmless at low, where
there is none to lose).
# one split at a time; detections cache, so an interrupted run resumes for free
for split in richmond bend clovis morgantown paterson gainesville \
budapest_district5 sao_paulo manual_gold; do
python scripts/model_comparison/compare.py benchmark/$split \
--models claude:claude-opus-5 --claude-effort low
done
# publish + verify (--publish-as, because effort is in the cache signature and both
# efforts of one model id would otherwise write the same filename)
python scripts/analysis/export_model_cache.py \
--models claude:claude-opus-5 --claude-effort low \
--publish-as claude-opus-5-effort-low
python scripts/analysis/export_model_cache.py --verify \
--models claude:claude-opus-5 --claude-effort low \
--publish-as claude-opus-5-effort-low
Gotchas that have already bitten this leg once
- The usage log is write-once. A cached re-run makes zero API calls and has no usage to
report, so spend that is not captured on the first pass is unrecoverable. The four original
legs' $28.82 exists only in console output for exactly this reason. Capture
--usage-log output on the first run of each split.
- A parse failure costs a whole panorama, not a box. An exception in
_raw_detect
propagates past all six views. Watch the per-pano failure count rather than assuming a
clean exit means clean coverage.
- Model enablement propagates unevenly in Vertex Model Garden — a valid request can 404
for some hours after enabling. Smoke-test one panorama before launching nine splits.
- JPEG round-trip and decoding temperature are unpinned on the existing legs (see the
caveats in docs/model_comparison.md). Match them — take the defaults — or the new splits
are not comparable to the committed annapolis numbers.
Done when
Related: #122 (the registry these legs are entered in, and where standing gets flipped
once this lands), #20 (the standing harness issue for newer models).
🤖 Generated with Claude Code (claude-opus-5[1m])
claude-opus-5ateffort=lowis the only model that has ever displacedgemini-3.1-proas top challenger — and it has run on 1 of 10 splits. That is enough coverage to make
the headline uncomfortable and not enough to change it.
Why this one matters more than the other coverage gaps
On annapolis, the only split where both ran:
docs/scoreboard.mdreports RampNet's lead as +0.221 F1 over the best challenger, andthat best challenger is
gemini-3.1-proat a pooled 0.606. The model that beat it on theone split where both ran is not in the pool. If the +0.021 annapolis edge held, Claude would
take the row and the lead would read ≈0.20.
That extrapolation is exactly what this issue exists to test, not to assume. annapolis is
one split, and it is the survey-grade Trimble MX7 city — the least representative rig in the
benchmark. Opus could just as easily regress on Mapillary 360s. Either answer is worth having:
a confirmed challenger changes the headline row, and a regression is a real result about what
annapolis's imagery flatters.
Scope
Run
claude:claude-opus-5 --claude-effort lowon the nine splits it has not seen:richmond, bend, clovis, morgantown, paterson, gainesville, budapest_district5, sao_paulo,
manual_gold. 1,984 panoramas.
Deliberately not in scope:
effort=highon anything. It is a measured negative: Opus 0.588 → 0.520 and Sonnet0.463 → 0.456, while spending ~127k extra thinking tokens on 125 panoramas. Effort moves
the operating point (recall up, precision down); it does not raise the ceiling. Running it
comprehensively would roughly double the bill to re-measure a result we have.
claude-sonnet-5low. At 0.463 it is mid-field, so it adds a row rather than a result.Worth completing later for the registry's sake; it is not what would change a headline.
Cost
From the measurement already in
docs/model_comparison.md—claude-sonnet-5ateffort=lowbills 2,229 input / 39 output tokens per call, 0 thinking, six calls perpanorama — and the verified rates in
scripts/model_comparison/pricing.py:claude-sonnet-5lowclaude-opus-5lowOpus is 2.5× Sonnet per token; token counts are assumed comparable, which is the one
soft number here. Sonnet's promotional rate ends 2026-08-31 ($3/$15 after, +50%); Opus
is not promotional so its estimate is stable.
Batching halves it and there is no reason not to — this is an offline benchmark leg with
no latency requirement.
Running it
Credentials are the same Vertex ADC the Gemini legs use — no Anthropic key, no new secret.
Two constraints are already documented in
docs/model_comparison.md§ "Claude on Vertex" andneither needs re-discovering:
structured_outputsis blocked by org policy so the tool muststay un-
strict, and forcingtool_choicesuppresses thinking (harmless atlow, wherethere is none to lose).
Gotchas that have already bitten this leg once
report, so spend that is not captured on the first pass is unrecoverable. The four original
legs' $28.82 exists only in console output for exactly this reason. Capture
--usage-logoutput on the first run of each split._raw_detectpropagates past all six views. Watch the per-pano failure count rather than assuming a
clean exit means clean coverage.
for some hours after enabling. Smoke-test one panorama before launching nine splits.
caveats in
docs/model_comparison.md). Match them — take the defaults — or the new splitsare not comparable to the committed annapolis numbers.
Done when
claude-opus-5-effort-low__<split>.jsonand--verifyreports IDENTICAL for 10/10 pairsanalysis_out/usage_log.jsonl, captured at run timerampnet/roster.py's entry updated (density measured across ten splits, not one)docs/scoreboard.mdregenerated — Opus moves from the partial table into the headline,the PR-curve figure's point set, and the generalization figure.
scoreboard.py --checkgreen
docs/scoreboard.mdanddocs/model_comparison.mdRelated: #122 (the registry these legs are entered in, and where
standinggets flippedonce this lands), #20 (the standing harness issue for newer models).
🤖 Generated with Claude Code (claude-opus-5[1m])