Skip to main content
EvaluationLoop implements the “Ralph Loop” pattern: run an agent, judge the output, provide feedback, and repeat until the quality threshold is met.

How It Works

Quick Start

Modes

Optimize Mode

Stops as soon as the threshold is met. Best for production use.

Review Mode

Runs all iterations regardless of score. Best for analysis.

Configuration

Agent
required
The Agent instance to evaluate
string
required
Evaluation criteria for the Judge (e.g., “Response is thorough and accurate”)
float
default:"8.0"
Score threshold for success (1-10 scale)
int
default:"5"
Maximum number of iterations before stopping
string
default:"optimize"
"optimize" (stop on success) or "review" (run all iterations)
Callable
Optional callback called after each iteration with IterationResult
bool
default:"false"
Enable verbose logging
Callable[[str], float]
Numeric metric on (output). When set, the loop scores with this callable instead of the LLM Judge. Non-finite results (NaN / inf) are floored to 0.0.

Keep the Best Iteration

The result exposes the highest-scoring iteration, not just the last one.
success is now best.score >= threshold, not iterations[-1].score >= threshold. A run that improves and then regresses reports the improvement instead of the regression.
IterationResult
The highest-scoring iteration
IterationResult
The highest-scoring iteration (falls back to max() over iterations if best is unset)
float
Score of the best iteration
string
Output of the best iteration

Score with a Numeric Metric

Pass a metric to score iterations with an empirical function instead of the LLM Judge.
The Judge remains the default — the metric only takes over when set. This works with any empirical score (rouge_l, accuracy, latency, or a custom function).
Non-finite metric results (NaN / inf) are floored to 0.0 so they never win selection.

Results

EvaluationLoopResult

bool
Whether the loop achieved the threshold
float
Score from the last iteration (1-10)
list[float]
All scores across iterations
string
Output from the last iteration
list[string]
All findings/suggestions collected
int
Number of iterations completed
float
Total time taken

IterationResult

Each iteration produces an IterationResult:

Async Support

Best Practices

Be specific in your criteria to get consistent results:
  • 8.0 (default): Good for most use cases
  • 9.0+: High quality, may require more iterations
  • 7.0: Acceptable quality, faster completion
Each iteration makes LLM calls. Set max_iterations based on your budget:
Track progress in real-time:

Judge

LLM-as-judge for evaluating outputs

Evaluator-Optimizer

Multi-agent evaluator-optimizer pattern

Goal Loop

Gate a tool-using loop on an independent acceptance-criteria judge

Prompt Optimizer

Optimise an agent’s instructions against an eval set
EvaluationLoop uses lazy loading - the Judge is only imported when you actually run an evaluation, ensuring zero performance impact when not in use.