1. Define evaluators
Evaluators score actual output against each example’s expected output. Put them inevaluators.yaml:
exact-difffor output that should match exactly.llm-judgefor fuzzy correctness using explicit evaluation criteria.custom-scriptfor correctness you can compute in typed TypeScript.
passThreshold is workflow-level: the weighted mean across evaluators must
reach it for the run to pass.
Per-field exact-diff rules
Underconfig.rules, each key is a path into the workflow output. $ targets
the full output; {} selects a path with inherited platform defaults. An
ancestor rule covers its subtree, and more specific descendants override
inherited settings.
order: unorderedon an array path compares items by value, not position. Matches always use distinct item slots;itemsindependently controls whether missing expected or additional actual items are allowed.matchByon an unordered array of objects pairs items by exact identity (skuor[country, sku]) before comparing the paired objects. It requiresorder: unorderedon the same rule and is not inherited by nested arrays. A matching identity with a wrong field reports that field path. Identity type and value must both match: numeric10differs from string'10'; there is no coercion or numeric tolerance. Omit it to keep structural matching, including legitimate duplicate objects. Withitems: at-least, extra actual items may omit or duplicate identities; withat-most, missing expected identities are allowed but every actual item being checked needs a unique valid identity;exactlyvalidates both sides.items: at-leastrequires every expected item and allows additional actual items.items: at-mostallows missing expected items but rejects unexpected actual items.items: exactlypermits neither. The default isat-least.orderis independent. Ordered arrays use positional prefix matching:at-leastrequires expected to match actual from index 0 (only trailing actual extras allowed);at-mostrequires actual to match expected from index 0 (only trailing expected extras allowed);exactlyis equal-length positional comparison.unorderedignores positions. Setorder,items, andmatchByon the array path (lineItems), not the item path (lineItems[]).allowExtraFields: falseon an object path (oftensomeArray[]) rejects extra object keys in actual output.numericTolerancesets an absolute tolerance for numeric fields at that path. When omitted, comparison keeps the historical relative epsilon.ignore: trueremoves that path and its descendants from both expected and actual output. Use it under a selected parent to discard volatile evidence, citations, timestamps, or other fields captured in golden output. It cannot be combined with other settings on the same rule. If every rule is ignored, exact-diff compares the full output minus those paths.
lineItems for the array, lineItems[] for each element, and
lineItems[].unitPrice for a field inside every element. Extract steps may add
_grounding metadata; exact-diff strips it automatically before comparison.
Configs authored before per-field rules continue to run unchanged. Do not mix
legacy top-level options with rules in the same evaluator.
Validate and push:
2. Run an experiment
An experiment runs the workflow across the whole dataset and collects every score in one batch:--wait blocks until the experiment finishes and exits non-zero if any example
failed, so it works in CI. Some CLI help still calls the experiment id a
batchId; it is the same identifier.
3. Compare versions
Change the workflow, push a new version, run a second experiment, then diff the two experiments:Tips
llm-judgescores have variance. Average across runs or raisepassThresholddeliberately rather than chasing single-run noise.- Keep expected outputs in the dataset so
exact-diffandllm-judgehave ground truth to compare against.