By Sagar Shankaran, Founder of CallSphere
Implement cost allocation for enterprise AI agents with per-department chargebacks, showback reporting, budget management, and automated alerts. Learn how to track LLM token costs, infrastructure expenses, and generate financial reports.
Key takeaways
When AI agents launch, the monthly LLM bill is modest — perhaps a few hundred dollars. Six months later, it reaches five figures and no one can explain where the money went. Finance asks which department is responsible. Engineering points at usage logs that show API calls but not dollar amounts. The support team claims they barely use the agent, while the data shows they generate 60% of the traffic.
Cost allocation solves this by attributing every dollar of AI spending to the team, project, or cost center that generated it. This is not just accounting — it changes behavior. Teams that see their actual costs make smarter decisions about prompt design, model selection, and caching strategies.
Every agent request generates a cost record that captures the LLM provider charges (based on token counts and model pricing), infrastructure costs (compute, memory, storage), and any third-party tool costs.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
flowchart LR
subgraph IN["Inputs"]
I1["Monthly call volume"]
I2["Average deal value"]
I3["Current answer rate"]
I4["Receptionist cost<br/>per month"]
end
subgraph CALC["CallSphere Captures"]
C1["Missed calls converted<br/>at 24 by 7 coverage"]
C2["Receptionist payroll<br/>displaced or freed"]
end
subgraph OUT["Outputs"]
O1["Recovered revenue<br/>per month"]
O2["Operating cost saved"]
O3((Net ROI<br/>monthly))
end
I1 --> C1
I2 --> C1
I3 --> C1
I4 --> C2
C1 --> O1 --> O3
C2 --> O2 --> O3
style C1 fill:#4f46e5,stroke:#4338ca,color:#fff
style C2 fill:#4f46e5,stroke:#4338ca,color:#fff
style O3 fill:#059669,stroke:#047857,color:#fff
from dataclasses import dataclass, field
from datetime import datetime
from uuid import uuid4
MODEL_PRICING = {
"gpt-4o": {"input_per_1k": 0.0025, "output_per_1k": 0.01},
"gpt-4o-mini": {"input_per_1k": 0.00015, "output_per_1k": 0.0006},
"claude-sonnet-4": {"input_per_1k": 0.003, "output_per_1k": 0.015},
"claude-haiku": {"input_per_1k": 0.00025, "output_per_1k": 0.00125},
}
@dataclass
class CostRecord:
record_id: str = field(default_factory=lambda: str(uuid4()))
request_id: str = ""
timestamp: str = field(
default_factory=lambda: datetime.utcnow().isoformat()
)
user_id: str = ""
department: str = ""
cost_center: str = ""
agent_id: str = ""
model: str = ""
input_tokens: int = 0
output_tokens: int = 0
llm_cost_usd: float = 0.0
infra_cost_usd: float = 0.0
tool_cost_usd: float = 0.0
total_cost_usd: float = 0.0
class CostCalculator:
def __init__(self, pricing: dict = MODEL_PRICING):
self.pricing = pricing
def calculate(
self,
model: str,
input_tokens: int,
output_tokens: int,
tool_calls: int = 0,
) -> dict:
model_price = self.pricing.get(model, self.pricing["gpt-4o"])
llm_cost = (
(input_tokens / 1000) * model_price["input_per_1k"]
+ (output_tokens / 1000) * model_price["output_per_1k"]
)
infra_cost = 0.0001 # base per-request infrastructure cost
tool_cost = tool_calls * 0.001 # per tool execution cost
return {
"llm_cost_usd": round(llm_cost, 6),
"infra_cost_usd": round(infra_cost, 6),
"tool_cost_usd": round(tool_cost, 6),
"total_cost_usd": round(llm_cost + infra_cost + tool_cost, 6),
}
Each request is tagged with the user's department and cost center from the SSO claims. Aggregation queries produce monthly reports per department, per agent, and per cost center.
class CostReporter:
def __init__(self, db_pool):
self.db = db_pool
async def department_summary(
self, year: int, month: int
) -> list[dict]:
rows = await self.db.fetch(
"""
SELECT
department,
cost_center,
COUNT(*) AS total_requests,
SUM(input_tokens) AS total_input_tokens,
SUM(output_tokens) AS total_output_tokens,
ROUND(SUM(llm_cost_usd)::numeric, 2) AS llm_cost,
ROUND(SUM(infra_cost_usd)::numeric, 2) AS infra_cost,
ROUND(SUM(tool_cost_usd)::numeric, 2) AS tool_cost,
ROUND(SUM(total_cost_usd)::numeric, 2) AS total_cost
FROM cost_records
WHERE EXTRACT(YEAR FROM timestamp) = $1
AND EXTRACT(MONTH FROM timestamp) = $2
GROUP BY department, cost_center
ORDER BY total_cost DESC
""",
year, month,
)
return [dict(r) for r in rows]
async def agent_cost_breakdown(
self, agent_id: str, days: int = 30
) -> dict:
rows = await self.db.fetch(
"""
SELECT
date_trunc('day', timestamp) AS day,
model,
COUNT(*) AS requests,
SUM(input_tokens) AS input_tokens,
SUM(output_tokens) AS output_tokens,
ROUND(SUM(total_cost_usd)::numeric, 4) AS daily_cost
FROM cost_records
WHERE agent_id = $1
AND timestamp > NOW() - INTERVAL '%s days'
GROUP BY day, model
ORDER BY day DESC
""" % days,
agent_id,
)
return {"agent_id": agent_id, "period_days": days, "data": [dict(r) for r in rows]}
async def top_cost_users(
self, department: str, month: int, limit: int = 10
) -> list[dict]:
rows = await self.db.fetch(
"""
SELECT
user_id,
COUNT(*) AS requests,
ROUND(SUM(total_cost_usd)::numeric, 2) AS total_cost,
ROUND(AVG(total_cost_usd)::numeric, 4) AS avg_cost_per_request
FROM cost_records
WHERE department = $1
AND EXTRACT(MONTH FROM timestamp) = $2
GROUP BY user_id
ORDER BY total_cost DESC
LIMIT $3
""",
department, month, limit,
)
return [dict(r) for r in rows]
Departments set monthly budgets. The system tracks spending against budgets in real time and sends alerts at configurable thresholds — typically 50%, 80%, and 100%.
class BudgetManager:
def __init__(self, db_pool, notifier):
self.db = db_pool
self.notifier = notifier
async def check_budget(self, department: str, cost_center: str) -> dict:
budget = await self.db.fetchrow(
"SELECT monthly_budget_usd, alert_thresholds "
"FROM department_budgets "
"WHERE department = $1 AND cost_center = $2",
department, cost_center,
)
if not budget:
return {"status": "no_budget_set"}
current_spend = await self.db.fetchval(
"""
SELECT COALESCE(SUM(total_cost_usd), 0)
FROM cost_records
WHERE department = $1 AND cost_center = $2
AND date_trunc('month', timestamp) = date_trunc('month', NOW())
""",
department, cost_center,
)
utilization = (current_spend / budget["monthly_budget_usd"]) * 100
thresholds = budget["alert_thresholds"] # e.g. [50, 80, 100]
for threshold in sorted(thresholds):
if utilization >= threshold:
await self.notifier.send_budget_alert(
department=department,
cost_center=cost_center,
utilization_pct=round(utilization, 1),
threshold=threshold,
current_spend=round(current_spend, 2),
budget=budget["monthly_budget_usd"],
)
return {
"department": department,
"budget_usd": budget["monthly_budget_usd"],
"current_spend_usd": round(current_spend, 2),
"utilization_pct": round(utilization, 1),
}
Chargebacks transfer actual costs to department budgets. Showback reports costs without transferring them. Most organizations start with showback to build awareness, then move to chargebacks once departments understand their usage patterns and have had time to optimize.
Attribute costs to the department of the user making the request. If a shared analytics agent is used by sales, marketing, and finance, each department pays for its own usage. For agents that run background tasks without a user context, allocate costs to the agent owner's department or split proportionally based on historical usage patterns.
Still reading? Stop comparing — try CallSphere live.
CallSphere ships complete AI voice agents per industry — 14 tools for healthcare, 10 agents for real estate, 4 specialists for salons. See how it actually handles a call before you book a demo.
Track at per-request granularity and aggregate upward. Per-request records let you identify expensive individual queries, unusual usage patterns, and optimization opportunities. Daily or monthly aggregates lose this detail. Storage cost for per-request records is minimal compared to the LLM costs you are tracking.
Track cache hits as zero-cost LLM requests but include the infrastructure cost (cache storage, lookup time). This gives departments credit for their caching efficiency and incentivizes prompt designs that maximize cache hit rates. The cost report should show both actual spend and estimated savings from caching.
#EnterpriseAI #CostAllocation #Chargebacks #FinOps #BudgetManagement #CostTracking #AgenticAI #LearnAI #AIEngineering

Written by
Sagar Shankaran· Founder, CallSphere
LinkedInSagar Shankaran is the founder of CallSphere, where he builds production AI voice and chat agents deployed across healthcare, hospitality, real estate, and home services. He writes about agentic AI, LLM engineering, and shipping voice agents that handle real calls in production.
See how AI voice agents work for your industry. Live demo available -- no signup required.
A three-way comparison of Gemini Enterprise, Anthropic managed agents and OpenAI Frontier Platform after Cloud Next 2026 — strengths, gaps, buyer fit.
ServiceNow Project Arc vs Anthropic Managed Agents — runtime, governance, integration, and use cases. The 2026 enterprise autonomous agent comparison.
A2A unlocks cross-vendor agent coordination, but most enterprise voice/chat workloads still ship faster on a single-vendor stack. Here is how to choose.
Working memory, permanent memory, sandboxes, harnesses, governance — the practical blueprint enterprises are using to ship long-horizon AI agents in 2026.
AI Control Tower is the governance layer for ServiceNow's Project Arc — policy, monitoring, and audit logs for autonomous agents. Here is how it works.
Anthropic announced full Microsoft 365 integration in May 2026. What the integration covers, what it means for Outlook, Word, Excel, and Teams users, and where the boundaries are.
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.