Most agent frameworks focus on orchestration. The hard problems are elsewhere - state management, recovery, and knowing when to stop.
Every agent framework wants to sell you on the DAG. Define your nodes, wire up your edges, let the LLM decide which path to take. It's a clean abstraction and a beautiful demo. It's also maybe 10% of what makes an agent work in production.
The other 90% is the stuff nobody puts in their README.
State is the whole game
An agent that runs for thirty seconds doesn't need state management. An agent that runs for thirty minutes - or thirty hours - does. And the moment your agent touches external systems (databases, APIs, file systems), you have a distributed state problem whether you wanted one or not.
The question isn't "what's the agent's current step." It's "if this process dies right now, can I resume without corrupting anything or repeating side effects?" Most frameworks punt on this entirely.
A minimal checkpoint looks something like this:
checkpoint = {
"run_id": run.id,
"step": current_step,
"completed_actions": [a.id for a in actions if a.committed],
"pending_effects": [e.serialize() for e in side_effects],
"timestamp": time.time()
}
store.save(checkpoint)Simple, but most agent code doesn't even get this far.
Recovery isn't retry
Retry logic is table stakes. Recovery is harder. When an agent fails mid-task, you need to figure out what already happened, what the downstream effects were, and whether the world has changed since the last successful step. This is transactional thinking, not orchestration thinking.
The teams that get this right tend to come from infrastructure backgrounds, not ML backgrounds. They've built job schedulers and workflow engines before. They think in terms of idempotency and checkpoints, not chains and prompts.
Knowing when to stop
The hardest problem in agent systems isn't getting them to do things. It's getting them to stop. An agent with access to tools and a vague objective will happily burn tokens forever, exploring every tangent, retrying every failure, elaborating on every response.
Budgets help (token limits, step limits, time limits). But the real solution is tighter scoping. The best agent systems I've seen do less per invocation and compose at a higher level. Small, focused agents that finish fast and hand off cleanly beat one mega-agent that tries to do everything.
The boring parts matter most
Logging. Observability. Cost tracking. Audit trails. None of this is exciting. All of it is mandatory if you're running agents in production with real users and real money. If you can't answer "what did the agent do, why, and how much did it cost" for every run, you're not ready to ship.