The problem in one line: your provider invoice is a single number, and cost-per-1K-tokens is a rate — neither tells you which customer, feature, or job is losing you money. The unit that decides whether you're profitable is the task: one ticket resolved, one document processed, one agent run. In 2026, a single task is a dozen LLM calls — planning, tool calls, retries, a final summary. You need to sum all of them, tagged by who and what. Here's how, with the exact attributes and code.
Step 1 — Emit token counts on every call (OpenTelemetry, zero call-site changes)#
The OpenTelemetry GenAI semantic conventions standardize what every LLM span carries. The two attributes that become dollars:
gen_ai.usage.input_tokensgen_ai.usage.output_tokens
(plus gen_ai.request.model and gen_ai.operation.name for grouping). Because the names are vendor-neutral, the same setup works across OpenAI, Anthropic, and open models. You don't set these by hand — auto-instrumentation does it:
# pip install traceloop-sdk
from traceloop.sdk import Traceloop
Traceloop.init(app_name="my-agent") # patches OpenAI/Anthropic/etc.
# every LLM call your code already makes now emits a span
# carrying gen_ai.usage.input_tokens / output_tokens
That's the whole instrumentation step. Your existing client.messages.create(...) calls are untouched.
Step 2 — Group calls into tasks, and price them (Langfuse)#
Token counts on a span are raw material. To get cost per task you need two things: a grouping (all the calls in one task) and a price. Langfuse gives you both. A trace is one unit of work; each LLM call is an observation inside it. Langfuse multiplies token usage by each model's price — from its model-definitions table, which you can override with your own custom prices — and rolls the per-call costs up to a trace total. (Already know the cost? Send it directly instead of the price table.)
The move that makes it your FinOps data is tagging the trace:
from langfuse import get_client
langfuse = get_client()
with langfuse.start_as_current_span(name="support-reply") as root:
# ... your agent runs here: many LLM calls, all captured ...
langfuse.update_current_trace(
user_id="acct_8821", # → cost per customer
session_id="conv_4f9c", # → group a multi-turn thread
metadata={
"task_type": "support_reply", # → cost per feature
"plan": "pro", # → cost per tier
"env": "prod",
},
)
You cannot group by a dimension you didn't record. Add user_id, session_id, and a task_type on day one — back-filling attribution after a cost surprise is the painful path.
If you're already exporting OpenTelemetry, skip the Langfuse SDK entirely: point your OTLP exporter at Langfuse's endpoint and it ingests the gen_ai.usage.* attributes as usage automatically. Either way, you now have a USD cost per trace, sliceable by customer, feature, and model.
Step 3 — Watch three numbers, not the token rate#
With cost attributed to tasks, produce the numbers that actually change decisions:
- **Cost per task — median and p95.** The p95 is the one that matters: it exposes the runaway agent loops that the average quietly buries. A 3¢ median with a $2.40 p95 means a small slice of tasks is spiraling — usually retries or an agent that won't stop calling tools.
- Cost per active user, per period. Your true variable cost of serving one user. This is the number that belongs next to your pricing page.
- Cost per paying customer vs. what they pay you. The margin check. Almost every team that runs this finds a handful of accounts underwater — heavy users on a flat plan.
Each has a concrete lever. High p95 → cap agent iterations per task. Cheap-but-frequent step dominating the bill → route it to a smaller model (this is the practical payoff of a good model-routing decision). Same context re-sent every turn → cache it; that pattern is exactly why agent costs scale quadratically if you don't.
The one idea#
Cost lives on the call, but it bills by the task. Instrument once with OpenTelemetry, group and price in Langfuse, and tag every trace with the customer and feature. The token rate is a distraction; cost per task, per user, and per paying customer is the ledger that tells you what to cache, what to route, and what to reprice. For the full tracing-and-eval setup underneath this, see our Langfuse v4 + OTel instrumentation walkthrough and the Honeycomb vs Langfuse view on APM lineage.



