
Agent Patterns That Survive Production
Loop limits, tool timeouts, and a hard budget. An agent without these is an outage with a personality.
An agent demo is a model calling three tools and solving a problem. An agent in production is the same thing at 3am, with a malformed API response, in a loop, spending money.
The difference is entirely in the constraints you put around it.
Hard limits, set before launch
A maximum step count. Every agent loop needs a ceiling. Without one, a model that cannot make progress will try forever, and "forever" has a per-token price.
A timeout on every tool. One hanging HTTP call should not hang the whole run. Short timeouts, and treat a timeout as a normal result the agent can reason about.
A token or cost budget per run. Track spend as the run proceeds and stop when it exceeds the ceiling. A single runaway conversation should never be able to consume a month of budget.
A wall-clock deadline. Users abandon; your infrastructure should too.
const MAX_STEPS = 12
for (let step = 0; step < MAX_STEPS; step++) {
if (Date.now() > deadline || spend > budget) break
// ...
}
Tool design decides reliability
Most agent failures I have debugged were tool design problems, not model problems.
Return errors as data, not exceptions. { ok: false, reason: "no booking with that id" } lets the agent recover. A thrown exception ends the run.
Make tools narrow. get_booking_by_id beats a general query_database — narrow tools are harder to misuse and easier to authorise.
Make them idempotent where possible. Agents retry. A create_booking that runs twice must not produce two bookings, which is what idempotency keys are for.
Describe them precisely. The description is the interface. Ambiguity there produces wrong calls that look like model failures.
The security posture
Assume every tool argument originates from untrusted input, because a document the agent read can contain instructions.
Authorise on the server using the session's identity, never the agent's claim about who it is acting for. Read-only by default; writes are a deliberate exception. And any action that is expensive, destructive, or externally visible — sending email, issuing a refund, deleting records — gets a human confirmation step.
Observability
Log every step: the model's reasoning, the tool called, the arguments, the result, the tokens. When an agent does something strange, that trace is the only way to understand why. Debugging a multi-step run without it is guessing.
Resources
- Repo: openai/openai-agents-python
- Video walkthroughs: YouTube: AI agent patterns
- Related: The blast radius of an autonomous agent
Need this built properly?
I build secure, fast, bilingual platforms for clients across Egypt, Saudi Arabia, the UAE and Kuwait.


