This guide covers proven patterns for structuring your evaluations.
Pattern 1: Simple Assertion
The most straightforward pattern—use assertions like pytest:
Use when: Most evaluations. This is the default approach.
Pattern 2: Pre-populated Decorator
Configure inputs in the decorator for cleaner code:
Use when: Clean separation of test data from logic.
Pattern 3: Target Hook
Separate agent invocation from scoring:
Use when: Multiple tests with same agent, different assertions.
Pattern 4: Multiple Results
Return multiple results from one function:
Use when: Dynamic test case generation, external data sources.
Pattern 5: Cases with Context
Combine cases with context for clean data-driven tests:
Or with custom input fields:
Use when: Testing many input/output pairs.
Pattern 6: File-Level Defaults
Share configuration across multiple evaluations:
Use when: Many evaluations share configuration.
Pattern 7: Multi-Metric Evaluation
Use store(scores=...) when you need multiple named metrics or numeric scores:
Use when: You need numeric scores or multiple independent metrics.
Pattern 8: Comparison Testing
Compare multiple approaches:
Use when: Benchmarking models, comparing approaches.
Pattern 9: Error Handling
For robustness testing, you may want to catch specific errors:
Use when: Testing reliability, edge cases.
Anti-Pattern: Forgetting to Set Output
Always set ctx.output before assertions so results are recorded for debugging.