<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[rari's Substack]]></title><description><![CDATA[My personal Substack]]></description><link>https://whrrari.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!ZsQx!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcafaeef6-532d-4b38-b535-282af60f2982_400x400.png</url><title>rari&apos;s Substack</title><link>https://whrrari.substack.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 04 Nov 2026 23:05:24 GMT</lastBuildDate><atom:link href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Ffeed" rel="self" type="application/rss+xml"/><copyright><![CDATA[rari]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[whrrari@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[whrrari@substack.com]]></itunes:email><itunes:name><![CDATA[rari]]></itunes:name></itunes:owner><itunes:author><![CDATA[rari]]></itunes:author><googleplay:owner><![CDATA[whrrari@substack.com]]></googleplay:owner><googleplay:email><![CDATA[whrrari@substack.com]]></googleplay:email><googleplay:author><![CDATA[rari]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Jev Engineering: Stop Using LLMs for Every Decision]]></title><description><![CDATA[The fast decision layer that makes AI agents cheaper, faster, and easier to control]]></description><link>https://whrrari.substack.com/p/jev-engineering-stop-using-llms-for</link><guid isPermaLink="false">https://whrrari.substack.com/p/jev-engineering-stop-using-llms-for</guid><dc:creator><![CDATA[rari]]></dc:creator><pubDate>Sun, 27 Sep 2026 18:28:34 GMT</pubDate><enclosure url="iframe.php?url=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F124a1f06-a125-4703-b286-695b400efaf3_1733x908.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most AI agents are built around one expensive assumption</p><p>Every intelligent decision needs another LLM call</p><p>Which worker should act next</p><p>Is this source relevant</p><p>Is the result safe to publish</p><p>Does the task look finished</p><p>Should the system retry, escalate, or stop</p><p>None of those decisions require a paragraph</p><p>Yet most agent stacks still ask a generative model to reason in prose, emit JSON, wait for a parser, and hope the schema survives</p><p>That is not intelligence architecture</p><p>It is a chatbot being used as a switch statement</p><p>Jev changes the primitive</p><p>It does not generate text</p><p>It reads the current state of a system, evaluates typed questions, and returns probabilities that software can act on directly</p><blockquote><p>The gains aren&#8217;t free: Jev can't generate text<br><br><strong>Diogo Almeida, TypeSafe AI's founder</strong></p></blockquote><p>That limitation is the entire point</p><p>When a model gives up open-ended strings, it can become a much faster and more composable decision layer inside code</p><p><a href="iframe.php?url=https%3A%2F%2Fx.com%2FCompleteSkeptic%2Fstatus%2F2099925682726002904">Diogo Almeida post</a></p><p>The important launch is not another model</p><p>It is a new division of labor inside an agent</p><pre><code><code>LLM   creates the work
JEV   decides what happens next
CODE  executes and enforces the decision</code></code></pre><p>This article is about how to engineer that split properly</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3F"><span>Subscribe now</span></a></p><div><hr></div><h1>The expensive mistake inside most agents</h1><p>An agent loop looks simple from the outside</p><pre><code><code>goal -&gt; model -&gt; tool -&gt; observation -&gt; model -&gt; tool -&gt; result</code></code></pre><p>But zoom in and you find dozens of small judgments hidden between the large actions</p><pre><code><code>Is the request clear enough
Which tool should run
Which model should receive this task
Which source should survive retrieval
Is the tool call risky
Did the action actually work
Is the evidence strong enough to stop</code></code></pre><p>The usual response is to send every question back to the same frontier LLM</p><p>That creates four problems</p><h2>Latency compounds</h2><p>One extra model call does not feel expensive</p><p>Twenty sequential calls do</p><p>An agent can spend more time deciding whether to continue than doing the work itself</p><h2><strong>Cost moves into invisible branches</strong></h2><p>The final answer may be short</p><p>The internal routing, scoring, checking, and retry decisions can consume most of the token budget</p><h2><strong>Strings create integration work</strong></h2><p>The model returns prose or JSON</p><p>Your code validates it, repairs it, retries it, or quietly accepts a malformed edge case</p><h2><strong>Confidence is improvised</strong></h2><p>An LLM can say it is 95% confident</p><p>That number is usually another generated token, not a calibrated operating signal</p><p>The deeper problem is architectural</p><p>Generation and decision-making have been collapsed into the same call</p><p>Jev engineering begins by separating them</p><div><hr></div><h1><strong>Jev is not a smaller chatbot</strong></h1><p>TypeSafe calls Jev its first System One Model</p><p>The interface is closer to a frontier-intelligence function than a conversation</p><pre><code><code>INPUT
current state + typed questions

OUTPUT
typed answers + probability distributions</code></code></pre><p>Jev does not draft the email</p><p>It can decide which queue should receive the email</p><p>It does not write the research report</p><p>It can score whether the collected evidence is sufficient</p><p>It does not execute the shell command</p><p>It can estimate whether the proposed command requires approval</p><p>It does not explain itself in a long chain of thought</p><p>It returns a constrained answer your code already knows how to handle</p><p>TypeSafe built the model around a training method it calls Reinforcement Learning for Calibrated Decisions, or RLCD</p><p>The goal is not prettier language</p><p>The goal is decision quality plus useful uncertainty</p><p>TypeSafe reports end-to-end latency of roughly 70&#8211;500ms for Jev-shaped queries and pricing of $0.042 per million input tokens, with no metered output-token cost</p><p>Its larger speed and cost claims come from favorable workflow evaluations and should be treated as ceilings, not promises for every application</p><p>That nuance matters</p><p>Jev is valuable even when it is not 200x faster</p><p>The deeper win is that a decision becomes an explicit, typed, testable component</p><p><a href="iframe.php?url=https%3A%2F%2Fx.com%2FCompleteSkeptic%2Fstatus%2F2099925682726002904">TypeSafeAI post</a></p><div><hr></div><h1>The three-layer agent stack</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21YeEf%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YeEf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21YeEf%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg" width="1200" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!YeEf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!YeEf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f112f87-ba5a-42ee-aabe-fbc84fa3292c_1200x576.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The cleanest architecture has three different owners</p><pre><code><code>GENERATE  -&gt;  LLM
DECIDE    -&gt;  JEV
ENFORCE   -&gt;  CODE</code></code></pre><h2><strong>The LLM generates</strong></h2><p>Use a generative model when the output itself must be created</p><ul><li><p>Research</p></li><li><p>Writing</p></li><li><p>Planning</p></li><li><p>Code</p></li><li><p>Explanations</p></li><li><p>Open-ended synthesis</p></li></ul><h2><strong>Jev decides</strong></h2><p>Use Jev when the meaning is fuzzy but the possible answer shape is known</p><ul><li><p>Route to one worker</p></li><li><p>Score against a rubric</p></li><li><p>Estimate yes or no</p></li><li><p>Choose whether to retry</p></li><li><p>Select whether to escalate</p></li></ul><h2><strong>Code enforces</strong></h2><p>Use deterministic code when the rule must be exact</p><ul><li><p>Permissions</p></li><li><p>Budgets</p></li><li><p>Retry limits</p></li><li><p>Account access</p></li><li><p>Database writes</p></li><li><p>Publishing</p></li><li><p>Deletion</p></li><li><p>Money movement</p></li></ul><p><strong>This creates a useful rule</strong></p><blockquote><p>If the system must create language, use an LLM<br><br>If it must interpret meaning and choose from known outcomes, use Jev<br><br>If it must obey an exact invariant, use code</p></blockquote><p>The most dangerous mistake is to let a confidence score become permission</p><p>Jev can recommend an action</p><p>Only the harness should authorize it</p><div><hr></div><h1><strong>Jev has three decision primitives</strong></h1><p>Jev keeps the interface deliberately small</p><p>The three primitives are enough to build most semantic branches inside an agent</p><h2><strong>Choice</strong></h2><p>Use <strong>Choice</strong> when exactly one option should win</p><pre><code><code>from typesafe_sdk import Choice

next_worker = Choice(
    instructions="Which worker should act next?",
    criteria={
        "research": "Important evidence is still missing",
        "write": "Enough evidence exists to draft the answer",
        "review": "The request is unclear, complete, or consequential",
        "none": "No listed worker is appropriate",
    },
)</code></code></pre><p>The result includes the selected option, a probability distribution over the options, and confidence</p><p>Do not design a closed menu when reality is open</p><p>If the options might be incomplete, include &#8216;none&#8217;, &#8216;other&#8217;, or &#8216;escalate&#8217;</p><p>Otherwise probability mass is forced onto the least-wrong answer</p><h2><strong>Score</strong></h2><p>Use <strong>Score </strong>when the decision lives on an ordered rubric</p><pre><code><code>from typesafe_sdk import Score

evidence_quality = Score(
    instructions="How well does the evidence support the requested conclusion?",
    criteria=[
        "No direct support",
        "Partial support with important gaps",
        "Strong support from multiple independent sources",
    ],
)</code></code></pre><p>The output can fall between levels</p><p>That does not turn an ordinal rubric into an exact measurement</p><p><strong>A score of 1.6 is not &#8220;80% good&#8221;</strong></p><p>It is a position between descriptions you defined</p><h2><strong>Noul</strong></h2><p>Use <strong>Noul</strong> for a yes-or-no probability</p><pre><code><code>from typesafe_sdk import Noul

requires_approval = Noul(
    instructions=(
        "Would executing the proposed action publish, purchase, delete, "
        "change permissions, or represent the user externally?"
    ),
)</code></code></pre><p>A result near <strong>1.0</strong> means likely yes</p><p>A result near <strong>0.0</strong> means likely no</p><p>A result near <strong>0.5</strong> means the model cannot distinguish confidently</p><p>It does not mean <strong>medium approval risk</strong></p><p>If you need low, medium, and high risk, use <strong>Score</strong></p><div><hr></div><h1><strong>The question is part of the program</strong></h1><p>Many builders will treat Jev questions like casual prompts</p><p>That wastes the entire advantage</p><p>A production question is a decision contract</p><p>It defines what evidence matters, which outcomes exist, and how the result enters code</p><pre><code><code>DECISION CONTRACT

state fields
question instructions
option descriptions or rubric
fallback outcome
confidence thresholds
allowed action
escalation path
version</code></code></pre><p>One subtle detail matters immediately</p><p>Jev does not learn the task from your internal question ID</p><p>Calling a field <strong>safe_to_publish</strong> does not instruct the model what safe means</p><p>The actual rule must appear in the instructions and criteria</p><pre><code><code># weak
"safe_to_publish": Noul(
    instructions="Is this safe?"
)

# stronger
"safe_to_publish": Noul(
    instructions=(
        "Does the draft contain only verified claims with citations, avoid "
        "private information, and require no unresolved legal or financial approval?"
    )
)</code></code></pre><p>The key name helps your code</p><p>The instructions help the model</p><p>Confusing the two creates invisible bugs</p><div><hr></div><h1><strong>State engineering matters more than prompt decoration</strong></h1><p>Jev can only judge the state you provide</p><p>Do not send a giant conversation and expect the model to reconstruct your workflow</p><p>Give it the compact evidence required for the decision</p><pre><code><code>state = {
    "goal": "Prepare a cited briefing on three new agent tools",
    "constraints": {
        "publish": False,
        "deadline": "09:00 UTC",
        "max_sources": 12,
    },
    "completed_work": {
        "sources_collected": 7,
        "draft_exists": True,
        "fact_check_complete": False,
    },
    "evidence": [
        {"id": "s1", "kind": "official_docs", "supports": ["pricing"]},
        {"id": "s2", "kind": "launch_post", "supports": ["availability"]},
    ],
    "available_workers": ["research", "write", "fact_check", "review"],
}</code></code></pre><p>Good state is separated by function</p><pre><code><code>GOAL          what success means
FACTS         what the system knows
ARTIFACTS     what already exists
EVIDENCE      what supports the next judgment
CONSTRAINTS   what the system may not cross
OPTIONS       what can happen now</code></code></pre><p>Bad state mixes claims, instructions, old attempts, and irrelevant history into one text blob</p><p>The model may still return a valid type</p><p>It can still choose the wrong valid option</p><p>This is the most important correction to the &#8220;zero hallucination&#8221; headline</p><p>Jev cannot break the declared output schema</p><p>It can still be semantically wrong</p><p>Type safety removes one failure class</p><p>It does not remove the need for evidence, thresholds, tests, and review</p><div><hr></div><h1><strong>Ask independent questions in parallel</strong></h1><p>Most agent decisions are evaluated sequentially because LLM generation is sequential</p><p>Jev is designed to evaluate multiple typed questions against the same state in one request</p><pre><code><code>client = TypeSafeClient(model="jev-latest")

response = client.system_one(
    state=state,
    questions={
        "next_worker": Choice(
            instructions="Which available worker should act next?",
            criteria={
                "research": "Evidence gaps remain",
                "write": "Evidence is sufficient for drafting",
                "fact_check": "A draft exists but claims need verification",
                "review": "The work is complete, unclear, or consequential",
            },
        ),
        "urgency": Score(
            instructions="How urgent is the request?",
            criteria=[
                "No time pressure",
                "Time-sensitive but can wait",
                "Immediate business impact",
            ],
        ),
        "requires_approval": Noul(
            instructions="Would the next action create an external side effect?"
        ),
    },
)</code></code></pre><p>The three questions inspect one snapshot of reality</p><p>That makes the decision record easier to understand</p><pre><code><code>{
  "state_version": "run_184:step_7",
  "next_worker": "fact_check",
  "next_worker_confidence": 0.91,
  "urgency_score": 1.24,
  "approval_probability": 0.82
}</code></code></pre><p>Parallel does not mean dependent</p><p>One question cannot consume another question&#8217;s fresh answer inside the same call</p><p>If the second decision depends on a search result, perform the search first, update state, then ask again</p><p>The boundary is simple</p><pre><code><code>SAME EVIDENCE     -&gt; ask together
NEW EVIDENCE      -&gt; update state first</code></code></pre><div><hr></div><h1>Confidence is a routing signal</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Jh_f%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jh_f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Jh_f%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg" width="1200" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Jh_f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Jh_f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa800c491-ff8d-4c52-8130-11dfb69bc8b3_1200x576.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Most systems flatten probability into a label too early</p><pre><code><code>0.51 -&gt; YES
0.99 -&gt; YES</code></code></pre><p>Those answers should not receive the same authority</p><p>The probability distribution should change the route</p><pre><code><code>def route_decision(choice, confidence, consequence):
    if consequence == "irreversible":
        return "human_review"

    if confidence &gt;= 0.90 and consequence == "low":
        return choice

    if confidence &gt;= 0.70:
        return "collect_more_evidence"

    return "human_review"</code></code></pre><p>This creates three operating zones</p><h2><strong>High confidence, low consequence</strong></h2><p>Automate the branch</p><p>Examples: choose a worker, sort an internal queue, rank a shortlist</p><h2><strong>Medium confidence</strong></h2><p>Improve the state</p><p>Fetch another source</p><p>Ask a stronger model</p><p>Run a deterministic check</p><p>Narrow the options</p><h2><strong>Low confidence or high consequence</strong></h2><p>Escalate</p><p>Do not make the system repeat the same uncertain decision with the same evidence</p><p>Confidence without a different next action is decoration</p><p>Calibration only becomes useful when the harness routes uncertainty somewhere</p><div><hr></div><h1>Jev belongs inside the harness</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21x-f0%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!x-f0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21x-f0%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg" width="1200" height="576" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!x-f0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 424w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 848w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!x-f0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b939c09-c50a-464c-a333-7f58c565280e_1200x576.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The best Jev integrations do not put the model at the center of everything</p><p>They place small decision nodes at expensive or risky transitions</p><h2><strong>Before the model: route the task</strong></h2><pre><code><code>simple classification  -&gt; Jev or code
routine drafting       -&gt; fast LLM
ambiguous research     -&gt; stronger LLM
high-stakes request    -&gt; human review</code></code></pre><p>The router should know the models currently available, their capabilities, and the cost or latency budget</p><p>Do not hard-code yesterday&#8217;s model menu into a permanent prompt</p><h2><strong>Before the tool: gate the action</strong></h2><p>The LLM proposes a tool call</p><p>Jev classifies its semantic risk</p><p>Code decides whether the action can proceed</p><pre><code><code>decision = classify_tool_call(proposed_call)

if decision == "allow":
    execute(proposed_call)
elif decision == "review":
    queue_for_human(proposed_call)
else:
    block(proposed_call)</code></code></pre><p>Jev does not receive the authority to publish, purchase, delete, or change permissions</p><p>It only supplies judgment to the policy engine</p><h2><strong>After the tool: verify the outcome</strong></h2><p>A successful HTTP response is not proof that the goal was achieved</p><p>The verifier should inspect new evidence</p><pre><code><code>ACTION
create the report

EVIDENCE
file exists
required sections exist
claims have citations
output path is correct

DECISION
pass / repair / escalate</code></code></pre><p>The builder and verifier should not share a vague feeling of completion</p><p>They should share an artifact and a rubric</p><h2><strong>Around retrieval: filter and rank context</strong></h2><p>Embeddings find things that are topically close</p><p>They do not always identify evidence that is decision-relevant</p><p>A useful retrieval pipeline is</p><pre><code><code>cheap deterministic filter
        &#8595;
embedding shortlist
        &#8595;
Jev relevance score
        &#8595;
small evidence packet
        &#8595;
generative model</code></code></pre><p>The generative model receives less noise</p><p>The trace shows why each item survived</p><div><hr></div><h1><strong>Rebuild the menu after every action</strong></h1><p>One of the strongest patterns appears in browser agents</p><p>The available actions change after every click</p><p>The decision layer should choose from what exists now, not from a static list written before the run</p><pre><code><code>controls = observe_current_page()

criteria = {
    control.id: control.semantic_description
    for control in controls
    if control.is_visible and control.is_enabled
}

question = Choice(
    instructions="Which available control best advances the current goal?",
    criteria={**criteria, "stop": "The goal is complete or no safe action exists"},
)</code></code></pre><p>This pattern generalizes beyond browsers</p><p>Workers come online and go offline</p><p>Sources become stale</p><p>Budgets shrink</p><p>Files appear</p><p>Permissions change</p><p>Queues fill</p><p>A decision model choosing from a stale menu is not making a bad inference</p><p>It is operating on an invalid graph</p><p>For very large option sets, pre-filter obvious mismatches in code</p><p>Then score the survivors</p><p>Then make one explicit <strong>Choice</strong></p><p>Use Jev for semantic ambiguity</p><p>Do not make it rediscover facts your program already knows</p><div><hr></div><h1><strong>What Jev should not do</strong></h1><p>New tools are usually overused before they are understood</p><p>Jev has clear boundaries</p><h2><strong>Do not use it to generate the artifact</strong></h2><p>If you need an explanation, email, plan, program, or report, use an LLM</p><p>Jev returns decisions, not prose</p><h2><strong>Do not use it for exact rules</strong></h2><pre><code><code># use code
if attempts &gt;= 3:
    stop()

if spend_usd &gt; budget_usd:
    block()</code></code></pre><p>Semantic judgment should not replace arithmetic, date comparison, exact strings, allowlists, or permission checks</p><h2><strong>Do not ask it to invent unknown values</strong></h2><p>Jev can choose from declared possibilities</p><p>It is not an extraction engine for arbitrary names, URLs, IDs, or numbers that are absent from the schema</p><h2><strong>Do not hide a multi-step plan inside one label</strong></h2><p>If a decision requires new evidence, run the tool that creates the evidence</p><p>Then ask the next question</p><h2><strong>Do not confuse type safety with truth</strong></h2><p>Jev can guarantee that the answer matches the declared type</p><p>It cannot guarantee that the chosen valid answer is correct</p><p>The system still needs evaluation</p><div><hr></div><h1><strong>The production rollout</strong></h1><p>Do not replace every decision at once</p><p>Start with one high-volume, low-consequence branch where the correct answer can be labeled later</p><pre><code><code>GOOD FIRST DECISION
route an internal support ticket

BAD FIRST DECISION
approve a payment with no human review</code></code></pre><h2><strong>Step 1: define the contract</strong></h2><p>Write the state fields, options, criteria, fallback, threshold, and allowed action before integrating the model</p><h2><strong>Step 2: build a representative set</strong></h2><p>Include normal examples, ambiguous cases, missing evidence, adversarial language, and cases where no option fits</p><h2><strong>Step 3: run in shadow mode</strong></h2><p>Let the existing production path make the real decision</p><p>Log what Jev would have chosen</p><pre><code><code>{
  "decision_contract": "ticket-router@3",
  "state_hash": "b476...",
  "jev_model": "jev-latest",
  "answer": "technical",
  "confidence": 0.87,
  "production_answer": "technical",
  "human_label": null,
  "action_taken": false
}</code></code></pre><h2><strong>Step 4: plot accuracy against confidence</strong></h2><p>Do not ask only whether the average answer is correct</p><p>Ask whether high-confidence answers are actually more reliable than low-confidence answers in your workload</p><p>That determines where automation is safe</p><h2><strong>Step 5: automate one branch</strong></h2><p>Start with the safest outcome</p><p>Keep uncertain, rare, or consequential cases behind the existing review path</p><h2><strong>Step 6: monitor drift</strong></h2><p>Your options, users, tools, and language change</p><p>Version the decision contract separately from application code</p><pre><code><code>router@1  broad options
router@2  adds none-of-the-above
router@3  separates billing from account access</code></code></pre><p>A semantic decision is production logic</p><p>Treat changes like code changes</p><p>Review them</p><p>Test them</p><p>Roll them back when necessary</p><div><hr></div><h1><strong>Failure modes that look like model problems</strong></h1><h2><strong>The state contains conclusions instead of evidence</strong></h2><pre><code><code>BAD
the research is probably enough

BETTER
7 sources collected &#183; 3 official &#183; pricing verified &#183; security claim unresolved</code></code></pre><p>The model should judge the evidence</p><p>It should not inherit the previous agent&#8217;s confidence as a fact</p><h2><strong>The menu has no escape hatch</strong></h2><p>The answer is forced into one of several wrong options</p><p>Add <strong>other,</strong> <strong>none</strong>, <strong>stop</strong>, or <strong>review</strong></p><h2><strong>One threshold controls every consequence</strong></h2><p>Routing an internal note and publishing a public statement should not share an automation threshold</p><p>Thresholds belong to the action class, not only the model output</p><h2><strong>The option list is stale</strong></h2><p>The selected worker is unavailable</p><p>The chosen button disappeared</p><p>The cited source changed</p><p>Rebuild the choice set from live state</p><h2><strong>The same state is retried</strong></h2><p>Nothing new was learned</p><p>The model is asked again anyway</p><p>Retries should spend new evidence, not just more tokens</p><h2><strong>The decision has no receipt</strong></h2><p>The system stores only the winning label</p><p>Keep the contract version, state reference, full distribution, threshold, route, and resulting action</p><h2><strong>The policy lives inside the classifier</strong></h2><p>The question says what should be allowed</p><p>The code blindly executes the answer</p><p>This turns probabilistic judgment into unbounded authority</p><p>The safe order is</p><pre><code><code>JEV JUDGES
CODE CHECKS POLICY
TOOL EXECUTES
TRACE RECORDS</code></code></pre><div><hr></div><h1><strong>The Jev engineering playbook</strong></h1><p>Use this sequence for the first integration</p><pre><code><code>01  Map the agent loop
02  Mark every hidden yes / no / route / score decision
03  Keep exact rules in code
04  Keep open-ended creation in the LLM
05  Choose one repeated semantic decision for Jev
06  Define state, rubric, options, and escape hatch
07  Ask independent questions in parallel
08  Route confidence into auto / improve / human paths
09  Run shadow mode and measure calibration
10  Automate the safest branch first</code></code></pre><p>Then expand one boundary at a time</p><pre><code><code>FIRST
internal routing

THEN
retrieval filtering
completion verification
model selection
low-risk tool gating

LATER
consequential actions with explicit policy and approval</code></code></pre><p>The point is not to maximize the number of Jev calls</p><p>It is to remove expensive generative calls from places where generation was never needed</p><div><hr></div><h1><strong>The economics are downstream</strong></h1><p>TypeSafe&#8217;s published price makes the decision itself extremely cheap</p><p>But cost per call is not the metric that matters</p><p>Cost per completed task is</p><p>A cheap router that sends a worker down the wrong branch can create more cost than it saves</p><p>A fast verifier that passes weak work can create more latency later</p><p>Track the whole system</p><pre><code><code>decision latency
decision cost
branch accuracy
downstream tool cost
recovery cost
human review rate
completed-task rate</code></code></pre><p>This is where Jev engineering becomes more important than Jev itself</p><p>The model provides a new primitive</p><p>The graph decides where that primitive sits</p><p>The loop decides what happens after uncertainty</p><p>The harness decides what the system is allowed to do</p><p>The trace tells you whether the architecture worked</p><div><hr></div><h1><strong>The Jev launch checklist</strong></h1><p>Before a Jev decision controls a production branch, ask</p><pre><code><code>[ ] Is this truly a semantic decision rather than generation or an exact rule
[ ] Is the state compact, current, and evidence-based
[ ] Are the instructions explicit instead of hidden in the question ID
[ ] Does every Choice include an escape hatch when the menu may be incomplete
[ ] Are Score levels ordered descriptions rather than fake measurements
[ ] Is a Noul probability interpreted as yes / no uncertainty
[ ] Are independent questions batched against the same state
[ ] Are dependent questions separated by a state update
[ ] Does confidence change the route
[ ] Are thresholds specific to the consequence of the action
[ ] Does code retain authority over permissions, budgets, and side effects
[ ] Is the decision contract versioned
[ ] Is the full distribution logged with the resulting action
[ ] Has the decision run in shadow mode on representative examples
[ ] Can the system escalate when no safe option exists
[ ] Does every retry add new evidence</code></code></pre><p>If several answers are no, the system is not ready for more automation</p><p>It is ready for a better decision contract</p><div><hr></div><h1><strong>The real shift</strong></h1><p>Jev is not a replacement for the LLM</p><p>It is a missing layer beside it</p><pre><code><code>LLM
turns context into new work

JEV
turns state into typed judgment

CODE
turns judgment into controlled action</code></code></pre><p>Most builders will continue asking one expensive model to generate, classify, route, verify, authorize, and explain</p><p>Their agents will spend frontier-model time on decisions that never needed a sentence</p><p>The better stack is smaller and more explicit</p><p>Use the LLM where open-ended intelligence creates value</p><p>Use Jev where software needs a fast semantic branch</p><p>Use code where the rule cannot be negotiable</p><p>That is Jev engineering</p><p>Not a smarter prompt</p><p>A better boundary between intelligence and execution</p><div><hr></div><h1><strong>If you read this far</strong></h1><p><strong>-&gt; Join my <a href="iframe.php?url=https%3A%2F%2Ft.me%2F%2BqqS3Qn-x1305ZmUy">Telegram</a></strong></p><p><strong>-&gt; Bookmark this article before you add another LLM call to your agent loop</strong></p><p><strong>-&gt; Follow <a href="iframe.php?url=https%3A%2F%2Fx.com%2F%400xwhrrari">@0xwhrrari</a></strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3F"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Graph Engineering: How to Build AI Agent Systems That Don't Break at Scale]]></title><description><![CDATA[Most builders still design AI agents as a straight line]]></description><link>https://whrrari.substack.com/p/graph-engineering-how-to-build-ai</link><guid isPermaLink="false">https://whrrari.substack.com/p/graph-engineering-how-to-build-ai</guid><dc:creator><![CDATA[rari]]></dc:creator><pubDate>Wed, 12 Aug 2026 23:09:30 GMT</pubDate><enclosure url="iframe.php?url=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1f0c0c0-cffc-4c9c-913c-cda63215e77f_1200x630.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading rari's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>Most builders still design AI agents as a straight line</p><p>Research first</p><p>Write second</p><p>Review third</p><p>Ship last</p><p>Each step waits for the one before it, even when half of them never needed the previous result</p><p>The system does not branch</p><p>It does not parallelize</p><p>It does not know how to recover</p><p>It just keeps feeding one context window until the agent gets slow, confused, or expensive</p><p>The problem is no longer the prompt</p><p>The problem is the shape of the work</p><p>That is what graph engineering fixes</p><blockquote><p><strong><span>I publish practical breakdowns of AI agents, workflows, and production systems on Substack</span></strong></p><p><strong><a href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3Fnext%3Dhttps%253A%252F%252Fsubstack.com%252F%2540whrrari%252Fnotes%26amp%3Butm_source%3Dprofile-page%26amp%3Butm_medium%3Dweb%26amp%3Butm_campaign%3Dsubstack_profile%26amp%3Bjust_signed_up%3Dtrue"><span>Join the newsletter here</span></a></strong></p></blockquote><h2>What graph engineering actually means</h2><p>Graph engineering is the practice of turning an agentic workflow into an explicit execution map</p><p>Instead of hiding every decision inside one model loop, you define the system as nodes and edges</p><pre><code><code>NODE   = one bounded unit of work
EDGE   = a real dependency between two nodes
STATE  = the data that survives between nodes
ROUTER = the rule that selects the next edge
GATE   = the check that decides whether work can continue</code></code></pre><p>A node can be an agent, a tool call, a deterministic function, a verifier, or a human approval step</p><p>An edge says what is allowed to run next and what data crosses the boundary</p><p>The graph decides which loops run, in what order, with which branches, joins, and recovery paths</p><blockquote><p><strong><span>A loop helps one agent improve its work A graph coordinates many loops into one system</span></strong></p></blockquote><h2>1. Stop treating every &#8220;and then&#8221; as a dependency</h2><p>Most agent workflows are linear because that is how people write instructions</p><p>Do A, then B, then C</p><p>But sequence is not the same as dependency</p><p>If B does not consume A&#8217;s output, there is no reason for B to wait</p><pre><code><code>BAD

collect market data -&gt; inspect repository -&gt; check competitor pricing

BETTER

                 -&gt; collect market data ---------
USER REQUEST     -&gt; inspect repository ----------&gt; SYNTHESIZE
                 -&gt; check competitor pricing ----</code></code></pre><p>The first question in graph engineering is simple</p><blockquote><p><strong><span>Does the next step actually read the previous step&#8217;s output</span></strong></p></blockquote><p>If the answer is no, cut the edge</p><p>That single change usually turns a slow chain into a fast parallel graph</p><h2>2. Give every node a contract</h2><p>A node you cannot describe precisely is a node you cannot route, test, or replace</p><p>Every useful node needs four things</p><ul><li><p>One job</p></li><li><p>Explicit input</p></li><li><p>Structured output</p></li><li><p>A clear failure state</p></li></ul><pre><code><code>{
  "node": "source_researcher",
  "input": {
    "topic": "string",
    "source_type": "primary"
  },
  "output": {
    "claim": "string",
    "source_url": "string",
    "confidence": "high | medium | low"
  },
  "failure": "no_primary_source_found"
}</code></code></pre><p>Free text forces the next node to guess what happened</p><p>Structured output turns a model response into something the graph can trust</p><p>This also makes nodes replaceable</p><p>You can swap the model, prompt, or tool without rebuilding the entire system as long as the contract stays the same</p><h2>3. Treat edges as data contracts, not arrows</h2><p>An edge should not mean &#8220;B comes after A&#8221;</p><p>It should mean &#8220;A produced data that B is allowed to consume&#8221;</p><p>That distinction matters because most workflow plumbing does not need another model call</p><p>Flattening arrays, removing duplicates, filtering nulls, checking a status, and joining records are deterministic operations</p><pre><code><code>const usable = results
  .filter(Boolean)
  .flatMap(result =&gt; result.items)

