Overview
The workflow-levelbudget: block sets cumulative ceilings on a run. The executor checks the running totals after every node and enforces the limits you declare. At least one of max_tokens, max_cost_usd, or max_duration_s must be set — an empty budget: block is rejected at validation time.
max_tokens_per_call ceiling: max_tokens_per_call bounds a single response, while budget: bounds the whole run.
Fields
on_exceeded actions
BudgetExceededError is exported from the top-level package and carries the violation reason, tokens used, and the USD estimate at the point of the violation:
Cost estimation
USD estimates come from a bundled LiteLLM pricing snapshot, refreshed from a local cache when available. Models without a pricing entry (Ollama and other local backends) reportestimated_usd: null, and a max_cost_usd ceiling is effectively unenforced for those models — use max_tokens or max_duration_s instead when running locally.
Budget status in the trace
When abudget: block is configured, the trace summary includes a budget object:
Reading budget state in when: expressions
Budget state is also exposed to edge conditions as _budget, so you can route around expensive work as the run approaches its ceiling:
_budget exposes total_tokens (int) and estimated_usd (float or None). See YAML Reference → when expressions.
When to use a budget
Use a budget when:- Running untrusted or open-ended input where token usage is hard to predict.
- Enforcing a hard cost ceiling per run in production.
- Bounding wall-clock time for latency-sensitive integrations.
- Per-node
max_tokens_per_callto bound individual responses. - The
cost_capguardrail for agent-level enforcement.
Cookbook recipe
- Budget Guarded — a workflow that aborts when its USD ceiling is reached.