Skip to main content

Eval Lab

Myrm’s Eval Lab is a built-in evaluation dashboard that lets you run test cases against your agent, compare performance across different agent profiles, and track quality over time — all from the WebUI.

Key capabilities

  • Single-profile eval — Run a test suite against your current agent configuration and see pass/fail results in real time.
  • Cross-profile matrix eval — Run the same test cases across multiple agent profiles to detect regressions before switching models or prompts.
  • Environment reproducibility — Every eval run captures a frozen EvalManifest snapshot (model, tools, profile, benchmark mode) so results are always reproducible.
  • Benchmark mode — One-click toggle that strips user customizations (skills, MCPs, memory, web search) to produce a fair baseline score using only core tools.
  • Historical trend tracking — View pass-rate trends over time with interactive charts. History table shows Profile, Model, pass rate, average time, and token usage per run.
  • Click-to-detail reports — Click any historical run to load the full report with per-case results, environment snapshot, and diff view.

Getting started

  1. Navigate to Eval Lab from the sidebar (or go to /eval-lab).
  2. In the Config tab, select a dataset and optionally enable Benchmark Mode.
  3. Click Run to start evaluation. Progress updates in real time.
  4. View results in the Report tab — summary cards, per-case table, and environment snapshot.
  5. Switch to the History tab to compare across runs.

WorkBuddy Bench benchmark

The Eval Lab ships with a built-in adapter for WorkBuddy Bench (Tencent’s multi-domain coding-agent benchmark), covering all four official tracks with paper-aligned scoring:

Download a subset

  1. Open Eval Lab and switch to the WorkBuddy Bench tab.
  2. Each track shows its task count, approximate size, and local status (Not downloaded / Downloaded).
  3. Click Download to fetch the archive from Hugging Face in the background. Progress is streamed via SSE; the button disables while a download is running.
  4. Archives are verified against the official SHA-256 checksums and installed atomically — a corrupt or partial archive is never used.
  5. Use Refresh anytime to re-read local disk state; a just-finished download immediately flips the button to Downloaded.

Run a benchmark

  1. Click Run on a downloaded track to evaluate every task in that subset.
  2. A Stop control is available while the evaluation is running — abort is honored mid-run and mid-download.
  3. When finished, the run produces a reproducible report (model, tools, profile, scoring mode recorded in the manifest).
:::tip Security tasks are graded by their own task-native tests/scoring.py (no LLM judge); Code/Web/Office use the composite verifier — matching the WBBench paper’s acceptance layering. :::

International authority benchmarks (BrowseComp)

Beyond WorkBuddy Bench, the Eval Lab integrates BrowseComp — OpenAI’s official benchmark of 1,266 real-world research questions that require multi-hop evidence retrieval and web browsing. Scores produced here use the same task format top AI labs cite, so you get an authority-grade number you can point to in releases or proposals.
  • Sampled runs first — big benchmarks auto-suggest a small sample (e.g. 20 of 1,266) so you validate the whole pipeline at a fraction of the token cost before committing to a full run. Clear the sample to run the full set. Reports badge runs that truly sampled (sampled), so the label is never a guess.
  • Fair baseline by design — benchmark mode strips your skills, MCPs and memory, so the score reflects the model plus core tools only.
  • Pre-flight checks — the run verifies the search / embedding services the benchmark needs are configured and reachable before spending any tokens.

Deterministic scoring: layered acceptance (CompositeVerifier)

Every task’s own test suite drives the score — no black-box LLM grading in the pass/fail path. The composite verifier runs the exact tests/ code shipped inside each downloaded track inside a clean, seeded workspace and turns the result into a real per-turn score:
  • Run the task’s own tests — the test_suite assertion executes the task-bundled tests against the agent’s workspace output. Results are parsed from JUnit XML or a plain reward-script exit code.
  • Per-turn pass_rate — multi-turn conversations score each turn separately, so a task that passes on turn 1 but degrades later is caught early and stops wasting tokens (configurable on_turn_fail strategy).
  • No hidden LLM judge — parsing is deterministic: pass/fail comes from the test runner, not from a model reading the output. This keeps scores reproducible and immune to judge-prompt drift.
  • Partial credit, not binaryskipped tests are excluded from the denominator so an uncollectable flaky test can’t tank a real pass; reward-script outputs map to graduated scores.
  • Test-level visibility — each track card shows both the run pass rate and the test pass rate (avg_pass_rate over turns), and every report carries the aggregated test-level average.
The test_suite timeout defaults to 600s and is configurable per case, so long-running task tests (e.g. compile + run) finish instead of being killed early.

Judge model configuration

Semantic (LLM-as-a-judge) assertions never hard-code a vendor judge. The judge model resolves from your own configuration — explicit per-run override, then assertion-level fields, then your default model config — so scoring works with whatever model provider you already use. Every report records which judge model scored the run (judge_model), and task-native benchmarks honestly mark it none (no LLM judge involved).

Scoring diagnostics: failures never go silent