const unique = [...new Map(
  usable.map(item =&gt; [item.source_url, item])
).values()]</code></code></pre><p>No agent is needed here</p><p>Save model calls for judgment</p><p>Use code for plumbing</p><blockquote><p><strong><span>A graph where every edge is another agent is paying tokens for its own wiring</span></strong></p></blockquote><h2>4. Learn the four shapes behind almost every agent graph</h2><p>You do not need fifty patterns</p><p>Most production graphs are combinations of four shapes</p><p><strong><span>The chain</span></strong></p><pre><code><code>A -&gt; B -&gt; C</code></code></pre><p>Use it when every step genuinely requires the previous output</p><p>It is simple, predictable, and often slower than necessary</p><p><strong><span>The diamond</span></strong></p><pre><code><code>        -&gt; B1 -
A -&gt;    -&gt; B2 --&gt; C
        -&gt; B3 -</code></code></pre><p>Split one job into independent branches, run them together, then merge the results</p><p>This is the workhorse for research, code review, due diligence, and market scans</p><p><strong><span>The router</span></strong></p><pre><code><code>             -&gt; QUICK PATH
CLASSIFY  ---
             -&gt; FULL AUDIT</code></code></pre><p>Inspect state and choose only the path the task needs</p><p>Small work stays cheap</p><p>Risky work gets a deeper graph</p><p><strong><span>The controlled cycle</span></strong></p><pre><code><code>WORK -&gt; VERIFY -&gt; PASS -&gt; EXIT
          |
          -&gt; FAIL -&gt; FEEDBACK -&gt; WORK</code></code></pre><p>Repeat only when evidence says the result is incomplete</p><p>Every cycle needs a hard stop, a budget, and a convergence rule</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%210TSU%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0TSU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%210TSU%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg" width="680" height="340" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:340,&quot;width&quot;:680,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!0TSU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!0TSU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00e5ec11-4aa8-480d-bec3-59e77929937a_680x340.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>5. Fan out independent work, then join it deliberately</h2><p>Parallelism is the easiest graph advantage to understand and the easiest one to abuse</p><p>If five nodes are independent, run them together</p><pre><code><code>const settled = await Promise.allSettled(
  sources.map(source =&gt; researchNode(source))
)

