Cost and tokens
In this lesson you will
- Name where tokens go in an agent request
- Measure cost per task and find the heaviest step
- Pull cost levers in an order that protects quality
- Make cost per task part of the release gate
Cost per task is a release metric
Teams usually meet agent cost as a surprise on an invoice. We treat it as a number you design for, measure per task and check before every release. The number that matters to the business is cost per task: what it costs to finish one unit of work, such as one handled request or one processed document.
In this lesson we find where tokens go, measure them, and pull the levers in an order that protects quality. We do not discuss provider rate cards. They change, and your agreement may differ. Use the numbers from your own contract.
Where the tokens go
One agent request carries much more than the question. Each part has its own driver.
| Part of the request | What drives it |
|---|---|
| System prompt and instructions | Length of the rules, repeated on every call |
| Retrieved context | Number and length of passages |
| Conversation history | Turns replayed, and whether they are summarised |
| Tool definitions | Number of tools and length of each description |
| Tool outputs | How much a tool returns beyond what the next step needs |
| Reasoning tokens | The model's effort setting and the difficulty of the step |
| The answer | The format asked for and the content required |
| Retries and loops | Failed calls and steps that circle back |
An agent calls the model many times per task, and each call replays the history and the tool definitions. That is why a "cheap" model with a bloated loop can cost more than an "expensive" model with a tight one. The loop and the context decide the bill at least as much as the model does.
Our post on what drives cost and latency in inference on Azure Databricks explains the serving options in more depth: batch, pay-per-token, provisioned throughput and self-hosted.
Step 1: measure per task, per step
You cannot lower what you have not measured. Capture, for every task:
- Tokens in and out per model call, and per step in the loop.
- Latency per step and per task.
- The number of loop passes and retries.
- A quality score from the evaluation set, next to the cost.
MLflow Tracing records each step of an agent run with its inputs, outputs, latency and token usage, so the data exists once tracing is on. Unity Gateway can log requests and responses to Delta tables and track usage, including token usage and latency, in system tables, with cost analysis by service, model, principal and tag.
# Cost per task from token counts. Rates come from YOUR agreement, per million tokens.
RATE_IN_PER_M = 1.0 # placeholder: replace with your contract rate for input tokens
RATE_OUT_PER_M = 4.0 # placeholder: replace with your contract rate for output tokens
def call_cost(tokens_in: int, tokens_out: int) -> float:
return tokens_in / 1_000_000 * RATE_IN_PER_M + tokens_out / 1_000_000 * RATE_OUT_PER_M
def task_cost(calls: list[dict]) -> float:
"""calls: one dict per model call in the task, with tokens_in and tokens_out."""
return sum(call_cost(c["tokens_in"], c["tokens_out"]) for c in calls)
def heaviest_step(calls: list[dict]) -> dict:
return max(calls, key=lambda c: call_cost(c["tokens_in"], c["tokens_out"]))The rates are placeholders on purpose. Keep the money figures in configuration, and keep the token counts as the primary measure, since tokens do not change when a provider changes its rates.
Step 2: pull the levers, in this order
Pick levers by what the measurements show. Test each one on your evaluation set before it ships.
| Lever | What it does | Proof that quality holds |
|---|---|---|
| Limits on loops and retries | Caps steps and repeated calls per task | Tracing shows the cap is rarely hit |
| Tool output compaction | Tools return only the fields the agent uses | Task success stays the same |
| Context trimming and history summaries | Keep only what the next step needs | Quality measured before and after |
| Prompt caching | Put the stable prefix first: instructions, tools, context | Answers stay identical, only cost changes |
| Retrieval tuning | Fewer, better passages | Answer quality and source accuracy |
| Structured outputs and early exit | Short fixed formats, stop when done | Format validity and success rate |
| Reasoning effort control | Less thinking on easy steps | Quality compared per setting |
| Model routing | Easy steps to a small model, hard steps to a larger one | The rule comes from evaluation |
| Model choice and swapping | The model that fits each task | Same evaluation set per candidate |
| Fine-tuning or self-hosting | A small model for one narrow task, or your own infrastructure | Must match the evaluation set before taking traffic |
The first rows are the cheapest to pull and carry the least quality risk. Routing deserves a warning: it is a quality control problem, not a cost switch. A router that sends hard cases to a weak model saves tokens and loses answers. Our post on model routing as a quality control problem goes deeper.
Step 3: guardrails on spend
Put limits where an agent cannot talk its way past them.
- Per-task limits in the harness: steps, time and tokens, as in lesson 1.
- Per-team and per-user limits at the gateway. Unity Gateway supports rate limits on model and MCP services, and budgets with per-user thresholds and hard caps.
- Alerts on spend per use case, so an agent that starts looping shows up the same day.
Step 4: make cost per task a release gate
Add a rule to the pipeline from lesson 4: a new version may ship only if quality holds on the evaluation set and cost per task stays within the agreed budget. A prompt change that improves quality by a point and doubles the tokens should be a conscious decision, not an accident found at month-end.
Record the result per release, next to the quality score. Over a few releases you will see which changes paid off.
Common mistakes
- Optimising the model first. Fix the loop and the context first.
- Averages only. Look at the expensive tail: the tasks that loop.
- Cutting quality for cost without measuring. Every lever needs the evaluation set.
- Hard-coding rates. Keep them in configuration.
Summary
Measure tokens per step and cost per task. Pull the cheap, low-risk levers first. Enforce limits at the harness and the gateway. Gate releases on quality and cost together.
Next lesson: how to bring your own model and swap models without a rebuild.
The idea in one picture
Cost per task as a release gate
- Trace tokensPer step
- Cost per task
- Pull a leverCheap, low risk first
- Run evaluation set
- Gate: quality and cost
Knowledge check
Answer each question. You see the reason behind every answer at once.
0 of 3 answered
Hands-on lab
Goal. Compute cost per task from token logs, find the heaviest step and test two levers.
Where to run it
Local Python Run this lab on your own machine with Python 3.10 or newer in a virtual environment.
Steps
- Create tasks.json with 10 tasks. Each task has 3 to 8 model calls with tokens_in and tokens_out. Make two tasks loop with 12 calls.
- Paste task_cost and heaviest_step from the lesson. Set the two rates in a config dictionary.
- Print cost per task, the average and the 90th percentile. Note which tasks form the expensive tail.
- Apply lever 1: cap calls at 8 per task. Apply lever 2: halve tool output tokens. Recompute and compare.
- Write a gate that fails if cost per task rises more than 10 per cent against the baseline.
Expected result
A before and after table, the expensive tail identified and a gate that passes the optimised version and fails a version with the loop restored.
Go deeper
Official documentation and recommended courses from the providers.
- DeepLearning.AI
- Cost not stated
- Intermediate
- 18 h 56 min
Context Engineering
A longer course on designing what an agent sees, matching the Databricks Context Engineer exam.
Open course : Context Engineering. Opens the provider site in a new tab
- docs.databricks.com
Unity Gateway: budgets and limits
Open documentation : Unity Gateway: budgets and limits. Opens at the provider
- docs.databricks.com
MLflow Tracing
Read at NexOps
Articles from our own projects on the same topic.
Sources
Last verified 2026-11-11
We check every source against the official documentation. Products change, so confirm details there before you build.