This example demonstrates multi-grader gates that combine multiple evaluation metrics with sophisticated pass/fail logic.
- Logical gates with AND/OR operators
- Weighted average gates for combining metrics with different importance
- Different aggregation functions (avg_score, accuracy, min, max, percentiles)
- Custom pass thresholds for accuracy calculations
- Combining rubric grading (LLM judge) with tool grading (deterministic functions)
Multi-grader gates enable sophisticated evaluation criteria that go beyond single metrics. You can:
- Require multiple conditions to pass simultaneously (AND logic)
- Pass if any condition passes (OR logic)
- Combine metrics with weighted importance
- Use different aggregation functions per metric
Start your local Letta server:
letta serverSet your OpenAI API key (required for rubric grader):
export OPENAI_API_KEY=your-keyThen run either suite:
cd examples/multi-grader-gate
letta-evals run suite.logical-and.yaml
letta-evals run suite.weighted-average.yamlexport LETTA_API_KEY=your-api-key
export LETTA_PROJECT_ID=your-project-id
export OPENAI_API_KEY=your-openai-keyUpdate base_url in the suite files:
target:
base_url: https://api.letta.com/Gates on a single metric:
gate:
kind: simple
metric_key: quality
aggregation: avg_score
op: gte
value: 0.6Combines multiple conditions with AND/OR logic. All conditions must pass for AND, at least one must pass for OR.
Example (AND):
gate:
kind: logical
operator: and
conditions:
- metric_key: quality
aggregation: avg_score
op: gte
value: 0.6
- metric_key: ascii_only
aggregation: accuracy
pass_threshold: 1.0
op: gte
value: 60This passes only if:
- Quality (avg_score) >= 0.6: Average quality score across all samples >= 0.6
- ASCII-only (accuracy) >= 60%: At least 60% of samples have perfect ASCII scores (1.0)
Example (OR):
gate:
kind: logical
operator: or
conditions:
- metric_key: exact_match
aggregation: accuracy
op: eq
value: 100
- metric_key: quality
aggregation: avg_score
op: gte
value: 0.9This passes if EITHER exact matches are 100% OR quality is very high (>= 0.9).
Nested logical conditions:
Logical gates can be nested for complex logic like "(A AND B) OR C":
gate:
kind: logical
operator: or
conditions:
- kind: logical
operator: and
conditions:
- metric_key: accuracy
aggregation: avg_score
op: gte
value: 0.8
- metric_key: coherence
aggregation: min
op: gte
value: 0.6
- metric_key: fallback_check
aggregation: accuracy
op: eq
value: 100Combines multiple metrics with configurable weights. The weighted average is compared against a threshold.
gate:
kind: weighted_average
aggregation: avg_score
weights:
quality: 0.7
ascii_only: 0.3
op: gte
value: 0.75This computes: 0.7 * avg(quality) + 0.3 * avg(ascii_only) and passes if the result >= 0.75.
Key points:
- Weights are automatically normalized (don't need to sum to 1.0)
- The same aggregation function is applied to all metrics before weighting
- Useful for expressing relative importance of different quality dimensions
Each condition in a gate can use different aggregation functions:
| Aggregation | Description | Use Case |
|---|---|---|
avg_score |
Average score across all samples | Overall quality metrics |
accuracy |
Percentage of samples passing pass_threshold |
Binary pass/fail checks |
min |
Minimum score across all samples | Worst-case requirements |
max |
Maximum score across all samples | Best-case requirements |
median |
Median score | Robust to outliers |
p50 |
50th percentile (same as median) | Robust to outliers |
p95 |
95th percentile | High-end performance |
p99 |
99th percentile | Tail behavior |
Examples:
# average quality must be high
- metric_key: quality
aggregation: avg_score
op: gte
value: 0.8
# worst-case safety must be acceptable
- metric_key: safety
aggregation: min
op: gte
value: 0.5
# at least 90% of samples must pass
- metric_key: format_check
aggregation: accuracy
pass_threshold: 1.0
op: gte
value: 90
# 95th percentile latency must be acceptable
- metric_key: response_time
aggregation: p95
op: lte
value: 5.0When using aggregation: accuracy, the pass_threshold parameter defines what score counts as "passing" for a sample:
- metric_key: ascii_only
aggregation: accuracy
pass_threshold: 0.8 # sample passes if score >= 0.8
op: gte
value: 90 # at least 90% of samples must passHow it works:
- Each sample gets a score from the grader (e.g., 0.0 to 1.0)
- A sample "passes" if its score >=
pass_threshold(defaults to 1.0) - Accuracy = (passed samples / total samples) * 100
- The gate condition checks if accuracy meets the threshold
Example:
- Scores: [1.0, 0.9, 0.85, 0.7, 0.6]
pass_threshold: 0.8- Passed samples: 3 (1.0, 0.9, 0.85)
- Accuracy: 3/5 = 60%
All gate conditions support these operators:
| Operator | Symbol | Description |
|---|---|---|
gte |
≥ | Greater than or equal |
gt |
> | Greater than |
lte |
≤ | Less than or equal |
lt |
< | Less than |
eq |
= | Equal |
LLM-as-judge using detailed scoring rubric in rubric.txt:
- Instruction compliance (0.30)
- Requested item match (0.30)
- Recognizability (0.20)
- Craftsmanship (0.10)
- Effort (0.10)
Scores sum to 1.0 for normalized evaluation.
Deterministic check using built-in ascii_printable_only function:
- Returns 1.0 if all characters are printable ASCII
- Returns 0.0 if non-ASCII characters are found
Demonstrates logical AND gate requiring:
- High quality (avg_score >= 0.6)
- Valid ASCII in most samples (accuracy >= 60%)
Use case: Strict requirements where multiple independent criteria must all pass.
Demonstrates weighted average gate combining:
- Quality (70% weight)
- ASCII validation (30% weight)
- Overall threshold >= 0.75
Use case: Balancing multiple quality dimensions with different importance levels.
When to use Logical Gates:
- Multiple independent requirements must all pass (AND)
- Any of several alternatives can satisfy the requirement (OR)
- Complex boolean logic (nested conditions)
- Example: "Safety must be perfect AND quality must be good"
When to use Weighted Average:
- Trading off between multiple quality dimensions
- Some metrics are more important than others
- Continuous quality assessment with balanced criteria
- Example: "60% quality + 40% style must average to 0.7"
When to use Simple Gates:
- Single metric is sufficient
- Clear threshold for pass/fail
- Example: "Average quality must be >= 0.6"
gate:
kind: logical
operator: and
conditions:
- metric_key: safety
aggregation: accuracy
op: eq
value: 100 # all samples must pass safety
- metric_key: quality
aggregation: avg_score
op: gte
value: 0.6 # quality can be moderategate:
kind: weighted_average
aggregation: avg_score
weights:
accuracy: 0.4
coherence: 0.3
style: 0.2
format: 0.1
op: gte
value: 0.75gate:
kind: logical
operator: or
conditions:
- metric_key: exact_match
aggregation: accuracy
op: eq
value: 100 # prefer exact matches
- metric_key: semantic_similarity
aggregation: avg_score
op: gte
value: 0.9 # but accept high semantic similaritygate:
kind: logical
operator: and
conditions:
- metric_key: quality
aggregation: avg_score
op: gte
value: 0.8 # average must be high
- metric_key: quality
aggregation: min
op: gte
value: 0.5 # worst case must be acceptable