const findings = settled
  .filter(result =&gt; result.status === "fulfilled")
  .map(result =&gt; result.value)</code></code></pre><p>One failed branch should not destroy the other four</p><p>But do not place a barrier after every stage</p><p>A join is worth the wait only when the next node needs the complete set</p><p>Examples include cross-source deduplication, ranking all candidates, comparing alternatives, or deciding whether coverage is complete</p><p>If each item can continue independently, keep the graph streaming</p><blockquote><p><strong><span>Parallel is not automatically fastYour topology decides where the system waits</span></strong></p></blockquote><h2>6. Make routing inspectable</h2><p>The model can make a judgment</p><p>The graph should enforce what that judgment is allowed to trigger</p><pre><code><code>const decision = await classifyRisk(change)

switch (decision.severity) {
  case "low":
    return quickReview(change)

  case "high":
    return fullParallelAudit(change)

  default:
    return humanReview(change)
}</code></code></pre><p>The classifier is probabilistic</p><p>The allowed routes are deterministic</p><p>This gives you the model&#8217;s flexibility without giving it unlimited control over the system</p><p>OpenAI&#8217;s visual Agent Builder makes this shift obvious: agent behavior is increasingly designed as an inspectable workflow instead of a hidden chain of prompts</p><div class="captioned-image-container"><figure><div class="image-link image2" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ddux!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Ddux%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg" width="48" height="48" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:48,&quot;width&quot;:48,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Square profile picture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Square profile picture" title="Square profile picture" srcset="https://substackcdn.com/image/fetch/$s_!Ddux!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Ddux!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4514d7cb-f61b-4cfc-b982-5a6b54d7d0fe_48x48.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div></div></div></div></figure></div><p>OpenAI Developers</p><p>Introducing AgentKit&#8212;build, deploy, and optimize agentic workflows.</p><p> ChatKit: Embeddable, customizable chat UI</p><p> Agent Builder: WYSIWYG workflow creator</p><p> Guardrails: Safety screening for inputs/outputs</p><p> Evals: Datasets, trace grading, auto-prompt optimization</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21foXX%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!foXX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 424w, https://substackcdn.com/image/fetch/$s_!foXX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 848w, https://substackcdn.com/image/fetch/$s_!foXX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!foXX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21foXX%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg" width="1200" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:675,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!foXX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 424w, https://substackcdn.com/image/fetch/$s_!foXX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 848w, https://substackcdn.com/image/fetch/$s_!foXX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!foXX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27e8d4ff-4e71-4ee4-8ad7-5efb4e39c1da_1200x675.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>7. Put verification on the edge</h2><p>The highest-leverage node in a graph is often the one that produces nothing new</p><p>Its job is to stop weak work from moving downstream</p><p>A verifier can check</p><ul><li><p>Whether every claim has a source</p></li><li><p>Whether the cited source supports the claim</p></li><li><p>Whether code passes tests</p></li><li><p>Whether the result matches the requested schema</p></li><li><p>Whether another independent path reaches the same conclusion</p></li></ul><pre><code><code>GENERATOR -&gt; VERIFIER -&gt; PASS -&gt; SYNTHESIZER
                 |
                 -&gt; FAIL -&gt; REPAIR</code></code></pre><p>Do not ask the same agent to generate, approve, and publish its own work in one context</p><p>Separate the roles</p><p>Separate the prompts</p><p>Separate the failure boundaries</p><p>Anthropic&#8217;s production research system follows this logic at a larger scale: a lead agent coordinates parallel subagents, findings are synthesized, and a dedicated citation stage attaches evidence before the result reaches the user</p><div class="captioned-image-container"><figure><div class="image-link image2" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rYec!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 424w, https://substackcdn.com/image/fetch/$s_!rYec!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 848w, https://substackcdn.com/image/fetch/$s_!rYec!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!rYec!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21rYec%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg" width="48" height="48" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:48,&quot;width&quot;:48,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!rYec!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 424w, https://substackcdn.com/image/fetch/$s_!rYec!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 848w, https://substackcdn.com/image/fetch/$s_!rYec!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!rYec!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd02682a0-5707-4673-8334-88869f1844a1_48x48.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div></div></div></div></figure></div><p>Claude</p><p>Introducing Claude Managed Agents: everything you need to build and deploy agents at scale. It pairs an agent harness tuned for performance with production infrastructure, so you can go from prototype to launch in days. Now in public beta on the Claude Platform.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%218G36%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8G36!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8G36!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8G36!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8G36!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%218G36%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg" width="1200" height="675" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:675,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8G36!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8G36!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8G36!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8G36!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a58fe28-3431-4ae7-9919-0c46a0e28b7e_1200x675.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21hxAP%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hxAP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21hxAP%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg" width="680" height="340" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:340,&quot;width&quot;:680,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!hxAP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!hxAP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F074fffba-f585-4694-9aab-abea8adcad27_680x340.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>8. State is the part most diagrams hide</h2><p>Boxes and arrows look clean until the system has to resume after a crash</p><p>A production graph needs durable state</p><pre><code><code>task_id
