Problem
When writing EVAL.yaml with many cases, common evaluators (latency, safety, format) must be repeated on every case.
Proposal
Add a defaults block that applies to all cases unless overridden:
name: customer-support-eval
version: "1.0"
defaults:
evaluators:
- name: latency_check
type: latency
max_ms: 5000
- name: safety
type: llm_judge
prompt: evaluators/no-ai-disclosure.md
cases:
- id: refund-request
input: "I want a refund"
evaluators:
- name: helpful
type: llm_judge
prompt: evaluators/helpful.md
# Also gets the two default evaluators
- id: greeting
input: "Hello"
# Only gets default evaluators
Merge Behavior
- Default evaluators are appended to case-specific evaluators
- To skip defaults for a case:
skip_defaults: true
Why Not $ref or Templates?
YAML already has anchors (&anchor / *anchor) for reuse. Adding $ref or a custom template system introduces new concepts without adding capability. Keep the config surface minimal.
Design Principles Alignment
- ✅ Non-Breaking Extension —
defaults is optional; existing configs unchanged
- ✅ Lightweight Core — minimal parser change, no new concepts
- ✅ AI-First — less repetition = fewer tokens for AI to reason about
Acceptance Criteria
Problem
When writing EVAL.yaml with many cases, common evaluators (latency, safety, format) must be repeated on every case.
Proposal
Add a
defaultsblock that applies to all cases unless overridden:Merge Behavior
skip_defaults: trueWhy Not $ref or Templates?
YAML already has anchors (
&anchor/*anchor) for reuse. Adding$refor a custom template system introduces new concepts without adding capability. Keep the config surface minimal.Design Principles Alignment
defaultsis optional; existing configs unchangedAcceptance Criteria
defaults.evaluatorsparsed and appended to all casesskip_defaults: trueper case to opt out