<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mark Fussell</title>
    <description>The latest articles on DEV Community by Mark Fussell (@mfussell).</description>
    <link>https://dev.to/mfussell</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1026869%2F37ada0d7-1cac-4f7a-a825-b53a2663e585.jpeg</url>
      <title>DEV Community: Mark Fussell</title>
      <link>https://dev.to/mfussell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mfussell"/>
    <language>en</language>
    <item>
      <title>Strip the Branding Off Your Agent Framework. It's the Same Five Lines.</title>
      <dc:creator>Mark Fussell</dc:creator>
      <pubDate>Wed, 30 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/mfussell/strip-the-branding-off-your-agent-framework-its-the-same-five-lines-3a35</link>
      <guid>https://dev.to/mfussell/strip-the-branding-off-your-agent-framework-its-the-same-five-lines-3a35</guid>
      <description>&lt;p&gt;Strip the branding off your sgent framework and it's the same five lines.&lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;goal_reached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;thought&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# decide
&lt;/span&gt;    &lt;span class="n"&gt;action&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thought&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;# choose a tool
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;# the side effect happens HERE
&lt;/span&gt;    &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;# remember
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;h2&gt;
  
  
  The line that matters
&lt;/h2&gt;

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

&lt;p&gt;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. &lt;/p&gt;

&lt;p&gt;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:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@workflow&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;goal&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;goal_reached&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;thought&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="c1"&gt;# journaled
&lt;/span&gt;        &lt;span class="n"&gt;action&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;thought&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                    &lt;span class="c1"&gt;# deterministic, safe to replay
&lt;/span&gt;        &lt;span class="n"&gt;result&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# journaled, retried if in flight
&lt;/span&gt;        &lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvcjk4fvxg167wi8b5w8o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvcjk4fvxg167wi8b5w8o.png" alt="What happens when an agent crashes mid-loop" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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."&lt;/p&gt;

&lt;h2&gt;
  
  
  The corollary
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;I've written the longer history of where this loop came from in &lt;a href="https://www.diagrid.io/blog/agentic-execution-evolution-6-agent-loop" rel="noopener noreferrer"&gt;chapter 6 of my series&lt;/a&gt;, and there's a practical companion on &lt;a href="https://www.diagrid.io/blog/keep-your-agent-framework" rel="noopener noreferrer"&gt;keeping your framework while adding durable execution&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Disagree? Tell me which framework's core loop is genuinely a different shape. I'll happily be wrong.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>python</category>
    </item>
  </channel>
</rss>