current_node
completed_nodes
artifacts
decisions
evidence
budgets
retry_counts
human_approvals</code></code></pre><p>Do not move giant transcripts between nodes</p><p>Move references to artifacts</p><p>A research node should store its report and return a path, ID, or structured summary</p><p>A reviewer should read the artifact directly instead of receiving a compressed retelling through three agents</p><p>This reduces context loss and makes every transition auditable</p><p>The graph should be able to answer three questions at any moment</p><pre><code><code>What has already happened
Why did the system choose this route
Where can execution safely resume</code></code></pre><p>If it cannot answer them, the graph is still a demo</p><h2>9. Add cycles only when they converge</h2><p>A cycle is useful when the amount of work is unknown in advance</p><p>Bug discovery, deep research, and iterative repair are good examples</p><p>But &#8220;repeat until good&#8221; is not a stop condition</p><p>Use measurable convergence</p><pre><code><code>let dryRounds = 0
let iteration = 0
const seen = new Set()

while (dryRounds &lt; 2 &amp;&amp; iteration &lt; 6) {
  const findings = await discover()
  const fresh = findings.filter(item =&gt; !seen.has(item.key))

  fresh.forEach(item =&gt; seen.add(item.key))
  dryRounds = fresh.length === 0 ? dryRounds + 1 : 0
  iteration += 1
}</code></code></pre><p>Notice what the system remembers</p><p>It deduplicates against everything already seen, not only the findings that passed verification</p><p>Otherwise rejected ideas keep returning and the graph pays to rediscover the same dead ends forever</p><p><strong><span>Every controlled cycle needs</span></strong></p><ul><li><p>A completion test</p></li><li><p>A maximum number of rounds</p></li><li><p>A token or cost budget</p></li><li><p>A record of previous attempts</p></li><li><p>An escalation path when convergence fails</p></li></ul><h2>10. Design failure as a local event</h2><p>In a chain, one broken step can freeze the whole workflow</p><p>In a graph, failure should stay inside the smallest possible boundary</p><p>Each node needs a policy</p><pre><code><code>RETRY      transient tool or network failure
FALLBACK   preferred model or source unavailable
SKIP       optional branch failed
REPAIR     output failed validation
ESCALATE   risk or uncertainty crossed a threshold
STOP       budget, safety, or permission boundary reached</code></code></pre><p>Checkpoint after expensive nodes</p><p>Make writes idempotent so a retry does not duplicate side effects</p><p>Give parallel workers isolated workspaces when they modify files</p><p>Record every routing decision with the state that produced it</p><p>Reliability does not come from hoping every node succeeds</p><p>It comes from deciding what the graph does when one does not</p><h2>11. Topology is your cost model</h2><p>A graph is not automatically cheaper than one agent</p><p>It can burn far more tokens if every task spawns a fleet</p><p>The shape controls both latency and cost</p><p>Use cheaper models for bounded extraction, classification, and formatting</p><p>Use stronger models for decomposition, synthesis, and difficult verification</p><p>Route simple tasks through a short path</p><p>Reserve the full graph for work that earns it</p><pre><code><code>SIMPLE REQUEST -&gt; SMALL MODEL -&gt; QUICK CHECK -&gt; DONE

COMPLEX REQUEST -&gt; PLANNER -&gt; PARALLEL SPECIALISTS
                              -&gt; VERIFIERS
                              -&gt; STRONG SYNTHESIZER
                              -&gt; HUMAN GATE</code></code></pre><p>Anthropic reports that multi-agent research can materially outperform a single agent on breadth-first work, but it also uses far more tokens</p><p>That is the tradeoff</p><p>Graph engineering is not about maximizing the number of agents</p><p>It is about spending coordination only where parallelism, specialization, or independent verification creates enough value</p><h2>12. A production graph for research and publishing</h2><p>Here is a practical graph for turning one idea into a cited article</p><pre><code><code>                                  -&gt; COMPANY SOURCES -----
TOPIC -&gt; SCOPE -&gt; DECOMPOSE       -&gt; PAPERS --------------&gt; DEDUPE
                                  -&gt; EXPERT POSTS ---------
                                                             |
                                                             v
                PUBLISH &lt;- HUMAN GATE &lt;- FINAL CHECK &lt;- DRAFT
                                                |          ^
                                                -&gt; FAIL -&gt; REPAIR</code></code></pre><p><strong><span>The system works like this</span></strong></p><ol><li><p>The scope node defines the question, audience, and completion criteria</p></li><li><p>The decomposition node creates independent research lanes</p></li><li><p>Research nodes run in parallel with separate contexts</p></li><li><p>Deterministic code removes duplicates and normalizes sources</p></li><li><p>The draft node writes from structured evidence</p></li><li><p>The checker validates claims, citations, style, and missing sections</p></li><li><p>Failed checks route only the relevant section back to repair</p></li><li><p>A human approves the final artifact before publishing</p></li></ol><p>This is not one giant agent pretending to be a team</p><p>It is a system with explicit ownership, state, and authority</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%215LhH%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5LhH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%215LhH%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg" width="680" height="340" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:340,&quot;width&quot;:680,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image" title="Image" srcset="https://substackcdn.com/image/fetch/$s_!5LhH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 424w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 848w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!5LhH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2baa1ae4-228f-439c-9c45-944892066dcf_680x340.jpeg 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When a graph is the wrong answer</p><p>Do not turn every prompt into an architecture diagram</p><p>Keep one agent in one loop when</p><ul><li><p>The task is short</p></li><li><p>One context can hold all relevant information</p></li><li><p>There are no independent branches</p></li><li><p>Failure is cheap</p></li><li><p>A human can review the final result quickly</p></li></ul><p>Move to a graph when</p><ul><li><p>Work can run in parallel</p></li><li><p>Different nodes need different tools or permissions</p></li><li><p>Outputs require independent verification</p></li><li><p>The task must resume after interruption</p></li><li><p>Several loops need shared state</p></li><li><p>Cost and authority must be controlled by route</p></li></ul><p>Start with one loop</p><p>Draw a graph only when the dependencies force you to</p><h2>The graph engineering checklist</h2><p>Before you ship, ask</p><pre><code><code>[ ] Does every edge carry real data or authority
