float or an EvaluationResult) as the task’s second yield.
What grading scores
Grading decides what the reward measures. Two framings cover most tasks:- Grade the answer - compute a float from what the agent said.
- Grade the world - score the state the agent left behind: tests passing, a file written, a service responding. Because the agent acts on a real system through its capabilities, this is outcome verification: the rigor of a test suite with no fixed protocol the agent has to follow.
Approaches
Three approaches cover grading, in increasing power. Each produces thefloat or
EvaluationResult yielded as the task’s second yield.
Comparison helpers
Each returns afloat (0.0-1.0) you can yield directly or wrap in a SubScore.
BashGrader
Runs a shell command via /bin/bash -lc and scores by exit code (1.0 if it exits 0). Async; returns a SubScore. Needs bash - macOS, Linux, WSL, or a built image; on native Windows it scores 0.0 with a /bin/bash not found error.
cwd is the host directory to run in - for a workspace-backed task, pass the workspace root so the grader sees the same files the agent edited.
LLMJudgeGrader
Scores an answer against weighted criteria with an LLM judge (uses the HUD gateway). Each criterion is graded MET/UNMET in parallel and combined by weight; no extra install needed.
criteria items are strings, or (requirement, weight) tuples. A negative weight marks an error to
avoid: the criterion scores as a penalty, MET when the answer actually makes the mistake.
combine - compose multiple graders
combine resolves SubScores and grader coroutines in parallel and combines them into a weighted EvaluationResult. Positive weights are normalized to sum to 1.0; negative weights are penalties.
The subscores appear in the trace, so a partial reward is legible.
combine_any/combine_all collapse alternatives into a single component you can feed to combine - e.g. “tests pass via pytest OR via make test” as one 0/1 subscore.
Custom graders
SubclassGrader and implement async compute_score (return a float, or (float, metadata)):
SubScore and EvaluationResult
A SubScore is one component of a grade: name, value (0-1), weight (default 1.0; negative = penalty), optional metadata.
An EvaluationResult is the combined grade payload you can yield from a task:
EvaluationResult.from_float(value) wraps a bare reward.
Graders run as the second yield of a task; for choosing a reward that separates
good work from bad, see designing tasks.