The eval.yaml schema¶
A single eval.yaml in your project root drives everything. It is parsed into an
EvalConfig and validated at load time. Every top-level key is optional and has a
sensible default — a minimal config is just a name, what to execute, a dataset, and
one judge.
Describe what, not where
eval.yaml describes what to evaluate. The execution backend (Local,
Harbor, EvalHub) is always a CLI flag (--runner), never a config key — so the
same file runs unchanged everywhere.
skill: — use execution.skillTop-level keys¶
| Key | Purpose | Reference |
|---|---|---|
name |
Experiment / run name (defaults to the file stem) | (inline) |
description |
Human-readable description | (inline) |
execution |
What to run and how cases are processed | execution |
runner |
Agent runtime + runtime-specific knobs | runner |
models |
Model per role: skill, subagent, judge, hook | models |
permissions |
Tool allow/deny for headless runs | permissions |
mlflow |
Experiment tracking (opt-in) | mlflow |
dataset |
Where cases live and what they contain | dataset |
generation |
How /eval-dataset sources cases |
generation |
inputs |
Tool interception handlers (inputs.tools) |
inputs.tools |
outputs |
Artifacts / tool calls to collect | outputs |
traces |
Which execution data to capture | traces |
hooks |
Lifecycle shell hooks | hooks |
judges |
How each case is scored | judges |
thresholds |
Regression gates per judge | thresholds |
reward |
Collapse judges into an RL reward scalar | reward |
skill |
Deprecated — use execution.skill |
(see below) |
skill: at the top level is deprecated
A top-level skill: still works but is auto-normalized into execution.skill
with a deprecation warning. Always author new configs with execution.skill.
Two minimal configs¶
Which keys you set depends on whether you're testing a skill or a capability. See the execution model for the difference.
A fully annotated config¶
The repository's root eval.yaml
is the canonical, heavily-commented reference — every block with inline comments and
commented-out variants for all four judge types, tool interception, batch_pattern,
and thresholds. It's the best single file to copy from.
name: my-skill-eval
description: Evaluate the main skill pipeline
execution:
mode: case # per-case (default) or batch
skill: my-skill-name # skill to test (use `prompt:` for prompt mode)
arguments: "{prompt}" # resolved per case from input.yaml fields
runner:
type: claude-code # claude-code | cli | responses-api
# effort: high # low | medium | high | xhigh | max
models:
skill: claude-opus-4-6 # required (or pass --model)
judge: claude-opus-4-6 # used by LLM and pairwise judges
permissions:
deny:
- "mcp__*" # block all MCP tools during eval
mlflow:
experiment: my-skill-eval # opt-in: omit the block to disable tracking
dataset:
path: eval/dataset/cases
schema: |
Each case has input.yaml (a 'prompt' field) and reference.md (gold output).
outputs:
- path: artifacts
schema: "One markdown file per case, named NNN-slug.md."
traces:
stdout: true
stderr: true
events: false
metrics: true
judges:
- name: has_content
check: |
content = outputs["main_content"]
if len(content.strip()) < 100:
return False, f"Output too short ({len(content.strip())} chars)"
return True, f"Output has {len(content.strip())} chars"
- name: output_quality
prompt: "Score 1-5 vs the reference for completeness, clarity, accuracy."
thresholds:
has_content: { min_pass_rate: 1.0 }
output_quality: { min_mean: 3.5 }
Conventions¶
- Schema fields are natural language.
dataset.schemaandoutputs[].schemaare documentation for the LLM agents and judges — scripts operate on file paths, not a parsed spec. There are no hardcoded field names. - Load-time validation is strict. Mutually-exclusive keys (
skill+prompt), invalid enums (execution.mode), and malformed reward formulas fail at load, not mid-run.
Per-key reference¶
- execution — mode, skill/prompt, arguments, timeout, budget, parallelism, env
- runner — type, effort, settings, plugin_dirs, env, system_prompt, command, workspace_mode
- models — skill, subagent, judge, hook roles and precedence
- permissions — allow/deny patterns and the path-based compiler
- mlflow — experiment, tracking_uri, tags
- dataset — path, schema, workspace.files
- generation — strategy, context, seeds
- inputs.tools — tool interception handlers
- outputs — path vs tool, schema, batch_pattern, types
- traces — stdout, stderr, events, metrics
- hooks — before/after all/each, before_scoring
- judges — the four judge types and all fields
- thresholds — min_mean, min_pass_rate, min_win_rate
- reward — single-judge and formula reward modes