An agent that can call tools is an agent that can call them forever. The first thing I add to any agent graph is a budget.
Budgets first
Before a single tool runs, cap the loop on three axes: max steps, max tokens, and max wall-clock. A runaway agent should fail loudly and cheaply, not silently and expensively.
const budget = { steps: 0, maxSteps: 8, deadline: Date.now() + 30_000 };
while (budget.steps < budget.maxSteps && Date.now() < budget.deadline) {
const step = await planner.next(state);
if (step.done) break;
state = await execute(step);
budget.steps++;
}Add a critic
The second thing I add is a critic — a separate pass that asks 'is this actually done, and is it correct?' before the result escapes the loop. The generator is optimistic; the critic is paid to be skeptical.
A demo needs a generator. Production needs a generator and a critic that can veto it.
Guardrails
- Validate every tool output against a schema — never parse free text downstream.
- Gate irreversible actions (payments, emails, deletes) behind explicit confirmation.
- Log the full trace so any run can be replayed and debugged.
Together they convert an impressive demo into something you can put in front of production traffic without losing sleep.
Keep reading
Enjoyed this?
Get new deep dives on systems and AI in your inbox.