[ ] Does every node have one bounded job
[ ] Are inputs and outputs structured
[ ] Can independent nodes run in parallel
[ ] Are joins placed only where the full set is required
[ ] Are important results verified before moving downstream
[ ] Can failures be retried without duplicating side effects
[ ] Can the graph resume from a checkpoint
[ ] Does every cycle have a hard stop and budget
[ ] Can a human interrupt high-risk paths
[ ] Can you explain why every route was selected
[ ] Is the graph simpler than the problem it solves</code></code></pre><p>If the answer to the last question is no, delete nodes</p><h2>The real shift</h2><p>Prompt engineering improves the instruction</p><p>Context engineering controls what the model sees</p><p>Harness engineering builds the environment around the model</p><p>Loop engineering makes one unit of work improve through feedback</p><p>Graph engineering coordinates the entire job</p><pre><code><code>PROMPT -&gt; CONTEXT -&gt; HARNESS -&gt; LOOP -&gt; GRAPH
message    memory     machine    run     coordination</code></code></pre><p>The model is only one node</p><p>The product is the system around it</p><blockquote><p>A prompter asks the agent to do more An architect redesigns the graph so the system can do more safely</p></blockquote><p>For shorter notes, new tools, and AI systems I am testing</p><p><strong><a href="iframe.php?url=https%3A%2F%2Ft.me%2F%2BqqS3Qn-x1305ZmUy"><span>Join my Telegram</span></a></strong></p><p>For deeper breakdowns delivered directly</p><p><strong><a href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3Fnext%3Dhttps%253A%252F%252Fsubstack.com%252F%2540whrrari%252Fnotes%26amp%3Butm_source%3Dprofile-page%26amp%3Butm_medium%3Dweb%26amp%3Butm_campaign%3Dsubstack_profile%26amp%3Bjust_signed_up%3Dtrue"><span>Subscribe to my Substack</span></a></strong></p><h2>If you read this far</h2><p><strong><span>Bookmark the article so you can use the patterns later</span></strong></p><p><strong><span>Follow</span></strong></p><p><strong><a href="iframe.php?url=https%3A%2F%2Fx.com%2F%400xwhrrari"><span>@0xwhrrari</span></a></strong></p><p><strong><span> for more practical AI systems</span></strong></p><p>And send this to a builder who is still forcing every agent through one long chain</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading rari's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[The Three Layers Behind Reliable AI Agents]]></title><description><![CDATA[How harnesses, feedback loops and execution graphs solve three different agent failures]]></description><link>https://whrrari.substack.com/p/the-three-layers-behind-reliable</link><guid isPermaLink="false">https://whrrari.substack.com/p/the-three-layers-behind-reliable</guid><dc:creator><![CDATA[rari]]></dc:creator><pubDate>Thu, 30 Jul 2026 20:22:28 GMT</pubDate><enclosure url="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Cy-K%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3F"><span>Subscribe now</span></a></p><p>Most agent systems do not fail because the model is too weak</p><p>They fail because the system around the model was never designed as a system</p><p>The tools are unreliable</p><p>The state disappears between runs</p><p>The agent retries without learning anything</p><p>The workflow branches in ways nobody can inspect</p><p>Then every failure gets blamed on the model</p><p>That is the wrong diagnosis</p><p>There are three different engineering layers behind a serious agent:</p><ul><li><p>the harness gives the model a place to work</p></li><li><p>the loop gives the work a feedback cycle</p></li><li><p>the graph gives the process an explicit route</p></li></ul><p>They overlap</p><p>They can contain one another</p><p>But they solve different problems</p><blockquote><p>A model decides</p><p>A harness lets it act</p><p>A loop makes it prove the result</p><p>A graph controls what is allowed to happen next</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Cy-K%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cy-K!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 424w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 848w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21Cy-K%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png" width="1456" height="582" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:582,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:343617,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://whrrari.substack.com/i/209154469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Cy-K!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 424w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 848w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 1272w, https://substackcdn.com/image/fetch/$s_!Cy-K!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fce6bbc84-7882-41f5-b1af-e96a3b3ea2a8_1500x600.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><div><hr></div><h2>The 30-second version</h2><p><strong>Harness engineering</strong> builds the operating environment around the model</p><p>Tools, memory, files, permissions, sandboxes, routing, checkpoints, traces and human approvals all live here</p><p><strong>Loop engineering</strong> designs repeated work and feedback</p><p>The agent produces something, checks it against evidence, receives a useful failure signal and tries again under a bounded rule</p><p><strong>Graph engineering</strong> makes control flow explicit</p><p>It defines the nodes, branches, joins, parallel work, legal cycles, state transitions and exit paths</p><p>The easiest way to remember the difference is:</p><pre><code><code>HARNESS = ENVIRONMENT
LOOP    = FEEDBACK
GRAPH   = FLOW</code></code></pre><p>This distinction matters as soon as an agent leaves a demo and starts touching real files, APIs, customers, money or production code</p><div><hr></div><h2>Why people keep mixing them together</h2><p>All three layers sit around the same model</p><p>All three affect reliability</p><p>All three may include something that looks like a loop</p><p>And in a small prototype, all three are usually buried inside one script</p><p>That makes them feel interchangeable</p><p>They are not</p><p>Consider a basic tool-using agent</p><pre><code><code>ask model
receive tool call
run tool
return observation
ask model again
stop when finished</code></code></pre><p>That small cycle is part of the runtime</p><p>But the tool definitions, filesystem and state store belong to the harness</p><p>The test-and-retry policy is a loop design decision</p><p>The choice between researcher, reviewer and publisher is a graph design decision</p><p>One piece of software can contain all three layers at once</p><p>The cleanest architecture starts by naming them separately</p><div><hr></div><h2>Layer 1: Harness Engineering</h2><p>A raw model can transform input into output</p><p>It cannot independently maintain project state, run a test suite, inspect a browser, write files safely, enforce permissions or resume tomorrow where it stopped today</p><p>The harness supplies those capabilities</p><p>The simplest definition is:</p><blockquote><p>The model is the intelligence</p><p>The harness is the machinery that makes that intelligence useful&lt;br&gt;</p></blockquote><p>Remove the model from your architecture diagram</p><p>Everything still visible is probably part of the harness</p><p>This is the production shift Boris Cherny keeps pointing at through Claude Code: hooks, scheduled runs, isolated worktrees, custom agents and parallel execution are not prompt tricks</p><p>They are harness primitives</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/bcherny/status/2038454336355999749&quot;,&quot;full_text&quot;:&quot;I wanted to share a bunch of my favorite hidden and under-utilized features in Claude Code. I'll focus on the ones I use the most.\n\nHere goes.&quot;,&quot;username&quot;:&quot;bcherny&quot;,&quot;name&quot;:&quot;Boris Cherny&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1902044548936953856/J2jeik0t_normal.jpg&quot;,&quot;date&quot;:&quot;2026-03-30T03:12:41.000Z&quot;,&quot;photos&quot;:[],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:543,&quot;retweet_count&quot;:2497,&quot;like_count&quot;:23088,&quot;impression_count&quot;:3967361,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><p></p><h3>What belongs inside a serious harness</h3><p><strong>Context</strong></p><ul><li><p>system instructions</p></li><li><p>retrieved knowledge</p></li><li><p>conversation state</p></li><li><p>task policies</p></li><li><p>skills and operating procedures</p></li></ul><p><strong>Action surfaces</strong></p><ul><li><p>APIs</p></li><li><p>browser control</p></li><li><p>shell and code execution</p></li><li><p>databases</p></li><li><p>MCP tools</p></li><li><p>specialist agents</p></li></ul><p><strong>Persistence</strong></p><ul><li><p>files</p></li><li><p>checkpoints</p></li><li><p>session state</p></li><li><p>progress logs</p></li><li><p>git history</p></li><li><p>long-term memory</p></li></ul><p><strong>Execution control</strong></p><ul><li><p>timeouts</p></li><li><p>retry limits</p></li><li><p>token and cost budgets</p></li><li><p>model routing</p></li><li><p>handoffs</p></li><li><p>approval gates</p></li></ul><p><strong>Safety</strong></p><ul><li><p>isolated environments</p></li><li><p>least-privilege permissions</p></li><li><p>allow lists</p></li><li><p>secret handling</p></li><li><p>human authorization</p></li></ul><p><strong>Observability</strong></p><ul><li><p>traces</p></li><li><p>tool inputs and outputs</p></li><li><p>state transitions</p></li><li><p>cost and latency</p></li><li><p>evaluation results</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21QOzP%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QOzP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21QOzP%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:601932,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://whrrari.substack.com/i/209154469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QOzP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!QOzP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ec485d4-9a6d-4b2e-8113-f68bad25bb3e_1500x750.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3>Where harness engineering earns its keep</h3><p>Harness work becomes critical when tasks last longer than one context window</p><p>A coding agent that works for hours cannot rely on chat history alone</p><p>It needs durable artifacts that another session can understand</p><p>A useful setup might include:</p><ul><li><p>an initializer that inspects the workspace</p></li><li><p>a progress file that explains what is done and what remains</p></li><li><p>git commits that preserve working states</p></li><li><p>checkpoints before risky actions</p></li><li><p>verification tools that produce clear evidence</p></li></ul><p>This is not a better prompt</p><p>It is a better working environment</p><p>Start with harness engineering when the agent:</p><ul><li><p>cannot access the right capability</p></li><li><p>loses progress between sessions</p></li><li><p>has permissions that are too broad</p></li><li><p>behaves differently across environments</p></li><li><p>cannot be paused, inspected or resumed</p></li><li><p>produces failures nobody can reconstruct</p></li></ul><div><hr></div><h2>Layer 2: Loop Engineering</h2><p>Every tool-using agent already has a small internal loop</p><pre><code><code>model -&gt; action -&gt; observation -&gt; model</code></code></pre><p>Loop engineering begins when you intentionally design the cycles around that behavior</p><p>The goal is not to make the agent repeat itself forever</p><p>The goal is to turn a one-shot attempt into a managed process</p><h3>The verification loop</h3><p>The most useful outer loop is simple</p><pre><code><code>BUILD
  &#8595;
CHECK AGAINST EVIDENCE
  &#8595;
PASS? &#9472;&#9472; yes &#9472;&#9472;&gt; STOP
  &#9474;
  no
  &#8595;
RETURN SPECIFIC FEEDBACK
  &#8595;
