VynarisEarly beta Kimi K3Get your API key

How to attribute a multi-agent LLM bill: cost per agent, per task, and per user without double-counting

Attribute a multi-agent LLM bill without double-counting: amortize shared caches, split the orphaned judge, reconcile to the invoice. (2026-07-26)

A multi-agent workflow hands you one blended invoice and two ways to get the split wrong. In a 3-agent run that costs $0.3267 total, two subtasks that did identical work bill 1.93x apart on the raw usage object, and a judge pass worth 19.6% of the spend belongs to no single agent's task. Attribution is the layer above per-call metering: given correct per-call dollars, how do you allocate shared and blended cost across agents, tasks, and users so every dollar lands once? Prices verified 2026-07-26.

TL;DR

The workflow we are attributing

One user request fans out to a 3-agent pipeline over three subtasks. All numbers come from multi-agent-llm-cost-attribution-per-agent-task-user-finops-math.py; swap your own token counts in.

Using input tokens, output tokens (which include reasoning tokens, billed at the output rate), and the cache fields from the usage object, the per-call dollars are:

Agent                    Model      Raw cost      Share of bill
-----------------------  ---------  ------------  -------------
Planner                  Opus 5     $0.19000      58.1%
Worker #1 (wrote cache)  Haiku 4.5  $0.03575      10.9%
Worker #2 (read cache)   Haiku 4.5  $0.01850      5.7%
Worker #3 (read cache)   Haiku 4.5  $0.01850      5.7%
Judge                    Sonnet 5   $0.06400      19.6%
**Total**                           **$0.32675**  100%

That table is the per-agent view, and it is correct as far as it goes. The trouble starts the moment you ask "what did subtask 2 cost?" or "what did this user cost?"

A correctness constraint most write-ups get wrong

Before allocating, one mechanic decides the whole model: prompt caching is per-model. A cache written by an Opus call cannot be read by a Haiku call. So a "shared cache across all your agents" only exists within one model's calls. That is why our shared 15k context lives inside the Haiku worker swarm and nowhere else. The Opus planner and the Sonnet judge are different models, so they are separate cache namespaces and get treated as shared overhead, not shared cache. Any attribution model that shares a cache across models is describing billing that cannot happen.

Step 1: per agent (role), no allocation needed

Group calls by role and sum. Planner $0.19000, workers $0.07275, judge $0.06400. This view answers "which agent is expensive?" and the answer is the planner at 58.1% of spend, which is the number that should drive your optimization. No dollar is shared between roles, so nothing needs splitting. If per-agent were the only question, you could stop here.

Step 2: the cache-attribution trap

Now attribute cost per task. The three workers did identical real work: same 2,000-token prompt, same 3,000-token answer. Yet the raw usage object bills them $0.03575, $0.01850, $0.01850 — a 1.93x spread. The entire difference is the 15,000-token cache write, which one worker had to pay because it went first.

Cache write on Haiku 4.5 is 1.25x input ($1.25/MTok), so 15,000 tokens = $0.01875 parked on whichever worker created the cache. Reads bill at 0.1x ($0.10/MTok), so each reader saved relative to a fresh pass. "Creator pays" is the default if you attribute straight from cache_creation_input_tokens, and it overstates subtask #1 by +47.4% while understating #2 and #3 by 23.7% each. It is an ordering artifact, not a cost signal — re-run the workers in a different order and a different subtask carries the fee.

The fix: amortize the cache write across every call that reads it. Worker total $0.07275 / 3 = $0.02425 per subtask, identical work priced identically. The cache-creation line being mis-parked is $0.01875, or 25.8% of worker spend — not a rounding error.

Step 3: the orphaned-overhead trap

The judge scored all three worker outputs in one call: $0.06400, or 19.6% of the bill. It belongs to no single subtask. Two wrong moves are common:

  1. Bucket it as a "judge agent" and report per-task cost from worker dollars only. Every per-task number then silently drops a fifth of the real spend.
  2. Assign the whole judge cost to whichever task triggered it. That task looks 3x more expensive than its siblings for work the siblings equally consumed.

The planner has the same shape: one Opus call whose plan drove all three subtasks. Together, planner + judge = $0.25400 of shared overhead that no single task owns.

The fix: split shared overhead across the tasks it served. $0.25400 / 3 = $0.08467 per subtask.

Step 4: per task, done right, and the reconciliation test

Add the amortized worker cost to the overhead share:

Component                                Per subtask
---------------------------------------  ------------
Worker (amortized cache)                 $0.02425
+ shared overhead / 3 (planner + judge)  $0.08467
**= true cost per subtask**              **$0.10892**

The test that proves it: 3 x $0.10892 = $0.32675, matching the total to the cent. This is the only check that matters. If your per-task numbers do not sum back to the invoice, you have either double-counted a shared line or orphaned one.

Contrast with the naive per-task figure — raw worker dollars, overhead orphaned. Subtask #1 reads as $0.03575, which is 33% of its true $0.10892 cost: the naive view under-counts every task by 67%. That gap is exactly the shared overhead you dropped plus the cache fee you mis-parked. A FinOps dashboard built on raw usage-object dollars will tell you each task costs a third of what it does.

