Agent Max Budget
Set a USD cap on agent spend via ExecutionConfig
Cap how much an agent can spend per run with ExecutionConfig(max_budget=...) — when the limit is hit, PraisonAI stops the run and raises BudgetExceededError.
from praisonaiagents import Agent, ExecutionConfig
agent = Agent(
name="Researcher",
instructions="You research topics thoroughly",
execution=ExecutionConfig(max_budget=0.50),
)
agent.start("Summarise today's AI news")The user sets a spend cap; the agent stops the run and raises BudgetExceededError once estimated cost exceeds the limit.
Three ways to set it
Python, YAML, and the CLI all set the same ExecutionConfig.max_budget.
Python
from praisonaiagents import Agent, ExecutionConfig
agent = Agent(
name="Researcher",
instructions="You research topics thoroughly",
execution=ExecutionConfig(max_budget=0.50),
)
agent.start("Summarise today's AI news")YAML
process: workflow
roles:
researcher:
role: Researcher
goal: Research topics thoroughly
backstory: You research topics thoroughly
execution:
max_budget: 0.50
on_budget_exceeded: stop
tasks:
t1:
description: Summarise today's AI news
expected_output: One paragraphCLI
praisonai loop "Summarise today's AI news" --max-budget 0.50The cap covers the whole loop, not each iteration. Add --on-budget-exceeded warn to log and continue instead of stopping. See CLI Budget Handling.
Quick Start
- Set a simple USD cap
python from praisonaiagents import Agent, ExecutionConfig agent = Agent( name="Researcher", instructions="You research topics thoroughly", execution=ExecutionConfig(max_budget=0.50), ) agent.start("Research the history of AI")When spend reaches $0.50, the run stops with
BudgetExceededErrorincluding agent name and totals. - Async run with budget cap
python import asyncio from praisonaiagents import Agent, ExecutionConfig agent = Agent( name="AsyncResearcher", instructions="Research topics asynchronously", execution=ExecutionConfig(max_budget=0.50), ) async def main(): try: await agent.astart("Research the history of AI") except Exception as e: if "BudgetExceeded" in type(e).__name__: print(f"Budget exceeded: {e}") asyncio.run(main())astart()raisesBudgetExceededErrorthe same waystart()does — the async path now has identical pre-call guards and post-call cost accounting. - Warn instead of stopping
python from praisonaiagents import Agent, ExecutionConfig agent = Agent( name="Analyst", instructions="Analyse data carefully", execution=ExecutionConfig( max_budget=1.00, on_budget_exceeded="warn", ), ) agent.start("Summarise this quarterly report")With
on_budget_exceeded="warn", the agent logs a warning but continues. Default is"stop".
How It Works
Every way of building the agent’s LLM is covered:
| How the agent’s LLM is set | max_budget enforced | total_cost / cost_summary populated |
|---|---|---|
llm="gpt-4o" and other OpenAI-style names | ✅ | ✅ |
llm="anthropic/...", mistral/..., ollama/..., openrouter/... | ✅ | ✅ |
llm={"model": "...", "base_url": "..."} | ✅ | ✅ |
llm=LLM(...) model object | ✅ | ✅ |
A turn answered by a fallback_models entry | ✅ priced as the model that answered | ✅ |
The cap is checked after each LLM call, including calls inside a tool loop:
from praisonaiagents import Agent, ExecutionConfig
def fetch_price(ticker: str) -> str:
"""Fetch the latest price for a ticker."""
return f"{ticker}: 123.45"
agent = Agent(
name="Analyst",
instructions="Look up prices for the symbols the user names.",
llm="anthropic/claude-3-5-sonnet-20240620",
tools=[fetch_price],
execution=ExecutionConfig(max_budget=0.10),
)
try:
agent.start("Price AAPL, MSFT, and GOOG.")
except Exception as e:
print(type(e).__name__, e) # BudgetExceededError Agent 'Analyst' exceeded budget: ...Budget tracking adds zero overhead when max_budget is None (the default).
Schedulers use the same brake — see Async Scheduler → Budget-aware Scheduling. Setting max_cost=0 on AsyncAgentScheduler is a real (zero) budget and short-circuits start() (returns False, no background task) when combined with run_immediately=True. As of PraisonAI PR #5766 the sync AgentScheduler matches this behavior on every entry point, including execute_once() (returns None) and start(run_immediately=True).
Configuration Options
| Option | Type | Default | Description | ||
|---|---|---|---|---|---|
max_budget | `float \ | None` | None | Hard USD limit per agent run. None disables tracking. | |
on_budget_exceeded | `”stop” \ | “warn” \ | callable` | "stop" | Action when the cap is reached |
Best Practices
Start with a conservative cap in production
Set max_budget on any agent that runs unattended or loops over tools. $0.25–$1.00 is a sensible starting range for research agents.
Use warn mode during development
on_budget_exceeded="warn" lets you see full output while still logging when you’d have been stopped in production.
Retrying after the cap sends no request
For a provider/model agent with on_budget_exceeded="stop", once it has crossed max_budget, every later chat() / achat() raises BudgetExceededError again before contacting the provider. Catching the error and retrying cannot spend more — create a new agent (or one with a higher cap) to continue.
Combine with rate limiting
Budget caps control spend; rate limiters control request frequency. Use both for cost-sensitive deployments.
See also: Autonomous run budget
ExecutionConfig.max_budget is one of two budget mechanisms. run_autonomous / run_autonomous_async have their own independent cap via AutonomyConfig — pick the one that matches your run type.
| Mechanism | Where | On limit hit | Resumable? |
|---|---|---|---|
ExecutionConfig.max_budget | Any run | Raises BudgetExceededError | No |
AutonomyConfig.max_budget_usd / max_tokens | run_autonomous / run_autonomous_async only | Returns AutonomyResult(completion_reason="budget_exhausted") | Yes when budget_action="pause" |
For autonomous runs, prefer the AutonomyConfig cap — it pauses recoverably instead of raising. See Autonomy Budget.