<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jason Zhou</title>
    <description>The latest articles on DEV Community by Jason Zhou (@aijasonz).</description>
    <link>https://dev.to/aijasonz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4016065%2Fc8733b85-0ffe-4f56-8506-e52be5a4fad4.jpg</url>
      <title>DEV Community: Jason Zhou</title>
      <link>https://dev.to/aijasonz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aijasonz"/>
    <language>en</language>
    <item>
      <title>Context Engineering: The Complete Guide (2026)</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Fri, 24 Jul 2026 05:49:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/context-engineering-the-complete-guide-2026-27a8</link>
      <guid>https://dev.to/aijasonz/context-engineering-the-complete-guide-2026-27a8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Manus measured their production agents: 100 input tokens for every 1 output token.&lt;/strong&gt; Read that again. The model's "intelligence" in an agent system is mostly a function of those 100 tokens - what got included, what got cut, how it's arranged. The Karpathy framing: the LLM is a CPU, the context window is RAM, and you are the operating system deciding what loads into memory.&lt;/p&gt;

&lt;p&gt;Prompt engineering asks "how do I phrase the ask?" Context engineering asks "what does the model see at this exact moment?" The second question is where production agents live or die. Here's the field in one pass: why context degrades, the four management strategies, the four failure modes, and the cache economics underneath it all.&lt;/p&gt;

&lt;p&gt;Prefer to watch? Here's the full walkthrough of putting this into practice with a structured &lt;code&gt;.agent&lt;/code&gt; folder in Claude Code:&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Long Context Degrades: Context Rot
&lt;/h2&gt;

&lt;p&gt;Bigger windows didn't fix this. Two structural reasons:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attention is quadratic and finite.&lt;/strong&gt; Every token attends to every other token - n² relationships. More tokens means each one gets a thinner slice of attention. Anthropic's framing: context is a resource with &lt;strong&gt;diminishing marginal returns&lt;/strong&gt;. Each appended token spends attention budget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance decays before the window fills.&lt;/strong&gt; The measured phenomenon is called context rot. Galileo's benchmark: GPT-4o at 98.1% accuracy on short contexts dropped to &lt;strong&gt;64.1%&lt;/strong&gt; at scale - same model, same task, more tokens. This affects every transformer. It's a gradient, not a cliff, but a 34-point slide will absolutely ruin your agent's afternoon.&lt;/p&gt;

&lt;p&gt;And tool definitions compound it. Berkeley's function-calling leaderboard found a quantized Llama 3.1 8B that worked fine with 19 tools and &lt;strong&gt;fell apart at 46&lt;/strong&gt;. The window had room; the model's discrimination didn't. Complexity, not length, was the killer.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "Context" Actually Includes
&lt;/h2&gt;

&lt;p&gt;Wider than most people draw it - four layers, each failing differently:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Contains&lt;/th&gt;
&lt;th&gt;Failure mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Instructions&lt;/td&gt;
&lt;td&gt;System prompt, rules, few-shot examples&lt;/td&gt;
&lt;td&gt;Bloated rules dilute everything downstream&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Knowledge&lt;/td&gt;
&lt;td&gt;Retrieved docs, user prefs, facts&lt;/td&gt;
&lt;td&gt;Too much = lost model; too little = confabulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tools&lt;/td&gt;
&lt;td&gt;Definitions, call results, errors&lt;/td&gt;
&lt;td&gt;Tool overload (the 46-tool collapse)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;History&lt;/td&gt;
&lt;td&gt;Prior messages, decisions, trajectory&lt;/td&gt;
&lt;td&gt;Stale conclusions steering current work&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Context engineering is budget allocation across these four. Spend where the task needs it; cut everywhere else.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Four Strategies
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbp5zuxikwpqcrf45tbx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbp5zuxikwpqcrf45tbx.png" alt="The context window's four layers (instructions, knowledge, tools, history) and the four management strategies: offload, retrieve, isolate, compress" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Offloading - the filesystem is free memory
&lt;/h3&gt;

&lt;p&gt;Don't carry what you can fetch. Manus's pattern: scrape a webpage, keep a 500-token summary plus the URL, drop the 50,000-token body. &lt;strong&gt;100:1 compression, fully reversible&lt;/strong&gt; - the agent re-fetches if it actually needs the details.&lt;/p&gt;

&lt;p&gt;The other offloading move: the agent maintains a &lt;code&gt;todo.md&lt;/code&gt; and re-reads it before each step. External memory doubles as an attention anchor - rewriting current goals into the &lt;em&gt;recent&lt;/em&gt; end of context keeps long tasks from drifting. Same reason you write a checklist instead of memorizing it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Retrieval - just-in-time beats preloading
&lt;/h3&gt;

&lt;p&gt;Classic RAG retrieves once, up front. Agentic retrieval hands the model lightweight pointers - file paths, query templates, URLs - and lets it pull what each step needs. Claude Code is the reference implementation: it never loads your database into context; it writes a query, stores results, reads slices with &lt;code&gt;head&lt;/code&gt;. The pointer is cheap; the data stays on disk until summoned.&lt;/p&gt;

&lt;p&gt;Hybrid is the practical answer: preload the stable essentials (CLAUDE.md), let the agent explore the rest. Where you draw the line is the craft.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Isolation - don't share everything with everyone
&lt;/h3&gt;

&lt;p&gt;The trap in multi-agent systems: a giant shared context everyone reads. Now every agent wades through everyone else's noise and bills for the privilege.&lt;/p&gt;

