By Sagar Shankaran, Founder of CallSphere
Learn to accurately track and optimize the total cost of AI agent conversations including token usage, tool call expenses, infrastructure overhead, and strategies for reducing cost per interaction.
Key takeaways
An AI agent that costs 45 cents per conversation might look like a bargain compared to a human agent at 7 dollars. But if your agent handles 200,000 conversations a month, that is 90,000 dollars — and the cost can double overnight if a prompt change adds more tokens or a new tool makes extra API calls. Without granular cost tracking, you cannot forecast budgets, optimize spend, or make informed decisions about model selection.
The true cost of an AI agent conversation goes far beyond LLM token costs. It includes tool execution fees, embedding lookups, vector database queries, infrastructure compute, and the cost of human escalations when the agent fails.
Start with the largest cost component: LLM tokens.
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 typing import Optional
MODEL_PRICING = {
"gpt-4o": {"input": 2.50, "output": 10.00},
"gpt-4o-mini": {"input": 0.15, "output": 0.60},
"gpt-4.1": {"input": 2.00, "output": 8.00},
"gpt-4.1-mini": {"input": 0.40, "output": 1.60},
"claude-sonnet-4-20250514": {"input": 3.00, "output": 15.00},
"claude-haiku-4-20250414": {"input": 0.80, "output": 4.00},
} # per million tokens
@dataclass
class TokenUsage:
model: str
input_tokens: int
output_tokens: int
cached_tokens: int = 0
@property
def cost_usd(self) -> float:
pricing = MODEL_PRICING.get(self.model)
if not pricing:
return 0.0
input_cost = (
self.input_tokens * pricing["input"] / 1_000_000
)
output_cost = (
self.output_tokens * pricing["output"] / 1_000_000
)
# Cached tokens are typically 50% cheaper
cache_savings = (
self.cached_tokens * pricing["input"] * 0.5
/ 1_000_000
)
return round(input_cost + output_cost - cache_savings, 6)
@dataclass
class ConversationCost:
conversation_id: str
llm_calls: list[TokenUsage] = field(default_factory=list)
tool_costs: list[dict] = field(default_factory=list)
infra_cost_usd: float = 0.0
@property
def total_llm_cost(self) -> float:
return sum(call.cost_usd for call in self.llm_calls)
@property
def total_tool_cost(self) -> float:
return sum(t.get("cost_usd", 0) for t in self.tool_costs)
@property
def total_cost(self) -> float:
return round(
self.total_llm_cost
+ self.total_tool_cost
+ self.infra_cost_usd,
6,
)
def cost_breakdown(self) -> dict:
return {
"conversation_id": self.conversation_id,
"llm_cost_usd": round(self.total_llm_cost, 6),
"tool_cost_usd": round(self.total_tool_cost, 6),
"infra_cost_usd": round(self.infra_cost_usd, 6),
"total_cost_usd": self.total_cost,
"llm_calls_count": len(self.llm_calls),
"total_input_tokens": sum(
c.input_tokens for c in self.llm_calls
),
"total_output_tokens": sum(
c.output_tokens for c in self.llm_calls
),
}
Track every LLM call within a conversation — agents often make multiple calls per turn (reasoning, tool selection, response generation). Missing even one call throws off your accounting.
Hear it before you finish reading
Talk to a live CallSphere AI voice agent in your browser — 60 seconds, no signup.
External tools have their own costs: API fees, database compute, third-party service charges.
@dataclass
class ToolCostConfig:
tool_name: str
cost_per_call: float = 0.0
cost_per_unit: float = 0.0
unit_name: str = "call"
class ToolCostTracker:
def __init__(self):
self.configs: dict[str, ToolCostConfig] = {}
def register_tool(self, config: ToolCostConfig):
self.configs[config.tool_name] = config
def calculate_cost(
self, tool_name: str, units: float = 1.0
) -> dict:
config = self.configs.get(tool_name)
if not config:
return {
"tool_name": tool_name,
"cost_usd": 0.0,
"warning": "unregistered_tool",
}
cost = config.cost_per_call + (
config.cost_per_unit * units
)
return {
"tool_name": tool_name,
"cost_usd": round(cost, 6),
"units": units,
}
# Example registration
tracker = ToolCostTracker()
tracker.register_tool(ToolCostConfig(
tool_name="web_search",
cost_per_call=0.005,
))
tracker.register_tool(ToolCostConfig(
tool_name="database_query",
cost_per_call=0.0001,
cost_per_unit=0.00001,
unit_name="rows_scanned",
))
tracker.register_tool(ToolCostConfig(
tool_name="send_email",
cost_per_call=0.001,
))
Register every tool with its cost model. Some tools charge per call, some per data unit processed. Flagging unregistered tools ensures new tools do not silently run up costs without visibility.
Allocate shared infrastructure costs to individual conversations using a per-second model.
from datetime import datetime
class InfraCostAllocator:
def __init__(
self,
monthly_infra_cost: float,
avg_monthly_conversations: int,
):
self.per_conversation = round(
monthly_infra_cost / max(avg_monthly_conversations, 1),
6,
)
def allocate(self, duration_seconds: float) -> float:
# Adjust base cost by conversation duration
avg_duration = 120 # assumed average seconds
multiplier = duration_seconds / avg_duration
return round(self.per_conversation * multiplier, 6)
# GPU inference server: $2000/month, 150k conversations
allocator = InfraCostAllocator(2000.0, 150_000)
# A 60-second conversation
infra_cost = allocator.allocate(60)
# Result: ~$0.0067
This is a simplification, but it gives a reasonable per-conversation allocation. For more precision, use actual compute time tracked by your container orchestrator.
Aggregate cost data into summaries that drive optimization decisions.
from collections import defaultdict
class CostDashboard:
def __init__(self):
self.conversations: list[ConversationCost] = []
def add(self, cost: ConversationCost):
self.conversations.append(cost)
def summary(self) -> dict:
if not self.conversations:
return {}
costs = [c.total_cost for c in self.conversations]
return {
"total_conversations": len(costs),
"total_spend_usd": round(sum(costs), 2),
"avg_cost_per_conversation": round(
sum(costs) / len(costs), 4
),
"median_cost": round(
sorted(costs)[len(costs) // 2], 4
),
"max_cost": round(max(costs), 4),
"p95_cost": round(
sorted(costs)[int(len(costs) * 0.95)], 4
),
}
def cost_by_model(self) -> dict[str, float]:
model_costs = defaultdict(float)
for conv in self.conversations:
for call in conv.llm_calls:
model_costs[call.model] += call.cost_usd
return {
k: round(v, 4)
for k, v in sorted(
model_costs.items(),
key=lambda x: -x[1],
)
}
The p95 cost is critical — it shows the cost of your most expensive conversations. These are often multi-turn debugging sessions or conversations where the agent enters a retry loop, making many LLM calls for a single user request.
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.
Once you have visibility, optimization becomes systematic. Route simple queries to cheaper models. Cache frequent tool results. Truncate conversation history to reduce input tokens. Use prompt caching when available. Each optimization should be tracked against its impact on quality — saving money at the cost of accuracy is rarely worthwhile.
Most providers report cached versus non-cached tokens in their API response. Track the cached_tokens field from the usage object and apply the discount rate (typically 50 percent off input token price). This gives you accurate cost numbers and shows how much your caching strategy is actually saving.
It varies enormously. A simple FAQ agent using GPT-4o-mini might cost 0.2 to 0.5 cents per conversation. A complex multi-tool agent using GPT-4o with web search and database lookups ranges from 3 to 15 cents. Voice agents add TTS and STT costs, often doubling the total. Track your actual costs rather than relying on estimates.
Set hard limits: maximum LLM calls per conversation (for example 10), maximum tokens per call, and a total cost ceiling per conversation. When any limit is hit, gracefully end the conversation with an escalation to a human agent. Log every limit-hit event so you can investigate whether the limit is too low or the agent is genuinely stuck.
#CostOptimization #TokenTracking #AgentEconomics #Python #MLOps #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.
Reasoning models (Claude Mythos, o3, Opus 4.7, DeepSeek V4-Pro) for browser-side llms (webgpu) — a May 2026 comparison grounded in current model prices, benchmark...
Self-hosted on-prem stack for browser-side llms (webgpu) — a May 2026 comparison grounded in current model prices, benchmarks, and production patterns.
Reasoning models (Claude Mythos, o3, Opus 4.7, DeepSeek V4-Pro) for edge / on-device llm inference — a May 2026 comparison grounded in current model prices, bench...
Self-hosted on-prem stack for edge / on-device llm inference — a May 2026 comparison grounded in current model prices, benchmarks, and production patterns.
DeepSeek V4 vs Llama 4 vs Qwen 3.5 vs Mistral Large 3 for edge / on-device llm inference — a May 2026 comparison grounded in current model prices, benchmarks, and...
Reasoning models (Claude Mythos, o3, Opus 4.7, DeepSeek V4-Pro) for multilingual customer support — a May 2026 comparison grounded in current model prices, benchm...
© 2026 CallSphere Inc. All rights reserved.
Made within San Francisco
Watch how CallSphere handles real customer calls, schedules appointments, and processes payments — live.