Skip to main content

agent-eval

Run eval fixtures against review agents and grade results. Use this after adding or modifying a review agent, to validate detection accuracy, or when the user says "run the evals", "test the agents", "check for regressions", or "how accurate is the agent".

Informações da origem

Repositório
bdfinst/agentic-dev-team
Última atividade na origem
23 de setembro de 2026 às 13:40
Idioma detectado do SKILL.md
inglês
Estrelas
299
Forks
36

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
agent-eval
description
Run eval fixtures against review agents and grade results. Use this after adding or modifying a review agent, to validate detection accuracy, or when the user says "run the evals", "test the agents", "check for regressions", or "how accurate is the agent".
argument-hint
[--agent <name>] [--skill <name>] [--fixture <name>] [--trials <n>] [--in-session] [--integration] [--ablation <agent>] [--no-cache] [--verbose]
user-invocable
true
allowed-tools
Read, Grep, Glob, Bash(readlink *, ls *, date *, mkdir *, command -v claude, claude -p *, python3 scripts/eval_cache.py *, python3 scripts/run_integration_eval.py *, python3 scripts/eval_variance.py *, python3 "$CLAUDE_PLUGIN_ROOT/scripts/eval_ablation.py" *, python3 scripts/citation_lint.py *, python3 "$CLAUDE_PLUGIN_ROOT/scripts/test_review_mechanics.py" *), Skill(review-agent *), Skill(test-design-advisor *)
# Agent Eval Role: orchestrator. This skill dispatches fixtures to agents and grades results — it does not review code itself. You have been invoked with the `/agent-eval` skill. Run review agents against eval fixtures and grade the results. **Monorepo-relative by design (#1637).** Every `scripts/eval_*.py`/`citation_lint.py` call in this skill is intentionally bare, not a dangling-path defect: none of these scripts ship under `plugins/dev-team/scripts/` (verified mechanically — see `tests/repo/test_agent_implemented_by_resolves.py`'s `INTENTIONAL_BARE_INVOCATION` set), so no `${CLAUDE_PLUGIN_ROOT}` path could ever resolve one. They operate on *this repo's own* `evals/` corpus, explicitly not shipped — see repo CLAUDE.md's Repository Structure — and the repo-root eval runners (`scripts/run-full-eval.sh`, `scripts/eval-changed.sh`, `scripts/run-ablation.sh`) plus `.github/workflows/agent-eval.yml` all materialize `evals/fixtures`/`evals/expected` into `.claude/evals/` via a `$PWD`-relative symlink before invoking this skill — meaningful only from this checkout's own root. The `allowed-tools` frontmatter above additionally hardcodes these bare strings as Bash permission patterns, which would stop matching if qualified. ## Orchestrator constraints 1. **Do not review or design yourself.** Delegate reviews to `/review-agent` and advisory analysis to the skill under eval (e.g. `test-design-advisor`). Your job is dispatching and grading. 2. **Grade deterministically.** Compare agent JSON output against expected JSON using exact criteria (status match, count ranges, keyword checks). Do not apply judgment. 3. **Minimize context per agent.** Pass only the fixture file to the agent — not the expected results, not other fixtures, not prior transcripts. One narrow exception: a `test-review` dispatch also receives its fixture's own `test_review_mechanics.py` mechanical pre-phase result (Step 3 below, #2169 follow-up) — computed from the fixture file itself, not from grading data, so it does not weaken this constraint's intent. 4. **Track results.** Save transcripts for saturation detection. Do not modify fixtures or expected files. 5. **Be concise.** Output the report table and failure details. No narration of each fixture run — just the grades. ## Parse Arguments Arguments: $ARGUMENTS - `--agent <name>`: Run only the named review agent (e.g., `js-fp-review`) - `--skill <name>`: Run only the named advisory skill (e.g., `test-design-advisor`) against its skill fixtures - `--fixture <name>`: Run only the named fixture (e.g., `fp-array-mutations.ts`) - `--trials <n>`: Run each fixture N times (default: 1). Enables pass@k scoring. - `--in-session`: Dispatch agents in this session instead of a fresh subprocess (see *Dispatch mode* below). Faster, but evaluates the agent definitions as already loaded — use only for cheap re-grades when no agent/skill file has been edited since they were loaded. - `--integration`: Dispatch the **integration tier** instead of the unit tier (see *Confidence pyramid* below). Routes fixtures that declare an `integration` block in their expected JSON through `scripts/run_integration_eval.py` (orchestrator dispatched against a spec in an ephemeral worktree, then the fixture's `testCommands` are graded by the `integration` grader). Cannot be combined with `--agent` or `--skill` — integration fixtures target the orchestrator, not a single reviewer. - `--ablation <agent>`: Causal drop-candidate evidence (#868). Implies the integration tier and runs it **twice** — a baseline arm (full review-agent roster) and an ablated arm (roster minus `<agent>`) — K=3 trials per arm, then reports the outcome delta (issues caught, `testCommands` results, token cost). See *Ablation mode* below for the full procedure. Rejected in combination with `--agent`/`--skill` (integration fixtures target the orchestrator) and with more than one target agent — v1 supports exactly one ablated agent per run: "error: --ablation supports exactly one agent per run (v1); combining with --agent/--skill or naming multiple agents is not supported." - `--no-cache`: Bypass the fingerprint replay cache (see *Cache* below). Default is cache-on, so a pair whose transitive inputs are unchanged replays from `evals/.eval-cache.json` at zero token cost. Use `--no-cache` when you suspect cache corruption or want a clean cost baseline. - `--verbose`: Show full agent output for each fixture - No arguments: run all agents against all applicable fixtures ## Confidence pyramid `/agent-eval` dispatches at one of three tiers, in increasing confidence and cost. See [ADR 0007](../../../../docs/adr/0007-eval-confidence-pyramid-tier-vocabulary.md) for the full vocabulary; this skill is responsible for selecting the tier and routing to the right runner. - **Unit** (default) — one reviewer or one advisory skill against one fixture, graded by the `verdict` or `skill_gate` grader. Cheap, deterministic, used for every reviewer change. This is what runs when neither `--integration` nor any tier-specific flag is set. - **Integration** (`--integration`) — the orchestrator builds against a golden-repo spec in an ephemeral worktree; the fixture's `testCommands` must all exit 0 (graded by the `integration` grader). Validates that a plan produces code that compiles and passes tests, not just that a reviewer flagged the right thing. Opt-in, costs orchestrator + builder tokens. - **Acceptance** — production-style runs over real PRs / merged code, scheduled outside this skill (the live regression gate in CI). `/agent-eval` does not dispatch acceptance directly; mention it for context only. When the operator does not specify a tier, run **unit** and report in the final table how many fixtures would have routed to integration (the count of expected JSON files whose `integration` block is non-empty). That nudge keeps integration coverage visible without forcing every run to pay for it. ## Ablation mode (`--ablation <agent>`, #868) Gives `/harness-audit` **causal** drop-candidate evidence instead of the correlational usage data it derives from `.claude/metrics/review-value.jsonl` alone: does removing this agent from the roster actually change integration-tier pipeline outcomes? **OPT-IN / LABEL-GATED — same policy as the integration tier (#134).** Before doing anything else, confirm the opt-in gate is present (a `run-integration` / live-eval label on the invoking issue or PR, or the operator explicitly confirming a live, cost-incurring run in this session). If the gate is absent: ```text refused: --ablation requires the label-gated live-eval opt-in (#134) — the same policy that gates the integration tier. Add the `run-integration` label or have the operator explicitly confirm a live run, then retry. Nothing was dispatched; nothing was written to .claude/metrics/. ``` Stop there — dispatch nothing, write nothing to `.claude/metrics/`. **Argument validation.** Reject before any dispatch if `--ablation` is combined with `--agent`/`--skill`, or if more than one agent is named (v1 is single-agent only — see *Parse Arguments* above for the exact error text). **Fixtures.** Default to every expected JSON with a non-empty `integration` block (narrow with `--fixture <name>`). **Cost estimate + explicit confirmation — before any dispatch.** Two arms (baseline, ablated) × K=3 trials each × the number of selected fixtures is 6× the integration tier's normal per-fixture cost. Print an estimate before dispatching the first trial of either arm: ```text Ablation cost estimate: <agent> × <N> fixture(s) × 2 arms × 3 trials = <6·N> integration dispatch(es). Prior integration runs on this fixture set averaged ~<tokens> tokens/dispatch (or: "no prior run recorded — using the integration tier's stated per-dispatch heuristic"), so expect roughly <estimate> tokens total. Proceed? [y/N] ``` Declining aborts immediately — zero tokens spent, nothing written. **Dispatch — cache bypassed.** Both arms must be live to be comparable, so skip the fingerprint-replay cache pre-flight entirely for ablation arms (same stance as the plain integration tier). For each selected fixture, run 3 trials of each arm, writing each trial's actuals to its own file under a per-arm trials directory: ```bash # baseline arm (full roster) — repeat 3x into baseline-trials/trial-<n>.json python3 scripts/run_integration_eval.py --fixtures-dir evals/fixtures \ --expected-dir evals/expected --only <fixture> --model <model> \ --out baseline-trials/trial-1.json # ...trial-2.json, trial-3.json # ablated arm (roster minus <agent>) — repeat 3x into ablated-trials/ python3 scripts/run_integration_eval.py --fixtures-dir evals/fixtures \ --expected-dir evals/expected --only <fixture> --model <model> \ --ablate-agent <agent> --out ablated-trials/trial-1.json # ...trial-2.json, trial-3.json ``` `--ablate-agent <agent>` scopes `DEV_TEAM_ABLATE_AGENT=<agent>` to that one subprocess's environment — no file mutation, no cleanup risk; the roster reverts the instant the subprocess exits. Never edit an agent/skill file to achieve the exclusion. **Delta computation and persistence.** Hand both trial directories to `eval_ablation.py --mode agent` — the deterministic, model-free half that grades each arm (pass@k over the 3 trials, per the same machinery `eval_variance.py` uses for `--trials`) and computes the delta. `eval_ablation.py` ships under `plugins/dev-team/scripts/` (#1653 — its `--find-latest` mode has no repo-shape assumption), so it is `${CLAUDE_PLUGIN_ROOT}`-qualified below even though this specific invocation (`--mode agent --expected-dir evals/`) still only succeeds from this repo's own dev checkout, same as its still-bare siblings (`eval_cache.py`, `eval_variance.py`, `run_integration_eval.py`, `citation_lint.py`) — this is per-script, not per-skill: the FILE moved, the eval-corpus dependency the `--mode agent` path carries did not: ```bash python3 "$CLAUDE_PLUGIN_ROOT/scripts/eval_ablation.py" --mode agent \ --expected-dir evals/expected \ --baseline-trials-dir baseline-trials --ablated-trials-dir ablated-trials \ --ablated-agent <agent> --model <model> \ --append metrics/eval-ablation.jsonl ``` This appends one `schema: "eval-ablation/v1"` JSONL record (`recorded_at`, `ablated_agent`, `fixtures`, `model`, `baseline`/`ablated`/`delta` — each covering `issues_caught`, `test_commands`(_passed for delta), `tokens` — and `verdict`). **A failing baseline arm blocks any drop/retain claim**: the script itself forces `verdict: "baseline failed — inconclusive"` when the baseline didn't pass every trial — report that plainly, do not paraphrase it into a drop/retain recommendation. **Console report.** Show a small table: baseline vs ablated vs delta for the three dimensions, the verdict, and the path (`metrics/eval-ablation.jsonl` — deliberately not relocated under `.claude/`) the record was appended to. ## Cache (fingerprint replay) `scripts/eval_cache.py` SHAs each `fixture::target` over the target's definition + the **transitive closure** of files it reaches (knowledge/, skills/, and any bare `scripts/<n>.py` it names — e.g. `test-review.md`'s pointer to `test_review_mechanics.py`, #2169) + the fixture + expected JSON + grader version. An unchanged SHA with a stored PASS replays at zero token cost; any changed input busts the cache — including an edit to `test_review_mechanics.py` itself, so a Phase 0 detection-logic change correctly busts cached `test-review` pairs instead of silently replaying a result computed under the old script. Default behaviour (cache-on): 1. Before dispatch, run `python3 scripts/eval_cache.py --plan --replay-out replay.json` over the resolved fixture/target pair list. This produces the **hit/miss** split. 2. Dispatch ONLY the misses through Step 3. 3. After grading, run `python3 scripts/eval_cache.py --store --actuals actuals.json` to memoize the new passes. 4. Report `cache: <hits>/<total> replayed at $0` in the summary. `--no-cache` skips steps 1-3 and dispatches everything. Use it only when you suspect the cache is wrong; the cache busts automatically on any input change, so there is normally no operator decision to make. ## Cites: enforcement (drift prevention for the evals themselves) This skill grades reviewers; if a reviewer carries thresholds with no `Cites:` declaration, `/agent-eval` is grading drift it cannot detect. Before dispatching a `--agent <name>` run: 1. Probe `python3 scripts/citation_lint.py --plugin-root plugins/dev-team plugins/dev-team/agents/<name>.md`. 2. If it emits an `advisory — states N normative token(s) ... declares no Cites:` warning, surface that **once** above the run report: ```text ⚠ agent <name> states N numeric threshold(s) on RFC-2119 lines but has no Cites: declaration. Eval results will not catch drift in those thresholds. Add a Cites: list naming the canonical sources. ``` 3. Continue with dispatch — the warning is advisory, never blocking (matches the Phase-1 lint contract). This makes the eval skill itself a regression guard against threshold drift, not just a grader for it. ## Dispatch mode The agent and skill definitions under eval are **plain files on disk**. An eval is only honest if it grades what is *currently on disk*, not a copy that was loaded into this session before you started editing. - **Default — fresh subprocess (disk is authoritative).** Each fixture/agent pair is dispatched via a fresh `claude -p` subprocess (Step 3). The subprocess loads the agent/skill definitions from disk on every run, so a definition you edited a moment ago is reflected immediately. This is the correct mode after any edit and the default for that reason. - **`--in-session` — fast path (no fresh load).** Dispatches via the in-session `/review-agent` and skill invocations. This reuses whatever was already loaded, so it is cheaper and quicker, but it can evaluate a **stale** definition if the file changed mid-session. Use it only for repeated grading when you have not touched the agent/skill/knowledge files. **No silent fallback.** Default mode requires the `claude` CLI on `PATH`. If `command -v claude` finds nothing, **stop with a clear error** — do not quietly run in-session, because that would grade a stale definition without the user knowing: ```text error: /agent-eval default (fresh-subprocess) mode needs the `claude` CLI on PATH, which was not found. Install it, or re-run with --in-session to dispatch in this session (warning: --in-session can grade a stale, already-loaded definition if you have edited agent/skill files this session). ``` ## Steps ### 1. Resolve eval corpus Verify `.claude/evals/fixtures/` exists. If not, error: "Cannot find eval fixtures. Expected at `.claude/evals/fixtures/`." ### 2. Load fixtures and expected results Read all files from `.claude/evals/fixtures/` and corresponding JSON from `.claude/evals/expected/`. For each fixture: - Match the fixture stem (filename without extension) to its expected JSON - For directory fixtures (cs-*), the directory name is the stem - Parse `applicableAgents` (review-agent fixtures) and/or `applicableSkills` (advisory-skill fixtures, e.g. the `tlg-*` test-layer-gates corpus) to know what to dispatch. A fixture is an **agent fixture**, a **skill fixture**, or both, depending on which keys its expected JSON declares. If `--agent` is specified, filter to fixtures where that agent is in `applicableAgents`. If `--skill` is specified, filter to fixtures where that skill is in `applicableSkills`. If `--fixture` is specified, filter to that fixture only. ### 3. Run agents against fixtures If `--ablation <agent>` is set, skip the rest of this section and follow *Ablation mode* above in full (opt-in gate check, argument validation, cost estimate + confirmation, two-arm × 3-trial dispatch, delta computation and persistence, console report). Do not fall through to plain `--integration` handling below. If `--integration` is set, skip the rest of this section and dispatch through `python3 scripts/run_integration_eval.py` for every fixture whose expected JSON declares an `integration` block. The runner builds the ephemeral worktree from the fixture's `goldenRepo` tarball, dispatches the orchestrator against the spec, runs the `testCommands`, records exit codes, and tears the worktree down unconditionally. Pass the actuals it writes directly to Step 4 — the `integration` grader will pick them up from the expected JSON's `integration` block. Skip the cache pre-flight in this branch for now (cache wiring for the integration tier is tracked separately to keep the rollout small). For unit-tier runs, first resolve the dispatch mode (see *Dispatch mode* above) and consult the cache (see *Cache* above): - **Default (fresh subprocess).** Run `command -v claude`. If it is missing, STOP with the error in *Dispatch mode* — do not fall back to in-session. Otherwise dispatch each pair through a fresh subprocess so the definition is re-read from disk every run. - **`--in-session`.** Skip the `claude` check and use the in-session invocations described under each pair below. For each fixture/agent pair (agent fixtures): 1. **Test-review Phase 0 pre-phase (#2169 follow-up).** When `<agent-name>` is `test-review`, first compute the mechanical pre-phase result for the fixture file — the same invocation `/code-review` step 2b uses:
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub