License: MIT Python 3.11+ Node 20+ Status
Repo: github.com/Onur45500/SampleMoreStudio
At matched token cost, independent sampling tends to beat self-critique loops.
SampleMoreStudio is an open-source benchmark harness + live dashboard that tests that claim under equal completion-token budgets — first on single-turn reasoning tasks, then on short tool-using agent scaffolds. Local models (Ollama) are first-class so you can reproduce at ~0ドル.
This is an independent reproduction / extension inspired by the 2026 Sample More, Reflect Less finding. It is not a copy of that paper’s harness.
Delta Charts — strategy accuracy at matched budget
Delta Charts — equal-budget strategy comparison with hero Δ callout (preliminary data).
Prompt-engineering folklore and many agent scaffolds favor self-critique loops (Self-Refine, Reflexion). A competing idea is simpler: spend the same token budget on independent samples and aggregate (majority vote / best-of-N).
SampleMoreStudio makes that comparison auditable:
- Same model, same temperature, same total completion-token budget
B - Full transcripts (every sample, critique, tool call)
- Deterministic graders (no LLM-as-judge)
- Dashboard charts for the "reflect loses" delta, budget curves, and turn-by-turn inspection
Results are always scoped: on this suite, at these budgets, with these models.
- Equal-cost sweep harness — every
(model ×ばつ strategy ×ばつ task ×ばつ budget ×ばつ seed)cell, resume-safe - 8 strategies — Phase 1: CoT, Self-Refine, Best-of-N, Majority-Vote@K · Phase 2: ReAct, Plan-then-Act, Reflexion, Majority-of-N-agent
- ~120 tasks — math (offline GSM8K slice), code, logic, and fake file/JSON/calc tool tasks
- React dashboard — live monitor, leaderboard, delta charts, budget curves, run explorer, transcript viewer (+ side-by-side compare); see Dashboard features
- Static export — dump SQLite → JSON + frontend build for a backend-free publishable site
Open http://localhost:5173 after starting the API and frontend. The left sidebar has a Phase filter (Phase 1 / Phase 2 / Combined) that applies across all views, plus navigation to each page.
| View | Route | What it does |
|---|---|---|
| Live Monitor | / |
Default landing page. Sweep progress bar, ETA, current model/strategy/task/budget, live leaderboard preview, token/cost gauges, auto-scrolling log tail. Start a named preset or Stop a running sweep. |
| Leaderboard | /leaderboard |
Sortable aggregates per (model, strategy, budget): accuracy, tokens spent vs target, n_or_k, per_sample_cap, truncation_rate, tool calls (Phase 2), overshoot count. CSV export. |
| Delta Charts | /delta |
Signature "reflect loses" grouped bar chart (accuracy by model ×ばつ strategy at a selected budget). Hero Δ callout with paired bootstrap CI. Toggle refine before/after for Self-Refine / Reflexion (initial draft vs final answer). |
| Budget Curves | /budget-curves |
Line chart: accuracy vs token budget, one line per strategy (does sampling-vs-reflect hold as B grows?). |
| Run Explorer | /runs |
Every individual run (filter by strategy / correct). Click a row’s model link to open that run’s transcript. |
| Transcript Viewer | /runs/:runId |
Turn-by-turn cards: role, label (e.g. sample_2_of_4, critique_round_1, tool call/result), tokens, truncation flag, full content. Target vs spent budget bar (red if overshoot). |
| Side-by-side compare | /compare?a=...&b=... |
From Run Explorer, click A on one run and B on another (same task recommended), then Compare A/B. Two transcripts, final answers, and correctness side by side — ideal for "why did Majority-Vote win and Self-Refine lose on this problem?" screenshots. |
| Tasks | /tasks |
Task catalog with category, prompt preview, and pass-rate across runs (spot broken/outlier tasks). |
How to open a transcript
- Sidebar → Run Explorer
- Click the model link on any row → Transcript Viewer
How to compare two strategies on the same task
- Run Explorer → click A on e.g.
self_refine/math_003 - Click B on
majority_vote/ samemath_003 - Click Compare A/B
You need finished runs in the DB first (python scripts/cli.py phase0 ... or a sweep). Live Monitor polls /api/progress every 2s (no SSE required).
Live Run Monitor — presets, progress, live leaderboard, cost gauges, log tail:
Side-by-side compare — two runs on the same task (turn labels, tokens, truncation, correctness):
Side-by-side transcript compare
flowchart LR
cfg[config YAML] --> runner[sweep_runner]
runner --> strat[Strategy.run]
strat --> budget[token_budget]
strat --> model[Ollama or litellm]
strat --> grade[deterministic graders]
runner --> db[(SQLite transcripts)]
db --> api[FastAPI]
api --> ui[React dashboard]
db --> export[static site]
| Piece | Location |
|---|---|
| Budget engine | backend/token_budget.py |
| Strategy interface | backend/strategies/base.py |
| Sweep + resume | backend/sweep_runner.py |
| API | backend/main.py, backend/api/ |
| Dashboard | frontend/src/ |
| Config | config/ (models.yaml, budgets.yaml, strategies.yaml, sweeps.yaml) |
| Tasks | tasks/ |
The unifying abstraction is a Strategy:
run(task, model, token_budget) → transcript + final_answer + tokens_spent
Everything else (grading, storage, dashboard) is strategy-agnostic and shared across phases.
Primary budget = completion tokens. Prompt tokens and estimated $ cost are recorded alongside but do not consume B.
Invariant: never exceed B. Undershoot is normal (models stop early). Overshoot > 10% is flagged. Every generation records a truncated flag.
A fixed per-sample cap (e.g. always 128) silently truncates Best-of-N / Majority-Vote while CoT uses the full B. Defaults in config/budgets.yaml:
sample_cap = max(128, B ×ばつ 0.25)→ 256→128, 512→128, 1024→256, 2048→512selection_cap = max(64, B ×ばつ 0.125)
The leaderboard exposes n_or_k, per_sample_cap, and truncation_rate so fairness is auditable.
| Strategy | Allocation |
|---|---|
| CoT | One call, max_tokens = B |
| Self-Refine(R) | Even split across 2R+1 slices (initial + ×ばつ(critique + revision)); unspent rolls forward |
| Best-of-N | N = floor((B − S_sel) / S_sample); selection is a model call |
| Majority-Vote@K | K = floor(B / S_sample); selection free (counting) — K can exceed BoN’s N |
| Phase 2 scaffolds | Budget across the multi-turn loop; early stop + budget_exhausted if needed |
| Majority-of-N-agent | N independent agent attempts within B, then majority vote |
All strategies use the same temperature (default 0.7 in config/models.yaml).
git clone https://github.com/Onur45500/SampleMoreStudio.git
cd SampleMoreStudio- Python 3.11+
- Node 20+
- Ollama with a local model matching config, e.g.:
ollama pull qwen2.5:7b-instruct-q4_K_M
Windows
.\setup.ps1 .\.venv\Scripts\Activate.ps1 $env:PYTHONPATH = (Get-Location).Path
Unix
chmod +x setup.sh && ./setup.sh source .venv/bin/activate export PYTHONPATH="$(pwd)"
python scripts/cli.py phase0 --tasks 20 --seeds 1 --budget 512
Runs Self-Refine vs Majority-Vote on math, dumps transcripts under results/transcripts/, and prints Δpp + budget integrity.
# Terminal 1 uvicorn backend.main:app --reload --port 8000 # Terminal 2 cd frontend npm run dev
Open http://localhost:5173.
docker compose up --build
Ollama must be reachable from the backend container (host.docker.internal on Docker Desktop).
Get-NetTCPConnection -LocalPort 8000 | Select-Object OwningProcess Stop-Process -Id <pid> -Force
Or use --port 8001.
Named presets live in config/sweeps.yaml:
python scripts/cli.py sweep --preset phase0 python scripts/cli.py sweep --preset phase1_publish # resume-safe; long-running python scripts/cli.py sweep --preset phase2_publish
Overrides: --seeds, --budgets, --categories, --task-limit, --models, --strategies.
The dashboard Start preset control uses the same presets. Re-run to resume; completed cells are skipped.
python scripts/cli.py generate-tasks # rebuild task JSON from generators / offline GSM8K slice python scripts/test_budget.py # budget + extraction unit tests python scripts/summarize.py # quick leaderboard dump from SQLite
- Model — edit
config/models.yaml(ollama/...local, or OpenRouter via.envOPENROUTER_API_KEY) - Task — add JSON under
tasks/phase1_reasoning/<cat>/ortasks/phase2_agent/<cat>/withid,prompt,answer,grader,grader_params - Strategy — implement
Strategyunderbackend/strategies/, register inconfig/strategies.yamlandbackend/strategy_registry.py
python export/build_static_site.py --build
Writes a backend-free site to export/out/ (including transcripts).
Numbers below are from small local smokes on qwen2.5:7b-instruct-q4_K_M. Treat them as signal checks, not a published claim. Larger phase1_publish / phase2_publish sweeps (with bootstrap CIs) should replace these when complete — please open an issue or PR with updated tables rather than overstating early results.
| Strategy | Accuracy |
|---|---|
| Majority-Vote | 16.7% (n=6) |
| Self-Refine | 0.0% (n=6) |
Δ ≈ +16.7 pp (sampling over reflecting); CI wide at this n. Budget spent/target ≈ 1.0, 0 overshoot flags. At B=256 with thin slices, Self-Refine rarely emits a usable Answer:.
| Strategy | Accuracy | Tokens spent / target |
|---|---|---|
| CoT | 87.5% | 195/512 |
| Best-of-N | 37.5% | 483/512 |
| Majority-Vote | 12.5% | 511/512 |
| Self-Refine | 0.0% | 512/512 |
Majority-Vote beat Self-Refine on the claim under test. CoT won overall in part because fixed sample_token_cap=128 truncated multi-sample strategies — V2 scales caps with B to reduce that confound.
| Strategy | Accuracy | Avg tool calls |
|---|---|---|
| Plan-then-Act | 83.3% | 1.0 |
| Reflexion | 66.7% | 2.5 |
| ReAct | 33.3% | 1.3 |
| Majority-of-N-agent | ~30%+ | ~0.8–2 |
On short deterministic tool tasks, a single good plan can win; Majority-of-N needs enough tokens per attempt for a full Action/Observation loop.
Transcript dumps: results/transcripts/sweep_*/*.txt.
Limitations
- Compare strategies within a model; local vs API absolute skill differs
- Small
n→ wide CIs on hero Δpp - Allocation formulas are necessarily somewhat arbitrary (documented above)
- Offline GSM8K slice may be contaminated for absolute accuracy; rankings are the target claim
- Code grading =
subprocess+ timeout — not a security boundary - Run from repo root (
PYTHONPATH); not published as a PyPI package
Non-goals (v1/v2)
- No LLM-judge grading
- No auth / multi-tenant SaaS
- No distributed multi-GPU orchestration
- No fine-tuning
- No claim of universal settlement of "sample vs reflect"
Contributions welcome — see CONTRIBUTING.md for setup, tests, and how to add models / tasks / strategies.
Good first directions: more offline tasks, preset docs, dashboard UX polish, reproducing a publish sweep and updating the preliminary findings table with CIs.