A grading run can fail before any test produces output — the scoring command may be blocked by the sandbox security policy, hit the timeout, or crash. These failures are now attributed precisely and surfaced with real evidence:
  • Attributed failures — execution-level failures (security block, timeout, crash) are reported as such, instead of being misreported as an “unreadable reward file”. You can immediately tell why a grade failed: the policy blocked it, it timed out, or the command itself errored.
  • stdout tail attached — every “command failed”, “reward file unreadable”, and “JUnit file unreadable” message carries up to 800 characters of the grading command’s real stdout, so you see what actually happened instead of guessing.
  • Counts-based reward fallback — reward payloads that only carry tests_passed/tests_total counters (or a tests[] array), rather than the full score.json/reward.json schema, are now parsed and scored correctly instead of being rejected as unreadable. This mirrors the official WBBench runner’s counting semantics while staying compatible with lightweight scorer scripts.

Layered evaluation: how much does each harness layer actually contribute?

“Does the framework really help, or is it just a smarter model?” Layered evaluation answers this with a single run: the same task set runs across an ascending capability chain — from a fair stripped baseline to the full agent configuration — and the report shows the incremental gain of each layer (harness core, skills, memory) as measured deltas instead of marketing claims.

The layer chain

How to run

  1. Open Eval LabMatrix tab.
  2. Pick a downloaded benchmark and start a Layered run.
  3. Progress streams live (download bytes → per-layer case progress), the report renders in the familiar matrix view, and every run lands in history for later comparison.

Why you can trust the numbers

  • Fingerprints pin the exact switches — each layer’s benchmark_mode / skills_enabled / memory_enabled combination is locked by a SHA-256 fingerprint in the report, so the layer definitions stay comparable across harness upgrades.
  • Full model disclosure — reports record agent_model, judge_model, and harness_version (same honesty contract as Memory A/B and benchmark manifests), so a score curve can only drift when real capability changed — never because the ruler moved.
  • Behavior evidence, not just scores — each layer reports how many times the agent actually called memory tools (memory_tool_calls), so “memory didn’t help” is never confused with “memory was never used”.
  • Isolated measurement — all layers run with shared contexts disabled and throwaway memory volumes (SQLite + embedded Qdrant) that are evicted and deleted after the run; the memory layer’s gain reflects the memory mechanism itself, not your real shared memory.
This is the Harness Leverage Ratio (HLR) idea made practical: instead of telling you “our framework is strong”, Myrm measures how much each capability layer moves task completion — a number you can cite in proposals, releases, and migration decks.

Cross-profile matrix eval

To compare how different agent configurations handle the same tasks:
  1. In the Config tab, select 2 or more profiles from the chip-based multi-selector.
  2. A Matrix mode badge appears automatically when 2+ profiles are selected.
  3. Click Run Matrix to start. The dashboard switches to the Matrix tab showing real-time progress:
    • Which profile is currently being evaluated
    • Profile progress (e.g., 2/3)
    • Case completion progress bar
  4. When complete, the Matrix tab displays:
    • Summary cards — total cases, stable rate, regression count, total time
    • Per-profile table — pass rate, tokens, cost, and time for each profile
    • Case × Profile grid — color-coded matrix showing each case’s status on each profile (green = stable, amber = regression, red = all failed)
  5. Cases are classified as:
    • Stable — passes on ALL selected profiles (safe to switch models)
    • Regression — passes on some but fails on others (risky areas)
    • All failed — fails on every profile (needs investigation regardless)
:::tip If any evaluation fails (e.g., API key expired, model unavailable), a toast notification shows the error immediately — no silent failures. :::

Memory A/B: prove memory’s value with numbers

Is enabling memory actually making your agent better? Memory A/B answers this with a side-by-side experiment instead of marketing claims.

How it works

  1. Open Eval LabWorkBuddy Bench and pick a downloaded track.
  2. Click Memory A/B on a track card — a confirmation dialog shows exactly what will run.
  3. The dialog probes your embedding model first: memory retrieval depends on embeddings, so a missing or unreachable embedding model is reported before you waste a run.
  4. Myrm runs the same tasks twice — once with enable_memory=True, once with enable_memory=False — everything else identical.
  5. Live progress streams over SSE; the header Stop button aborts the run and cleans up mid-run.
:::note The dialog honestly notes that WBBench tasks are single-turn, so memory gains show more clearly in long multi-turn sessions. We’d rather you interpret results correctly than oversell. :::

The report

The matrix report shows both arms side by side:
  • Pass rate — task completion rate with vs without memory
  • Tokens & cost — the price of remembering
  • memory_tool_calls — how many times memory tools were actually invoked. If memory helped, you can see it was really used — no false positives from “enabled but never used” memory.

History

Every Memory A/B run lands in the Run History table (timestamp, dataset, both arms’ pass rates and memory_tool_calls). Click View to reopen any past report — track whether memory’s value changes as your product evolves.

Isolation & safety

Memory A/B runs use temporary, isolated memory storage that is discarded after the run — your real memory data is never touched or polluted.

