HomeBlog › I budget my AI agents like a library — pages, books, and shelves
Blog

I budget my AI agents like a library — pages, books, and shelves

Jul 16, 20267 min readBy the Rysh team

Nobody has intuition for "600,000 tokens." So I started budgeting my agents in pages, books, and shelves — and the loops finally became safe to walk away from.

My biggest fear with autonomous agents was never "will it work."

It was walking away. You give an agent a goal, it starts looping — browse, extract, save, judge, repeat — and the moment you close the laptop, a question starts nagging: what is this costing right now? I've checked an API dashboard at 7am the way you check your phone after a night out. Nervously.

The fix sounds boring: give the loop a budget. But when I actually tried to do that, I ran into a problem I didn't expect — and it wasn't technical.

"This run gets 600,000 tokens" means nothing

Tokens are the natural unit for LLM spend, and they are a terrible unit for humans. Quick: is 600,000 tokens a lot for a research task? Is 50,000 stingy? If a teammate says "I capped the nightly job at 2 million tokens," do you nod because you understand, or because nodding is easier?

Nobody has intuition for raw token counts. Which means token budgets don't get set — or get set once, wrong, and never touched again.

While building rysh (an agentic terminal multiplexer — every pane can be a shell, an agent, or a chat), I ended up giving agent budgets a vocabulary borrowed from reading:

So a run gets --budget-size 20p — twenty pages. My Instagram-scouting automation gets 3b — three books per session. A serious overnight job might get a shelf.

The units changed the conversation more than the enforcement did. "This run gets three books" is a sentence you can say out loud in a planning meeting, and everyone in the room has the same rough picture. "This run gets 600,000 tokens" is a number you paste into a config file and forget. Legible budgets get set, argued about, and tuned. Illegible ones rot.

(And yes — the ceiling is enforced, not advisory. The loop cannot outspend it.)

The anatomy of a budgeted loop

In rysh, an automation is a markdown file with YAML frontmatter, stored under .rysh/automations/ — so the whole loop lives in git, next to the code it serves. Here's the (trimmed) recipe for a real one I run: it scouts podcast-guest candidates on Instagram for a show, discovery-only, and saves a shortlist file.

loop:
  do:                       # inner loop — one working session
    interval: 30
    max_duration: 7m
    budget:
      size: 3b              # 3 books = 600k tokens, hard ceiling
      watch:
        takeover_when: 90   # at 90% spent, switch to the wrap-up leg
        takeover_prompt: >
          The discovery budget is used up — stop browsing now.
          Save the shortlist as-is, add a note that it is PARTIAL,
          then print the file path and what to cover next time.

  while:                    # outer loop — repeat until the goal holds
    max_iterations: 5
    max_duration: 40m
    budget: 15b             # whole job: 15 books
    prompts:
      until: >
        The saved shortlist has at least 12 strong candidates, each
        with a handle, a why-they-fit line, and a contact — no dupes.
      iterate_with: >
        Continue scouting for {{args}}. The current shortlist is
        seeded above: find what's missing, merge, save back.

Two loops, two budgets:

That last sentence is the whole point. You can answer "what will this cost tonight?" at review time, from the diff.

The takeover leg — because dying at 100% is also a failure

Budgeted loops usually fail in one of two default ways:

  1. No budget → the bill surprises you.
  2. A hard cutoff → the run dies mid-thought at 100%, and the work in flight is lost.

Both are bad, and the second one quietly teaches teams to remove budgets — which gets you back to the first one.

So the budget has a watch. takeover_when: 90 means: when 90% of the ceiling is spent, the task's own prompt is taken off the wheel and the takeover_prompt takes over — with the reserved 10% as its budget. Its job is not to make progress. Its job is to land the plane: save what exists, label it PARTIAL, note what's missing, exit clean.

The run always ends with saved, labeled output. Never a wall.

Reset and resume — the loop is interruptible by design

When a do session ends (goal-ish reached, budget spent, or clock expired), an LLM judge reads the saved output against the until: text — a stop condition that's written down in the file, reviewable in code review like everything else.

And because sessions checkpoint their state, you can interrupt the whole thing:

##auto web stop scout        # park it
##auto web continue scout    # resume from the last checkpoint, budget re-armed

stop isn't a kill. continue isn't a restart. The loop picks up where it left off, with a fresh session budget. Then you schedule it and go to sleep:

##cron add nightly-scout "0 7 * * *" ##auto web run --headless scout

Design decisions I'd defend (and what I'm less sure about)

Human units over raw tokens. Covered above, but it's the hill I'll die on: a budget nobody can reason about is a budget nobody maintains.

Percentage-based takeover over "detect when stuck." takeover_when is a number (10–99), not a natural-language predicate. Detecting "the agent is stuck" reliably is a research problem; "90% of budget is gone" is a fact. Plain-language guardrails ("stop on any login wall") live in the recipe prompt itself, where the agent applies them per-step.

Artifact-seeded resume over transcript replay. Restarting from the saved file keeps each pass cheap and forces the automation to define what "its output" actually is — which turns out to be great discipline.

What I'm less sure about: the judge. An LLM evaluating until: is far better than iteration counting, but it's still an LLM reading your criteria — vague goals get vague verdicts. Writing a crisp until: is the skill; mine took three edits before "12 strong candidates, no dupes, each with a contact" stopped being gameable.

rysh is my product. It's in private beta, built on Claude (bring your own Anthropic key), self-hostable — your automations are files in your repo, not rows in my database. The longer write-up, with the takeover and tunneling mechanics side by side, is here: agents on a leash

If you run agents in loops and want to kick the tires while it's early, we're onboarding design partners: rysh.ai/design-partner — or tell me why pages/books/shelves is the wrong abstraction. I've been wrong before; that's what the takeover leg is for.

Try Rysh

Every pane is a shell and an AI agent — install takes one command.

Get started free →