RETRY WITH A LIMIT</code></code></pre><p>The check may be deterministic:</p><ul><li><p>tests pass</p></li><li><p>schema validates</p></li><li><p>links resolve</p></li><li><p>numbers reconcile</p></li><li><p>files compile</p></li></ul><p>Or it may require a reviewer:</p><ul><li><p>the argument is complete</p></li><li><p>the tone matches the audience</p></li><li><p>the evidence supports the conclusion</p></li><li><p>the change is scoped correctly</p></li></ul><p>The rule is the same</p><p>Do not loop on confidence</p><p>Loop on evidence</p><p>&#8220;The agent says it is finished&#8221; is not proof</p><p>&#8220;The tests pass, the sources resolve and the reviewer approved the diff&#8221; is proof</p><p>The leverage comes from building the cycle once and letting the system run it for you</p><p>Claude&#8217;s scheduled tasks are the visible product version of the same shift: define recurring work once and let the system re-enter it without another manual prompt</p><p>Scheduling is only the trigger</p><p>The checks, feedback and exit condition are what turn the recurring task into an engineered loop</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/claudeai/status/2026720870631354429&quot;,&quot;full_text&quot;:&quot;New in Cowork: scheduled tasks.\n\nClaude can now complete recurring tasks at specific times automatically: a morning brief, weekly spreadsheet updates, Friday team presentations. &quot;,&quot;username&quot;:&quot;claudeai&quot;,&quot;name&quot;:&quot;Claude&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/1950950107937185792/QOfEjFoJ_normal.jpg&quot;,&quot;date&quot;:&quot;2026-02-25T18:08:04.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!aqW3!,w_1028,c_limit,f_auto,q_auto:best,fl_progressive:steep/l_play_button_usfui2,w_88,e_colorize:0/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F__ss-rehost__tw-video-preview-13_2026717570380992512.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/7ucKZbAVip&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:973,&quot;retweet_count&quot;:1644,&quot;like_count&quot;:22039,&quot;impression_count&quot;:8249635,&quot;expanded_url&quot;:null,&quot;video_url&quot;:&quot;https://video.twimg.com/amplify_video/2026717570380992512/vid/avc1/1280x720/j2mey8kGwr3_xrQe.mp4&quot;,&quot;video_preview_media_key&quot;:&quot;13_2026717570380992512&quot;,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21khIW%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!khIW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!khIW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!khIW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!khIW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%21khIW%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:452450,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://whrrari.substack.com/i/209154469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!khIW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!khIW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!khIW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!khIW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F65b2e223-2882-42cf-9c38-c8bbec50acbb_1500x750.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"></figcaption></figure></div><p></p><h3>The anatomy of a useful loop</h3><p>Every production loop needs seven things</p><p><strong>1. Trigger</strong></p><p>What starts another cycle: a request, schedule, webhook, failed test, new document or evaluator result</p><p><strong>2. Goal</strong></p><p>A measurable state to reach, not &#8220;keep improving&#8221;</p><p><strong>3. State</strong></p><p>What the next attempt must know without replaying the entire history</p><p><strong>4. Action policy</strong></p><p>What the agent may change, call, delegate or spend</p><p><strong>5. Evidence</strong></p><p>Tests, citations, diffs, metrics, schemas or human review</p><p><strong>6. Feedback</strong></p><p>A compact explanation of what failed and what must change</p><p><strong>7. Stopping rule</strong></p><p>Success, maximum attempts, budget exhaustion, timeout, hard error or human escalation</p><h3>Loops can stack</h3><p>The agent loop performs the work</p><p>The verification loop checks the work</p><p>An event loop wakes the system when new work arrives</p><p>An improvement loop studies production traces and changes the harness itself</p><pre><code><code>EVENT LOOP
&#9492;&#9472;&#9472; VERIFICATION LOOP
    &#9492;&#9472;&#9472; AGENT LOOP

TRACE IMPROVEMENT LOOP
&#9492;&#9472;&#9472; updates prompts, tools, policies and graders</code></code></pre><p>This is why loop engineering is larger than prompt engineering</p><p>A prompt defines what should happen during one model call</p><p>A loop defines what the system does after that call</p><p>The cost is obvious</p><p>Every retry, grader and reviewer adds latency and spend</p><p>Add a loop when the expected cost of failure is higher than the cost of verification</p><div><hr></div><h2>Layer 3: Graph Engineering</h2><p>Graph engineering asks a different question</p><p>Not &#8220;how should the agent work&#8221;</p><p>But &#8220;what is allowed to run next&#8221;</p><p>Work becomes nodes</p><p>Allowed transitions become edges</p><p>State moves through the graph</p><p>That structure can represent:</p><ul><li><p>fixed sequences</p></li><li><p>conditional branches</p></li><li><p>parallel fan-out</p></li><li><p>joins</p></li><li><p>bounded cycles</p></li><li><p>recovery paths</p></li><li><p>human interrupts</p></li></ul><h3>What graph engineers actually decide</h3><p><strong>Node boundaries</strong></p><p>Which work belongs in normal code, an LLM call, a specialist agent or a human review step</p><p><strong>State schema</strong></p><p>What each node may read or update and how parallel results are merged</p><p><strong>Routing conditions</strong></p><p>Which evidence moves work forward, backward, sideways or into escalation</p><p><strong>Concurrency</strong></p><p>What can run in parallel and what must wait for a join</p><p><strong>Cycles and exits</strong></p><p>Where retries are legal, how many attempts are allowed and what makes the cycle safe</p><p><strong>Durability</strong></p><p>Where execution is checkpointed and how it resumes after interruption</p><h3>When a graph is worth the ceremony</h3><p>Use a graph when the process contains meaningful branches, parallel specialists, approvals, recovery routes or stateful handoffs</p><p>Do not start with a graph only because the workflow has multiple steps</p><p>If one capable agent with three tools can solve the task, a graph may add structure without adding value</p><p>There is another failure mode</p><p>Teams formalize the workflow before they understand the work</p><p>The result is a beautiful diagram that encodes the wrong assumptions</p><p>Start with a simple harness</p><p>Study real traces</p><p>Formalize the paths that remain stable</p><p>The next step after loops is making the execution topology explicit</p><p>OpenAI packaged the same idea into Agent Builder: a visible workflow canvas for multi-agent execution with guardrails and evals around the graph</p><p></p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/OpenAIDevs/status/1975269388195631492&quot;,&quot;full_text&quot;:&quot;Introducing AgentKit&#8212;build, deploy, and optimize agentic workflows.\n\n&#128172; ChatKit: Embeddable, customizable chat UI\n&#128119; Agent Builder: WYSIWYG workflow creator\n&#128740;&#65039; Guardrails: Safety screening for inputs/outputs\n&#9878;&#65039; Evals: Datasets, trace grading, auto-prompt optimization &quot;,&quot;username&quot;:&quot;OpenAIDevs&quot;,&quot;name&quot;:&quot;OpenAI Developers&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/2022002720971096064/l3Kyt4qt_normal.jpg&quot;,&quot;date&quot;:&quot;2025-10-06T18:38:15.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!B2Fh!,w_1028,c_limit,f_auto,q_auto:best,fl_progressive:steep/l_play_button_usfui2,w_88,e_colorize:0/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F__ss-rehost__tw-video-preview-13_1975268157469470720.jpg&quot;,&quot;link_url&quot;:&quot;https://t.co/pGgNHKOvj3&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:291,&quot;retweet_count&quot;:1558,&quot;like_count&quot;:11275,&quot;impression_count&quot;:2993500,&quot;expanded_url&quot;:null,&quot;video_url&quot;:&quot;https://video.twimg.com/amplify_video/1975268157469470720/vid/avc1/1280x720/vlzzK-eSyinRLyac.mp4&quot;,&quot;video_preview_media_key&quot;:&quot;13_1975268157469470720&quot;,&quot;belowTheFold&quot;:true}" data-component-name="Twitter2ToDOM"></div><div><hr></div><p></p><h2>How all three layers work in one real system</h2><p>Imagine a research-and-publishing agent that produces a factual industry briefing</p><p>The harness provides:</p><ul><li><p>browser and search tools</p></li><li><p>source storage</p></li><li><p>a writing workspace</p></li><li><p>citation checking</p></li><li><p>permissions and approval rules</p></li><li><p>checkpoints and traces</p></li></ul><p>The graph controls the route:</p><pre><code><code>RESEARCH
   &#8595;
DRAFT
   &#8595;
FACT CHECK &#9472;&#9472; fail &#9472;&#9472;&gt; RESEARCH
   &#9474;
  pass
   &#8595;
EDITORIAL REVIEW &#9472;&#9472; fail &#9472;&#9472;&gt; DRAFT
   &#9474;
  pass
   &#8595;
HUMAN APPROVAL
   &#8595;