Test coverage

Full-link Chrome E2E coverage (real browser, real backend): card entry + confirmation dialog, seeded dual-arm report + history rendering, and a real run start + abort — 3 E2E tests, plus 12 frontend unit tests.

Eval workspace lifecycle: isolated sandboxes that self-clean

Every eval case runs in a physically isolated workspace (.myrm/eval_workspaces/{case_id}), so concurrent cases never race on the same files and an agent can only touch its own sandbox. The lifecycle is fully automatic:
  • Destroyed after every run — success, failure, abort, or crash all land in the same cleanup path (create_session and execute-only runs alike), so long-running servers never accumulate disk.
  • Crash self-healing — any workspace left behind by a dead process is swept automatically at the next server startup; nothing to clean by hand.
  • Failure-proof cleanup — each teardown step (memory-volume eviction, directory removal, per-profile workspace cleanup) is independently guarded, so one failing step can never leak the rest.
The same isolation extends to Memory A/B: both arms get throwaway memory volumes that are evicted and deleted after the run.

Evaluation integrity: decontamination, budgets & trajectory disclosure

A benchmark score is only worth trusting if the run can’t be gamed and the report can be audited. Eval Lab makes both structural.

Contamination-proof runs (HF leakage protection)

During benchmark runs the agent is barred from the repositories that hold reference answers — most importantly Hugging Face, where WBBench tracks and countless answer keys live. Defense in depth:
  • Web fetch — any hostname on the benchmark’s blocklist raises a benchmark_blocked tool error the moment it’s hit.
  • Web search — results from blocklisted hosts are silently dropped before ranking/formatting, and queries matching blocklisted terms fail fast.
  • Shell / code execution — the network policy defaults to no outbound access (or a strict allowlist without Hugging Face), so there is no side channel to exfiltrate the answer key.
  • Reports record whether decontamination was active (decontam_active), and the Report tab shows it as a badge — so a “clean” score is provable, not assumed.

Declared run budgets

Every third-party benchmark declares its own tool-call and iteration budgets (max_tool_calls / max_iterations):
  • A stuck agent can’t burn tokens forever — the tool-call middleware and the engine’s recursion budget enforce the caps.
  • The moment a cap is hit, the run stops and the per-case report records exactly which limit stopped it (limit_reached, e.g. max_tool_calls or max_iterations). Truncated cases are never silently indistinguishable from finished ones.
  • The manifest records the declared budget, and the Report tab shows it as Budget · N calls / M iterations.

Trajectory disclosure

Every report exposes the execution evidence behind each score:
  • Tool call details — how many tool calls the agent made ( badge with tooltip).
  • Blocked count — how many attempts the contamination guard intercepted (Blocked N badge).
  • Limit reached — which budget stopped the run (Limit badge with the specific type in the tooltip).
  • Judge transparency — semantic (LLM-as-a-judge) assertions accept a configurable judge_prompt, recorded in the report; agent_model / judge_model are disclosed for every run (task-native grades honestly mark none). Exact-match answers short-circuit the judge entirely, so trivial hits never spend judge tokens.
Together these make a score auditable down to every tool call — you can explain not just what the number is, but under what protection, budget, and trajectory it was produced.

Environment snapshot

Every eval run records an EvalManifest with: This snapshot appears in the Report tab under Environment and in the History table as the Profile and Model columns.

Benchmark mode

Toggle Benchmark Mode in the Config tab to get a clean baseline:
  • System prompt → empty
  • Tools → core-only (no MCP, no skills, no sub-agents)
  • Memory, web search, replan, compression → disabled
This lets you measure the raw model capability without your customizations, making scores comparable across setups.

Writing test cases

Test cases are JSONL files where each line is a JSON object:
For semantic assertions (LLM-as-Judge):
Multi-turn cases chain turns with configurable failure strategies:

Skill publish quality guard

When a skill evolves through Myrm’s Skill Evolution pipeline, it passes through 5 layers of defense before reaching production:
  1. EvolutionScreener — 5-phase screening (locked → force retry → cooldown → rejection history → LLM confirmation) blocks invalid evolution attempts before they consume resources.
  2. EvalCase Regression Gate — Runs bound EvalCases against candidate variants. Applies score penalties proportional to failed cases; hard-filters variants that fail 100% of cases.
  3. Improvement Gate — Injects the original skill as a baseline competitor. Only variants that genuinely score higher than the original survive.
  4. SandboxValidator — Executes candidates in an isolated sandbox to verify they actually work.
  5. ConfidenceApprovalFlow — Multi-signal risk control (diff ratio, effective rate, confidence threshold). Red flags downgrade to human Diff Review in the GUI.
After approval, Shadow AB testing validates the new version against real traffic before full rollout. If issues arise, one-click rollback restores the previous version instantly.

History & degradation

  • Old reports (created before manifest tracking) display - for Profile and Model columns — no data loss.
  • The history table supports horizontal scrolling on narrow screens.
  • Failed report loads show a toast notification instead of failing silently.