A support agent that costs more than the ticket it deflected
Support automation is justified on cost per contact: the agent has to be cheaper than the human it stands in for. That case is usually made once, on an estimate, and then never checked against what the agent actually spends — which moves every time a prompt, a model or a retry policy changes.
What a provider dashboard leaves you with
01
Cost per resolved conversation is not a number the provider can produce, so the business case is never re-tested.
02
A retry loop on a failing tool call turns one conversation into fifty requests, and nothing stops it.
03
Triage, drafting and escalation agents share a credential, so a cap on it stops the whole desk rather than the one misbehaving.
What Capsera does about it
- Cost per run, not per call
- A conversation is a run. Attribution at the run level is what makes cost per resolved contact a number you can actually read.
- Per-agent envelopes
- Triage, drafting and escalation each get their own budget, so one agent hitting its ceiling does not take the others down with it.
- Anomaly detection
- A loop that multiplies requests is flagged the same day it starts rather than the following month.
The number this is judged on
Cost per resolved conversation
None of this is assumed. We scanned 133 public agent repositories and found a cost defect in most of the ones making live model calls.
Read the method and limitationsimport capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")
on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()
assert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",
for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):
)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:
model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropic
def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)
for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02
from anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)# checked before the callcapsera.budget(monthly=500,on_exceed="block",)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(
)with capsera.agent("summarizer"):client = Anthropic()resp = client.messages.create(model="claude-sonnet-4-6",max_tokens=1024,)# no proxy, no gatewayassert resp.usage.cost < 0.02if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:
if capsera.over_budget():raise BudgetExceeded()@capsera.track()def extract(doc):return chain(doc)# cheaper route, same outputcapsera.route(prefer="cost")spend = capsera.usage(group_by="agent",window="30d",)for a, cost in spend:print(a, f"${cost:.2f}")# fails open, alwayscapsera.flush()for task in queue:run(task)log("run complete")import capserafrom anthropic import Anthropiccapsera.init(agent="reasoning_agent",run_id=ctx.run_id,)
Know what a resolved conversation costs.
Stop runaway agents before they become runaway invoices.