DEV Community

Cover image for Strip the Branding Off Your Agent Framework. It's the Same Five Lines.
Mark Fussell
Mark Fussell

Posted on

Strip the Branding Off Your Agent Framework. It's the Same Five Lines.

Strip the branding off your sgent framework and it's the same five lines.

This will annoy some framework authors, so let me be clear about the claim. Take LangGraph, CrewAI, Strands, Google ADK, Pydantic or Microsoft Agent Framework. Remove the branding, the abstractions, the graph builders. At the core of every one of them you find variations of this:

while not goal_reached(history):
    thought = llm(history)       # decide
    action  = parse(thought)     # choose a tool
    result  = execute(action)    # the side effect happens HERE
    history.append(result)       # remember
Enter fullscreen mode Exit fullscreen mode

Five lines of code. The model is almost comically simple, and I mean that as a compliment, because simple models win. The Windows message loop (GetMessage, TranslateMessage, DispatchMessage) was about this same size. I wrote those for Windows 3.0 back in the 90s, so the shape is an old friend.

Before the objections arrive: parallel tool calls just make action a list. Graph-based frameworks turn the while into edges between nodes. Multi-agent setups are loops calling loops. The shape holds.

So why do agent frameworks feel different? Because they compete on everything around the loop: nicer tool definitions, multi-agent hand-offs, streaming, tracing. All genuinely useful, and all decoration on the same five lines. It is still a loop.

The line that matters

Whether your agent survives production isn't decided by the loop or the decoration. It's decided by line four. execute(action) is where money moves, tickets open and emails get sent.

When the process dies mid-loop (a deploy, an eviction, an OOM kill), someone has to answer two questions: which steps already completed, and where should we resume? The loop has no idea. Agent framework checkpoints help, but they snapshot state at intervals, so recovery often means rerunning work since the last snapshot, including side effects that already fired. No frameworks have a failure detection mechanism included, which is the really hard problem to solve.

That's a runtime concern, and it has a name: durable execution. Here's the same loop on a durable runtime, in engine-agnostic pseudocode:

@workflow
def agent(ctx, goal):
    history = [goal]
    while not goal_reached(history):
        thought = yield ctx.step(llm, history)      # journaled
        action  = parse(thought)                    # deterministic, safe to replay
        result  = yield ctx.step(execute, action)   # journaled, retried if in flight
        history.append(result)
Enter fullscreen mode Exit fullscreen mode

What happens when an agent crashes mid-loop

Each completed step is recorded in a journal. After a crash, the runtime replays the journal. Completed steps return their recorded results instantly, with no second LLM bill and no duplicate email, and execution resumes at the exact step that was in flight.

One honest caveat: a step that crashes after its side effect fires but before the journal write will be retried. Durable execution gives you at-least-once steps, not magic. So your tools still need to be idempotent (pass an idempotency key to the payment API). The difference is that retries become precise and bounded instead of "rerun everything and hope."

The corollary

If the loop is the same five lines everywhere, durability doesn't need to live in the framework. Keep the framework you like, and put the loop on a durable runtime. These are separable decisions, and the ecosystem is already heading that way, with durable-runtime integrations appearing for several popular frameworks.

I'd go further: coupling the two is how the industry gets locked in for the next decade. This is workflow orchestration's oldest lesson wearing a new AI badge.

I've written the longer history of where this loop came from in chapter 6 of my series, and there's a practical companion on keeping your framework while adding durable execution.

Disagree? Tell me which framework's core loop is genuinely a different shape. I'll happily be wrong.

Top comments (0)