Skip to content

adagio

Earned-capacity pacing for agentic data discovery.

Cheap, informative calls earn tickets. Expensive calls spend them. An agent that has not explored cheaply cannot run expensive operations, so exploration proceeds from light to heavy — enforced at the call boundary rather than requested in a prompt.

It is a token bucket whose refill is event-driven rather than time-driven.

import adagio

ledger = adagio.Ledger()

@ledger.gate(size="xs", subject=lambda table: table)
def describe_table(table: str) -> dict:
    """Metadata only. Costs nothing, earns 1."""
    ...

@ledger.gate(estimator=adagio.estimators.Function(dry_run))
def run_query(sql: str) -> list[dict]:
    """Priced per call from what the query would actually read."""
    ...

with ledger.scope("session-123"):
    run_query("select * from order_items")   # refused — and told why

The refusal is not a bare error. It tells the agent what to do instead:

{
  "status": "insufficient_capacity",
  "required": 10, "available": 0, "shortfall": 10,
  "tier": "heavy", "estimated_bytes": 12884901888,
  "suggestions": [
    {"callable": "describe_table", "cost": 0, "yield": 1, "net": 1,
     "reason": "not yet called for order_items"}
  ]
}

Why not just a rate limit

Rate limits, dollar caps and maximum_bytes_billed are all caps. They stop runaway spend but do nothing about the order of exploration — an agent well under every limit can still open with a 12 GB scan against a table it knows nothing about. Adagio makes the expensive call unavailable until the cheap ones have happened.

Control Bounds spend Shapes order
Requests per minute yes no
Token / dollar budget yes no
maximum_bytes_billed per query no
Prompt instruction ("explore first") no not enforced
Adagio via the cap yes

You don't write the cost table

Balancing costs and yields by hand is the part that goes wrong. Pick a tempo instead:

Tempo Alias Novel cheap calls before one heavy call
adagio strict ~10
andante balanced ~5
allegro lenient ~3

Everything else is derived and stays internally consistent. See Configuration.

Where to go next

Status

M1. The mechanism is built and tested; the behavioral claim it rests on is not yet measured. See Concepts.