PUBLISH</code></code></pre><p>The loops live inside that route</p><p>The research node may search until source coverage is sufficient</p><p>The drafting node may revise until the style grader passes</p><p>The fact-check node may return exact unsupported claims instead of a vague rejection</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%210gdJ%21%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0gdJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 1456w" sizes="auto, 100vw"><img src="iframe.php?url=https%3A%2F%2Fsubstackcdn.com%2Fimage%2Ffetch%2F%24s_%210gdJ%21%2Cw_1456%2Cc_limit%2Cf_auto%2Cq_auto%3Agood%2Cfl_progressive%3Asteep%2Fhttps%253A%252F%252Fsubstack-post-media.s3.amazonaws.com%252Fpublic%252Fimages%252F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:631454,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://whrrari.substack.com/i/209154469?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0gdJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 424w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 848w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 1272w, https://substackcdn.com/image/fetch/$s_!0gdJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f8e1af1-2277-4f70-a3e5-2629b68ca2e4_1500x750.png 1456w" sizes="auto, 100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image buttonBase-GK1x3M"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg" class="icon-noB79L"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image buttonBase-GK1x3M"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2 icon-noB79L"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>The nesting is the important part</p><p>The graph runs inside the harness</p><p>The loops run inside parts of the graph</p><p>The harness supplies the tools, state and evidence those loops need</p><p>The layers overlap because real software layers overlap</p><p>They still give you three different levers when the system fails</p><div><hr></div><h2>Diagnose the failure before changing the architecture</h2><p><strong>The agent cannot access the right data safely</strong></p><p><em>Start with: Harness</em></p><p>Better tool contract, permissions, sandbox and context injection</p><p><strong>The agent forgets progress between sessions</strong></p><p><em>Start with: Harness</em></p><p>Durable state, checkpoints, progress artifacts and compaction</p><p><strong>The first attempt is close but unreliable</strong></p><p><em>Start with: Loop</em></p><p>External grader, deterministic tests, actionable feedback and bounded retry</p><p><strong>The agent continues after success or stops before proof</strong></p><p><em>Start with: Loop</em></p><p>Evidence-based terminal states and budget-aware stop rules</p><p><strong>Specialists must run in a controlled order</strong></p><p><em>Start with: Graph</em></p><p>Explicit nodes, edges, routing conditions and joins</p><p><strong>A multi-step failure is impossible to locate</strong></p><p><em>Start with: Graph + harness</em></p><p>Stateful traces aligned with nodes and transitions</p><p><strong>The process changes too quickly for a fixed diagram</strong></p><p><em>Start with: Simpler harness</em></p><p>Keep planning model-driven and delay graph formalization</p><p>This table is more useful than arguing about terminology</p><p>Find the layer that owns the failure</p><p>Fix that layer first</p><div><hr></div><h2>The expensive mistakes behind weak agent systems</h2><h3>Building the graph too early</h3><p>Do not convert an imagined business process into forty nodes before watching a strong agent perform the work</p><p>Trace first</p><p>Formalize second</p><h3>Letting the maker grade itself</h3><p>Self-review is useful but shares the same blind spots as the original attempt</p><p>Prefer deterministic checks where possible</p><p>Use an isolated reviewer context for subjective checks</p><p>Require human approval for high-impact actions</p><h3>Defining the loop as &#8220;keep trying&#8221;</h3><p>An unbounded retry is not reliability</p><p>It is a cost leak</p><p>Every cycle needs fresh evidence, a maximum attempt count and a named escalation path</p><h3>Turning the harness into a warehouse</h3><p>More tools do not automatically create a better agent</p><p>A crowded toolset increases selection errors</p><p>Noisy context increases confusion</p><p>Broad permissions increase risk</p><p>Give the agent the smallest environment that can complete the job</p><h3>Blaming the model for orchestration failures</h3><p>A stronger model cannot reliably repair stale state, broken APIs, ambiguous tool schemas or missing exit conditions</p><p>Do not upgrade the model before proving the model is the problem</p><div><hr></div><h2>A production-ready checklist</h2><h3>Harness</h3><ul><li><p>are the tools narrow, documented and observable</p></li><li><p>is state durable across sessions</p></li><li><p>are permissions least-privilege</p></li><li><p>can an operator pause, inspect and resume the run</p></li><li><p>can every important action be reconstructed from traces</p></li></ul><h3>Loop</h3><ul><li><p>what evidence proves success</p></li><li><p>what feedback is returned after failure</p></li><li><p>how many retries are allowed</p></li><li><p>what happens when the budget is exhausted</p></li><li><p>where human judgment is required</p></li></ul><h3>Graph</h3><ul><li><p>which paths must be deterministic</p></li><li><p>where can work run in parallel</p></li><li><p>what state is shared</p></li><li><p>where are the joins, approvals and recovery routes</p></li><li><p>which cycles are legal and how do they terminate</p></li></ul><h3>Evaluation</h3><ul><li><p>can the team replay real traces</p></li><li><p>can versions be compared against the same tasks</p></li><li><p>can an improvement be attributed to a specific change</p></li></ul><h3>Operations</h3><ul><li><p>are cost and latency monitored</p></li><li><p>is failure rate visible by node and tool</p></li><li><p>is human intervention measured</p></li><li><p>is task-level success measured in production</p></li></ul><div><hr></div><h2>The simplest way to remember the difference</h2><p>Harness engineering makes the model operational</p><p>Loop engineering makes the work iterative and verifiable</p><p>Graph engineering makes complex execution explicit and controllable</p><p>None replaces the others</p><p>A perfect graph cannot save an agent that loses its state</p><p>A perfect harness still wastes money if the loop has no evidence or stop rule</p><p>A strong loop becomes difficult to operate when branches, parallelism and approvals are hidden inside ad hoc code</p><p>Reliable agents appear when all three layers are designed together</p><p>And when every layer has one clear job</p><pre><code><code>ENVIRONMENT -&gt; HARNESS
FEEDBACK    -&gt; LOOP
FLOW        -&gt; GRAPH</code></code></pre><p>That is the whole framework</p><div><hr></div><h2>Sources and further reading</h2><ul><li><p><a href="iframe.php?url=https%3A%2F%2Fx.com%2Fclaudeai%2Fstatus%2F2026720870631354429">Claude scheduled tasks</a></p></li><li><p><a href="iframe.php?url=https%3A%2F%2Fopenai.com%2Findex%2Fintroducing-agentkit%2F">OpenAI AgentKit</a></p></li><li><p><a href="iframe.php?url=https%3A%2F%2Fdevelopers.openai.com%2Fapi%2Fdocs%2Fguides%2Fagents">OpenAI Agents SDK</a></p></li><li><p><a href="iframe.php?url=https%3A%2F%2Fmicrosoft.github.io%2Fautogen%2Fstable%2Fuser-guide%2Fagentchat-user-guide%2Fgraph-flow.html">AutoGen GraphFlow</a></p></li><li><p><a href="iframe.php?url=https%3A%2F%2Fresources.anthropic.com%2Fbuilding-effective-ai-agents">Building Effective AI Agents</a></p></li></ul><div><hr></div><p>If you read this far</p><p>Bookmark the article and follow <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;rari&quot;,&quot;id&quot;:530935508,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c95205f9-f551-4b35-8af6-88acf5b10068_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;615b42d1-9c1b-448f-b12d-bbad3887b2e9&quot;}" data-component-name="MentionToDOM"></span> for more practical agent engineering</p><p>Also follow <a href="iframe.php?url=https%3A%2F%2Fx.com%2F0xwhrrari">X</a> and <a href="iframe.php?url=https%3A%2F%2Ft.me%2F%2BqqS3Qn-x1305ZmUy">Telegram</a></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3F"><span>Subscribe now</span></a></p><p></p>]]></content:encoded></item><item><title><![CDATA[Loop Engineering: The AI skill every builder needs in 2026]]></title><description><![CDATA[Most people are still prompting agents manually.]]></description><link>https://whrrari.substack.com/p/loop-engineering-the-ai-skill-every</link><guid isPermaLink="false">https://whrrari.substack.com/p/loop-engineering-the-ai-skill-every</guid><dc:creator><![CDATA[rari]]></dc:creator><pubDate>Sun, 19 Jul 2026 00:06:11 GMT</pubDate><enclosure url="iframe.php?url=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F068902a4-b32b-4f2f-8480-49939732fc9c_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="iframe.php?url=https%3A%2F%2Fwhrrari.substack.com%2Fsubscribe%3F"><span>Subscribe now</span></a></p><p>Most people are still prompting agents manually.</p><p>They type one task.</p><p>Wait for one answer.</p><p>Review it themselves.</p><p>Fix the mistakes themselves.</p><p>Then prompt again.</p><p>That means the human is still the loop.</p><p>The next step is different.</p><p>You do not just prompt the agent.</p><p>You design the loop that prompts the agent, checks the result, decides the next move, and keeps running until the work passes.</p><p>That is loop engineering.</p><blockquote><p style="text-align: center;"><strong><span>&#8220;You should not be prompting coding agents anymore. You should be designing loops that prompt your agents.&#8221;</span></strong></p></blockquote><p>Then Boris Cherny, head of Claude Code at Anthropic, said the same thing differently:</p><blockquote><p style="text-align: center;"><strong><span>&#8220;I do not prompt Claude anymore. I have loops running that prompt Claude and figure out what to do. My job is to write loops.&#8221;</span></strong></p></blockquote><div><hr></div><h2 style="text-align: center;"><code>Why Most People Never Build Real Loops</code></h2><div><hr></div><p>Loops sound amazing until you look at the token bill.</p><p>A normal agent loop can burn a lot of context fast:</p><ul><li><p><strong><span>One medium coding loop can use 50K-200K tokens</span></strong></p></li><li><p><strong><span>A fleet loop with one orchestrator and several specialist agents can use 500K-2M tokens</span></strong></p></li><li><p><strong><span>A scheduled daily loop can reach millions of tokens per week</span></strong></p></li></ul><p>Every retry costs tokens.</p><p>Every self-correction costs tokens.</p><p>Every verification step costs tokens.</p><p>Every subagent costs tokens.</p><p>That is the hidden problem nobody talks about enough.</p><p>Loop engineering is not hard because the idea is complicated.</p><p>It is hard because most people cannot afford to let agents run freely for long.</p><blockquote><p style="text-align: center;"><strong><span>&#8220;Easy for you to say, you have unlimited OpenAI access.&#8221;</span></strong></p></blockquote><p>That reaction is fair.</p><p>This is why cheaper long-context models matter.</p><p>If you want loops to run every day, you need:</p><ul><li><p><strong><span>Cheap input tokens</span></strong></p></li><li><p><strong><span>Cheap output tokens</span></strong></p></li><li><p><strong><span>Large context windows</span></strong></p></li><li><p><strong><span>Tool calling</span></strong></p></li><li><p><strong><span>JSON output</span></strong></p></li><li><p><strong><span>High concurrency</span></strong></p></li><li><p><strong><span>Enough context to remember what happened earlier in the loop</span></strong></p></li></ul><p>Without that, loops become expensive experiments.</p><p>With that, loops become practical workflows.</p><div><hr></div><h2 style="text-align: center;"><code>The Old Way vs The New Way</code></h2><div><hr></div><p>For the last two years, most people used agents like this:</p><p>You prompt.</p><p>The agent answers.</p><p>You review.</p><p>You find the mistake.</p><p>You prompt again.</p><p>That works, but it does not scale.</p><p><strong><span>The old way:</span></strong></p><ul><li><p><strong><span>You give a prompt</span></strong></p></li><li><p><strong><span>The agent gives an output</span></strong></p></li><li><p><strong><span>You review the output</span></strong></p></li><li><p><strong><span>You fix the weak parts</span></strong></p></li><li><p><strong><span>You repeat manually</span></strong></p></li></ul><p><strong><span>The new way:</span></strong></p><ul><li><p><strong><span>You define the goal</span></strong></p></li><li><p><strong><span>The loop discovers what is needed</span></strong></p></li><li><p><strong><span>The loop plans the work</span></strong></p></li><li><p><strong><span>The agent executes</span></strong></p></li><li><p><strong><span>A checker verifies the result</span></strong></p></li><li><p><strong><span>The loop fixes failures</span></strong></p></li><li><p><strong><span>The system stops when the goal is reached</span></strong></p></li></ul><p>Prompting gives an agent an instruction.</p><p>Loop engineering gives an agent a job.</p><div><hr></div><h2 style="text-align: center;"><code>What Loop Engineering Actually Is</code></h2><div><hr></div><p>Loop engineering is the practice of designing repeatable feedback cycles for AI agents.</p><p>The goal is simple:</p><p>Get from attempt to verified result without needing a human to manually drive every step.</p><p><strong><span>The basic cycle has five stages:</span></strong></p><ol><li><p><strong><span>Discover</span></strong></p></li><li><p><strong><span>Plan</span></strong></p></li><li><p><strong><span>Execute</span></strong></p></li><li><p><strong><span>Verify</span></strong></p></li><li><p><strong><span>Iterate</span></strong></p></li></ol><p>If the output passes, ship it.</p><p>If it fails, send it back into the loop.</p><p>That is the whole idea.</p><p>Not one perfect prompt.</p><p>A system that keeps improving the output until it meets the standard.</p><div><hr></div><h2 style="text-align: center;"><code>Single Agent vs Fleet</code></h2><div><hr></div><p>There are two basic sizes of loops.</p><h3 style="text-align: center;"><code>Single-Agent Loop</code></h3><p>One agent runs the whole cycle.</p><p>It discovers what is needed, plans the work, executes the task, checks the result, and improves it if something fails.</p><p>This is like one person rewriting their own draft.</p><p><strong><span>Good for:</span></strong></p><ul><li><p><strong><span>Focused tasks</span></strong></p></li><li><p><strong><span>Small scopes</span></strong></p></li><li><p><strong><span>Simple goals</span></strong></p></li><li><p><strong><span>Content drafts</span></strong></p></li><li><p><strong><span>Bug fixes</span></strong></p></li><li><p><strong><span>Research summaries</span></strong></p></li></ul><p>One brain.</p><p>One loop.</p><p>Self-improvement.</p><h3 style="text-align: center;"><code>Fleet Loop</code></h3><p>A fleet loop is bigger.</p><p>You give one orchestrator agent the main goal.</p><p>It breaks the work into pieces.</p><p>Then it sends those pieces to specialist agents.</p><p>Each specialist can also use smaller subagents for narrow tasks.</p><p>Example:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;5552607e-9371-49f8-8191-6e7db9c79bd0&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Example: "Build a productivity app"

Orchestrator owns the mission
    &#8595;              &#8595;              &#8595;
Research      Engineering        QA
Specialist    Specialist         Specialist
    &#8595;              &#8595;              &#8595;
