Block the 201st Email Before It Sends
Consider an illustrative support-agent scenario: a template regression turns welcome messages into payment reminders, and the host sends 200 emails. The modeled token cost is about $1.40; customer and business impact are potentially much larger but not quantified by source data.
No spending limit would have caught this. The LLM calls were cheap. The damage was in what the agent did, not what it spent.
Why budget limits aren't enough
Budget governance answers: "Can this agent afford to run?" Action authority answers: "Should this agent be allowed to do this?"
A support agent with a $5 budget can send 200 emails for $1.40 and stay well within its spending limit. The problem isn't cost — it's consequence. Some actions have blast radius far beyond their token cost:
- Sending emails to customers
- Deploying code to production
- Writing to a database
- Calling a rate-limited external API
- Triggering a webhook that fires a real-world action
These need their own limits, independent of dollar spend.
How Cycles fixes it
Cycles supports RISK_POINTS — budgets denominated in consequence, not dollars. Assign a risk cost to each tool based on its blast radius:
from runcycles_openai_agents import CyclesRunHooks, ToolEstimateMap
hooks = CyclesRunHooks(
tenant="acme",
tool_estimates=ToolEstimateMap(
mapping={
"send_email": 50, # high consequence: 50 RISK_POINTS
"deploy_to_prod": 100, # critical: 100 RISK_POINTS
"search_knowledge": 0, # safe — no reservation needed
"read_docs": 0, # safe
},
default_estimate=1,
),
)In the constructed scenario, the host sends 200 emails unchecked. With risk points, you decide how much cumulative exposure is too much. If the host requires a successful reservation for every email, a budget of 200 risk points with 50 points per email permits 4 reservations; the fifth is rejected. A budget of 10,000 points permits 200 and rejects the reservation for email #201.
The point isn't the specific number. It is that every protected action the host classifies and routes through the boundary is budgeted before execution — not merely logged after the damage is done. Cycles does not infer risk or replace the host's tool and argument authorization.
What happens now
- Low-exposure actions can reserve zero. Reading, searching, and reasoning can use a zero risk estimate while remaining subject to the application's authorization policy.
- Higher-exposure actions consume a separate budget. Each instrumented email, deployment, or write operation reserves the amount assigned by the host.
- The agent can degrade instead of crashing. When the risk budget is exhausted, the host can queue remaining emails for human review instead of stopping the entire workflow.
- Scopes support isolation in multi-agent systems. Give agents distinct budget scopes, and separately give the researcher no email credential or tool permission. Cycles bounds submitted usage within those scopes; the orchestrator prevents one agent from invoking another's capabilities.
Cost and consequence together
The most powerful setup uses both dimensions on the same agent:
# LLM calls check the dollar budget
@cycles(estimate=2_000_000, unit="USD_MICROCENTS",
action_kind="llm.completion", action_name="gpt-4o")
def call_llm(prompt: str) -> str:
...
# Tool calls check the risk budget
@cycles(estimate=50, unit="RISK_POINTS",
action_kind="tool.email", action_name="send_customer_email")
def send_email(to: str, body: str) -> str:
...Each action checks its own unit's budget. The LLM call draws from the dollar budget. The email draws from the risk budget. Both enforced through the same protocol, with the same concurrency safety and scope hierarchy.
Now run the numbers for your agent
The blast-radius calculator below is pre-seeded with an illustrative support-bot scenario where the LLM cost is negligible but the modeled action damage is six figures. Rename the agent, edit the action rows, and set the containment slider to an assumption supported by your actual application authorization and budget boundary. Click Share to send the configured view; PNG to attach to a deck or follow-up email.
| Action | Rev. | Vis. | $/action | Users | $/user | Calls/day | Err % | Sev. | Blast / incident | Runaway blast | Blast / mo | w/ Cycles | Δ / mo | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ×11 | $2.8K | $275K | $82.5K | $82.5K | $0.00 | |||||||||
| ×11 | $550 | $55.0K | $49.5K | $49.5K | $0.00 | |||||||||
| ! | ×14 | $700K | $70M | $210K | $210K | $0.00 | ||||||||
| ×1 | $0.00 | $0.00 | $0.00 | $0.00 | $0.00 | |||||||||
| Totals — worst incident · worst runaway · monthly | $700K | $70M | $342K | $342K | $0.00 | |||||||||
Blast radius is the magnitude of damage that could occur if the action fires when it should not — a measure of risk exposure, not a prediction. Blast / incident is that exposure: the damage of a single wrong fire (discrete, worst-case). Runaway blast is that incident times the runaway ceiling — one action looping N times before it is stopped (the runaway / tool-loop failure mode). Blast / mo is the expected monthly loss at the given error rate — and because the catastrophic classes usually fire rarely, the monthly figure under-states them, which is exactly why the per-incident and runaway radii sit next to it. Severity is an additive weight — reversibility (1 / 3 / 10) plus visibility (0 / 1 / 4) — that multiplies the direct impact ($/action + users × $/user). Examples: irreversible + customer-facing = ×11; irreversible + public = ×14 (the catastrophic class — flagged with !). Weights are illustrative defaults, not measured industry data — replace with figures from your own incident history. Containment is the share of incidents Cycles' runtime action authority would prevent before they fire; effectiveness depends on policy. For the full model, see the Risk & Blast Radius Reference.
Go deeper
- AI Agent Risk & Blast Radius Reference — the full topic guide: risk scoring, blast-radius containment, degradation paths, delegation/attenuation, identity, audit, and compliance
- Action Authority: Controlling What Agents Do — the conceptual foundation
- Understanding Units — USD_MICROCENTS, TOKENS, CREDITS, RISK_POINTS
- OpenAI Agents SDK Integration — ToolEstimateMap and per-tool governance
- How Cycles Meters Caller-Assigned Action Exposure — metering patterns composed with host action authorization
- 5 Failures Only Action Controls Would Prevent — incidents where spend was negligible