Skip to content

Commit a63ee0e

Browse files
committed
perf(evals/tier2): pin --model sonnet, 8x speedup with no quality loss
Tier 2 was inheriting the invoker's configured default model. Eric is on Opus 4.7, so the SUT ran Opus — explains the 45-min runs we were seeing. Tier 1 already pins sonnet explicitly; Tier 2 should too. Reproducibility matters across people with different defaults. Add --sut-model / --judge-model CLI args (both default sonnet, pass "" to inherit user default for ad-hoc Opus runs). Smoke test (demo-signup-loom): - Opus inherited: 2676s (~45 min), 0.94 pass - Sonnet pinned: 337s (~5.6 min), 0.92 pass Sonnet produced 5 slides (vs Opus's 4), annotated all 5 (vs Opus's 3), and exercised the documented selector-miss recovery: tried 4 form selectors, fell back to fetching page HTML to find the real ID, then re-screenshotted with the corrected target. Loom voice intact throughout. The 0.02 score delta is sampling variance. The 8x duration win is structural. Now sub-10-min/seed which means full 4-seed Tier 2 sweeps are feasible (~25 min total) instead of "block out your afternoon" (~3 hours).
1 parent 9e6e131 commit a63ee0e

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

tests/evals/tier2/run.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ def claude_p(
262262
*,
263263
allow_tools: bool = False,
264264
max_budget_usd: float | None = None,
265+
model: str | None = None,
265266
) -> tuple[dict, dict]:
266267
"""Invoke claude -p with structured-output validation. Returns (parsed, envelope).
267268
@@ -291,6 +292,8 @@ def claude_p(
291292
cmd += ['--permission-mode', 'bypassPermissions']
292293
if max_budget_usd is not None:
293294
cmd += ['--max-budget-usd', str(max_budget_usd)]
295+
if model:
296+
cmd += ['--model', model]
294297
cmd.append(prompt)
295298

296299
proc = subprocess.Popen(
@@ -336,7 +339,9 @@ def claude_p(
336339
return parsed, envelope
337340

338341

339-
def run_seed(seed: dict, rubric: dict) -> dict:
342+
def run_seed(
343+
seed: dict, rubric: dict, sut_model: str | None = None, judge_model: str | None = None
344+
) -> dict:
340345
start = time.time()
341346
fixture_server = FixtureServer(seed['fixture'])
342347
fixture_server.start()
@@ -366,6 +371,7 @@ def run_seed(seed: dict, rubric: dict) -> dict:
366371
timeout=seed.get('timeout_s', 600),
367372
allow_tools=True,
368373
max_budget_usd=seed.get('max_budget_usd', 3.0),
374+
model=sut_model,
369375
)
370376
except (
371377
subprocess.CalledProcessError,
@@ -391,7 +397,7 @@ def run_seed(seed: dict, rubric: dict) -> dict:
391397
# Judge the result.
392398
judge_prompt = build_judge_prompt(seed, sut_report, transcript, rubric)
393399
try:
394-
judge_report, _ = claude_p(judge_prompt, JUDGE_SCHEMA, timeout=240)
400+
judge_report, _ = claude_p(judge_prompt, JUDGE_SCHEMA, timeout=240, model=judge_model)
395401
except (
396402
subprocess.CalledProcessError,
397403
subprocess.TimeoutExpired,
@@ -485,8 +491,27 @@ def print_summary(results: list[dict]) -> None:
485491
def main() -> int:
486492
parser = argparse.ArgumentParser()
487493
parser.add_argument('seed_ids', nargs='*', help='Specific seed IDs to run (default: all)')
494+
parser.add_argument(
495+
'--sut-model',
496+
default='sonnet',
497+
help=(
498+
'Model for the SUT (system-under-test) claude -p invocation. '
499+
'Default sonnet — pinning explicitly because Tier 2 inherits the '
500+
"invoker's configured default otherwise, which can be Opus ($$ and "
501+
'slow). Sonnet handles the agentclip workflow with no quality loss '
502+
'and ~2x speedup. Pass "" to inherit the user\'s default.'
503+
),
504+
)
505+
parser.add_argument(
506+
'--judge-model',
507+
default='sonnet',
508+
help='Model for the judge claude -p invocation. Default sonnet.',
509+
)
488510
args = parser.parse_args()
489511

512+
sut_model = args.sut_model or None
513+
judge_model = args.judge_model or None
514+
490515
seeds = json.loads(SEEDS_PATH.read_text())
491516
rubric = json.loads(RUBRIC_PATH.read_text())
492517

@@ -498,11 +523,14 @@ def main() -> int:
498523
print(f'unknown seed ids: {sorted(missing)}', file=sys.stderr)
499524
return 2
500525

501-
print(f'running {len(seeds)} Tier 2 seed(s) — stub stands in for api.agentclip.dev')
526+
print(
527+
f'running {len(seeds)} Tier 2 seed(s) — stub stands in for api.agentclip.dev '
528+
f'(sut={sut_model or "default"}, judge={judge_model or "default"})'
529+
)
502530
results = []
503531
for seed in seeds:
504532
print(f' -> {seed["id"]} ... ', end='', flush=True)
505-
r = run_seed(seed, rubric)
533+
r = run_seed(seed, rubric, sut_model=sut_model, judge_model=judge_model)
506534
write_result(r)
507535
results.append(r)
508536
if 'error' in r:

0 commit comments

Comments
 (0)