Cost and budgets
EvalCore reports token usage and cost per case and across the run, and can stop a run before it overspends. There is no shipped pricing table. You declare your provider’s rates in config, where code review can see them, and a stale table can’t produce confidently-wrong dollars.
Declaring rates
Section titled “Declaring rates”Add a cost: block to an openai-compatible or trace target, in USD per 1
million tokens:
targets: openai: type: openai-compatible url: https://api.openai.com/v1 model: gpt-4.1-mini api_key_env: OPENAI_API_KEY cost: input_per_1m: 0.40 # your provider's price per 1M input tokens output_per_1m: 1.60 # per 1M output tokensWithout a cost: block, EvalCore still reports token counts when the provider
returns usage, but no $ figure. It will not invent a price.
The formula
Section titled “The formula”Cost per case is computed from the token counts the provider reported:
cost = (input_tokens × input_per_1m + output_tokens × output_per_1m) / 1_000_000Totals are the sum across cases. The terminal summary appends tokens and cost when they’re available:
12 passed, 0 failed, 12 total · 48210 tokens · $0.0341A shell or http target reports neither (no standard usage shape), so those
runs simply have no token/cost line.
Per-case and total cost
Section titled “Per-case and total cost”Cost is tracked at both granularities:
- Per case: each case’s cost rides along in the JSON report (
cost_usd) and appears in the--htmlreport’s per-case row. - Totals: the tokens and
$on the summary line, and in the HTML header.
Because reporters are pure functions of recorded usage, these numbers are deterministic: the same run renders the same dollars every time.
Budgets: run.budget_usd
Section titled “Budgets: run.budget_usd”Cap what a run may spend with run.budget_usd. Once accumulated cost reaches the
cap, EvalCore stops dispatching new cases, but the run completes and exits
cleanly rather than aborting mid-flight:
run: budget_usd: 5.0 # stop dispatching new cases past $5 of spendSemantics to internalize:
- The run completes. Cases already in flight finish; new ones are not started once the budget is exhausted.
- Skipped cases are failures with a reason, following the “failures are data”
rule. They count as failed cases, so the run exits
1, and you can see exactly which cases were skipped and why in the report. - A budget requires rates.
budget_usdneeds a priced call to accumulate against: the target’scost:rates, ajudgescorer’scost:rates, or both. Cost is measured from token usage, so without any rates there’s nothing to accumulate. - Validation rejects a non-positive
budget_usd.
Cost in replay mode: recorded usage, $0 actual
Section titled “Cost in replay mode: recorded usage, $0 actual”A replayed run reports the recorded token usage and cost from the cassette, so
cost stays visible in CI even though the actual spend is $0 (nothing was
called). This is deliberate: your CI report shows what the suite would cost at
your declared rates, while replay itself is free.
evalcore run evals.yaml --cache replay # $ line reflects recorded usage; real spend is $0The same holds for budget_usd under replay: the recorded (virtual) cost
accumulates and can trip the budget, so a budget gate behaves consistently
whether you record or replay.
Trace-run costs from span tokens
Section titled “Trace-run costs from span tokens”Agent-trace runs have no live call to meter, so their cost comes from the token
usage found in the trace spans. Declare cost: on the trace target and
EvalCore prices the summed span usage:
targets: support-agent: type: trace cost: input_per_1m: 0.40 output_per_1m: 1.60The shipped agent-trace example shows this. One case’s OTel trace carries
220 input + 48 output tokens, so the run reports:
2 passed, 0 failed, 2 total · 268 tokens · $0.0002See Agents and traces for how usage is extracted from spans.
Judge calls are counted too
Section titled “Judge calls are counted too”LLM-judge tokens count toward the run’s token total, and, when the judge
scorer declares its own cost: block, its dollars fold into the case cost, the
run total, and run.budget_usd, exactly like target spend:
scorers: - type: judge url: https://api.openai.com/v1 model: gpt-4.1-mini api_key_env: OPENAI_API_KEY rubric: "Is the answer grounded in the provided context?" cost: input_per_1m: 0.15 output_per_1m: 0.60Without a judge cost: block, judge tokens still show up in the token total but
carry no dollar figure. Only the judge scorer is metered today; the
similarity scorer’s embedding calls are not yet costed. See
LLM-as-judge.
For field-level details, see the configuration reference.
See also
Section titled “See also”- Comparing models: per-target cost across
a matrix, and how
budget_usdbounds each arm. - Trials and statistics: how cost and
token totals sum across every trial under
run.trials. - LLM-as-judge: how judge calls are counted in the run’s cost when the judge declares rates.
- Configuration reference: the
cost:input and output rate fields.