Web           Code Writer        Test Writer
Researcher    + Debugger         + Bug Tracker</code></pre></div><p>This is not one agent working alone.</p><p>It is closer to a small team running a project end to end.</p><div><hr></div><h2 style="text-align: center;"><code>Open Loops vs Closed Loops</code></h2><div><hr></div><p>This is the most important practical distinction.</p><p>Not all loops are equal.</p><h3 style="text-align: center;"><code>Open Loops</code></h3><p>Open loops are exploratory.</p><p>You give the agent a broad goal and let it search for the path.</p><p>This is powerful because the agent can discover things you did not specify.</p><p>But it is also expensive and messy.</p><p><strong><span>Open loops can:</span></strong></p><ul><li><p><strong><span>Try too many paths</span></strong></p></li><li><p><strong><span>Burn too many tokens</span></strong></p></li><li><p><strong><span>Create low-quality output fast</span></strong></p></li><li><p><strong><span>Drift away from the real goal</span></strong></p></li><li><p><strong><span>Become hard to control</span></strong></p></li></ul><p>Open loops are exciting.</p><p>But for most people, they are not the best place to start.</p><h3 style="text-align: center;"><code>Closed Loops</code></h3><p>Closed loops are bounded.</p><p>The human designs the path first.</p><p>The loop still runs on its own, but inside clear rules.</p><p><strong><span>A closed loop has:</span></strong></p><ul><li><p><strong><span>Clear goal</span></strong></p></li><li><p><strong><span>Defined steps</span></strong></p></li><li><p><strong><span>Evaluation after each step</span></strong></p></li><li><p><strong><span>Stop condition</span></strong></p></li><li><p><strong><span>Hand-off point if it gets stuck</span></strong></p></li></ul><p>This is the version that actually pays off today.</p><p>It is cheaper.</p><p>It is more reliable.</p><p>It produces cleaner output.</p><p>Start with closed loops.</p><p>Open them up later when your checks are strong.</p><div><hr></div><h2 style="text-align: center;"><code>The 6 Building Blocks Of A Good Loop</code></h2><div><hr></div><p>Conceptually, every loop has five stages.</p><p>But practically, you need six building blocks to make the loop work.</p><h3><strong><span>1. Automations</span></strong></h3><p>This is the heartbeat.</p><p>The automation starts the loop without you manually remembering to run it.</p><p><strong><span>Examples:</span></strong></p><ul><li><p><strong><span>Run every morning</span></strong></p></li><li><p><strong><span>Run when a PR opens</span></strong></p></li><li><p><strong><span>Run when a file changes</span></strong></p></li><li><p><strong><span>Run when a new ticket appears</span></strong></p></li><li><p><strong><span>Run until all tests pass</span></strong></p></li></ul><p>If you still need to start everything manually, the loop is not really doing enough work.</p><h3><em><strong><span>2. Worktrees</span></strong></em></h3><p>Worktrees matter when multiple agents are editing code.</p><p>Without separation, agents collide.</p><p>Two agents can edit the same file.</p><p>One can overwrite the other.</p><p>A worktree gives each agent its own clean workspace and branch.</p><p>That lets multiple agents work in parallel without turning the repo into a mess.</p><h3><em><strong><span>3. Skills</span></strong></em></h3><p>Skills are reusable project knowledge.</p><p>Instead of explaining your project every time, you write the important context once.</p><p>Good skill files include:</p><ul><li><p><strong><span>Vision</span></strong></p></li><li><p><strong><span>Architecture</span></strong></p></li><li><p><strong><span>Rules</span></strong></p></li><li><p><strong><span>Build steps</span></strong></p></li><li><p><strong><span>Testing steps</span></strong></p></li><li><p><strong><span>Things the agent must never do</span></strong></p></li></ul><p>Without skills, every loop starts cold.</p><p>With skills, every loop starts with accumulated context.</p><h3><em><strong><span>4. Plugins And Connectors</span></strong></em></h3><p>A loop that only sees files is limited.</p><p>Connectors let the loop touch your real tools.</p><p>Examples:</p><ul><li><p><strong><span>GitHub</span></strong></p></li><li><p><strong><span>Slack</span></strong></p></li><li><p><strong><span>Linear</span></strong></p></li><li><p><strong><span>Jira</span></strong></p></li><li><p><strong><span>Gmail</span></strong></p></li><li><p><strong><span>Google Drive</span></strong></p></li><li><p><strong><span>Database</span></strong></p></li><li><p><strong><span>Staging API</span></strong></p></li></ul><p>This is the difference between &#8220;here is a suggested fix&#8221; and &#8220;I opened the PR, linked the ticket, watched CI, and posted the update.&#8221;</p><h3><em><strong><span>5. Subagents</span></strong></em></h3><p>The maker and checker should not always be the same model.</p><p>The agent that wrote the code will often be too generous when reviewing it.</p><p>The agent that wrote the article will miss its own weak sections.</p><p><strong><span>Use separate agents for:</span></strong></p><ul><li><p><strong><span>Exploration</span></strong></p></li><li><p><strong><span>Implementation</span></strong></p></li><li><p><strong><span>Review</span></strong></p></li><li><p><strong><span>Testing</span></strong></p></li><li><p><strong><span>Fact-checking</span></strong></p></li><li><p><strong><span>Final summary</span></strong></p></li></ul><p>Quality improves when the reviewer is not the same agent that made the work.</p><h3><em><strong><span>6. Memory</span></strong></em></h3><p>Memory is what lets a loop continue across runs.</p><p>The model forgets.</p><p>The repo does not.</p><p>The notes do not.</p><p>The project log does not.</p><p><strong><span>Memory can live in:</span></strong></p><ul><li><p><strong><span>Markdown files</span></strong></p></li><li><p><strong><span>Project logs</span></strong></p></li><li><p><strong><span>Linear tickets</span></strong></p></li><li><p><strong><span>GitHub issues</span></strong></p></li><li><p><strong><span>Obsidian vaults</span></strong></p></li><li><p><strong><span>Databases</span></strong></p></li><li><p><strong><span>Claude Projects</span></strong></p></li></ul><p>A long-running loop needs to know what was tried, what passed, what failed, and what still needs to happen.</p><p>Without memory, it starts from zero every time.</p><div><hr></div><h2 style="text-align: center;"><code>Real Loop Examples</code></h2><div><hr></div><p>Here are the loops that make the idea concrete.</p><h3 style="text-align: center;"><code>Coding Loop</code></h3><p><strong>The loop:</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;fa06bf66-b468-49cf-ab43-83854b0899d6&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Read VISION.md + ARCHITECTURE.md
&#8595;
Plan next change
&#8595;
Edit code
&#8595;
Run tests
&#8595;
If tests fail &#8594; read error &#8594; fix &#8594; test again
&#8595;
If tests pass &#8594; summarize changes
&#8595;
Stop</code></pre></div><p>No human needs to push every step.</p><p>The agent writes, tests, fixes, and verifies.</p><h3 style="text-align: center;"><code>Research Loop</code></h3><p><strong>The loop:</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;3b9a1c1c-e4bc-4a7f-8b20-8dafb9757f82&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Define research question
&#8595;
Search for sources
&#8595;
Summarize findings
&#8595;
Verify claims against sources
&#8595;
Compare conflicting information
&#8595;
Synthesize final answer
&#8595;
Stop when confidence threshold met</code></pre></div><p>This is much better than asking for one quick summary.</p><h3 style="text-align: center;"><code>Content Loop</code></h3><p><strong>The loop:</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;3b881199-50bc-41df-ab7b-8f7521ca0406&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">Topic + audience + goal defined
&#8595;
Draft created
&#8595;
Critique agent reviews draft
&#8595;
Rewrite based on critique
&#8595;
Score against success criteria
&#8595;
If score passes &#8594; publish
&#8595;
If score fails &#8594; rewrite again</code></pre></div><p>The loop turns one idea into a content system.</p><h3 style="text-align: center;"><code>Sales Outreach Loop</code></h3><p><strong>The loop:</strong></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;a3f4fa01-6720-4fc2-9727-9421c39cdb68&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">ICP (Ideal Customer Profile) defined
&#8595;
Find leads matching profile
&#8595;
Enrich with company data
&#8595;
Qualify against criteria
&#8595;
Personalize message
&#8595;
Quality review
&#8595;
Send or escalate to human</code></pre></div><p>Same skeleton:</p><p>Goal.</p><p>Action.</p><p>Check.</p><p>Fix.</p><p>Repeat until done.</p><div><hr></div><h2 style="text-align: center;"><code>Prompt Engineer vs Loop Engineer</code></h2><div><hr></div><p>This is the skill gap opening in 2026</p><h3 style="text-align: center;"><code>Prompt Engineer</code></h3><p>A prompt engineer focuses on better instructions.</p><p>They improve the wording.</p><p>They get a better single output.</p><p>But the human still reviews everything after the run.</p><p>The human is still the feedback loop.</p><h3 style="text-align: center;"><code>Loop Engineer</code></h3><p>A loop engineer designs the feedback system.</p><p><strong><span>They decide:</span></strong></p><ul><li><p><strong><span>What starts the loop</span></strong></p></li><li><p><strong><span>What context the agent needs</span></strong></p></li><li><p><strong><span>What tools it can use</span></strong></p></li><li><p><strong><span>What counts as success</span></strong></p></li><li><p><strong><span>Who checks the work</span></strong></p></li><li><p><strong><span>When the loop should stop</span></strong></p></li><li><p><strong><span>Where the result should be saved</span></strong></p></li></ul><p>A prompt engineer says:</p><p>&#8220;Write me a function.&#8221;</p><p>A loop engineer says:</p><p>&#8220;Write it, test it, fix it until it passes, then summarize the change.&#8221;</p><p>Same tools.</p><p>Different mindset.</p><p>The highest-leverage AI builders are not just writing better English prompts.</p><p>They are designing systems that discover, plan, execute, verify, and stop correctly.</p><div><hr></div><h2 style="text-align: center;"><code>The Short Version</code></h2><div><hr></div><p>Loop engineering is the shift from manual prompting to automated feedback cycles.</p><p>The shift:</p><ul><li><p>Old way: Prompt agents one task at a time</p></li><li><p>New way: Design loops that run the full cycle</p></li></ul><p>The 6 things you actually build:</p><ul><li><p>Automations: The heartbeat that starts the loop</p></li><li><p>Worktrees: Parallel agents without file conflicts</p></li><li><p>Skills: Project knowledge reused every run</p></li><li><p>Plugins and connectors: Access to real tools</p></li><li><p>Subagents: Makers and checkers separated</p></li><li><p>Memory: The loop remembers across runs</p></li></ul><p>The 2 sizes:</p><ul><li><p>Single-agent loop: One agent improves its own work</p></li><li><p>Fleet loop: Orchestrator plus specialists plus subagents</p></li></ul><p>The 2 types:</p><ul><li><p>Open loop: Powerful, exploratory, expensive</p></li><li><p>Closed loop: Bounded, reliable, affordable</p></li></ul><p>The 5 stages:</p><ol><li><p>Discover</p></li><li><p>Plan</p></li><li><p>Execute</p></li><li><p>Verify</p></li><li><p>Iterate</p></li></ol><p>The real cost problem:</p><ul><li><p>Loops burn tokens fast</p></li><li><p>Cheap long-context models make loops practical</p></li><li><p>Without affordable tokens, most people never get past experiments</p></li></ul><p>The mindset shift:</p><ul><li><p>Prompt engineers ask AI for outputs</p></li><li><p>Loop engineers design systems that produce verified outcomes</p></li></ul><p>That is the real unlock.</p><p>Stop trying to write one perfect prompt.</p><p>Start building the loop that makes imperfect outputs better.</p><p>A reliable loop beats a perfect prompt.</p><div><hr></div><p><strong><span>If you read this far:</span></strong></p><ul><li><p><strong><span>BOOKMARK THIS.</span></strong></p></li><li><p>Follow X <a href="iframe.php?url=https%3A%2F%2Fx.com%2F%400xwhrrari">@0xwhrrari</a> </p></li><li><p>Follow Substack</p></li><li><p>Follow my <strong><a href="iframe.php?url=https%3A%2F%2Ft.me%2F%2BqqS3Qn-x1305ZmUy"><span>Private Telegram Channel</span></a><span> </span></strong></p><div><hr></div><p></p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://whrrari.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading rari's Substack! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item></channel></rss>