Grouped bar chart comparing raw usage-object dollars against correctly allocated dollars for three identical subtasks in a multi-agent workflow. The raw bars are unequal (subtask 1 at $0.0357 versus subtasks 2 and 3 at $0.0185, a 1.93x spread from the cache-write ordering artifact) and all three sit far below the flat allocated bars at $0.1089 each, showing the raw view misses 67% of the true per-task cost.
Same three subtasks, two attribution methods. Raw usage-object dollars show a 1.93x cache-ordering spread and miss 67% of true per-task cost; correct allocation amortizes the cache and splits shared overhead to $0.1089 each. Planner Opus 5, 3 Haiku 4.5 workers sharing a 15k cache, Sonnet 5 judge; total $0.3267. Prices verified 2026-07-26; token counts illustrative.

Step 5: per user, and where sharing changes the math

One user running this dedicated workflow costs the full $0.32675. Per-user attribution gets interesting only when a call is genuinely shared across users. If the planner produces one plan that U users consume — a shared retrieval plan, a cached system context, a template — its cost amortizes while each user still runs their own workers and judge:

Users sharing the planner  Cost per user  Planner share per user
-------------------------  -------------  ----------------------
1                          $0.32675       $0.19000
5                          $0.17475       $0.03800
20                         $0.14625       $0.00950

The planner is 58.1% of a single-user bill, so sharing it across 20 users cuts per-user cost by 55%, to $0.14625. The rule is the same as the cache: a shared line divides across everyone who consumes it, and it must still reconcile — sum the per-user costs and you get back the real total spend.

The one rule, and the reconciliation guarantee

Every trap above is the same mistake in different clothes: a shared line (cache write, judge pass, planner call) attributed to one owner instead of split across its consumers. The single rule that fixes all three:

Attribute private lines to their owner; split shared lines across every consumer; then confirm the parts sum to the invoice.

All three views — per agent, per task, per user (U=1) — reconcile to $0.32675 by construction. That is not a coincidence; it is the definition of correct attribution. Any scheme where the views disagree has a double-count or an orphan hiding in it, and the reconciliation check is how you catch it before it reaches a dashboard. For turning these per-user numbers into enforceable limits, see token spend caps per team; for cutting the planner cost that dominates this bill, see route the plumbing, keep the planner.

Plug your own token counts into the cost calculator for each agent, sum the calls, then apply the allocation rule to the shared lines.

The honest tradeoff: when attribution costs more than the insight

Correct allocation is not free. To amortize a cache you have to track which calls read which cache_creation line; to split a judge you have to know which tasks it scored. That is a join across the usage objects of every call in a trace, keyed by request and cache ID. For a three-agent run it is trivial. For a swarm of forty agents with nested sub-caches and retries, the tracking code is real engineering and its own compute cost.

The break-even is straightforward: attribute at the granularity your decisions need, not finer. If your model routing and budgets are per user, allocate to the user and stop — you do not need per-subtask precision to decide a per-user cap. If the planner is 58% of every bill, per-agent is enough to know where to optimize, and per-subtask allocation is a rounding exercise on the remaining 42%. Spend the tracking effort where a wrong number would change a decision; everywhere else, the per-agent sum is honest and cheap. Attribution is a means to a routing or budgeting decision, not an end.

FAQ

Why do two identical subtasks bill different amounts? Because one of them wrote the shared prompt cache and paid the 1.25x write fee, while the other read it at 0.1x. The cache_creation_input_tokens line lands on whichever call went first. It is an ordering artifact — amortize the write across all readers and identical work prices identically.

Can I share one prompt cache across agents that use different models? No. Caches are per-model. A cache written by an Opus call cannot be read by a Haiku or Sonnet call. A shared cache only exists within one model's calls; cross-model shared context has to be modeled as overhead, not as a cache read.

Where should the judge or combiner cost go? Split it across the tasks it evaluated, not bucketed under a standalone "judge agent." A judge that scores three outputs is one shared line serving three tasks; parking it under an agent drops it from every per-task number and under-prices each task — by 67% in our run.

What is the fastest way to check my attribution is correct? Reconcile. Sum your per-task (or per-user) figures and compare to the invoice total. If they match to the cent, no line is double-counted or orphaned. If they do not, a shared line is mis-allocated.

Do reasoning tokens change attribution? No, but do not forget them. Reasoning and thinking tokens are billed at the output rate and appear in output_tokens. Attribute them exactly like any other output — to the agent and task that emitted them.

How is this different from per-call metering? Metering computes the correct dollars for one call from its usage object and cost per token. Attribution is the layer above: it takes those correct per-call dollars and allocates the shared and blended ones across agents, tasks, and users. Get the metering right first, then allocate.

Sources

Related: Metering agent cost per call · Token spend caps per team · Route the plumbing, keep the planner · What a coding agent costs per task across 6 models