Skip to main content

Evaluation suite schema

An evaluation suite is a TOML file you write by hand. It names a set of tasks; each task carries a prompt, a run count, an optional target agent, and a list of typed assertions that decide pass or fail. apollia-os eval run parses it, executes it, and exits non-zero if any assertion fails on any run.

For the operator walkthrough, with the interface steps and how to read a report, see Measure an agent with eval.

The tables below are generated from the Rust types that parse the file, so they cannot drift from what the parser accepts. A field absent from them is a field the parser rejects.

The suite​

KeyTypeRequiredMeaning
nameStringrequiredHuman-readable suite name, surfaced in reports.
tasksVec<EvalTask>optionalTasks to evaluate. Defaults to empty when the tasks array is absent.

A task​

KeyTypeRequiredMeaning
idStringrequiredStable identifier for the task, used as the report row key.
promptStringrequiredThe instruction submitted to the agent.
runsu32optionalNumber of times the task is executed. Defaults to 3.
agentOption<String>optionalTarget agent identifier. None defers the choice to the caller.
assertionsVec<Assertion>optionalTyped pass/fail assertions evaluated on each run.

Assertions​

Each entry under [[tasks.assertions]] carries a type key that selects the shape. The fields listed are the ones that shape accepts, and no others.

typeIts fieldsWhat it checks
exit_codeequalsPasses when the run exit code equals equals.
file_existspathPasses when a file exists at path after the run.
regexon, patternPasses when pattern matches the selected output channel.
llm_judgerubricPasses when an LLM judge rates the output against rubric as a pass.

on, the channel a regex assertion matches against​

ValueMeaning
stdoutThe streamed stdout of the run.
resultThe final result text of the run.

A complete example​

name = "my-validation-suite"

[[tasks]]
id = "summarize-text"
prompt = "Summarize this text in three sentences: [...]"
runs = 3

[[tasks.assertions]]
type = "exit_code"
equals = 0

[[tasks.assertions]]
type = "file_exists"
path = "output/summary.txt"

[[tasks.assertions]]
type = "regex"
pattern = "\\b(summary|synthesis)\\b"
on = "stdout"

[[tasks.assertions]]
type = "llm_judge"
rubric = "The answer must be a coherent three-sentence summary of the source text."

What the parser refuses​

Getting a field name wrong fails the load rather than silently skipping the check, which is the behaviour you want from a test harness. If apollia-os eval run reports an invalid suite, compare your assertion keys against the tables above before looking anywhere else.

llm_judge takes a rubric and nothing else. There is no expected value to supply: the rubric is the whole criterion, and the judge answers against it.

apollia-os eval run builds its runner without a judge, so every llm_judge assertion fails today, with the reason "llm judge not evaluated: this runner has no judge router". That is deliberate on the harness side, an assertion nothing checked is never counted as passing, and it is not a backend problem: configuring one changes nothing here. Until the command wires a judge, write your suites on exit_code, file_exists and regex.