Skip to main content

14 · Agents and AI engineering

Context, routing and cost

What a model gets to read, which model handles which task, and how to keep costs visible and under control.

11 minCase study: docket (opens in new window)

In ordinary software, running a function one more time costs almost nothing. In a system built on a language model, every step an takes costs , time and money, and that cost follows from design: how much text you send, which model answers and how many rounds you allow. The model's working memory, its , is also limited, and a crowded one hurts the model's well before anything visibly breaks.

This lesson covers five ideas: why an agent's cost grows faster than expected, keeping the context small on purpose, measured versus estimated cost, as stop signs, and choosing a model per role. Tokens and context windows are introduced in LLMs as software components.

Why agent cost grows fast

A model call is priced by the text going in and the text coming out, counted in tokens. The model also remembers nothing between calls, so every round of an agent's loop resends everything so far: instructions, files read, output of every command.

Picture a meeting where, before each new point, someone reads all the minutes so far out loud. The tenth point costs far more than the first, and a 20-round is not 20 equal calls for the same reason. Unless the history is trimmed, input cost grows roughly with the square of the number of rounds.

  1. Round 1instructions and the task
  2. Round 2round 1 again, plus new output
  3. Round 3everything so far, plus more
  4. Round 20the whole history, sent once more
The model remembers nothing, so each round carries everything before it. Every call is bigger than the last.

Keeping the context small on purpose

Deciding what goes into each call, in what form and order, is called : treating the context as a budget, not a bucket. Typical moves: cut long tool output, summarize old history, fetch only relevant documents (RAG), and hand subtasks to helper agents with their own context.

Three failures come up again and again:

  • Overflow. The request no longer fits, the provider rejects it, and the round's work is lost unless the system planned for it.
  • One giant output. A single command that prints a huge log fills the context in one step.
  • Summaries that break the conversation. A request to use a tool and the tool's answer belong together. A summary that keeps one and drops the other leaves a conversation the provider refuses.

The product callout below follows these moves in the order docket applies them before each model call.

In docket

  1. Cut tool outputeach result to a maximum length
  2. Summarize old historytool request and answer stay paired
  3. Check the fitdoes the request fit its budget?
  4. Call the modelor one last try without tools
Each step prevents one of the three failures above. If the budget cannot cover another tool round, the model is asked to say plainly what is unfinished. Source: Troubleshooting Guide · core/session.py

Measured versus estimated

There are two ways to know how many tokens something contains. An estimate is a rule of thumb, such as "about four characters per token"; it exists before the call, so it serves to decide what fits, with a margin. A measurement is the count the provider reports after the call; it is exact, so it is the one for budgets and accounting. Reporting an estimate as a measurement misleads whoever decides from that number.

Even exact token counts do not give the real bill. That depends on current prices, discounts, negotiated plans and middlemen's fees. Hence the rule: tokens are measured; dollars are estimated.

  • Estimatebefore the call
    • rule of thumb
    • decides what fits
  • Measurementafter the call
    • count reported by the provider
    • budgets and accounting
  • Dollarsalways an estimate
    • prices, discounts, fees
    • check against the invoice
Three numbers with three different jobs. Only the middle one is exact, and even it does not tell you the bill.

That gap is the general lesson: a cost control is only as good as its source of truth. In production, that source is the provider's or gateway's invoice, and internal numbers should be checked against it.

Budgets as stop signs

A runaway loop is an agent that keeps going without progress, each round costing more than the last. The defense is several hard limits at once, since each catches a different kind of loop:

Limit What it catches
Rounds going back and forth without progress
Tool uses bursts of tool activity
Repeated refusals insisting on something forbidden
Elapsed time slow calls and long waits
Measured tokens context growing without end
Dollars per agent team spending that builds up across tasks

Choosing a model per role

Not every step needs the most capable, most expensive model. is choosing which model answers each request: fixed per role, by how hard the request looks, as a cascade (try a cheap model, move up if a check fails), as a when a provider is down, or by cost and speed. The trade-offs: instructions tuned for one model can fail on another, failures get harder to reproduce, and a cascade sometimes pays twice.

Putting it into practice

  • Label every cost figure as measured or estimated, and check it against the real invoice.
  • Test with a small context window before trusting a system with a large one.
  • Set limits before the first deployment, and allow no spending without an explicit trigger.
  • Prove a cheaper model with evidence: compare it on the same tasks with evals before assigning it a role.

Go deeper

The docket and Tack documentation show these controls in working systems:

  • Workflow guide walks a task through a team of agents, including a budget cap stopping work between steps and reading measured tokens next to a labeled estimate.
  • Troubleshooting covers growing context and runaway turns: the per-turn limits, how to check what is resent every round, and trimming tool output for a small window.
  • Architecture explains the cheap and strong model classes, and how the hand-off between steps drops less important fields before it ever cuts the summary.
  • Agent runners and fleet execution describes, per coding tool, which usage Tack can really measure, and why an unknown cost reads "Not measured".

Key takeaways

  • The whole history is resent every round, so cost grows much faster than the number of steps.
  • Keep context small on purpose, and never split a tool request from its answer when summarizing.
  • Estimate to decide, measure to account, and never present an estimate as money spent.
  • Several limits at once stop runaway loops; each catches a different failure.
  • Routing by role saves money, but , not assumptions, show whether quality holds.

Check yourself

Why does a 20-round agent loop cost far more than 20 single calls?

The model keeps no memory between calls, so each round resends the whole history, which grows every round. Without trimming, input cost grows roughly with the square of the rounds.

What is wrong with showing $0.00 when cost was not measured?

It states something false: that the work cost nothing. "Not measured" is different information from "zero", and treating them alike leads to wrong decisions.

An agent team's dollar limit is checked against estimated prices. Why might it never trigger?

If a model is missing from the price list, its use adds nothing to the estimate, so real spending goes uncounted. A cost control is only as good as its source of truth.