&lt;p&gt;Treat inter-agent communication as &lt;strong&gt;interface design&lt;/strong&gt;: a research sub-agent returns verified findings and decision points - not its browsing history, dead ends, or internal monologue. Anthropic's multi-agent research system proved the economics: separate contexts per sub-agent cost 15x the tokens but delivered &lt;strong&gt;90.2% better task performance&lt;/strong&gt;. Isolation is what you're buying. (This is the entire thesis of &lt;a href="https://www.aibuilderclub.com/blog/claude-code-sub-agents-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;sub-agents&lt;/a&gt;.)&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Compression - shrink without losing the constraints
&lt;/h3&gt;

&lt;p&gt;When the window fills, summarize and restart - Claude Code triggers this automatically at 95% utilization. The subtle art is what survives compression. Importance is &lt;em&gt;lagged&lt;/em&gt;: the detail you drop at step 5 becomes load-bearing at step 50. Priority goes to facts that constrain future action - what failed, what got created, what's been ruled out, what's still unknown.&lt;/p&gt;

&lt;p&gt;Cheapest variant: clear old tool results. A file dump from 40 turns ago is almost never needed verbatim - it's the lowest-risk deletion in the window.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Four Failure Modes
&lt;/h2&gt;

&lt;p&gt;Name them and you'll start seeing them everywhere:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Poisoning&lt;/strong&gt; - one hallucination enters context and compounds. DeepMind's Gemini-plays-Pokémon logged the canonical case: a false game-state claim landed in the goal section, got re-read every turn, and the agent chased an impossible objective for dozens of cycles. Errors that enter context self-confirm.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distraction&lt;/strong&gt; - past ~100K tokens, models start pattern-matching their own history instead of reasoning fresh. Gemini 2.5's report describes the agent repeating past actions rather than planning. Databricks found worse: distracted models default to &lt;em&gt;summarizing the context&lt;/em&gt; - ignoring your instruction entirely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confusion&lt;/strong&gt; - irrelevant material degrades output even when it's ignorable. The 46-tool collapse, again. Models don't ignore noise; they pay attention tax on it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clash&lt;/strong&gt; - contradictions across turns derail reasoning. Microsoft/Salesforce sharded benchmark tasks across multi-turn conversations: average performance fell &lt;strong&gt;39%&lt;/strong&gt;. Their line: "when LLMs take a wrong turn in a conversation, they get lost and do not recover."&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The Money Layer: KV-Cache
&lt;/h2&gt;

&lt;p&gt;Agent contexts share a shape - stable prefix, growing tail - and inference engines cache the prefix computation. Claude Sonnet pricing makes the stakes plain: cached input &lt;strong&gt;$0.30/M tokens&lt;/strong&gt;, uncached &lt;strong&gt;$3.00/M&lt;/strong&gt;. At a 100:1 input ratio, cache hit rate basically &lt;em&gt;is&lt;/em&gt; your unit cost. Three rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Freeze the prefix.&lt;/strong&gt; One changed token invalidates everything after it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Append-only.&lt;/strong&gt; Never edit history. And serialize deterministically - JSON key order isn't guaranteed in most languages, and nondeterministic serialization silently breaks caching.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mask, don't remove, tools.&lt;/strong&gt; Tool definitions sit early in context; add/remove mid-session and the cache resets. Keep the definition set stable and constrain choices via logit masking instead.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Two Counterintuitive Practices
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Leave failures in.&lt;/strong&gt; The instinct after a failed tool call is to clean up and retry on a fresh slate. Wrong - the error trace is evidence. Models that see their own failure update away from repeating it; models with scrubbed history walk into the same wall. Manus treats error recovery as one of the clearest signals of real agentic behavior, and notes benchmarks systematically under-measure it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inject structured variety.&lt;/strong&gt; A context full of similar action-observation pairs becomes accidental few-shot pressure - the model mimics the pattern even when the situation changed. Varying serialization templates and phrasing breaks the rhythm.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to Bother
&lt;/h2&gt;

&lt;p&gt;If your agent is single-turn Q&amp;amp;A: don't. Strategy overhead beats no strategy. The escalation triggers: context regularly past ~30K tokens, more than ~20 tools, or 1,000+ sessions/day. Then add strategies in order of pain - usually compression first, retrieval second, isolation when you go multi-agent.&lt;/p&gt;

&lt;p&gt;One more trendline worth holding: stronger models make context engineering &lt;em&gt;more&lt;/em&gt; valuable, not less - capability unlocks longer tasks, longer tasks mean more context pressure. The window is RAM. The model is the CPU. You're the OS - and the OS is where agents are won.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>contextengineering</category>
      <category>llm</category>
      <category>advanced</category>
    </item>
    <item>
      <title>MCP Internals: STDIO, SSE, and JSON-RPC Explained</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Thu, 23 Jul 2026 05:49:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/mcp-internals-stdio-sse-and-json-rpc-explained-1lk6</link>
      <guid>https://dev.to/aijasonz/mcp-internals-stdio-sse-and-json-rpc-explained-1lk6</guid>
      <description>&lt;p&gt;&lt;strong&gt;You've pasted this config a dozen times. Can you explain what it does?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"filesystem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@modelcontextprotocol/server-filesystem"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"~/Downloads"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most builders run MCP servers daily without being able to answer. That's fine until something breaks - a server won't start on Windows, tools mysteriously don't appear, or you want to build your own client and realize the magic was never magic. This is the wire-level tour: transport, message format, and the exact six-step loop behind every MCP tool call.&lt;/p&gt;




&lt;h2&gt;
  
  
  What That Config Actually Is
&lt;/h2&gt;

&lt;p&gt;It's a &lt;strong&gt;command line, disassembled into JSON.&lt;/strong&gt; The client reassembles and runs it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; @modelcontextprotocol/server-filesystem ~/Downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npx&lt;/code&gt; - Node's run-a-package-without-installing tool (&lt;code&gt;uvx&lt;/code&gt; is the Python twin)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-y&lt;/code&gt; - skip the "install this package?" prompt, because no human is present to answer&lt;/li&gt;
&lt;li&gt;the package name - an ordinary npm package that speaks MCP&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;~/Downloads&lt;/code&gt; - an argument the server itself defined (here: the directory it's allowed to touch)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the entire trick. An MCP server is &lt;strong&gt;a process your client spawns&lt;/strong&gt;, no different in kind from anything else you'd launch from a shell. Which means you can skip npx entirely and run a local copy - &lt;code&gt;"command": "node", "args": ["/path/to/server.js"]&lt;/code&gt; - fully offline, immune to upstream version changes, and (per the &lt;a href="https://www.aibuilderclub.com/blog/mcp-security-attack-vectors?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;security article&lt;/a&gt;) the safest way to run anything important.&lt;/p&gt;

&lt;p&gt;The Windows gotcha that bites everyone once: Windows' default shell can't exec Unix-style commands directly, so the config needs wrapping - &lt;code&gt;"command": "cmd", "args": ["/c", "npx", ...]&lt;/code&gt;. If your server "just doesn't start" on Windows, it's this.&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabshpa5g7utlr2qb3e4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fabshpa5g7utlr2qb3e4i.png" alt="MCP client-server communication: STDIO for local servers, SSE for remote, JSON-RPC 2.0 messages, and the six-step interaction loop" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Transport: STDIO and SSE
&lt;/h2&gt;

&lt;p&gt;MCP defines &lt;em&gt;what&lt;/em&gt; messages say, not &lt;em&gt;how&lt;/em&gt; they travel. Two transports:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STDIO - for local servers.&lt;/strong&gt; The client writes JSON to the child process's stdin; the server answers on stdout. The same plumbing as &lt;code&gt;cat&lt;/code&gt; or any Unix pipe - you can literally drive a server from your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; @modelcontextprotocol/server-filesystem ~/Downloads &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'{"method":"tools/call","params":{"name":"list_directory","arguments":{"path":"~/Downloads"}},"jsonrpc":"2.0","id":1}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A directory listing comes back as JSON. No network stack, no ports, no auth handshake - process isolation is the security model. This is why local MCP servers feel instant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSE - for remote servers.&lt;/strong&gt; Client connects over HTTP; the server pushes via Server-Sent Events:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"browser"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:8000/sse"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use it when the server lives elsewhere - a shared team service, a SaaS endpoint, anything not on your machine. Trade-offs are the usual networked ones: latency, availability, and a real authentication story to care about.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Message Format: JSON-RPC 2.0
&lt;/h2&gt;

&lt;p&gt;Every MCP message is JSON-RPC - a request/response convention from long before LLMs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;request&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tools/call"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"params"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"query_db"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"arguments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"table"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"users"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;response&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(id&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;matches)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"jsonrpc"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;id&lt;/code&gt; pairs responses to requests so multiple calls can be in flight. Errors come back in a structured &lt;code&gt;error&lt;/code&gt; field with codes. The methods you'll see constantly: &lt;code&gt;tools/list&lt;/code&gt; (what can you do?) and &lt;code&gt;tools/call&lt;/code&gt; (do it). The protocol also specs resources, prompts, and sampling - but tools are ~90% of real-world traffic today.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Full Loop, Six Steps
&lt;/h2&gt;

&lt;p&gt;Here's a complete trace of "which courses does teacher Zhang teach?" against a database server (two tables: teachers, courses - so two tool calls). This pattern is identical across every client:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Init.&lt;/strong&gt; Client spawns/connects to each configured server, calls &lt;code&gt;tools/list&lt;/code&gt;, collects every tool's name + description + parameter schema into a catalog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompt assembly.&lt;/strong&gt; Your question + the tool catalog go to the LLM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model decides.&lt;/strong&gt; Returns a structured tool call: &lt;code&gt;search_teachers({ name: "Zhang" })&lt;/code&gt;. Crucially - &lt;em&gt;the model returns intent, JSON describing a wish.&lt;/em&gt; It has no hands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client executes.&lt;/strong&gt; Translates the wish into an actual &lt;code&gt;tools/call&lt;/code&gt; to the right server, gets the teacher's ID back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loop.&lt;/strong&gt; Result is appended to the conversation; model sees it, requests call #2: &lt;code&gt;search_courses({ teacherId: ... })&lt;/code&gt;. Steps 3-4 repeat until the model has enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesis.&lt;/strong&gt; Model writes the human answer: "Zhang teaches Advanced Mathematics."&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A two-hop question = 13 log entries in a typical client: one &lt;code&gt;tools/list&lt;/code&gt;, four LLM round trips, two tool executions, plus bookkeeping. Multi-step "agentic" behavior is this loop, repeated. Nothing else is happening. (If you've read &lt;a href="https://www.aibuilderclub.com/blog/how-to-build-ai-agent-from-scratch?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;the agent loop&lt;/a&gt;, you've recognized it - MCP just standardizes the tool side.)&lt;/p&gt;




&lt;h2&gt;
  
  
  How the Model Knows About Tools: Two Schools
&lt;/h2&gt;

&lt;p&gt;Packet-capture different MCP clients and a fault line appears - there are two ways to teach a model its tools:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;School 1: native Function Calling.&lt;/strong&gt; The client passes the tool catalog through the API's &lt;code&gt;tools&lt;/code&gt; parameter. The model emits structured &lt;code&gt;tool_calls&lt;/code&gt;, reliability backed by &lt;a href="https://www.aibuilderclub.com/blog/function-calling-how-llms-use-tools?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;constrained decoding&lt;/a&gt;. Clean, robust - but only works with models &lt;em&gt;fine-tuned for tool use&lt;/em&gt;, which is why some clients gray out MCP for certain models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;School 2: system-prompt convention.&lt;/strong&gt; The client writes the entire tool protocol into a giant system prompt - tool list, XML-ish call format, usage rules - and parses the model's &lt;em&gt;text&lt;/em&gt; output for tool invocations. Measured in the wild at &lt;strong&gt;~42,000 characters&lt;/strong&gt; of system prompt before you've said a word. Burns tokens, fragile to format drift - but works with &lt;em&gt;any&lt;/em&gt; model that can follow instructions, no tool-use fine-tuning required.&lt;/p&gt;

&lt;p&gt;Same protocol underneath; the difference is purely how the client talks to its LLM. This single distinction explains both why some tools support every model and why those tools cost more per request.&lt;/p&gt;




&lt;h2&gt;
  
  
  Build a Toy Client - It's One Loop
&lt;/h2&gt;

&lt;p&gt;Nothing demystifies MCP faster. The whole thing in pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. spawn configured servers, collect tools/list into a catalog
2. loop:
   - send messages + catalog to LLM
   - if response is text → print, await user
   - if response is tool call →
       route to owning server via tools/call,
       append result to messages,
       continue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An afternoon's work against the official SDK (the &lt;a href="https://www.aibuilderclub.com/blog/mcp-101-build-mcp-servers?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;MCP 101 guide&lt;/a&gt; covers the server side). Log every message as JSON while you're at it - watching your own client's traffic teaches more than any diagram, and it doubles as the &lt;a href="https://www.aibuilderclub.com/blog/mcp-security-attack-vectors?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;security audit&lt;/a&gt; habit of knowing exactly what your servers send and receive.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to Keep
&lt;/h2&gt;

&lt;p&gt;Four load-bearing facts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A server is a spawned process&lt;/strong&gt; (or an HTTP endpoint). The JSON config is a disassembled command line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport is STDIO locally, SSE remotely.&lt;/strong&gt; Messages are JSON-RPC 2.0 either way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model only ever outputs intent.&lt;/strong&gt; The client executes. Every "AI did something" is this handoff.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool awareness comes via Function Calling or via system prompt&lt;/strong&gt; - which one your client uses determines model compatibility and token cost.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The protocol's genius was never sophistication - it's that it standardized something dumb enough for everyone to implement. USB-C for AI tools: boring on the wire, transformative in the ecosystem.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/mcp-internals-client-server?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>aiagents</category>
      <category>protocol</category>
      <category>advanced</category>
    </item>
    <item>
      <title>Agent Memory Systems: The Complete Guide (2026)</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Wed, 22 Jul 2026 05:48:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/agent-memory-systems-the-complete-guide-2026-3i5n</link>
      <guid>https://dev.to/aijasonz/agent-memory-systems-the-complete-guide-2026-3i5n</guid>
      <description>&lt;p&gt;&lt;strong&gt;You spent 30 minutes teaching your agent the project: TypeScript, Vitest, Supabase, deploys on Vercel. It nailed the work. You closed the terminal. Tomorrow it knows nothing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not a bug - it's the architecture. An LLM's only "memory" is the context window: the text you send with each request. New session, empty window, total amnesia. The in-conversation memory you experience is just prior messages being re-sent every turn.&lt;/p&gt;

&lt;p&gt;For one-shot questions, fine. For an AI that works &lt;em&gt;with&lt;/em&gt; you across weeks - remembering your preferences, your stack, last Tuesday's debugging conclusion - you need a memory system bolted on from outside. Here's the full map: the three memory types, where memories physically live, the lifecycle that keeps them useful, and how MemGPT, Mem0, and Claude Code each solved it differently.&lt;/p&gt;

&lt;p&gt;Prefer the video version? Watch the full breakdown of whether agent memory is actually solved:&lt;/p&gt;




&lt;h2&gt;
  
  
  Three Kinds of Memory (Borrowed From Your Brain)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl30ws2cwqjzzhgvdikky.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl30ws2cwqjzzhgvdikky.png" alt="The three types of agent memory: episodic (what happened), semantic (what's true), procedural (how to do it)" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cognitive science gave agent design its most useful taxonomy. Three types, three jobs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Answers&lt;/th&gt;
&lt;th&gt;Agent examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Episodic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What happened?&lt;/td&gt;
&lt;td&gt;Past conversations, tool-call traces, "approach A failed last time, B worked"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Semantic&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;What's true?&lt;/td&gt;
&lt;td&gt;"User prefers terse answers", "project uses Supabase", "deploys are us-east-1"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Procedural&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;How do I do it?&lt;/td&gt;
&lt;td&gt;Learned workflows: the password-reset sequence, the standard debug routine&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A mature agent needs all three. Episodic-only over-indexes on anecdotes. Semantic-only never learns from experience. Procedural-only breaks on anything novel. Most builders start semantic (it's the easiest win - facts and preferences), add episodic when cross-session learning starts mattering, and find procedural memory emerging in things like &lt;a href="https://www.aibuilderclub.com/blog/agent-skills-best-practices-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Skills&lt;/a&gt; - which are essentially procedural memory you wrote by hand.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Memory Lives: Pick Your Layer
&lt;/h2&gt;

&lt;p&gt;A 107-page 2025 survey (Hu et al., &lt;em&gt;Memory in the Age of AI Agents&lt;/em&gt;) sorts storage into three forms. The practical conclusion is short:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Token-level - the layer you can actually use.&lt;/strong&gt; Memory stored as readable text - facts, summaries, profiles - in files or databases, injected into the prompt when needed. Every production system you've heard of lives here: Mem0, Letta/MemGPT, Zep, Claude Code's CLAUDE.md. The reason is brutal and simple: commercial APIs accept text and nothing else. You can't reach into Claude's attention layers. Your entire design space is what goes in the prompt.&lt;/p&gt;

&lt;p&gt;Within token-level there's a complexity ladder: &lt;strong&gt;flat&lt;/strong&gt; (entries + vector search - Mem0's original design), &lt;strong&gt;graph&lt;/strong&gt; (entities and relations for multi-hop queries - Zep's temporal knowledge graph), &lt;strong&gt;hierarchical&lt;/strong&gt; (raw entries → cluster summaries → global abstractions - HippoRAG). Benchmark reality check: flat retrieval ties or beats fancier structures on standard tests. Start flat; graduate only when you observe actual multi-hop retrieval failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implicit (KV-cache tricks, learned memory tokens)&lt;/strong&gt; - requires model internals; commercial APIs don't expose them. Skip unless you self-host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parameter-level (fine-tuning knowledge in)&lt;/strong&gt; - durable but can't update incrementally, and edits risk catastrophic forgetting of neighbors. Batch domain adaptation only; not a memory system.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lifecycle: Write, Maintain, Retrieve
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Writing - quality ceiling gets set here
&lt;/h3&gt;

&lt;p&gt;Garbage written = garbage retrieved, regardless of how clever retrieval is. Two workhorse methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extractive:&lt;/strong&gt; an LLM pulls discrete facts from conversation - "user prefers dark theme", "API limit 100/min". Precise, occasionally misses context. Mem0's core pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Summarative:&lt;/strong&gt; compress conversations into running or chunked summaries. Holds context; risks semantic drift over repeated updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use extraction for facts, summaries for conversational context. The bar for writing &lt;em&gt;anything&lt;/em&gt;: does this constrain future reasoning? Preferences, decisions, recurring patterns - yes. Everything else - high threshold. &lt;strong&gt;A memory system that faithfully saves everything is a garbage heap with an API.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintaining - the step everyone skips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merge:&lt;/strong&gt; "prefers concise answers" and "likes brief replies" are one memory, not two&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update:&lt;/strong&gt; "we migrated Postgres → Supabase" must supersede the old fact - Zep soft-deletes with timestamps so history survives but stale facts stop surfacing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Forget:&lt;/strong&gt; decay by age, prune by access, judge by importance - with one landmine:&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Retrieving - where good memories go to waste
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query rewriting&lt;/strong&gt; fixes the dirty secret of semantic search: questions and stored facts have different shapes. "How's auth handled?" sits far from "JWT validation in auth.ts middleware, 24h expiry" in embedding space. &lt;strong&gt;HyDE&lt;/strong&gt; is the counterintuitive fix: have the model hallucinate an answer &lt;em&gt;first&lt;/em&gt;, embed that, search with it. The fake answer is wrong but answer-&lt;em&gt;shaped&lt;/em&gt; - and shape is what embedding distance measures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid search&lt;/strong&gt; - BM25 keyword matching catches exact terms (&lt;code&gt;auth.ts&lt;/code&gt;); embeddings catch paraphrases ("login system" → "authentication middleware"). Either alone leaves recall on the table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Filter hard.&lt;/strong&gt; Three highly relevant memories injected beat ten half-relevant ones. Over-injection is just &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;context pollution&lt;/a&gt; with extra steps.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Three Production Architectures
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MemGPT / Letta - agent as memory manager.&lt;/strong&gt; The 2023 OS metaphor: context window = RAM, external store = disk, and the agent itself pages data between them via tools (&lt;code&gt;core_memory_append&lt;/code&gt;, archival search). Maximum flexibility; memory quality rides entirely on the model's judgment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mem0 - automated pipeline.&lt;/strong&gt; Every exchange flows through extract-then-reconcile: LLM pulls facts, vector similarity decides new/update/merge. Later added a graph layer for relational queries. On the LOCOMO benchmark, Mem0 beat &lt;em&gt;full-context stuffing&lt;/em&gt; - better accuracy, fewer tokens. Precise extraction + precise retrieval &amp;gt; brute force, officially measured.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code - files, that's it.&lt;/strong&gt; CLAUDE.md at the project root (auto-loaded, stable conventions), &lt;code&gt;~/.claude/CLAUDE.md&lt;/code&gt; for cross-project preferences, plus topic-split memory files behind an index. Radical properties: fully human-readable, git-versionable, zero infrastructure, agent edits its own memory with file tools. Weakness: no semantic search - retrieval is file names and index discipline. At large memory volumes it strains.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;MemGPT/Letta&lt;/th&gt;
&lt;th&gt;Mem0&lt;/th&gt;
&lt;th&gt;Claude Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Managed by&lt;/td&gt;
&lt;td&gt;The agent&lt;/td&gt;
&lt;td&gt;Pipeline&lt;/td&gt;
&lt;td&gt;Agent + you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage&lt;/td&gt;
&lt;td&gt;Tiered (core/recall/archival)&lt;/td&gt;
&lt;td&gt;Vectors + graph&lt;/td&gt;
&lt;td&gt;Markdown files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transparency&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Framework&lt;/td&gt;
&lt;td&gt;Vector DB&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fits&lt;/td&gt;
&lt;td&gt;Complex memory reasoning&lt;/td&gt;
&lt;td&gt;Products needing auto-memory&lt;/td&gt;
&lt;td&gt;Dev tools, local agents&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Minimum Viable Memory System
&lt;/h2&gt;

&lt;p&gt;Three steps, one afternoon, no vector database:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A &lt;code&gt;save_memory&lt;/code&gt; tool.&lt;/strong&gt; The agent calls it when something deserves persistence. Writes to a file or a Supabase table - either works at this scale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Index injection at session start.&lt;/strong&gt; Put memory titles + one-line summaries in the system prompt; the agent requests full entries when relevant. This is Claude Code's index-then-read pattern, and it's load-bearing: inject summaries, not bodies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduled hygiene.&lt;/strong&gt; Merge duplicates, expire stale facts. A monthly manual pass is genuinely enough at the start.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This takes you from "amnesia every morning" to "remembers what matters." Add embeddings, HyDE, graphs when you hit a real retrieval failure - not before.&lt;/p&gt;




&lt;h2&gt;
  
  
  The One-Sentence Version
&lt;/h2&gt;

&lt;p&gt;Memory ≠ context: context is RAM (visible now, gone at session end), memory is disk (persistent, useless until retrieved into context) - and the bridge between them, retrieval, is where memory systems are actually won. Build the smallest one that stops the amnesia, then earn each layer of complexity with a real failure. Done right, your agent gets better every week you use it. Skipped, every morning is a first date.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/agent-memory-systems-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>memory</category>
      <category>llm</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Claude Code Worktrees: File Isolation for Parallel Agents</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Tue, 21 Jul 2026 05:48:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/claude-code-worktrees-file-isolation-for-parallel-agents-57d</link>
      <guid>https://dev.to/aijasonz/claude-code-worktrees-file-isolation-for-parallel-agents-57d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Two agents, one &lt;code&gt;package.json&lt;/code&gt;, zero survivors.&lt;/strong&gt; Run parallel Claude Code agents in the same directory long enough and you will watch one agent's half-written file get clobbered by another's, or an &lt;code&gt;npm install&lt;/code&gt; from Agent A break Agent B's running build. Messaging between agents doesn't fix this. Physical separation does.&lt;/p&gt;

&lt;p&gt;That's what worktrees do: every agent gets its own complete working directory, backed by the same git repo. Work in parallel, merge at the end, let git referee the conflicts. Here's how Claude Code wraps it and when the overhead pays off.&lt;/p&gt;




&lt;h2&gt;
  
  
  Git Worktree in 60 Seconds
&lt;/h2&gt;

&lt;p&gt;Worktree is a native git feature, older than AI agents and underused by humans. Normally one repo = one working directory, and that directory can sit on exactly one branch at a time. Mid-feature and need to hotfix main? Stash, switch, fix, switch back. Annoying.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git worktree&lt;/code&gt; breaks the limit: spin up additional working directories from the same repo, each on its own branch. Shared &lt;code&gt;.git&lt;/code&gt; history, independent files. A house with one bookshelf and several desks - every desk holds a different draft.&lt;/p&gt;

&lt;p&gt;Three properties matter for agents:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Each worktree has its own physical files&lt;/li&gt;
&lt;li&gt;All worktrees share one git history&lt;/li&gt;
&lt;li&gt;Different worktrees can sit on different branches simultaneously&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Why Agents Need This More Than You Do
&lt;/h2&gt;

&lt;p&gt;A human does one thing at a time; one directory is fine. Parallel agents shred that assumption in three specific ways:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Write conflicts&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Two agents write the same file. Last writer wins, or the file ends up interleaved garbage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dirty reads&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent B reads a file Agent A has half-written. Every downstream decision builds on a broken premise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Environment pollution&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent A installs a package or edits config. Agent B's build explodes for reasons it can't see&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Human teams solve this with conventions and chat. Agents execute too fast for that - the gap between "decides to write" and "wrote" is milliseconds. You cannot coordinate at that speed. You can only isolate.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Claude Code Wraps It
&lt;/h2&gt;

&lt;p&gt;Start a session with the flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude &lt;span class="nt"&gt;--worktree&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creates a fresh git worktree from your repo&lt;/li&gt;
&lt;li&gt;Points the session's file operations at that directory&lt;/li&gt;
&lt;li&gt;Runs the whole session inside the isolated copy&lt;/li&gt;
&lt;li&gt;On exit, handles merge or cleanup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You work normally. The only difference is &lt;em&gt;where&lt;/em&gt; edits land - a private copy instead of your main checkout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With SubAgents:&lt;/strong&gt; sub-agents already get context isolation (own message history, scoped tools, summary-only returns). Worktrees add the fourth wall: file isolation. Let a sub-agent attempt a risky refactor in a worktree; if it faceplants, delete the worktree. Your main directory never knew anything happened. Cheapest undo button in the business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With &lt;a href="https://www.aibuilderclub.com/blog/claude-code-agent-teams-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Agent Teams&lt;/a&gt;:&lt;/strong&gt; each teammate gets its own worktree. Even when backend and frontend agents both touch &lt;code&gt;package.json&lt;/code&gt;, they edit private copies. Git merges at the end - and merge conflicts at integration time are reviewable; runtime overwrites are just lost work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;Lives under &lt;code&gt;.claude/&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;baseRef&lt;/code&gt;&lt;/strong&gt; - where a new worktree starts from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"fresh"&lt;/code&gt;: latest remote main. For independent tasks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"head"&lt;/code&gt;: your current local commit. For building on uncommitted work in progress.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;.worktreeinclude&lt;/code&gt;&lt;/strong&gt; - the gotcha file.&lt;/p&gt;

&lt;p&gt;List what must travel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# .worktreeinclude
&lt;/span&gt;.&lt;span class="n"&gt;env&lt;/span&gt;
.&lt;span class="n"&gt;env&lt;/span&gt;.&lt;span class="n"&gt;local&lt;/span&gt;
&lt;span class="n"&gt;supabase&lt;/span&gt;/.&lt;span class="n"&gt;temp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;node_modules&lt;/code&gt; is usually better reinstalled than copied - let the agent run the install.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lifecycle hooks&lt;/strong&gt; - &lt;code&gt;WorktreeCreate&lt;/code&gt; and &lt;code&gt;WorktreeRemove&lt;/code&gt; events fire on creation/deletion. Wire &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;hooks&lt;/a&gt; to auto-run &lt;code&gt;npm install&lt;/code&gt; or seed a local database whenever a worktree spins up.&lt;/p&gt;




&lt;h2&gt;
  
  
  What It Solves, What It Doesn't
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Solved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write conflicts - physically impossible across worktrees&lt;/li&gt;
&lt;li&gt;Environment pollution - each agent installs and configures privately&lt;/li&gt;
&lt;li&gt;Cheap rollback - bad experiment? &lt;code&gt;git worktree remove&lt;/code&gt;, done&lt;/li&gt;
&lt;li&gt;Confidence to parallelize - tasks you'd serialize out of fear now run together&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not solved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Merge conflicts.&lt;/strong&gt; Isolation defers conflict, doesn't delete it. Two agents rewriting the same function still collide at merge - but as a reviewable git conflict, not silent data loss.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic conflicts.&lt;/strong&gt; Agent A changes a function's return type; Agent B writes callers against the old one. Files merge clean, runtime breaks. Only inter-agent communication catches this - it's why worktrees pair with Agent Teams messaging instead of replacing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disk.&lt;/strong&gt; Every worktree is a near-full copy of working files (the &lt;code&gt;.git&lt;/code&gt; database is shared). A 2GB repo with five worktrees is 10GB+. Mind the laptop.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;Claude Code manages the lifecycle so you don't accumulate orphans:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Session ends with &lt;strong&gt;zero changes&lt;/strong&gt; → worktree auto-deleted&lt;/li&gt;
&lt;li&gt;Session ends &lt;strong&gt;with changes&lt;/strong&gt; → you choose: merge to main, keep as a branch, or discard&lt;/li&gt;
&lt;li&gt;Manual: list active worktrees, prune as needed&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Three-Layer Isolation Model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2v22k76783z7ak7ytxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk2v22k76783z7ak7ytxi.png" alt="The three layers of agent isolation: SubAgent isolates context, Agent Teams isolate roles, Worktree isolates files" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Worktrees complete a stack, each layer answering a different question:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Isolates&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SubAgent&lt;/td&gt;
&lt;td&gt;Context&lt;/td&gt;
&lt;td&gt;"How do I keep exploration noise out of the main conversation?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent Teams&lt;/td&gt;
&lt;td&gt;Roles&lt;/td&gt;
&lt;td&gt;"How do specialized agents coordinate?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Worktree&lt;/td&gt;
&lt;td&gt;Files&lt;/td&gt;
&lt;td&gt;"How do parallel agents not trash each other's work?"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Compose them based on what the work needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agents only &lt;strong&gt;read&lt;/strong&gt; code → SubAgents alone. No write risk, no worktree needed.&lt;/li&gt;
&lt;li&gt;Agents &lt;strong&gt;write&lt;/strong&gt;, with clean file ownership → Agent Teams messaging covers it.&lt;/li&gt;
&lt;li&gt;Agents &lt;strong&gt;write&lt;/strong&gt;, ownership unclear or overlapping → add worktrees and stop worrying.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When to Skip It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One agent working - no conflict exists, pure overhead&lt;/li&gt;
&lt;li&gt;Read-only workloads (reviews, codebase Q&amp;amp;A)&lt;/li&gt;
&lt;li&gt;Multi-GB repos on small disks&lt;/li&gt;
&lt;li&gt;Sub-10-minute tasks - worktree create/merge overhead eats the win&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Try It This Week
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Solo first:&lt;/strong&gt; &lt;code&gt;claude --worktree&lt;/code&gt; on a normal task with file edits. Feel the create → work → merge loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risky refactor in a sandbox:&lt;/strong&gt; point a sub-agent at your scariest "I've been meaning to restructure this" module, worktree on. Worst case costs one &lt;code&gt;git worktree remove&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full team:&lt;/strong&gt; three teammates, three worktrees, one real feature. The merge step at the end is where you'll learn the most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tune:&lt;/strong&gt; set &lt;code&gt;baseRef&lt;/code&gt;, fill &lt;code&gt;.worktreeinclude&lt;/code&gt; with whatever the agent complained about missing.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The mental shift is the actual product here. Without worktrees, you ration parallelism because you fear collisions. With them, "don't touch each other's files" stops being your problem and becomes git's. You stop planning around conflicts and just let the agents run.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/claude-code-worktree-parallel-agents?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>worktree</category>
      <category>git</category>
      <category>multiagent</category>
    </item>
    <item>
      <title>How to Evaluate AI Agents: What Works in 2026</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:47:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/how-to-evaluate-ai-agents-what-works-in-2026-3jf6</link>
      <guid>https://dev.to/aijasonz/how-to-evaluate-ai-agents-what-works-in-2026-3jf6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Ask your agent "did you complete the task correctly?" and the answer is yes. It is always yes.&lt;/strong&gt; Anthropic measured this while building long-running coding agents: models evaluating their own output skew systematically optimistic, and the fuzzier the criterion - design quality, completeness, "is this actually good" - the worse the skew. The agent isn't lying. It's grading homework it just wrote, with the same brain that wrote it.&lt;/p&gt;

&lt;p&gt;Evaluation is the &lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;harness component&lt;/a&gt; builders skip most, and it's the exact line between "demos well" and "deployed." Here's the toolkit that works: separated evaluators, trace debugging, eval sets grown from real failures, and the judge pitfalls that silently corrupt your numbers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Self-Evaluation Fails (It's Not the Model's Fault)
&lt;/h2&gt;

&lt;p&gt;Three structural reasons, none fixable by prompting harder:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirmation bias, mechanized.&lt;/strong&gt; The reasoning that produced the answer is sitting right there in context. Asked to verify, the model re-walks its own steps and finds them - surprise - reasonable. Same failure as a developer reviewing their own PR ten seconds after writing it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shared blind spots.&lt;/strong&gt; Whatever misunderstanding produced the bug also evaluates the bug. If the agent misread the spec, its self-check applies the same misreading and passes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Looks done" vs "is done."&lt;/strong&gt; Generation optimizes for plausible-looking output. Code that &lt;em&gt;reads&lt;/em&gt; correct and code that &lt;em&gt;runs&lt;/em&gt; correct are different claims - and only one of them can be checked by reading.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The fix follows from the diagnosis - and it's a rule older than AI: &lt;strong&gt;production and acceptance must be different parties.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frljf5prub3x5dc4mk059.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frljf5prub3x5dc4mk059.png" alt="The generator-evaluator loop: fresh-context evaluator operates the output and feeds failures back" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: The Generator-Evaluator Split
&lt;/h2&gt;

&lt;p&gt;The architecture Anthropic landed on for autonomous coding runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generator&lt;/strong&gt; builds the thing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evaluator&lt;/strong&gt; - a &lt;em&gt;separate agent with fresh context&lt;/em&gt; - checks it. It never sees the generator's reasoning, so it can't inherit the blind spots&lt;/li&gt;
&lt;li&gt;Failures route back as concrete feedback; the loop continues until the evaluator passes it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The detail that makes it work: &lt;strong&gt;the evaluator operates the output instead of reading it.&lt;/strong&gt; It opens the app in a browser, clicks the flow, runs the test suite, checks the console - behavioral verification, not code review. "Looks done" can't survive contact with a clicked button that doesn't work.&lt;/p&gt;

&lt;p&gt;You can run this pattern today at three budget levels: a &lt;a href="https://www.aibuilderclub.com/blog/claude-code-sub-agents-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;sub-agent&lt;/a&gt; with a review prompt and read-only tools (cheapest), an &lt;a href="https://www.aibuilderclub.com/blog/claude-code-agent-teams-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Agent Teams&lt;/a&gt; reviewer teammate with browser access (the multi-perspective version), or a &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Stop hook&lt;/a&gt; that runs lint+tests before the agent is allowed to finish (deterministic floor - the agent literally can't hand over broken code).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: Traces, or Debugging the Middle
&lt;/h2&gt;

&lt;p&gt;A 15-step agent run that produced a wrong answer is not one failure - it's one failure &lt;em&gt;somewhere in 15 steps&lt;/em&gt;, and without traces you're guessing which. Outcome-only evaluation tells you &lt;em&gt;that&lt;/em&gt; it failed; traces tell you &lt;em&gt;where&lt;/em&gt;: the retrieval that fetched the wrong doc at step 3, the tool error silently swallowed at step 7, the goal drift after the context filled at step 12.&lt;/p&gt;

&lt;p&gt;Minimum viable tracing: log every step's input, tool calls with arguments, results, and decision - structured (JSONL), replayable, and greppable. The &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;audit-log hook&lt;/a&gt; gives you this for Claude Code in one config entry. For your own agents it's an afternoon of plumbing that pays back the first time a run goes sideways. Two metrics worth computing from traces beyond pass/fail: &lt;strong&gt;steps-to-completion&lt;/strong&gt; (rising step counts = degrading efficiency, even while pass rate holds) and &lt;strong&gt;cost-per-success&lt;/strong&gt; (the number that decides if the agent ships).&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 3: Eval Sets Grown From Failures
&lt;/h2&gt;

&lt;p&gt;Public benchmarks (SWE-bench, GAIA, τ²-bench) tell you which &lt;em&gt;model&lt;/em&gt; to pick. They tell you nothing about whether &lt;em&gt;your agent&lt;/em&gt; handles &lt;em&gt;your tasks&lt;/em&gt; - your data shapes, your edge cases, your users' weird phrasings. For that you need your own eval set, and the cheapest way to build one is to never waste a failure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start embarrassingly small - 20 real tasks with verifiable expected outcomes&lt;/li&gt;
&lt;li&gt;Every production failure becomes a new eval case (the agent equivalent of regression tests)&lt;/li&gt;
&lt;li&gt;Run the set on every prompt change, model swap, or &lt;a href="https://www.aibuilderclub.com/blog/harness-engineering-agent-production-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;harness&lt;/a&gt; tweak&lt;/li&gt;
&lt;li&gt;Track pass rate, steps, cost over time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is eval-driven development, and it converts agent work from vibes ("feels better after the prompt change?") into engineering ("pass rate went 71% → 84%, cost per success down 12%"). LangChain's Terminal Bench climb - top 30 to top 5 &lt;em&gt;without touching the model&lt;/em&gt; - was exactly this loop applied relentlessly to the harness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 4: LLM-as-Judge, With Its Three Corruptions
&lt;/h2&gt;

&lt;p&gt;Many criteria can't be asserted in code - "is this summary faithful," "is the tone right." An LLM judging outputs against a rubric scales where human review doesn't. It works, &lt;em&gt;if&lt;/em&gt; you dodge three documented biases:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bias&lt;/th&gt;
&lt;th&gt;What happens&lt;/th&gt;
&lt;th&gt;Mitigation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Position&lt;/td&gt;
&lt;td&gt;Pairwise comparisons favor the first option&lt;/td&gt;
&lt;td&gt;Judge both orders, average&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Verbosity&lt;/td&gt;
&lt;td&gt;Longer outputs score higher at equal quality&lt;/td&gt;
&lt;td&gt;Length-cap or explicitly instruct against it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-preference&lt;/td&gt;
&lt;td&gt;Models rate their own family's prose higher&lt;/td&gt;
&lt;td&gt;Judge from a different provider than the generator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Two rules regardless: rubrics must be &lt;em&gt;specific&lt;/em&gt; ("does it cite a source for every numeric claim - yes/no per claim", not "rate quality 1-10"), and a 5-10% human spot-check sample stays forever. The judge is a scaling tool, not an unsupervised authority - calibrate it against humans before trusting it, and re-calibrate when you change the rubric.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Maturity Ladder
&lt;/h2&gt;

&lt;p&gt;Where most builders are vs where production agents need to be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Level 0 - vibes.&lt;/strong&gt; Run it, eyeball it, ship it. Every demo you've seen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 1 - deterministic gates.&lt;/strong&gt; Tests + lint via hooks. An afternoon. Catches the embarrassing class.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 2 - separated evaluator.&lt;/strong&gt; Fresh-context agent operates the output. Catches "looks done."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 3 - eval set + traces.&lt;/strong&gt; Regression suite from real failures, every run debuggable. Changes become measurable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 4 - continuous.&lt;/strong&gt; Production sampling scored by calibrated judges, alerts on drift, cost-per-success on a dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each level catches what the previous one structurally cannot. Most builders sit at 0; level 1 is one &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;hook&lt;/a&gt; away; level 3 is where "we think it works" becomes "we know what changed." And the cultural shift underneath is the same one &lt;a href="https://www.aibuilderclub.com/blog/prompt-context-harness-evolution?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;harness engineering&lt;/a&gt; keeps teaching: stop asking the model to be more trustworthy, and build the system that doesn't need to trust it. It's also the same lesson behind &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;loop engineering&lt;/a&gt; - in any agent loop, the evaluator (the verifier) is the bottleneck, not the model.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/how-to-evaluate-ai-agents?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>evaluation</category>
      <category>production</category>
      <category>advanced</category>
    </item>
    <item>
      <title>Claude Code Hooks: Complete Guide with 7 Recipes (2026)</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Sun, 19 Jul 2026 06:47:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/claude-code-hooks-complete-guide-with-7-recipes-2026-3ic2</link>
      <guid>https://dev.to/aijasonz/claude-code-hooks-complete-guide-with-7-recipes-2026-3ic2</guid>
      <description>&lt;p&gt;&lt;strong&gt;You told Claude Code to run Prettier after every file edit. It did - twice. Then it forgot.&lt;/strong&gt; You reminded it. It complied. Next session, forgot again. By the fourth reminder you are not pair programming anymore, you are babysitting.&lt;/p&gt;

&lt;p&gt;The fix is not a better prompt. The fix is a hook: a rule wired into Claude Code's execution pipeline that fires every single time, no matter what the model thinks. One user ran a force-push blocker for nine months. It fired 8 times - every one was Claude deciding "cleaning up git history seems like a good idea."&lt;/p&gt;

&lt;p&gt;This guide covers the full hooks system: lifecycle events, matchers, handler types, and the 7 hooks worth installing first.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Claude Code Hooks?
&lt;/h2&gt;

&lt;p&gt;A hook is an external command that runs automatically at a specific moment in the agent's lifecycle. File about to be written? Your hook fires first. Command finished? Your hook post-processes the result.&lt;/p&gt;

&lt;p&gt;The key property: &lt;strong&gt;hooks are deterministic&lt;/strong&gt;. Instructions in CLAUDE.md are suggestions the model usually follows. Hooks are pipeline machinery the model cannot skip. The difference matters most for the things you can never let slip:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Need&lt;/th&gt;
&lt;th&gt;CLAUDE.md instruction&lt;/th&gt;
&lt;th&gt;Hook&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Prefer English comments"&lt;/td&gt;
&lt;td&gt;Fine - occasional misses are harmless&lt;/td&gt;
&lt;td&gt;Overkill&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Format after every edit"&lt;/td&gt;
&lt;td&gt;Misses 1 in 10 times&lt;/td&gt;
&lt;td&gt;Fires 100%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Never force-push to main"&lt;/td&gt;
&lt;td&gt;One miss = disaster&lt;/td&gt;
&lt;td&gt;The only safe option&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Log every bash command for audit"&lt;/td&gt;
&lt;td&gt;Will drift over a long session&lt;/td&gt;
&lt;td&gt;Guaranteed complete&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Rule of thumb: if a miss costs you real money, real data, or real trust, it belongs in a hook, not a prompt.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lifecycle Events: Where Hooks Attach
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F60tqhvwhly8a1gbw80uv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F60tqhvwhly8a1gbw80uv.png" alt="The Claude Code hook lifecycle: SessionStart, UserPromptSubmit, PreToolUse (the only event that can block), tool execution, PostToolUse, and Stop" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claude Code exposes events covering every key moment in a session. The six you'll actually use:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;th&gt;When it fires&lt;/th&gt;
&lt;th&gt;What it's for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PreToolUse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Before any tool call executes&lt;/td&gt;
&lt;td&gt;The only event that can &lt;strong&gt;block&lt;/strong&gt; an action&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PostToolUse&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;After a tool call completes&lt;/td&gt;
&lt;td&gt;Post-processing: format, lint, test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Stop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When Claude is about to finish responding&lt;/td&gt;
&lt;td&gt;Quality gates: don't let it stop with failing tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Notification&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When Claude needs your attention&lt;/td&gt;
&lt;td&gt;Forward to desktop/Slack so you can context-switch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SessionStart&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;New session begins&lt;/td&gt;
&lt;td&gt;Inject env vars, check dependencies, start logging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UserPromptSubmit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;You send a message&lt;/td&gt;
&lt;td&gt;Attach extra context before the model sees it&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There are more (&lt;code&gt;SubagentStart&lt;/code&gt;/&lt;code&gt;SubagentStop&lt;/code&gt;, &lt;code&gt;PreCompact&lt;/code&gt;, &lt;code&gt;WorktreeCreate&lt;/code&gt;/&lt;code&gt;WorktreeRemove&lt;/code&gt;) but the six above cover 90% of real usage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Three Things a Hook Can Do
&lt;/h2&gt;

&lt;p&gt;Every hook returns one of three decisions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Allow&lt;/strong&gt; - do nothing, let the pipeline continue. Pure logging hooks live here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Block&lt;/strong&gt; - stop the action. Only available in &lt;code&gt;PreToolUse&lt;/code&gt;. Claude receives an error explaining the action was rejected by an external rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inject&lt;/strong&gt; - add information into the conversation. Example: your linter found 3 warnings after a file write, inject them so Claude sees and fixes them.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the whole API surface. Three verbs, composed across lifecycle events, cover almost every automation you'll want.&lt;/p&gt;




&lt;h2&gt;
  
  
  Matchers: Scoping When Hooks Fire
&lt;/h2&gt;

&lt;p&gt;You rarely want a hook on every tool call. Matchers filter by tool name using regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bash"&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;shell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;commands&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write|Edit"&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;modifications&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;everything&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(audit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;logs)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Typical scoping: security rules match &lt;code&gt;Bash&lt;/code&gt;, formatting matches &lt;code&gt;Write|Edit&lt;/code&gt;, audit logging matches everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Four Handler Types
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;What runs&lt;/th&gt;
&lt;th&gt;When to use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A shell command or script. Receives event JSON via stdin, returns decision via stdout.&lt;/td&gt;
&lt;td&gt;90% of hooks. Fast, deterministic, free.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HTTP&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A request to a URL&lt;/td&gt;
&lt;td&gt;Push events to audit systems or internal APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Prompt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Claude model evaluates the event&lt;/td&gt;
&lt;td&gt;Grey areas a regex can't judge ("is this code security-sensitive?"). Costs tokens.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A full agent instance investigates&lt;/td&gt;
&lt;td&gt;Heavyweight checks needing multi-step reasoning. Rare.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Start with Command. Reach for Prompt only when the rule genuinely can't be expressed as a regex or script - and accept that you've traded determinism for judgment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Configuration Lives
&lt;/h2&gt;

&lt;p&gt;Hooks go in &lt;code&gt;settings.json&lt;/code&gt; at three levels, all additive:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;Use for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~/.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All your projects&lt;/td&gt;
&lt;td&gt;Security rules, audit logs, notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.claude/settings.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This project, committed to git&lt;/td&gt;
&lt;td&gt;Team-shared rules: this repo formats with Prettier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.claude/settings.local.json&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This project, gitignored&lt;/td&gt;
&lt;td&gt;Personal preferences, machine-specific paths&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Multiple hooks on one event all run in order. Type &lt;code&gt;/hooks&lt;/code&gt; inside Claude Code to see everything currently registered - useful when a hook misbehaves and you forgot where you defined it.&lt;/p&gt;




&lt;h2&gt;
  
  
  7 Hooks Worth Installing First
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Auto-format after every edit
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PostToolUse&lt;/code&gt;, matcher &lt;code&gt;Write|Edit&lt;/code&gt;. Extract the file path from the event JSON, run your formatter on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PostToolUse"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"matcher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Write|Edit"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"hooks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"jq -r '.tool_input.file_path' | xargs npx prettier --write --ignore-unknown"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You never mention formatting again. Neither does Claude.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Block force-push to main
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PreToolUse&lt;/code&gt;, matcher &lt;code&gt;Bash&lt;/code&gt;. Script checks the command string for &lt;code&gt;push --force&lt;/code&gt; or &lt;code&gt;push -f&lt;/code&gt; targeting &lt;code&gt;main&lt;/code&gt;/&lt;code&gt;master&lt;/code&gt;, returns block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;cmd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.tool_input.command'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$cmd&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-qE&lt;/span&gt; &lt;span class="s1"&gt;'push\s+(--force|-f).*(main|master)'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"decision": "block", "reason": "Force push to main is not allowed. Use a feature branch."}'&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi
&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'{"decision": "allow"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Protect secret files
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PreToolUse&lt;/code&gt;, matcher &lt;code&gt;Write|Edit&lt;/code&gt;. Block writes to &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;credentials.json&lt;/code&gt;, anything matching your secrets patterns. Even if you ask Claude to "update the .env", the hook says no - which is exactly the point. Secrets get edited by humans.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Quality gate on Stop
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Stop&lt;/code&gt; event. Run your linter and test suite when Claude tries to finish. Errors found? Inject them back: "ESLint reports 2 errors in src/api/checkout.ts." Claude sees the failures and keeps working instead of handing you broken code. This single hook changes the default from "looks done" to "verified done."&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Desktop notification when input needed
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Notification&lt;/code&gt; event. On macOS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;osascript &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s1"&gt;'display notification "Claude Code needs your approval" with title "Claude Code"'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop staring at the terminal while long tasks run. Go do something else; the notification pulls you back.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Full audit log
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PreToolUse&lt;/code&gt; or &lt;code&gt;PostToolUse&lt;/code&gt;, no matcher. Append tool name, input, and timestamp to a JSONL file. After any session you have a complete record of what was read, written, and executed. Costs nothing until the day you really need it.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Supabase migration guard
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;PreToolUse&lt;/code&gt;, matcher &lt;code&gt;Bash&lt;/code&gt;. If the command contains &lt;code&gt;supabase db reset&lt;/code&gt; or a destructive migration against your production project ref, block it. Agents are enthusiastic about "fixing" databases. Production is not the place to learn this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hooks vs the Permission System
&lt;/h2&gt;

&lt;p&gt;Claude Code already has permissions (allow/ask/deny per tool). Where's the line?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permissions are a gate&lt;/strong&gt;: an action passes or it doesn't. &lt;strong&gt;Hooks are programmable machinery&lt;/strong&gt;: they can block, but also transform, inject context, trigger external systems, and post-process results.&lt;/p&gt;

&lt;p&gt;Use permissions for coarse access control ("always ask before bash"). Use hooks for everything with logic in it ("block bash only when it touches main"). They stack: permissions filter first, hooks refine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Rules From the Field
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Keep hooks dumb.&lt;/strong&gt; Check a path, match a regex, read an exit code. A hook's value is certainty - a "smart" hook that calls an LLM gives that certainty back. Sometimes worth it, but know the trade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Watch latency.&lt;/strong&gt; A 3-second hook on &lt;code&gt;PreToolUse&lt;/code&gt; means every tool call waits 3 seconds. Claude Code makes dozens of tool calls per task. Keep synchronous hooks under ~200ms; push slow work (remote logging) to async.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test the blocker hooks.&lt;/strong&gt; A formatting hook that silently fails costs you nothing. A force-push blocker that silently fails costs you a main branch. Trigger each blocking hook deliberately once and confirm it actually blocks.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Hooks compose with everything else in the Claude Code stack: give sub-agents a test-runner hook, give &lt;a href="https://www.aibuilderclub.com/blog/claude-code-agent-teams-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Agent Teams&lt;/a&gt; a quality gate on task completion, auto-initialize environments when a &lt;a href="https://www.aibuilderclub.com/blog/claude-code-worktree-parallel-agents?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;worktree&lt;/a&gt; is created.&lt;/p&gt;

&lt;p&gt;The model handles judgment. Hooks handle certainty. Agents are probabilistic - they do the right thing most of the time. Hooks exist for the things where "most of the time" is not good enough.&lt;/p&gt;

&lt;p&gt;Start with one: the auto-formatter. Five minutes of setup, and you will never type "can you format that" again.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>claudecode</category>
      <category>hooks</category>
      <category>automation</category>
      <category>advanced</category>
    </item>
    <item>
      <title>The 6 Components of a Production Agent Harness</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Sat, 18 Jul 2026 05:46:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/the-6-components-of-a-production-agent-harness-2a16</link>
      <guid>https://dev.to/aijasonz/the-6-components-of-a-production-agent-harness-2a16</guid>
      <description>&lt;p&gt;&lt;strong&gt;Same model, same API, same price - one team's agent acts like a seasoned employee, the other's like an intern with amnesia.&lt;/strong&gt; The difference has a location, and it isn't the weights. LangChain's equation names it: &lt;strong&gt;Agent = Model + Harness&lt;/strong&gt;, so Harness = everything that isn't the model. The labs set your model ceiling. The harness is entirely yours.&lt;/p&gt;

&lt;p&gt;"Everything that isn't the model" is too vague to build from, so here's the working decomposition - six components, what each does, and the characteristic failure that appears when it's missing. The last column is the useful one: agents fail in patterns, and the pattern points at the gap.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Question it answers&lt;/th&gt;
&lt;th&gt;Missing → failure looks like&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Context management&lt;/td&gt;
&lt;td&gt;What does the model see?&lt;/td&gt;
&lt;td&gt;Inconsistent quality, forgotten constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Tool system&lt;/td&gt;
&lt;td&gt;What can it touch?&lt;/td&gt;
&lt;td&gt;Hallucinated facts, wrong tool, no tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;What happens next?&lt;/td&gt;
&lt;td&gt;Half-finished pieces, no coherent whole&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;State &amp;amp; memory&lt;/td&gt;
&lt;td&gt;What persists?&lt;/td&gt;
&lt;td&gt;Every session starts from zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Evaluation &amp;amp; observability&lt;/td&gt;
&lt;td&gt;Was it right?&lt;/td&gt;
&lt;td&gt;Confident garbage, undebuggable runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Constraints &amp;amp; recovery&lt;/td&gt;
&lt;td&gt;What if it breaks?&lt;/td&gt;
&lt;td&gt;One bad step kills the run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs7qq0ov4op0iscsrk04t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs7qq0ov4op0iscsrk04t.png" alt="The six harness components surrounding the model: context, tools, orchestration, state and memory, evaluation, constraints and recovery" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Context Management: What the Model Sees
&lt;/h2&gt;

&lt;p&gt;The most counterintuitive truth in agent work: most "dumb model" complaints are &lt;em&gt;information environment&lt;/em&gt; complaints. Same intelligence, curated inputs, transformed output.&lt;/p&gt;

&lt;p&gt;Three sub-jobs. &lt;strong&gt;Boundary definition&lt;/strong&gt; - role, goal, success criteria. "Write an article" and "write a technical explainer for builders who know APIs but not transformers, optimizing for clarity over completeness" are different tasks; only one of them is the task you meant. &lt;strong&gt;Selection and exclusion&lt;/strong&gt; - the senior-engineer move of handing over three relevant docs instead of forwarding the whole wiki. Relevance in, noise out, because &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;noise costs attention&lt;/a&gt; even when ignored. &lt;strong&gt;Structure&lt;/strong&gt; - fixed rules, current task, run state, external evidence in stable layers, so the model never loses the constraint in the pile.&lt;/p&gt;

&lt;p&gt;This component is deep enough to be its own discipline - the &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;context engineering guide&lt;/a&gt; covers rot, poisoning, and the four management strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Tool System: What It Can Touch
&lt;/h2&gt;

&lt;p&gt;Without tools a model only predicts text. &lt;a href="https://www.aibuilderclub.com/blog/function-calling-how-llms-use-tools?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Tools&lt;/a&gt; are where prediction becomes action - and where three design questions hide:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which tools?&lt;/strong&gt; Scope to the job. A writing agent and a security-audit agent should have &lt;em&gt;disjoint&lt;/em&gt; toolsets; the universal-toolbelt design is how you get the 46-tool collapse, where selection accuracy degrades just from menu length. &lt;strong&gt;When to call?&lt;/strong&gt; Both failure directions are real: the agent that searches the web to answer "what's 2+2," and the agent that confidently invents your API's auth flow instead of reading the docs sitting in its toolset. Calibrating tool-reach is harness work - prompts, examples, and tool descriptions that draw the line. &lt;strong&gt;What happens to results?&lt;/strong&gt; Ten raw search results dumped into context is &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;pollution&lt;/a&gt;; the harness distills - extract the claims, keep the citations, drop the boilerplate - before the model reasons over it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Orchestration: What Happens Next
&lt;/h2&gt;

&lt;p&gt;The gap between "can do every step" and "does the whole job" is orchestration. An unorchestrated agent freestyles: does some things, in some order, stops at some point. The output is jagged - brilliant fragments, missing connective tissue, no verification pass.&lt;/p&gt;

&lt;p&gt;Mature orchestration makes five things explicit: &lt;strong&gt;step decomposition&lt;/strong&gt; (the task as a sequence, not a vibe), &lt;strong&gt;decision points&lt;/strong&gt; (where the path branches and on what), &lt;strong&gt;intermediate artifacts&lt;/strong&gt; (each step's output is the next step's input - so it gets named and stored), &lt;strong&gt;termination conditions&lt;/strong&gt; (what "done" means, mechanically), and &lt;strong&gt;escalation rules&lt;/strong&gt; (which failures invite a retry and which summon a human). The structure can be code (a LangGraph graph), convention (Claude Code's explore-plan-code-commit), or a &lt;a href="https://www.aibuilderclub.com/blog/claude-code-todowrite-vs-task?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;task list with dependencies&lt;/a&gt; - what matters is that the agent walks a track rather than wandering a field.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. State and Memory: What Persists
&lt;/h2&gt;

&lt;p&gt;A stateless agent is Groundhog Day with API costs - re-explaining the project every morning, re-discovering Tuesday's conclusion on Thursday. Statefulness splits into three tiers, and conflating them is the classic mistake:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Run state&lt;/strong&gt; - where am I in &lt;em&gt;this&lt;/em&gt; task? Done, doing, blocked. (The &lt;a href="https://www.aibuilderclub.com/blog/claude-code-todowrite-vs-task?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Task system's&lt;/a&gt; territory.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session memory&lt;/strong&gt; - what happened in &lt;em&gt;this&lt;/em&gt; conversation that later steps need?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-term memory&lt;/strong&gt; - what survives across sessions? Preferences, conventions, decisions. (&lt;a href="https://www.aibuilderclub.com/blog/agent-memory-systems-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Three memory types, write/maintain/retrieve lifecycle&lt;/a&gt; - its own discipline.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tier-mixing produces both failure flavors: agents that forget the project context (under-persistence) and agents whose memory is a junk drawer of expired facts steering current work (over-persistence, no hygiene).&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Evaluation and Observability: Was It Right?
&lt;/h2&gt;

&lt;p&gt;The harness layer most often skipped, and the one that separates demos from production. Two halves:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluation&lt;/strong&gt; - because models grade their own homework generously. Anthropic measured this directly: self-evaluation skews optimistic, especially on fuzzy criteria like design quality. Their fix - a separate evaluator agent with fresh context that &lt;em&gt;actually operates the output&lt;/em&gt; (clicks the UI, runs the tests) rather than admiring the code - is the &lt;a href="https://www.aibuilderclub.com/blog/harness-engineering-agent-production-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;generator/evaluator pattern&lt;/a&gt;, and the production results that followed are that article's whole story. The principle is older than AI: &lt;strong&gt;production and acceptance must be different parties.&lt;/strong&gt; When you run agents in a loop, this evaluator &lt;em&gt;is&lt;/em&gt; the &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;verifier that decides "good enough"&lt;/a&gt; - and it, not the model, is the bottleneck.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt; - a 15-step run with 8 tool calls that produced a wrong answer is undebuggable without structured traces: which step drifted, what the tool returned, where reasoning forked wrong. Log every step's inputs, outputs, and decision; make runs replayable; alert on no-progress loops. Boring. Indispensable. The first thing you'll wish you had.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Constraints and Recovery: What If It Breaks
&lt;/h2&gt;

&lt;p&gt;Demos run the happy path; production runs the other ones. Real runs hit expired tokens, malformed files, rate limits, and instructions the model creatively reinterprets. Three sub-layers hold the line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Constraints&lt;/strong&gt; - what's off-limits regardless of model opinion: &lt;a href="https://www.aibuilderclub.com/blog/agent-modes-plan-default-auto?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;permission boundaries&lt;/a&gt;, &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;deterministic hooks&lt;/a&gt; on dangerous patterns, &lt;a href="https://www.aibuilderclub.com/blog/agent-sandbox-os-level-security?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;sandbox walls&lt;/a&gt; underneath everything. Hard rails, not suggestions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation&lt;/strong&gt; - pre-handoff checks: does the output answer the ask, match the format, pass the tests? Catches "confidently wrong" at the cheapest possible moment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recovery&lt;/strong&gt; - the difference between a stumble and a dead run: classify the error, retry transients with backoff, reroute hard failures to an alternate path, drop back to the last good state when the branch is poisoned. (One nuance from the &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;context guide&lt;/a&gt;: keep the &lt;em&gt;evidence&lt;/em&gt; of failure in context while recovering - models that see their own error stop repeating it.)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Using This as a Gap Check
&lt;/h2&gt;

&lt;p&gt;The six aren't a maturity ladder you climb in order - they're load-bearing walls, and your agent's weirdest behavior points at the weak one. Run the diagnostic backwards from symptoms: quality varies run-to-run with identical inputs → context. Makes things up despite having the right tool → tool calibration. Great pieces, incoherent whole → orchestration. Asks you things it knew yesterday → state. You discover failures only when users do → evaluation. One flaky API call kills forty minutes of work → recovery.&lt;/p&gt;

&lt;p&gt;Most builders, honestly scored, are strong on tools, passable on context, and near-zero on evaluation and recovery - which is exactly why most agents demo beautifully and deploy badly. The labs keep shipping better engines. The six walls are the house, and &lt;a href="https://www.aibuilderclub.com/blog/harness-engineering-agent-production-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;the teams getting production results&lt;/a&gt; are the ones who built all six. And if you're unsure where these six walls end and the agent's &lt;em&gt;loop&lt;/em&gt; begins - the goal, the verifier, the stop condition - &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-vs-harness-engineering?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;the loop vs harness comparison&lt;/a&gt; draws that boundary precisely.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>harnessengineering</category>
      <category>production</category>
      <category>advanced</category>
    </item>
    <item>
      <title>Crabbox: Cloud Sandboxes for Parallel Coding Agents</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Thu, 16 Jul 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/aijasonz/crabbox-cloud-sandboxes-for-parallel-coding-agents-3bbc</link>
      <guid>https://dev.to/aijasonz/crabbox-cloud-sandboxes-for-parallel-coding-agents-3bbc</guid>
      <description>&lt;h1&gt;
  
  
  Crabbox: Isolated Cloud Sandboxes for Parallel Coding Agents
&lt;/h1&gt;

&lt;p&gt;When you run ten or fifteen coding agents in parallel, writing code stops being the bottleneck. Merging it becomes the bottleneck. Every agent produces a pull request, and every PR carries the risk of breaking the system, so the real work shifts from "make the agent write code" to "let the agent prove its code works before a human ever looks at it."&lt;/p&gt;

&lt;p&gt;That is the problem Crabbox - the new project from OpenClaw creator Peter Steinberger - is built to solve. Here is the full walkthrough, why parallel testing breaks on your laptop, and the open-source codebase harness that productizes the fix.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/1HkqTlXbQmQ"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  The merge bottleneck is the new bottleneck
&lt;/h2&gt;

&lt;p&gt;Once your team sets up loops - agents that get triggered on their own, pick up work, and ship it - you end up with a lot of sessions running at once. At almost any given time I have at least ten agent sessions going; Peter has posted screenshots of fifteen-plus in parallel. The result is a massive volume of PRs that simply was not possible before.&lt;/p&gt;

&lt;p&gt;That volume is the problem. Each PR has to be reviewed, and each one might break production. So the constraint moves up the stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   OLD bottleneck            NEW bottleneck
 ┌────────────────┐        ┌────────────────────┐
 │ writing code   │  ───►  │ getting code MERGED │
 │ (agents solved │        │ verifying + trusting│
 │  this)         │        │ 15 parallel PRs     │
 └────────────────┘        └────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix is not "review faster." It is to give each agent the tools to verify its own work and attach evidence - a passing test, a screenshot, a screen recording - to the PR, so a human is reviewing proof, not guessing. That is the first job of a codebase harness: make the repo agent-ready so agents can run, test, and verify before they hand work back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why parallel testing breaks on your laptop
&lt;/h2&gt;

&lt;p&gt;Giving one agent a browser tool and a dev server works fine. The setup falls apart when many agents run at once, because they share your machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One database, one schema.&lt;/strong&gt; If a local Supabase or Postgres instance is shared, one agent trying a new schema migration can break every other session at once.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hardcoded ports.&lt;/strong&gt; Most repos are not set up to run multiple instances side by side - a port is pinned for a good reason, and two dev servers collide.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One Docker daemon, one OS.&lt;/strong&gt; Parallel sessions share the same daemon and resources, so they step on each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource limits.&lt;/strong&gt; A modern production repo is heavy. Running many full instances locally is slow and often impossible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git work trees solve the &lt;em&gt;code&lt;/em&gt; isolation problem - each agent gets its own checkout to modify - but they do not solve the &lt;em&gt;runtime&lt;/em&gt; problem. Agents still need a live dev server and database to actually test against, and that is what collides.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: one isolated sandbox per work tree
&lt;/h2&gt;

&lt;p&gt;The right architecture is to stop running every session on your local machine and instead give each agent its own isolated cloud environment - its own box, its own database, its own dev server - that cannot affect any other session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            LOCAL (work trees: code isolation only)
   agent A ─┐   agent B ─┐   agent C ─┐
            │            │            │
            v            v            v
   ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
   │ CLOUD BOX A │ │ CLOUD BOX B │ │ CLOUD BOX C │   runtime isolation
   │  own DB     │ │  own DB     │ │  own DB     │
   │  own server │ │  own server │ │  own server │
   └─────────────┘ └─────────────┘ └─────────────┘
       test           test            test
   (no shared schema, ports, or daemon - they can't break each other)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Building that pipeline by hand is real work: spin up a machine on spot, mount a disk, copy the code in, install dependencies, start the app, open a browser to test, then tear it all down afterward. My team built exactly this, and it unlocked a lot - but one rough edge remained: when an agent finds a bug mid-test, getting the local fix back into the cloud box is awkward. The normal commit-push-CI flow floods the repo with throwaway commits, and you do not want to rebuild the box every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Crabbox does
&lt;/h2&gt;

&lt;p&gt;Crabbox closes that last gap. It lets an agent warm up a cloud box, sync the uncommitted diff straight from the local work tree, and run tests against it in real time - so you can change a file locally and retest in seconds.&lt;/p&gt;

&lt;p&gt;The workflow an agent runs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Warm up a box&lt;/strong&gt; - spin up an isolated cloud sandbox on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run any command in the cloud&lt;/strong&gt; - the agent runs bash commands as if local, but they execute in the box. Each run first syncs the dirty diff from your local work tree (no commit needed - the folder just has to be git-initialized), then runs the command against the latest code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate evidence&lt;/strong&gt; - collect screenshots, record video of the run, and publish artifacts to storage (such as an S3 bucket) so they can be posted inline as PR comments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stop the box&lt;/strong&gt; - tear it down and delete it when the task is done.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  agent finds a bug ─► fixes file LOCALLY ─► next `run` auto-syncs the diff
        ▲                                              │
        └──────────────── retest in the cloud ◄────────┘
   no extra commits, no box rebuild - always testing the latest version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The whole thing is configured with three files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;A Dockerfile&lt;/strong&gt; that encapsulates everything your local machine has - Node, Docker, the Supabase CLI, any tool the app needs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A &lt;code&gt;crabbox.yml&lt;/code&gt;&lt;/strong&gt; that defines the sandbox provider (the video uses Daytona for fast startup via prebuilt snapshots), the default work root, which folders to exclude from sync (heavy or unneeded ones - node_modules and build dirs are usually gitignored already), and environment variables to pass. Those vars are pushed to the box over an encrypted SSH connection, so the data plane stays relatively safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A &lt;code&gt;setup.sh&lt;/code&gt;&lt;/strong&gt; so the agent runs one script to install dependencies and bring the dev server up, instead of stepping through it each time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exact command names and flags live in the project and the video above - treat the steps here as the shape of the workflow, not copy-paste syntax.&lt;/p&gt;

&lt;h2&gt;
  
  
  The codebase harness that productizes this
&lt;/h2&gt;

&lt;p&gt;You do not have to wire all of this together from scratch. We packaged the setup my team runs into an open-source Claude Code plugin: the &lt;a href="https://github.com/AI-Builder-Club/skills" rel="noopener noreferrer"&gt;AI Builder Club skills repo&lt;/a&gt;. It ships two flagship skill sets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Codebase harness&lt;/strong&gt; - make any repo agent-ready so agents can run, test, verify, and ship, including an isolated cloud box per agent so loops can ship code in parallel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loops&lt;/strong&gt; - spin up compounding agent loops on a shared, file-based knowledge base.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install it in Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plugin marketplace add AI-Builder-Club/skills
/plugin install skills@ai-builder-club
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the two entry points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/setup-codebase-harness&lt;/code&gt;&lt;/strong&gt; - run it in the repo your agents work in, so they can run, test, and verify their own work (this is the harness Crabbox plugs into).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;/new-loop&lt;/code&gt;&lt;/strong&gt; - run it where your agent's memory should live; it bootstraps the shared knowledge base and scaffolds your first compounding loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want the full walkthrough of the concept - the four ingredients of a loop and how the harness fits - the &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;loop engineering guide&lt;/a&gt; is the written companion, and &lt;a href="https://www.aibuilderclub.com/blog/ai-agent-reliability-cost-control?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Agent Reliability and Cost Control&lt;/a&gt; covers why agent-generated evidence is what makes parallel work safe to merge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go deeper:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.aibuilderclub.com/courses/ai-agent-course?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Agent 101 Course&lt;/a&gt; - build agents that run, test, and verify their own work, then deploy them&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.aibuilderclub.com/courses/claude-code-course?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Claude Code 101 Course&lt;/a&gt; - CLAUDE.md, hooks, subagents, and work trees, the foundation a codebase harness sits on&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Want the step-by-step build alongside a team running this in production? &lt;a href="https://www.aibuilderclub.com/lp/loop-engineer?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=crabbox-parallel-agent-sandboxes" rel="noopener noreferrer"&gt;Join AI Builder Club&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/openclaw-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;OpenClaw: What It Is and How to Use It&lt;/a&gt;&lt;/strong&gt; - The prior project from Crabbox's creator, Peter Steinberger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Loop Engineering: Generators, Verifiers, and Stop Conditions&lt;/a&gt;&lt;/strong&gt; - The concept the codebase harness serves: agents that ship and verify on their own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/ai-agent-reliability-cost-control?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Agent Reliability and Cost Control&lt;/a&gt;&lt;/strong&gt; - Why agent-produced evidence is what makes parallel PRs safe to merge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/claude-code-dynamic-workflows?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Dynamic Workflows: Orchestrate Subagents at Scale&lt;/a&gt;&lt;/strong&gt; - Running many agents from one script once the harness is in place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Harness: The 6 Components&lt;/a&gt;&lt;/strong&gt; - Where run/test/verify fits in the larger harness picture.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Start Here
&lt;/h2&gt;

&lt;p&gt;Pick the repo your agents already work in and run &lt;code&gt;/setup-codebase-harness&lt;/code&gt; from the &lt;a href="https://github.com/AI-Builder-Club/skills" rel="noopener noreferrer"&gt;AI Builder Club skills repo&lt;/a&gt;. Get one agent running its own tests and attaching evidence to a PR before you scale to ten. The merge bottleneck only gets worse with volume, so solve verification first.&lt;/p&gt;

&lt;p&gt;For the full build alongside a team running this in production, join the AI Builder Club.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.aibuilderclub.com/lp/loop-engineer?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=crabbox-parallel-agent-sandboxes" rel="noopener noreferrer"&gt;Join AI Builder Club&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/crabbox-parallel-agent-sandboxes?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>codebaseharness</category>
      <category>parallelagents</category>
      <category>crabbox</category>
    </item>
    <item>
      <title>Codebase Memory MCP: Give Your Coding Agent a Map (2026)</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Thu, 16 Jul 2026 05:46:17 +0000</pubDate>
      <link>https://dev.to/aijasonz/codebase-memory-mcp-give-your-coding-agent-a-map-2026-535l</link>
      <guid>https://dev.to/aijasonz/codebase-memory-mcp-give-your-coding-agent-a-map-2026-535l</guid>
      <description>&lt;h1&gt;
  
  
  Codebase Memory MCP: Stop Making Your Coding Agent Read Your Repo as Flat Text
&lt;/h1&gt;

&lt;p&gt;Ask a coding agent to change something in a big codebase and you know what happens. It greps, gets a wall of matches, opens 20 files one by one, and still misses half the places that might break.&lt;/p&gt;

&lt;p&gt;Here is the thing though: your codebase is already a map. Every import is an edge. Every function call is an edge. Your agent throws that structure away and reads the whole thing as flat text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codebase Memory MCP fixes this by indexing your repo into a persistent code graph&lt;/strong&gt; - functions, classes, call chains, routes, cross-file and cross-service links - that the agent queries instead of grepping. It is written in C, parses 158 languages via tree-sitter, indexes most repos in seconds, and answers structural queries in under a millisecond. When I ran the same architecture question with and without it on my own monorepo, token consumption dropped from ~38,000 to ~11,000. Over a two-question session: 64,000 vs 33,000. About half.&lt;/p&gt;

&lt;p&gt;Prefer to watch? Here is the full walkthrough:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/iWRmtPdFbGw"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Why grep burns your context window
&lt;/h2&gt;

&lt;p&gt;The default exploration loop every coding agent runs on a structural question looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Grep for the identifier. Get matches across dozens of files.&lt;/li&gt;
&lt;li&gt;Read the files one by one. Each read dumps hundreds or thousands of lines into context.&lt;/li&gt;
&lt;li&gt;Follow the imports. More reads.&lt;/li&gt;
&lt;li&gt;Try to hold the reconstructed structure in the context window while doing the actual work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every step pays full price because grep returns &lt;em&gt;text&lt;/em&gt;, not &lt;em&gt;structure&lt;/em&gt;. The agent has to rebuild the relationships between symbols from scratch, on every task, by reading source. Claude Code has subagents to contain this (the search runs in a separate context), which helps with pollution but is slow, and the cost still gets paid somewhere.&lt;/p&gt;

&lt;p&gt;This is &lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;context engineering's&lt;/a&gt; ugliest corner: in production agents, roughly 100 input tokens are consumed for every output token, and on large-repo tasks a huge share of those inputs is just re-discovering how the code fits together. The project's &lt;a href="https://arxiv.org/pdf/2603.27277" rel="noopener noreferrer"&gt;arXiv evaluation&lt;/a&gt; across 31 real-world repositories puts numbers on it: graph-based exploration answered structural questions with 10x fewer tokens and 2.1x fewer tool calls than file-by-file exploration, at 83% answer quality. The README's extreme benchmark: five structural queries cost ~3,400 tokens via the graph versus ~412,000 via grep-and-read.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnc7cygfi24lksypu8gm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwnc7cygfi24lksypu8gm.png" alt="Diagram comparing a coding agent exploring a repo as flat text via grep, reading 20 files and consuming 38,000 tokens, versus querying a code graph with search_graph and trace_path and consuming 11,000 tokens for the same question" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Codebase Memory MCP actually is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/DeusData/codebase-memory-mcp" rel="noopener noreferrer"&gt;Codebase Memory MCP&lt;/a&gt; is an open-source (MIT) MCP server that extracts every function, class, method, route, and import from your code and builds a relationship graph out of them. Cross-file, cross-package, even cross-repo: if service A calls an HTTP route in service B, that edge is in the graph.&lt;/p&gt;

&lt;p&gt;Two design decisions make it different from the pile of codebase-index tools you have already seen and forgotten:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. No LLM in the indexing pipeline.&lt;/strong&gt; Earlier projects ran a language-model pass to write a "knowledge map" of your repo. Those maps cost money to build, took minutes to hours, and went stale the moment the code changed. Codebase Memory MCP parses with tree-sitter grammars in pure C. Indexing is purely programmatic: an average repo indexes in seconds, and the Linux kernel - 28 million lines across 75,000 files - indexes in about 3 minutes. Rebuilding on change is cheap enough that the graph just stays current.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. It meets the agent where it already works.&lt;/strong&gt; More on the hook pattern below, because it is the most copyable idea in the project.&lt;/p&gt;

&lt;p&gt;The agent gets a toolset that replaces the grep-read-repeat loop:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What the agent uses it for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_architecture&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quick overview: languages, packages, routes, hotspots, clusters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;search_graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Locate the node for a symbol by name, label, or file pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;trace_path&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Follow the call chain: who calls this, what does it touch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;detect_changes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Map a git diff to affected symbols, with risk classification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;query_graph&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cypher-like queries, e.g. "callers of handle_order with no test coverage"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_code_snippet&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pull just the source of one function by qualified name&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last pairing is the token win in miniature: instead of reading a 2,000-line file to see one function, the agent asks the graph where the function is and pulls only its body.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;detect_changes&lt;/code&gt; is the sleeper feature for teams. Point it at a PR diff and it returns the blast radius - every symbol the change can reach - which turns &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;agent code review&lt;/a&gt; from "read everything and hope" into a graph query.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hook pattern: why this MCP works when others get ignored
&lt;/h2&gt;

&lt;p&gt;Here is the failure mode that killed most code-search MCPs: the agent forgets to use them. You install a beautiful semantic search tool, and the agent... greps anyway. Claude Code and Codex are heavily optimized around their built-in search tools, and no system prompt reliably overrides that habit.&lt;/p&gt;

&lt;p&gt;Codebase Memory MCP acknowledges this instead of fighting it. On Claude Code it registers a &lt;strong&gt;PreToolUse hook&lt;/strong&gt;: when the agent calls its normal Grep or Glob tool, the hook intercepts the call, runs the graph lookup for matching symbols, and injects the structured context - call chains, relationships, definitions - alongside the ordinary grep results. The grep still runs. The agent just gets the map with the matches, whether or not it remembered the MCP exists.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4p25nqcu961sldjh49lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4p25nqcu961sldjh49lw.png" alt="Diagram of the PreToolUse hook pattern: the coding agent calls its normal grep tool, the hook intercepts the call, queries the code graph, and injects call-chain context into the grep result so the agent gets structure without changing its behavior" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are building MCP tools yourself, steal this. Do not rely on the model choosing your tool over its built-ins; use &lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;hooks&lt;/a&gt; to enrich the tools it already prefers. It is the difference between shipping a tool and shipping a behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real test: tracing a hidden lock through a monorepo
&lt;/h2&gt;

&lt;p&gt;I indexed the codebase for Superdesign, our vibe-design platform. It has a backend function called &lt;code&gt;createDesignDraftNode&lt;/code&gt; - the tool an agent calls to add a design to the infinite canvas. Because multiple agents can generate designs on the same canvas at once, everything flows through a queue guarded by a &lt;strong&gt;canvas lock&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The catch: the lock is invisible from where the work starts. &lt;code&gt;createDesignDraftNode&lt;/code&gt; never calls it directly; the protection is delegated down through layers. Grep that file for "lock" and you get nothing. Any agent (or human) reading the entry point would conclude the protection does not exist.&lt;/p&gt;

&lt;p&gt;So I asked two questions, in two sessions - one with the graph, one with MCP explicitly disabled:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;With Codebase Memory MCP&lt;/th&gt;
&lt;th&gt;Without (default grep)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Trace the createDesignDraftNode and canvas lock flow"&lt;/td&gt;
&lt;td&gt;~11,000 tokens, full flow returned in seconds&lt;/td&gt;
&lt;td&gt;~38,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"What breaks if I change the lock?" (cumulative)&lt;/td&gt;
&lt;td&gt;~33,000 tokens, all 13 call sites identified&lt;/td&gt;
&lt;td&gt;~64,000 tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Same model, same repo, same questions. Half the tokens, and the graph version found every call site - which matters more than the cost, because the expensive failure is the new engineer (or agent) who decides the lock "slows things down," tweaks it, and ships a race condition. Ask "what will break if I change this?" and the graph answers with the actual dependency list instead of a best-effort sample.&lt;/p&gt;

&lt;p&gt;Those are my numbers on one repo, measured from Claude Code's context inspector; your ratio will move with repo size and question type. The pattern held across every structural question I threw at it: the bigger and more cross-cutting the question, the wider the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set it up (2 commands, ~10 minutes)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Install.&lt;/strong&gt; One command on macOS/Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Want the graph visualization UI too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--ui&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installer auto-detects your installed agents (Claude Code, Codex CLI, Gemini CLI, Zed, OpenCode, Antigravity, Aider, KiloCode, VS Code, OpenClaw, Kiro) and configures the MCP entries and hooks for each. Single static binary, zero runtime dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Index.&lt;/strong&gt; Open your coding agent in the repo and tell it: "Help me use codebase memory MCP." It will run the indexing, and if your repo already has decent documentation it applies ignore filters on its own - mine correctly skipped the legacy folders. My semi-complex monorepo indexed in a few seconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Verify.&lt;/strong&gt; Ask it to trace a function you know is load-bearing. You should see &lt;code&gt;search_graph&lt;/code&gt; and &lt;code&gt;trace_path&lt;/code&gt; calls come back with the full chain, no file-by-file reading.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. (Optional) Look at your graph.&lt;/strong&gt; With the UI install: &lt;code&gt;codebase-memory-mcp --ui=true&lt;/code&gt; plus a port gives you a web view of the whole graph. Is it useful? Honestly not sure. It does look really cool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits: the codebase harness
&lt;/h2&gt;

&lt;p&gt;A code graph is one ingredient, not the whole meal. The repos where agents ship reliably have a full &lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;harness&lt;/a&gt;: a way to run the app locally in one command, end-to-end tests that gate PRs, isolated sandboxes for parallel work, and now a structural map of the code.&lt;/p&gt;

&lt;p&gt;That is why we added Codebase Memory MCP to &lt;code&gt;/setup-codebase-harness&lt;/code&gt; in the open-source &lt;a href="https://github.com/AI-Builder-Club/skills" rel="noopener noreferrer"&gt;AI Builder Club skills repo&lt;/a&gt;. Run the skill in your repo and it sets up the MCP and index alongside the rest: e2e test gates, the script toolkit that gets your local server running, and &lt;a href="https://www.aibuilderclub.com/blog/crabbox-parallel-agent-sandboxes?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Crabbox&lt;/a&gt; for parallel agent testing in remote sandboxes. One command, and your codebase goes from flat text to something an agent can actually navigate, run, and verify against.&lt;/p&gt;

&lt;p&gt;If you are optimizing agent costs more broadly, the graph attacks the input side; &lt;a href="https://www.aibuilderclub.com/blog/reduce-claude-code-api-costs?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;reducing Claude Code API costs&lt;/a&gt; covers the rest of the bill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/context-engineering-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Context Engineering: The 100:1 Ratio&lt;/a&gt;&lt;/strong&gt; - Why input tokens dominate agent costs and the four strategies for managing them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/claude-code-hooks-complete-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Claude Code Hooks: The Complete Guide&lt;/a&gt;&lt;/strong&gt; - The mechanism behind the PreToolUse pattern this project uses so well.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/crabbox-parallel-agent-sandboxes?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Crabbox: Cloud Sandboxes for Parallel Agents&lt;/a&gt;&lt;/strong&gt; - The runtime-isolation half of the same codebase harness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/mcp-101-build-mcp-servers?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;MCP 101: Build Your First MCP Server&lt;/a&gt;&lt;/strong&gt; - If the hook-enrichment pattern made you want to build your own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Loop Engineering Guide&lt;/a&gt;&lt;/strong&gt; - The bigger system this plugs into: agents that trigger, work, and verify on their own.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Start Here
&lt;/h2&gt;

&lt;p&gt;Install Codebase Memory MCP in the repo where your agent does real work, index it, and ask one question you already know the answer to: "what breaks if I change X?" Compare what comes back against what you know. That single test tells you whether your agent has been navigating your codebase or guessing at it.&lt;/p&gt;

&lt;p&gt;Then make it part of the harness: run &lt;code&gt;/setup-codebase-harness&lt;/code&gt; from the &lt;a href="https://github.com/AI-Builder-Club/skills" rel="noopener noreferrer"&gt;AI Builder Club skills repo&lt;/a&gt; so every agent session starts with the map.&lt;/p&gt;

&lt;p&gt;For the step-by-step build alongside a team running this in production, join the AI Builder Club.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.aibuilderclub.com/lp/loop-engineer?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=codebase-memory-mcp-guide" rel="noopener noreferrer"&gt;Join AI Builder Club&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/codebase-memory-mcp-guide?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>mcp</category>
      <category>codebaseharness</category>
      <category>developertools</category>
    </item>
    <item>
      <title>Loop Engineering Guide (2026)</title>
      <dc:creator>Jason Zhou</dc:creator>
      <pubDate>Sun, 05 Jul 2026 11:41:52 +0000</pubDate>
      <link>https://dev.to/aijasonz/loop-engineering-guide-2026-43f</link>
      <guid>https://dev.to/aijasonz/loop-engineering-guide-2026-43f</guid>
      <description>&lt;p&gt;&lt;strong&gt;Loop engineering is the discipline of designing the loop an agent runs inside - what it does between tool calls, when it checks its own work, and how it decides it's finished - instead of hand-writing each prompt.&lt;/strong&gt; It's the 2026 successor to prompt engineering. The model writes the prompts now. The scarce skill is defining what "good" and "done" mean, and the part almost every explainer skips is this: in any loop, the &lt;strong&gt;verifier&lt;/strong&gt; is the bottleneck, not the model.&lt;/p&gt;

&lt;p&gt;A few mornings ago I typed one sentence into Claude Code and went to make coffee. By the time I got back, something like forty agents had spun up, written code, checked each other's work, thrown away the bad attempts, and left me three pull requests to review.&lt;/p&gt;

&lt;p&gt;I didn't write forty prompts. I wrote one loop.&lt;/p&gt;

&lt;p&gt;If you've felt the ground shift under "prompt engineering" lately, this is why. Here's the decode - not the hype version, the version you can use this afternoon.&lt;/p&gt;

&lt;p&gt;AI Jason breaks down the same shift in his "Loop Engineer: Systemization and Artifacts" video - what the term actually means, the four core ingredients, and how his team designs loops that compound:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/W6x-hb44C0c"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  How Did We Get From Prompt Engineering to Loop Engineering?
&lt;/h2&gt;

&lt;p&gt;It helps to see the line this sits on:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;Era&lt;/th&gt;
&lt;th&gt;What you do&lt;/th&gt;
&lt;th&gt;Your role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2024&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Prompt engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Write a good prompt, get a good output&lt;/td&gt;
&lt;td&gt;Operator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Parallel agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stop babysitting one chat, run several at once&lt;/td&gt;
&lt;td&gt;Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2026&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Loop engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Build the loop that runs the agents for you&lt;/td&gt;
&lt;td&gt;System designer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The people behind Claude Code have said the quiet part out loud: some mornings they aren't really writing the prompts anymore - another model is - and they're managing hundreds, even thousands, of agents at a time. That sounds like a flex until you see what it implies: &lt;strong&gt;if you're not in the loop pressing enter between every step, something else has to decide when the work is good enough.&lt;/strong&gt; That something else is the whole game.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is a Loop, Exactly?
&lt;/h2&gt;

&lt;p&gt;Strip the jargon and a loop is four moves on repeat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;discover → plan → execute → verify → (repeat until a condition is met)&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You used to &lt;em&gt;be&lt;/em&gt; the loop. You were the thing standing between the agent's steps, reading the output, catching the mistake, deciding what happens next, telling it to try again. Loop engineering is the discipline of stepping &lt;em&gt;out&lt;/em&gt; of that inner cycle and &lt;em&gt;up&lt;/em&gt; to designing the track the agent runs on.&lt;/p&gt;

&lt;p&gt;Here's the simplest possible version. Give the agent a goal and a stopping condition, and let it run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal: get the test suite passing.
Loop: run the tests, read the failures, fix the most likely cause, run again.
Stop when: all tests green, or you've tried 6 rounds (then summarize what's left).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a loop. And it genuinely works on a simple task. But point a loop at something open-ended - "improve this app," "make this page better," "research X and write it up" - and it either produces something great or it quietly turns into a very expensive slop machine. The difference between those two outcomes is the part nobody talks about.&lt;/p&gt;




&lt;h2&gt;
  
  
  Loops Nest: Andrew Ng's Three-Loop Model
&lt;/h2&gt;

&lt;p&gt;The discover → plan → execute → verify cycle above is the &lt;em&gt;inner&lt;/em&gt; loop. Zoom out and you'll find it wrapped inside slower loops. Andrew Ng laid this out cleanly in a &lt;a href="https://x.com/AndrewYNg/status/2071988145667928442" rel="noopener noreferrer"&gt;June 2026 Batch letter&lt;/a&gt; - and the fact that &lt;em&gt;he&lt;/em&gt; wrote it is itself the signal: "'Loop engineering' is a hot buzzphrase after mentions of it by Boris Cherny (Claude Code's creator) and Peter Steinberger (OpenClaw's creator) went viral." When Andrew Ng devotes a whole letter to a term, it has left buzzword territory.&lt;/p&gt;

&lt;p&gt;His model is three loops running at different speeds:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Loop&lt;/th&gt;
&lt;th&gt;Cadence&lt;/th&gt;
&lt;th&gt;Who runs it&lt;/th&gt;
&lt;th&gt;What it decides&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agentic coding loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Seconds to minutes&lt;/td&gt;
&lt;td&gt;The agent&lt;/td&gt;
&lt;td&gt;Write code, test it, iterate until it's bug-free and meets the spec (and evals, if you have them)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Developer feedback loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Tens of minutes to hours&lt;/td&gt;
&lt;td&gt;You&lt;/td&gt;
&lt;td&gt;Review the product, steer the agent, update the spec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;External feedback loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hours to weeks&lt;/td&gt;
&lt;td&gt;The world&lt;/td&gt;
&lt;td&gt;Alpha testers, A/B tests, production data - feeds your vision back into the spec&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  ┌──────────────────────────────────────────────────────┐
  │  EXTERNAL FEEDBACK LOOP            (hours → weeks)     │
  │  alpha testers · A/B tests · production data          │
  │   ┌────────────────────────────────────────────────┐ │
  │   │  DEVELOPER FEEDBACK LOOP     (minutes → hours)  │ │
  │   │  you review · steer · update the spec          │ │
  │   │   ┌──────────────────────────────────────────┐ │ │
  │   │   │  AGENTIC CODING LOOP    (seconds → mins) │ │ │
  │   │   │  generate → test → verify → repeat       │ │ │
  │   │   └──────────────────────────────────────────┘ │ │
  │   └────────────────────────────────────────────────┘ │
  │              vision ──► spec ──► agent                 │
  └──────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Watch what changes as you move outward: the loop gets slower, and the verifier gets more human. The inner loop can verify itself with tests. The outer loops can't - they need you. Ng makes the sharpest point right here, and it's a friendly amendment to the "taste is the reward function" idea coming up next. People call the human contribution "taste," he writes, but he prefers "context advantage": "So long as the human knows something the AI does not, human-in-the-loop is needed to inject that knowledge." Taste sounds innate and unteachable. "Context advantage" tells you exactly what to encode into the loop: the things you know about your users and your problem that the model doesn't. That's your verifier, written down.&lt;/p&gt;

&lt;p&gt;And here's his tell for when to graduate from eyeballing output to a real verifier: "If you find that the system repeatedly runs into certain problems, building a set of evals for the agent becomes useful." Same lesson as the landing-page example below - the moment you're checking the same thing twice, write it into the loop.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Is the Verifier the Bottleneck, Not the Generator?
&lt;/h2&gt;

&lt;p&gt;Every loop has two halves. The &lt;strong&gt;generator&lt;/strong&gt; produces work - that's the model, and models are now extremely good. The &lt;strong&gt;verifier&lt;/strong&gt; judges whether that work is good. Put it plainly: a loop is just a generator wired to a verifier, and the generator was never the bottleneck. The verifier is.&lt;/p&gt;

&lt;p&gt;For two years we obsessed over the generator. We tuned prompts, swapped models, argued about temperature. But in a loop, the generator runs over and over for nearly free. The thing that decides whether all that motion produces &lt;em&gt;value&lt;/em&gt; is the verifier.&lt;/p&gt;

&lt;p&gt;And the freer you let the loop run, the more everything rides on the verifier. A loop with a weak "good enough?" check doesn't fail loudly. It succeeds at producing garbage, confidently, hundreds of times.&lt;/p&gt;

&lt;p&gt;This is the same shift &lt;a href="https://addyo.substack.com/p/code-review-in-the-age-of-ai" rel="noopener noreferrer"&gt;Addy Osmani&lt;/a&gt; keeps pointing at: the bottleneck moved from writing code to proving it works. Review, judgment, taste, knowing what "correct" looks like - that's now the most leveraged skill an engineer has. It's the same lesson &lt;a href="https://www.aibuilderclub.com/blog/how-to-evaluate-ai-agents?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;agent evaluation&lt;/a&gt; teaches at the production layer: a model grading its own homework always gives itself an A. In a loop-engineering world, your taste isn't a soft skill anymore. &lt;strong&gt;It's the reward function.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Loop vs Closed Loop: Which Should You Build?
&lt;/h2&gt;

&lt;p&gt;Once you accept that the verifier is the point, the engineering decision gets clear. Every loop sits somewhere between two poles.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Open loop&lt;/th&gt;
&lt;th&gt;Closed loop&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;What it is&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Give a goal and loose conditions, let it explore a wide space&lt;/td&gt;
&lt;td&gt;Pin success criteria in advance, evaluate every step, define an explicit stop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Upside&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Genuinely novel output. Surprising solutions live here&lt;/td&gt;
&lt;td&gt;Runs on a normal budget. Predictable. Safe to leave alone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Downside&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Burns tokens. Degrades into slop fast with loose criteria&lt;/td&gt;
&lt;td&gt;Won't surprise you. Does what you specified, not more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Lives or dies by&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The verifier (even more so)&lt;/td&gt;
&lt;td&gt;The verifier&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The actual &lt;em&gt;engineering&lt;/em&gt; is two decisions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Choose open or closed for this specific task.&lt;/strong&gt; Roughly: how much do I need novelty, and how much budget am I willing to risk?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write the verifier that matches.&lt;/strong&gt; A closed loop needs hard, checkable passes. An open loop needs an &lt;em&gt;even better&lt;/em&gt; verifier, because it's the only thing standing between exploration and slop.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What Does a Loop With a Weak Verifier Actually Produce?
&lt;/h2&gt;

&lt;p&gt;The most useful thing isn't a loop that works. It's the same task run two ways.&lt;/p&gt;



&lt;p&gt;Here's Take 2 written out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Goal: improve landing-page conversion clarity.
Done when ALL pass:
  - Lighthouse accessibility score &amp;gt;= 95
  - Exactly one primary CTA above the fold
  - Hero headline states the value prop in &amp;lt;12 words
  - No layout shift (CLS &amp;lt; 0.1)
Loop: propose a change -&amp;gt; run the checks -&amp;gt; keep it only if every check still passes
      -&amp;gt; stop when all green or after 5 rounds.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the loop converges, because every iteration clears a bar &lt;em&gt;you&lt;/em&gt; defined. Then comes the trick that rescues open loops too: keep those hard checks as the floor, and add one open instruction ("surprise me with the headline"). Now you get exploration &lt;em&gt;that can't degrade below your standard.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The lesson isn't "closed loops are better." It's: &lt;strong&gt;the verifier is what makes either kind ship.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Tools Can Run the Loop For You?
&lt;/h2&gt;

&lt;p&gt;You don't have to build the loop machinery from scratch. There's a clear lineage, from rigid to autonomous:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool / pattern&lt;/th&gt;
&lt;th&gt;How it decides "done"&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Ralph" loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A bare shell &lt;code&gt;while&lt;/code&gt; loop re-fires the same prompt until you stop it - no smart "done," you are the stop button&lt;/td&gt;
&lt;td&gt;Mechanical, repetitive tasks. Crude but bulletproof&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Claude Code &lt;a href="https://code.claude.com/docs/en/goal" rel="noopener noreferrer"&gt;&lt;code&gt;/goal&lt;/code&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A small fast model judges the stop condition after every turn&lt;/td&gt;
&lt;td&gt;Fuzzy "done" that still needs evaluating&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Goal-tracking setups&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Agent tracks its own progress in files, defines "done" up front&lt;/td&gt;
&lt;td&gt;Long runs that need to stay oriented&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Self-hosted agents (Hermes-style)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs continuously on its own infrastructure, keeps state across sessions&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.aibuilderclub.com/blog/hermes-nous-research-self-improving-agent?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Always-on agents you set up once and leave running&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;/goal&lt;/code&gt; is the cleanest entry point: you type a completion condition once, and after each turn a Haiku-class evaluator reads the transcript and decides yes or no, looping until it holds (or you hit your turn cap). One catch worth knowing - the evaluator only sees what Claude already printed, so your condition has to be provable from the agent's own output.&lt;/p&gt;

&lt;p&gt;Pick the least autonomous tool that does the job. Autonomy is not the goal. &lt;strong&gt;A shipped result is the goal.&lt;/strong&gt; When the work fans out wide and repetitive, push the loop into a script with &lt;a href="https://www.aibuilderclub.com/blog/claude-code-dynamic-workflows?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;dynamic workflows&lt;/a&gt; instead of babysitting it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does a Real Loop System Look Like?
&lt;/h2&gt;

&lt;p&gt;A single loop is useful. A &lt;em&gt;system&lt;/em&gt; of loops that share a brain is where the leverage compounds. This is what AI Jason runs inside his own company.&lt;/p&gt;

&lt;p&gt;Start with the simplest one: a &lt;strong&gt;support loop&lt;/strong&gt;. Every 30 minutes a cron wakes an agent. It pulls every support ticket, replies to the ones it can answer, and logs the frictions and product ideas it spots into a shared folder called &lt;code&gt;signals&lt;/code&gt;. That loop alone earns its keep.&lt;/p&gt;

&lt;p&gt;Now make it compound. The same loop doesn't just &lt;em&gt;log&lt;/em&gt; a bug - it spawns a coding agent to fix it, monitors whether the fix held, and tells the customer it shipped. If people still hit the issue, that means it wasn't fixed at the root, so the loop tries again.&lt;/p&gt;

&lt;p&gt;The real trick is that every loop reads &lt;em&gt;and&lt;/em&gt; writes the same shared folders. Jason runs several at once:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Loop&lt;/th&gt;
&lt;th&gt;Trigger&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;What it writes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Every 30 min&lt;/td&gt;
&lt;td&gt;Answer tickets, spot friction&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;signals&lt;/code&gt;, engineer tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SEO&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Daily, 9am&lt;/td&gt;
&lt;td&gt;Pull data, research topics, publish pages&lt;/td&gt;
&lt;td&gt;pages, conversion-gap &lt;code&gt;signals&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Product growth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Daily&lt;/td&gt;
&lt;td&gt;Prioritize experiments from analytics + signals&lt;/td&gt;
&lt;td&gt;tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Reddit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Scheduled&lt;/td&gt;
&lt;td&gt;Draft on-brand comments&lt;/td&gt;
&lt;td&gt;comment artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Because they share one file system, the SEO loop's "this keyword converts but we have no organic content" signal feeds the content loop. The support loop's repeated-bug signal gets picked up by the product loop. Each loop runs every hour or every day, reading what the others learned. &lt;strong&gt;The shared brain is what makes it compound&lt;/strong&gt; - and Jason's quoted output from this setup is 20 to 40 high-quality pages a day driving traffic without him looking at it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 4 Ingredients of a Loop That Compounds
&lt;/h2&gt;

&lt;p&gt;Jason's framework boils down to four parts. Most people nail the first three and skip the fourth - which is the one that actually decides whether autonomous work is possible.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Triggers.&lt;/strong&gt; What wakes the agent. A cron job, a webhook, another agent, a server incident. The point is the agent runs &lt;em&gt;without you&lt;/em&gt; pressing enter.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File structure.&lt;/strong&gt; The most important design decision. Where artifacts, contracts, and logs live (covered below).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools and connectors.&lt;/strong&gt; The skills and scripts that let the agent do real work - Intercom to fetch tickets, Stripe to check subscriptions, Supabase to debug, Playwright to test.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An agent-ready codebase.&lt;/strong&gt; The setup that lets many agents work in parallel and verify their own output. This is the one everyone misses.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How Do You Make a Codebase Agent-Ready?
&lt;/h2&gt;

&lt;p&gt;Before any loop works, the environment has to let an agent operate solo. Three properties:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Legible&lt;/strong&gt; - the agent can find where to change what. Keep &lt;code&gt;AGENTS.md&lt;/code&gt; / &lt;code&gt;CLAUDE.md&lt;/code&gt; as a ~100-line index that points to deeper docs (OpenAI keeps theirs around 100 lines). Then bake rules into &lt;strong&gt;custom lints&lt;/strong&gt; so the agent gets a warning automatically instead of you hoping it reads the right doc. Example: lint-fail any import from a legacy folder you don't want touched.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executable&lt;/strong&gt; - the agent starts work with the dev server already up, at near-zero token cost. Write a &lt;code&gt;dev local&lt;/code&gt; script so it doesn't burn 3-5 minutes booting the app every run. Make the repo worktree-friendly so five parallel agents each spin up their own server without colliding. Add scripts that jump to a specific state to test scenarios fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verifiable&lt;/strong&gt; - give the agent tools to test and &lt;em&gt;prove&lt;/em&gt; it worked. The Playwright CLI is the standout: it drives the browser and records a video clip you can attach to the GitHub PR, so review takes seconds. Back it with end-to-end tests on the flows you never want broken - sign-up, upgrade, core action.&lt;/p&gt;

&lt;p&gt;One hard rule from the video, and it lines up exactly with the verifier point above: &lt;strong&gt;don't let an agent self-verify.&lt;/strong&gt; It doesn't work well. Jason's PR skill always spawns a separate read-only verifier agent with the detailed spec. Generator and verifier stay different agents.&lt;/p&gt;




&lt;h2&gt;
  
  
  The File System: Artifacts, Contracts, Logs
&lt;/h2&gt;

&lt;p&gt;This is ingredient #2, and it's the heart of the system. Three file types, three jobs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Artifacts&lt;/strong&gt; - the shared knowledge layer. The output of each loop's work. Types include &lt;code&gt;docs&lt;/code&gt;, &lt;code&gt;signals&lt;/code&gt;, &lt;code&gt;tasks&lt;/code&gt;, &lt;code&gt;tickets&lt;/code&gt;, even &lt;code&gt;campaigns&lt;/code&gt; for an ads loop. Each artifact type gets its own folder with a &lt;code&gt;README&lt;/code&gt; defining what goes in, what doesn't, the process for adding an item, and the schema. Each artifact file carries front-matter metadata, a body, and a timeline of every change.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A &lt;strong&gt;signal&lt;/strong&gt; is the unit that makes loops compound. It captures a product idea, a friction, or a missed opportunity, links to its raw sources (a support ticket, a customer quote), and any loop can read or write it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Contracts&lt;/strong&gt; - one per loop, usually a &lt;code&gt;README&lt;/code&gt; in the loop's folder. It states the goal, the workflow, the boundaries, the outstanding backlog, and a timeline. Every time the loop fires, it reads its contract first - goal, workflow, what happened last time - then takes the next best action.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logs&lt;/strong&gt; - a single global work-log file. Different from the timelines because your day mixes reviewing loop output with hands-on copilot work. Before an agent starts a big task it reads the last 5-10 entries; when it finishes it appends what it did. That's how cross-domain context survives between sessions.&lt;/p&gt;

&lt;p&gt;The workflow to stand one up: run the loop manually once as a test, calibrate the workflow with the agent, then ask it to write the contract and register the trigger. Test run first, loop second.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Writing a Verifier Is Like Defining a Reward Function
&lt;/h2&gt;

&lt;p&gt;If you've touched reinforcement learning, this clicks instantly. In RL you don't tell the agent every move - you define the &lt;em&gt;reward&lt;/em&gt;, and the agent iterates toward it on positive and negative signal.&lt;/p&gt;

&lt;p&gt;That's exactly what you're doing here. You are not training the model. You are &lt;strong&gt;defining the reward&lt;/strong&gt;: the end goal, and what counts as good. Your domain knowledge - knowing what correct looks like in &lt;em&gt;your&lt;/em&gt; problem - is the moat. The model is a commodity. The reward function is yours.&lt;/p&gt;

&lt;p&gt;This is also why the field keeps drifting toward &lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;harness engineering&lt;/a&gt;: the leverage isn't in the phrasing anymore, it's in the system around the model - context, tools, state, and the evaluation loop that decides when to stop. Loop engineering is that same move, named from the loop's point of view.&lt;/p&gt;

&lt;p&gt;And watch where the vocabulary goes next. Once you accept that the verifier is the point, the natural follow-up question is &lt;em&gt;how do you write a good one&lt;/em&gt; - which is exactly the ground "evals" cover. Ng's own advice ("build a set of evals when the system keeps hitting the same problems") points straight at it, and the term already circulating for this next layer is &lt;strong&gt;eval engineering&lt;/strong&gt;: formalizing the verifier into a versioned dataset you can measure against. If loop engineering is designing the loop, eval engineering is designing the bar the loop clears. Same lineage, one level deeper.&lt;/p&gt;

&lt;p&gt;Which is why I keep saying it: &lt;strong&gt;writing the verifier is the new prompt engineering.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Is Loop Engineering Just a New Buzzword?
&lt;/h2&gt;

&lt;p&gt;I'd be doing you a disservice not to flag the counter-take, because in the three weeks after the term went viral, the skeptic case grew real teeth. The strongest version has four distinct arguments, not one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The vocabulary mockery.&lt;/strong&gt; One widely-shared post maps the whole lexicon back to CS primitives - "a while loop becomes 'loop engineering'... unit tests become 'evals'" - and it's now a genre: a 1,800-comment Hacker News thread arguing agents are "just a while loop with an LLM call," and an entire site (extra-steps.dev) dedicated to the bit, both rounded up in &lt;a href="https://posthog.com/newsletter/loops" rel="noopener noreferrer"&gt;PostHog's "WTF is loop engineering"&lt;/a&gt;. Anyone who's written a CI pipeline or a Kubernetes reconciliation loop has been "designing loops" for years.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The autonomy check.&lt;/strong&gt; &lt;a href="https://www.theregister.com/ai-and-ml/2026/06/24/loop-engineering-latest-ai-buzzword-still-needs-humans-in-the-loop/5261735" rel="noopener noreferrer"&gt;The Register's June 24 take&lt;/a&gt;: the latest AI buzzword "still needs humans in the loop." The demos hide how much steering real work still takes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The economic critique.&lt;/strong&gt; Ed Zitron's version: the trend amounts to "celebrating and evangelizing autonomous token consumption" - spending the model vendors would very much like to stimulate. And he has a live exhibit: Uber reportedly capped engineers at $1,500/month for agent tooling after burning through its annual AI budget in four months. An unattended loop with a weak verifier doesn't fail loudly; it fails &lt;em&gt;at token prices, all night&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The sampling-bias point.&lt;/strong&gt; The subtlest one, from developer &lt;a href="https://x.com/_kboy_/status/2072169280150327436" rel="noopener noreferrer"&gt;@_kboy_ on X&lt;/a&gt;: Claude Code solving "writing software" is real, but that doesn't "give anyone the evidence to start defining how everyone should develop software" - the vendors' data comes from people already using their product.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both things are still true at once, and that's the honest read. The word is riding a wave &lt;em&gt;and&lt;/em&gt; the shift under it is real. The tell is who's using it seriously: Boris Cherny (Claude Code's creator), Peter Steinberger (OpenClaw's creator), and Andrew Ng - who wrote an &lt;a href="https://x.com/AndrewYNg/status/2071988145667928442" rel="noopener noreferrer"&gt;entire letter&lt;/a&gt; mapping out his three loops - are not chasing a hashtag. When the people building the tools and the person who taught half the industry machine learning independently converge on the same frame, the frame is load-bearing. (And the wave is still rising: three weeks in, "Loop Engineer" is already a module title in GenAI bootcamp curricula, and Jensen Huang was echoing "prompt engineering is dead" on stage.)&lt;/p&gt;

&lt;p&gt;So here's your filter. Ignore the &lt;em&gt;word&lt;/em&gt;. Look at whether the underlying shift is real:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you increasingly designing systems that run agents, instead of prompting agents directly? &lt;strong&gt;Yes.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Is the scarce, valuable part now defining "done" and "good," rather than phrasing the request? &lt;strong&gt;Yes.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Does a loop with a weak verifier reliably produce expensive garbage? &lt;strong&gt;Also yes - see Uber's invoice.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the thing to notice: every serious criticism above attacks &lt;em&gt;weak loops&lt;/em&gt;, not the discipline. Loops that still need un-budgeted human steering. Loops that burn tokens with no &lt;a href="https://www.aibuilderclub.com/blog/ai-agent-reliability-cost-control?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;halt condition or spend cap&lt;/a&gt;. Loops graded on the vendor's own telemetry. The skeptics aren't refuting loop engineering - they're describing what happens when you skip the verifier, which is the entire argument of this guide. The label is optional. The shift is not. Whether you call it loop engineering or just "building agents that don't waste my money," the move is the same: &lt;strong&gt;stop perfecting prompts, start writing verifiers.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Loop Engineering Starting Checklist
&lt;/h2&gt;

&lt;p&gt;If you build one loop this week, run it through this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define "done" in measurable terms&lt;/strong&gt; before you write a single instruction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin the passes&lt;/strong&gt; - the tests, the rubric, the eval - &lt;em&gt;up front&lt;/em&gt;, not after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose open vs closed&lt;/strong&gt; by &lt;code&gt;need-for-novelty x budget-you'll-risk&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always attach the run data&lt;/strong&gt; to whatever you hand back to a human.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use the least autonomous harness&lt;/strong&gt; that gets the result.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set the trigger&lt;/strong&gt; - cron, webhook, or another agent - so it runs without you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Give it shared folders&lt;/strong&gt; - artifacts, a loop contract, a global log - so the next run, and every other loop, can build on this one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do that and you've crossed the line from someone who &lt;em&gt;prompts&lt;/em&gt; AI to someone who &lt;em&gt;engineers the system that does the work.&lt;/em&gt; That's the whole skill. The rest is reps.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related Content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-vs-harness-engineering?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Loop Engineering vs Harness Engineering&lt;/a&gt;&lt;/strong&gt; - The boundary between the two disciplines, the failure modes of each, and which to build first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/how-to-evaluate-ai-agents?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;How to Evaluate AI Agents&lt;/a&gt;&lt;/strong&gt; - The generator-evaluator pattern, traces, and why self-evaluation skews optimistic. The production version of "write a verifier."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/harness-six-components?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Harness: The 6 Components&lt;/a&gt;&lt;/strong&gt; - Context, tools, orchestration, state, evaluation, recovery. The system around the loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/claude-code-dynamic-workflows?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Dynamic Workflows: Orchestrate Subagents at Scale&lt;/a&gt;&lt;/strong&gt; - Move the loop into a script and run up to 1,000 subagents without flooding context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/prompt-context-harness-evolution?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;From Prompts to Loops: The 4 Shifts&lt;/a&gt;&lt;/strong&gt; - Why AI engineering moved from phrasing to information to control to loops that run without you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.aibuilderclub.com/blog/hermes-nous-research-self-improving-agent?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;Hermes: Self-Hosted, Never Forgets&lt;/a&gt;&lt;/strong&gt; - The "runs while you sleep" autonomous-agent pattern taken to its end.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Start Here
&lt;/h2&gt;

&lt;p&gt;Pick one repetitive task this week. Before you write a single instruction, write down what "done" means in measurable terms. Then pin the checks, choose open or closed, and let the loop run against &lt;em&gt;your&lt;/em&gt; bar instead of the model's.&lt;/p&gt;

&lt;p&gt;For closed-loop templates, verifier checklists, and teardowns of loops that shipped (and loops that burned money), join the AI Builder Club - come ship something real.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.aibuilderclub.com" rel="noopener noreferrer"&gt;Join AI Builder Club&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.aibuilderclub.com/blog/loop-engineering-guide-2026?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;AI Builder Club&lt;/a&gt;, where the full &lt;a href="https://www.aibuilderclub.com/blog?utm_source=devto&amp;amp;utm_campaign=offsite-syndication" rel="noopener noreferrer"&gt;free agent-engineering curriculum&lt;/a&gt; lives.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aiagents</category>
      <category>loopengineering</category>
      <category>evaluation</category>
      <category>production</category>
    </item>
  </channel>
</rss>
