<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Decoding AI Magazine]]></title><description><![CDATA[Join for content on designing, building, and shipping AI software. Learn AI engineering, end-to-end, from idea to production. Every Tuesday.]]></description><link>https://www.decodingai.com</link><image><url>https://substackcdn.com/image/fetch/$s_!k2ig!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F00bc74e0-3601-49ce-8ab9-4c7b499ce597_1280x1280.png</url><title>Decoding AI Magazine</title><link>https://www.decodingai.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 25 Aug 2026 18:38:39 GMT</lastBuildDate><atom:link href="https://www.decodingai.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Paul-Emil Iusztin]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[decodingai@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[decodingai@substack.com]]></itunes:email><itunes:name><![CDATA[Paul Iusztin]]></itunes:name></itunes:owner><itunes:author><![CDATA[Paul Iusztin]]></itunes:author><googleplay:owner><![CDATA[decodingai@substack.com]]></googleplay:owner><googleplay:email><![CDATA[decodingai@substack.com]]></googleplay:email><googleplay:author><![CDATA[Paul Iusztin]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Context Engineering for Coding Agents]]></title><description><![CDATA[The 4 harness components that keep your context window high-signal.]]></description><link>https://www.decodingai.com/p/context-engineering-for-coding-agents</link><guid isPermaLink="false">https://www.decodingai.com/p/context-engineering-for-coding-agents</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 25 Aug 2026 05:01:37 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!BvUU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39d1f394-e419-4ab6-a9f1-da5a0425a6f6_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="callout-block" data-callout="true"><p><em><strong><span data-color="#c02f26" style="color: rgb(192, 47, 38);">Every AI application that wraps an agent is a harness!</span></strong><span data-color="#c02f26" style="color: rgb(192, 47, 38);"> </span></em></p><p>In LangChain&#8217;s Terminal-Bench experiment, changing only the harness (with the same model) moved a coding agent from ~30th place into the top 5: the harness, not the model, is what makes a coding agent good.</p><p>In the&nbsp;<strong>open-source course</strong>&nbsp;<strong><a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">Building a Coding Agent From Scratch</a></strong>, you&#8217;ll build that harness from scratch in Python:&nbsp;<strong>Decode</strong>, a complete coding agent that grows lesson by lesson from a bare agent loop into a swarm of remote agents running in parallel in the cloud.</p><p><strong>Why?</strong>&nbsp;You&#8217;ll be able to engineer custom harnesses for your own AI products (the skill behind that leaderboard jump), and you&#8217;ll understand what Claude Code and Codex actually do under the hood, turning you into a power user.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ge05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1446989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Lessons:</strong></p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a><strong> </strong></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop </a></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p><strong>Context Engineering for Coding Agents</strong> <strong>&#8592; </strong><em><strong>you are here</strong></em></p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out <strong>&#8592; </strong><em>Available next week</em></p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course&quot;,&quot;text&quot;:&quot;Full open-source course&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course"><span>Full open-source course</span></a></p></div><h1>Lesson 4: Context Engineering for Coding Agents</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7tX-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7tX-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7tX-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;What you carry is what you can move with. The craft is in what you leave on the bench.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="What you carry is what you can move with. The craft is in what you leave on the bench." title="What you carry is what you can move with. The craft is in what you leave on the bench." srcset="https://substackcdn.com/image/fetch/$s_!7tX-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!7tX-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F544e7250-15d4-4cc8-bc3d-b30f3e8e16db_1376x768.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I got hooked on running Claude Code agents 24/7. Getting things done while answering emails, cooking, or watching a movie. Until my subscription maxed out mid-turn with the agent halfway through a feature. Sounds familiar?</p><p>Complaining to your employer, buying a bigger subscription, changing the model, or switching harnesses only treats the symptom. Doesn&#8217;t solve the root cause. You spend money while the window stays noisy, degrading output no matter whose model is behind it.</p><p>The actual solution is to better understand harnesses and the context engineering behind them. Improve planning, develop stronger skills and memory, and know when to drop your context.</p><p>So far in the course, we have focused on harness engineering and building a sandboxed agent loop. Now it&#8217;s finally time for some context engineering for coding agents: memory, skills, LSP servers and compaction.</p><p>The whole problem resolves to what to put into context, what not to put, how to trim it down, plus creating as many feedback loops as possible for the agent, as Anthropic frames it as <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">finding the smallest possible set of high-signal tokens</a>.</p><p>You will walk away understanding and building from scratch:</p><ul><li><p>What the agent should carry between sessions.</p></li><li><p>How skills load nothing until needed.</p></li><li><p>The cheapest feedback loop in the system.</p></li><li><p>How the window gets trimmed before it rots.</p></li></ul><h2>The context lifecycle of a session</h2><p>To see how the 4 components cooperate, look at the <code>demo-5-sandbox-feature-pr</code> skill from the course repo (<code>.decode/skills/demo-5-sandbox-feature-pr</code>), where we encoded a demo where <strong>Decode</strong> writes a new feature into Decode by spinning up a background sandboxed session, where the host agent acts as the orchestrator and the sandboxed one as the feature executor. The final artifact from the demo will be a PR containing the new feature.</p><p>Go to <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">repository</a>, run <code>decode</code>, type <code>/demo-5-sandbox-feature-pr</code>, and enter. Let Decode do the rest of the work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!U0HN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!U0HN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 424w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 848w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 1272w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!U0HN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png" width="1200" height="374" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:374,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;skill demo&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="skill demo" title="skill demo" srcset="https://substackcdn.com/image/fetch/$s_!U0HN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 424w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 848w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 1272w, https://substackcdn.com/image/fetch/$s_!U0HN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa54ad14-87da-4731-bd5e-b3e2d310f634_1200x374.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here is a snapshot of the skill, where Decode spawns another Decode subagent:</p><pre><code><code>...

## 1. Launch decode against a sandboxed clone of the course repo

Launch the local Docker run (Docker must be running):

"""
SANDBOX_MODE=docker decode --repo git@github.com:decodingai-magazine/building-a-coding-agent-from-scratch-course.git
"""

...</code></code></pre><p>At session start, the system prompt is assembled from four parts: the base prompt, the active agent&#8217;s prompt, memory files (<code>AGENTS.md</code> + <code>.decode/MEMORY.md</code>), and the skills catalog (one line per skill). Pydantic AI adds each tool&#8217;s schema, paying off <a href="https://www.decodingai.com/p/the-coding-agent-loop">Lesson 2&#8217;s warning</a> that every tool costs tokens. This assembled prompt enters context, shaping the probabilities of the model&#8217;s next steps.</p><p>The run fills the window. Invoking the skill loads its <code>SKILL.md</code> body (tier 2 of progressive disclosure). Plan mode dumps repo files as <code>read</code> outputs. During the build loop, each <code>edit</code> lands, the Diagnostics Enricher appends type errors for free, and <code>bash</code> runs tests until green output signals completion.</p><p><em>Now, from the context window point of view, what happens within the harness?</em></p><p>As in the image below, as soon as we open the agent, the context window is filled with its system prompt, tool and skill descriptions and memory files. After invoking the <code>/demo-5-sandbox-feature-pr</code> skill, it gets filled with tool inputs and outputs, plus the SKILL.md file containing the specific instructions.</p><p>Next, through progressive disclosure, the agent begins reading the relevant files and scripts associated with the skills. Ultimately, it starts writing new Python files or editing existing ones that are statically checked for syntax issues via our <code>ty</code> Language Server Protocol (LSP) server.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pnf_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pnf_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 424w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 848w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 1272w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pnf_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png" width="1200" height="455" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:455,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The context lifecycle &#8212; what each iteration of one session appends to the window.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The context lifecycle &#8212; what each iteration of one session appends to the window." title="The context lifecycle &#8212; what each iteration of one session appends to the window." srcset="https://substackcdn.com/image/fetch/$s_!pnf_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 424w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 848w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 1272w, https://substackcdn.com/image/fetch/$s_!pnf_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc59b6055-6ca8-49b1-b716-c8a8f023f987_1200x455.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The context lifecycle of a coding agent</figcaption></figure></div><p>On Modal&#8217;s self-hosted <code>Qwen3.6-35B</code>, the window is 262,144 tokens. Usually, microcompaction fires at 60%, while full compaction is at 80%. After compaction, usage drops back to roughly 5&#8211;10%, so the session continues instead of crashing.</p><p>In the video below, you can see part of the 219 spans trace in <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a>, clearly monitoring the LLM tool calls, token counts, and latency of the harness and LLM calls:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;764baba6-361a-4c1f-9249-14735e9987cc&quot;,&quot;duration&quot;:null}"></div><p>Every component in this lifecycle has specific mechanics: memory, skills, the LSP server, and compaction. Let&#8217;s explore each.</p><h2>Memory: Stop repeating your instructions</h2><p>In my early agent runs, the agent kept writing naive datetime objects instead of timezone-aware ones and added type hints inconsistently, forcing me to retype the same corrections session after session. The fix was to write the preference down once into the <code>AGENTS.md</code>, where the agent reads it every turn.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mNNY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mNNY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mNNY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The two memory files &#8212; one you write by hand, one that writes itself.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The two memory files &#8212; one you write by hand, one that writes itself." title="The two memory files &#8212; one you write by hand, one that writes itself." srcset="https://substackcdn.com/image/fetch/$s_!mNNY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!mNNY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5fa3410-408d-4668-a13b-5bdeb47650f5_1200x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><code>AGENTS.md</code><em> (the one you write by hand) vs. </em><code>.decode/MEMORY.md</code><em> (the one the agent extracts from each session).</em></figcaption></figure></div><p><code>AGENTS.md</code> injects project context: business logic, why components exist, the tech stack, and the processes around it (docs, deploy, review, testing). The code is the source of truth, so avoid duplicating it. Add metadata and references the agent can discover without heavy reasoning.</p><p>Keep it under 300 lines, with a guardrail of around 600 lines. Write each line in response to an observed mistake so the agent avoids repeating it, following <a href="https://mitchellh.com/writing/my-ai-adoption-journey">Mitchell Hashimoto&#8217;s rule</a>.</p><p>Decode recursively looks within all the project directories for <code>AGENTS.md</code> files (root-most first, so the nearest file takes precedence), appends <code>.decode/MEMORY.md</code> last, stamps each with a <code># From &lt;path&gt;</code> provenance header, and dumps the result into the system prompt.</p><p>If <code>AGENTS.md</code> is what you manually define, <code>.decode/MEMORY.md</code> is what the agent automatically extracts from your conversations, replicating Claude Code&#8217;s auto-memory</p><p>At the end of each session &#8212; on quit and on <code>/clear</code> &#8212; one cheap LLM call summarizes the session into a single plain sentence, appended as a dated bullet (<code>- 2026-06-26: &#8230;</code>), as an append-only log. As this can grow big fast, the file has a hard cap of 200 lines or 25,000 bytes, dropping the oldest lines first.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/memory/extract.py">src/decode/memory/extract.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def extract_on_exit(messages: list[ModelMessage], cwd: Path) -&gt; None:
    summary = await summarize_session(messages, model_or_settings=settings)
    append_session_summary(cwd, summary, now=_utc_now())

    if settings.memory_compression_enabled:
        await compress_memory_file(cwd, model_or_settings=settings)</code></pre></div><p><code>summarize_session</code> is the single LLM call that distills the conversation into one sentence (or <code>None</code> if it&#8217;s not worth saving). <code>append_session_summary</code> writes that sentence into <code>.decode/MEMORY.md</code> and enforces the hard cap.</p><p><code>compress_memory_file</code> runs <strong>Memory Compression</strong> to rewrite the file in place, merging duplicate or superseded notes while preserving dated bullets.</p><h2>Skills: Never load what you can reference</h2><p>My Python testing and PR conventions used to live directly in my memory file, bloating the context of every session. Moving them into skills left behind just a few lines, as references, that specify when to access each one.</p><p>Skills prevent context rot from 2 directions. On the tools side, upfront schemas burn budget: <a href="https://mariozechner.at/posts/2025-11-30-pi-coding-agent/">Mario Zechner measured that popular MCP servers consume 7&#8211;9% of the context window</a> before any work begins. On the memory side, stuffing review guides and workflow templates into <code>AGENTS.md</code> pollutes every turn. Skills solve both: each phase-specific behavior lives in its own skill, referenced from a one-line catalog entry, and loads only when that workflow phase runs.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zEr0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zEr0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zEr0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png" width="1200" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The three tiers of progressive disclosure, seen inside the context window.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The three tiers of progressive disclosure, seen inside the context window." title="The three tiers of progressive disclosure, seen inside the context window." srcset="https://substackcdn.com/image/fetch/$s_!zEr0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 424w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 848w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 1272w, https://substackcdn.com/image/fetch/$s_!zEr0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6d0163ba-5206-4477-a774-4a2593499b42_1200x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The 3 tiers of loading a skill and its bundled files into the context window</figcaption></figure></div><p>Skills follow the <a href="https://agentskills.io/home">Agent Skills standard</a>. In Decode, skills live in <code>.decode/skills/</code>, or you can open the TUI, type <code>/</code>, and pick one. A separate public registry lives at <a href="https://www.skills.sh/">skills.sh</a> (<code>npx skills install &lt;skill&gt;</code>):</p><pre><code><code>my-skill/
&#9500;&#9472;&#9472; SKILL.md          # Required: metadata + instructions
&#9500;&#9472;&#9472; scripts/          # Optional: executable code
&#9500;&#9472;&#9472; references/       # Optional: documentation
&#9500;&#9472;&#9472; assets/           # Optional: templates, resources
&#9492;&#9472;&#9472; ...               # Any additional files or directories</code></code></pre><p><strong>Progressive disclosure</strong> operates across <strong>3 tiers</strong>. In <strong>tier 1</strong>, only the skills catalog stays in context: one <code>name + description</code> line per skill. As your library grows, an optional guard can cap the catalog at ~1% of the context window.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhAh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhAh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 424w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 848w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 1272w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhAh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png" width="1200" height="292" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:292,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The tier-1 skills pipeline &#8212; descriptions gathered into a catalog, optionally capped, wrapped into the system prompt.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The tier-1 skills pipeline &#8212; descriptions gathered into a catalog, optionally capped, wrapped into the system prompt." title="The tier-1 skills pipeline &#8212; descriptions gathered into a catalog, optionally capped, wrapped into the system prompt." srcset="https://substackcdn.com/image/fetch/$s_!xhAh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 424w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 848w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 1272w, https://substackcdn.com/image/fetch/$s_!xhAh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd4e626a-873a-40a9-8ca8-9255652381cb_1200x292.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><em>Loading the skills catalog into the system prompt.</em></figcaption></figure></div><p>A common strategy Decode doesn&#8217;t have yet is user-invocable-only skills, where you flag a skill as callable only. This means you can remove its name and description from the catalog, leaving it with zero context until explicitly invoked by the user.</p><p>In <strong>tier 2</strong>, invoking a skill via the <code>skill</code><strong> dispatcher tool</strong> or <code>/&lt;skill-name&gt;</code> loads only its <code>SKILL.md</code> body and any other files packed within the skill.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/tools/skills.py">src/decode/tools/skills.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def skill(ctx: RunContext[AgentDeps], name: str) -&gt; str:
    home = ctx.deps.harness_home or ctx.deps.cwd
    catalog = load_skills(home)
    found = catalog.get(name)

    return format_skill_payload(found, cwd=home)</code></pre></div><p>In <strong>tier 3</strong>, because within <code>format_skill_payload</code> we properly format and expose all the available resources (files, scripts, docs, assets) from a skill to the agent, if it considers them necessary, it will load them via its read tool or execute the containing scripts via the bash tool.</p><p>This is the core idea of progressive disclosure. It&#8217;s mostly just exposing a manifest of bundled files with exact cwd-relative paths, making it super clear to the agent how to access them. The key here is that the LLM is properly trained for tool calling to make the right decisions about whether to call read or bash tools.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/skills/payload.py">src/decode/skills/payload.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def format_skill_payload(skill: SkillDef, *, cwd: Path) -&gt; str:
    if skill.resource_dir is None:
        return f"{skill.body}\n\n{_OUTPUTS_TRAILER}"
    rel_dir = os.path.relpath(skill.resource_dir, cwd)
    files = _bundled_files(skill.resource_dir)
    
    listing = "\n".join(f"- {rel_dir}/{name}" for name in files)
    trailer = (
        f"Bundled files for this skill (all under `{rel_dir}/` &#8212; use these EXACT paths):\n"
        f"{listing}\n"
        "Read them with the `read` tool; run `scripts/` files with `bash`."
    )

    return f"{skill.body}\n\n{trailer}\n\n{_OUTPUTS_TRAILER}"</code></pre></div><p>Now let&#8217;s look at the cheapest feedback loop in the whole coding agent.</p><h2>The LSP server: Replace guessing with precision</h2><p>In my multi-agent setup, each turn between the engineer and tester agents re-ran the linter, type checker, formatter, and test suite. My Prefect orchestrator integration tests took 15 minutes on their own, so I split them to speed up the feedback loop.</p><p>The takeaway was clear: the most important part of your agentic flow is to always give as many feedback loops as possible. <strong>The LSP server is the fastest way to feed in code-related signal.</strong></p><p>An LSP server is one of the most underrated components, particularly for coding harnesses. It maintains a live index of symbols across your codebase: variables, functions, classes, definitions, references, and type errors. Your IDE already runs one per language. You need one for each programming language. Decode uses <a href="https://github.com/astral-sh/ty">ty by Astral</a>, an extremely fast type checker and language server written in Rust, to support Python. Made by the same guys behind uv and ruff.</p><p>The server feeds the agent signal through 2 channels.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N2P_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N2P_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 424w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 848w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 1272w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N2P_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png" width="1200" height="515" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:515,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Two ways into one LSP server &#8212; the agent asks, or the edit asks on its behalf.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Two ways into one LSP server &#8212; the agent asks, or the edit asks on its behalf." title="Two ways into one LSP server &#8212; the agent asks, or the edit asks on its behalf." srcset="https://substackcdn.com/image/fetch/$s_!N2P_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 424w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 848w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 1272w, https://substackcdn.com/image/fetch/$s_!N2P_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fffa5c0a8-ed47-4023-8ba1-6537bf9ba0a3_1200x515.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The two LSP channels. 1. The agent queries the </em><code>lsp</code><em> tool on demand 2. Every Python edit/write passively pulls diagnostics.</em></figcaption></figure></div><p><strong>Channel 1</strong> is the <code>lsp</code><strong> tool</strong>, which handles active queries with 4 ops: <code>definition</code>, <code>references</code>, <code>hover</code>, and <code>diagnostics</code>. One call returns a precise <code>file:line:column</code> answer instead of 3 speculative file reads. It&#8217;s read-only, so the permission gate auto-allows it across all modes.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/tools/lsp.py">src/decode/tools/lsp.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def lsp(
    ctx: RunContext[AgentDeps],
    op: str,
    path: str,
    line: int | None = None,
    column: int | None = None,
) -&gt; str:
    if op == "definition":
        return await _run_definition(ctx, path, line, column)
    if op == "references":
        return await _run_references(ctx, path, line, column)
    if op == "hover":
        return await _run_hover(ctx, path, line, column)
        
    return await _run_diagnostics(ctx, path)

async def _run_definition(ctx: RunContext[AgentDeps], path: str, line: int, column: int) -&gt; str:
    result = await lsp_service.definition(ctx.deps.cwd, path, line, column)

    return _format_location(result)</code></pre></div><p>The server runs as a background process at each project root, communicating via JSON-RPC (a plain request/response protocol over standard input/output). Decode&#8217;s <code>LspClient</code> initializes the session, negotiates capabilities, and sends requests:</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/services/lsp/service.py">src/decode/services/lsp/service.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">from decode.services.lsp.client import LspClient


process = await asyncio.create_subprocess_exec(
    "ty", "server",
    stdin=PIPE, stdout=PIPE, cwd=root,
)
client = LspClient(process, root)
await client.initialize()</code></pre></div><p>In the <code>demo-5</code> session, the agent resolves the entry point via <code>lsp("definition", "src/decode/cli.py", &lt;line&gt;, &lt;column&gt;)</code> over JSON-RPC <code>textDocument/definition</code>. On the next turn, the model targets its edit tool call at that exact location, rather than blindly exploring the codebase first.</p><p><strong>Channel 2</strong> is the <strong>Diagnostics Enricher</strong>, which runs passively on every successful <code>.py</code> write or edit to append an errors-only block to the tool result. It displays at most 10 errors, and stays silent on clean files or when the server is unavailable, matching the pattern in <a href="https://github.com/anomalyco/opencode">OpenCode</a>.</p><p><code>_enrich</code> wraps the return value of file modification tools without requiring extra turns or tools.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/tools/files.py">src/decode/tools/files.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def _enrich(base: str, cwd: Path, path: str) -&gt; str:
    summary = _format_lsp_errors(lsp_service.diagnostics_on_edit(cwd, path))
    if summary is None:
        return base
    return f"{base}\n\n{summary}"

def _format_lsp_errors(diagnostics: list[Diagnostic] | None) -&gt; str | None:
    ...
    errors = [d for d in diagnostics if d.severity == _LSP_ERROR_SEVERITY]
    shown = errors[:_LSP_DIAGNOSTICS_LIMIT]
    lines = [f"LSP diagnostics ({settings.lsp_server_command}) &#8212; fix these:"]
    ...
    return "\n".join(lines)</code></pre></div><p>In the <code>demo-5</code> session, when the agent updates <code>src/decode/cli.py</code> with an unimported reference, the file writes successfully, but the enricher appends <code>LSP diagnostics (ty) &#8212; fix these: ...</code> with the error details. The model sees this feedback immediately and fixes the import on the next <code>edit</code> before running any tests.</p><p>In the video below, you can clearly see in <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a> how the LLM outputs LSP tool calls and how they are executed in the harness:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;88759aa0-fa9a-469e-a237-03c62c9bb762&quot;,&quot;duration&quot;:null}"></div><p>Memory, skills, and the LSP all shape what enters the window. Now let&#8217;s see how we can trim it down.</p><h2>Compaction: Delete before the window rots</h2><p>Back in Nov 2025, when building the writing agent for my agent engineering course, requests started degrading around 180,000 input tokens on Gemini Pro, taking&gt;3 minutes per request or directly returning timeout errors and disconnections. Considering that on paper Gemini handles up to 1M input tokens.</p><p>A full window degrades model performance and reliability long before hitting the hard token ceiling, following the <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">degradation curves documented by Anthropic</a>. That&#8217;s why you need compaction to continually reduce your context window while minimizing context loss.</p><p>Compaction handles this in 3 ways. The simplest is <code>/clear</code>, which wipes the entire window after running the on-exit memory write-back so key learnings persist in <code>.decode/MEMORY.md</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!apDX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!apDX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 424w, https://substackcdn.com/image/fetch/$s_!apDX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 848w, https://substackcdn.com/image/fetch/$s_!apDX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 1272w, https://substackcdn.com/image/fetch/$s_!apDX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!apDX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png" width="1200" height="815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63c3ab58-49a6-4264-a317-249b97680134_1200x815.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:815,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The three compaction modes and what each one leaves in the window.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The three compaction modes and what each one leaves in the window." title="The three compaction modes and what each one leaves in the window." srcset="https://substackcdn.com/image/fetch/$s_!apDX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 424w, https://substackcdn.com/image/fetch/$s_!apDX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 848w, https://substackcdn.com/image/fetch/$s_!apDX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 1272w, https://substackcdn.com/image/fetch/$s_!apDX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c3ab58-49a6-4264-a317-249b97680134_1200x815.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The three compaction modes: </em><code>/clear</code><em> keeps only the system prompt, </em><code>/compaction</code><em> rebuilds it as summary plus tail, and </em><code>/microcompaction</code><em> swaps old tool outputs for placeholders in place.</em></figcaption></figure></div><p>The second option is <strong>full compaction</strong>, triggered automatically at 80% capacity or manually via <code>/compact</code>. An LLM summarizes the conversations into a six-part template (goal, constraints &amp; preferences, progress, key decisions, next steps, critical context), and older messages are dropped. The window becomes <code>[system prompt] + [summary] + [recent tail]</code>, where the tail retains &#8776;20,000 tokens of recent messages snapped cleanly to a <strong>Compaction Boundary</strong> so tool calls remain paired with their results, matching <a href="https://github.com/earendil-works/pi">Pi&#8217;s implementation</a>.</p><p>Both tiers evaluate <code>should_compact</code> using the provider&#8217;s reported token window against reserve thresholds (80% full compaction -&gt;20% empty, 60% microcompaction -&gt; 40% empty):</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/context/compaction.py">src/decode/context/compaction.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def should_compact(usage: RunUsage, *, window: int, reserve: float, enabled: bool) -&gt; bool:
    if not enabled:
        return False
    if usage.input_tokens &lt;= 0:
        return False
    return usage.input_tokens &gt;= reserve_threshold(window, reserve)</code></pre></div><p>Everything happens within the <code>compact()</code> method from <code>AgentTurnHandler</code>. <code>split_tail</code> walks backward through message history estimating token counts to locate the Compaction Boundary. <code>summarize_for_compaction</code> generates the summary, <code>build_summary_message</code> wraps it as a synthetic user message that is itself part of the history the next compaction summarizes (so successive compactions merge for free), and the handler sends <code>[summary_message, *tail]</code> on the next loop iteration. The harness owns the list it feeds the model, so replacing the list IS the compaction:</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/agent/loop.py">src/decode/agent/loop.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">class AgentTurnHandler:
    ...

    async def compact(self) -&gt; CompactOutcome:
        split = split_tail(
            self.message_history, keep_recent_tokens=settings.compaction_keep_recent_tokens
        )
        skeleton = await summarize_for_compaction(
            self.message_history, model=self._compaction_model
        )

        before_tokens = self._last_input_tokens
        summary_message = build_summary_message(skeleton)
        tail = self.message_history[split:]

        self.message_history = [summary_message, *tail]

        return CompactOutcome.COMPACTED</code></pre></div><p>The 3rd and last option is <strong>microcompaction</strong>, which runs without LLM calls at 60% capacity. It replaces tool outputs outside the recent tail with a placeholder string by inspecting each <code>ToolReturnPart</code> (the message part that holds a tool&#8217;s output). Because tool outputs are consumed each turn, conclusions live on in subsequent messages. Nothing is lost because the tool input remains available in the messages, allowing the agent to rerun the tool if necessary. That is why <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">Anthropic calls tool-result clearing the safest, lightest touch of compaction</a>.</p><p>After every completed turn, the handler checks the same number against both thresholds: full compaction first, then <code>microcompact</code>, replacing <code>message_history</code> through the same reassignment.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/context/compaction.py">src/decode/context/compaction.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">_MICRO_PLACEHOLDER = "[tool output elided by microcompaction]"

def microcompact(
    messages: list[ModelMessage],
    *,
    keep_recent_tokens: int,
    placeholder: str = _MICRO_PLACEHOLDER,
) -&gt; list[ModelMessage]:
    boundary = split_tail(messages, keep_recent_tokens=keep_recent_tokens)

    new_messages: list[ModelMessage] = []
    for index, message in enumerate(messages):
        if index &gt;= boundary or not isinstance(message, ModelRequest):
            new_messages.append(message)
            continue

        new_parts = list(message.parts)
        changed = False
        for position, part in enumerate(message.parts):
            if not isinstance(part, ToolReturnPart | RetryPromptPart):
                continue
            new_parts[position] = dataclasses.replace(part, content=placeholder)

        new_messages.append(dataclasses.replace(message, parts=new_parts))

    return new_messages</code></pre></div><p>When saving the session to JSONL files, there is no compaction. The file is a simple snapshot of the entire message history. To save a compacted session, you either have to run it before exiting the session or resume, run it and then exit.</p><p>In the image below, you can see how the <code>/compact</code> command reduced the context window from <code>&#9681; 57%</code> (~149539) to 8% of the context window.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_ExA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_ExA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 424w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 848w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 1272w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_ExA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png" width="1173" height="445" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:445,&quot;width&quot;:1173,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!_ExA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 424w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 848w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 1272w, https://substackcdn.com/image/fetch/$s_!_ExA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa16b6e09-7ab9-48e7-a208-c20bb0ac32e4_1173x445.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Next steps</h2><p>There are other components we haven&#8217;t touched on in this article, such as an MCP client or an auto-mode permission layer. Still, these are the 4 harness components that are omnipresent in every coding harness you will use. Maybe Pi, with its minimalist design, is the only exception.</p><div class="callout-block" data-callout="true"><p>&#129489;&#8205;&#128187; <span>We encourage you to&nbsp;</span><strong>clone our&nbsp;<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">course repo</a></strong><span>, open your terminal, type </span><strong><span data-color="#38761d" style="color: rgb(56, 118, 29);">&#8221;decode&#8221;</span></strong>,<strong> </strong>and test out the coding agent.</p></div><p>Within the next lesson, we will add the final harness piece to the puzzle: creating an agent&#8217;s catalog used to fan out subagents whose work never pollutes your window.</p><p><span>Here is the</span><strong> course roadmap, </strong><span>lesson by lesson </span><em><span>(</span><a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-course-outline">see all in GitHub</a></em><span>):</span></p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop</a></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p><strong>Context Engineering for Coding Agents &#8592; you are here</strong></p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out &#8592; <em>Available next week</em></p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>When your coding agent&#8217;s window fills up mid-task, what do you actually do today: </strong></em><code>/clear</code><em><strong> and lose the thread, </strong></em><code>/compact</code><em><strong> and hope the summary gets the job done, or just keep going until it degrades?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/context-engineering-for-coding-agents/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/context-engineering-for-coding-agents/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/context-engineering-for-coding-agents?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/context-engineering-for-coding-agents?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <strong><a href="https://modal.com?source=decodingai&amp;campaign=harnesseng">Modal</a></strong>, <strong><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik (by Comet)</a></strong>, and <strong><a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru (by ZenML)</a></strong> for sponsoring this open-source course and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uq-1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images &amp; videos</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[From a Raw Shell to a Sandboxed Coding Agent]]></title><description><![CDATA[The guide to isolating your harness and safely executing its commands, locally or remotely.]]></description><link>https://www.decodingai.com/p/run-coding-agents-safely</link><guid isPermaLink="false">https://www.decodingai.com/p/run-coding-agents-safely</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 18 Aug 2026 11:02:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!k1Xr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="callout-block" data-callout="true"><p>In LangChain&#8217;s Terminal-Bench experiment, changing only the harness (with the same model) moved a coding agent from ~30th place into the top 5: the harness, not the model, is what makes a coding agent good.</p><p>In the&nbsp;<strong>open-source course</strong>&nbsp;<strong><a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">Building a Coding Agent From Scratch</a></strong>, you&#8217;ll build that harness from scratch in Python:&nbsp;<strong>Decode</strong>, a complete coding agent that grows lesson by lesson from a bare agent loop into a swarm of remote agents running in parallel in the cloud.</p><p><strong>Why?</strong>&nbsp;You&#8217;ll be able to engineer custom harnesses for your own AI products (the skill behind that leaderboard jump), and you&#8217;ll understand what Claude Code and Codex actually do under the hood, turning you into a power user.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ge05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1446989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Lessons:</strong></p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a><strong> </strong></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop </a></p></li><li><p><strong>From a Raw Shell to a Sandboxed Coding Agent</strong> <strong>&#8592; </strong><em><strong>you are here</strong></em></p></li><li><p>Context Engineering for Coding Agents <strong>&#8592; </strong><em>Available next week</em></p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course&quot;,&quot;text&quot;:&quot;Full open-source course&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course"><span>Full open-source course</span></a></p></div><h1>Lesson 3: From Raw Shell to a Sandboxed Coding Agent<em>.</em></h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k1Xr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k1Xr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k1Xr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The agent keeps all of its power. The room is what changes.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The agent keeps all of its power. The room is what changes." title="The agent keeps all of its power. The room is what changes." srcset="https://substackcdn.com/image/fetch/$s_!k1Xr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!k1Xr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F97e3b938-fb2a-462c-923f-fbd591667a65_1376x768.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Mid-session, Claude Code was running inside my Obsidian Second Brain when it fired off a cleanup command that deleted half my notes. If I hadn&#8217;t been backing them up with Obsidian Sync, two years of work would have been gone.</p><p>Even if you carefully isolate your agent, it can still reach the internet and go off the rails. In July 2026, <a href="https://www.scientificamerican.com/article/openai-admits-its-agent-went-rogue-and-hacked-ai-startup-hugging-face/">OpenAI&#8217;s agents</a> hacked Hugging Face. A week later, Anthropic <a href="https://www.anthropic.com/news/investigating-incidents-cybersecurity-evals">disclosed</a> that, after analyzing 141,006 eval runs from an isolated harness, their Claude models had gained unauthorized access to production infrastructure across 3 real organizations.</p><p>Still, for normal people who care about protecting their data, sandboxing is THE containment solution.</p><p>In Lesson 2, we saw how to implement an agent loop that controls your computer through 4 core tools: <code>read</code>, <code>write</code>, <code>edit</code>, and <code>bash</code>. In this article, we will learn how to isolate every computer-use tool from the rest of your system inside a <strong>sandbox</strong>.</p><p>We will hook it to two types of sandbox backends &#8212; local Docker and remote Modal &#8212; plus explore the other options and their trade-offs.</p><p>The cherry on top? GPU compute and scaling out of the box, plugged straight into your harness as a control center.</p><p>By the end, you will run:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">SANDBOX_MODE=modal decode --repo https://github.com/&lt;your-repo&gt;.git "Swap from Gemini to Kimi K3."</code></pre></div><p>Which will spin up a remote Modal sandbox hooked to Decode &#8212; the educational harness we are building throughout this course &#8212; set up the given repo, implement the requested feature, and end with a PR for review as the final artifact.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course&quot;,&quot;text&quot;:&quot;Try it yourself&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course"><span>Try it yourself</span></a></p><h2>The tools you love already use a sandbox</h2><p>Locally, every <code>bash</code> command Claude Code or <a href="https://github.com/openai/codex">Codex CLI</a> runs is wrapped in an OS-level jail &#8212; Seatbelt on macOS, bubblewrap on Linux (kernel features that block a process&#8217;s filesystem reach and syscalls).</p><p>In the cloud, Codex isolates <a href="https://blog.bytebytego.com/p/how-openai-codex-works">every task in its own environment (aka sandbox) preloaded with your repo</a>.</p><p><strong>In that case, what&#8217;s a sandbox?</strong> It&#8217;s an execution boundary: the agent runs every tool that can alter the host inside a &#8220;jail&#8221;, so a wrong command runs inside a container, not your host.</p><p>Ok&#8230; That&#8217;s abstract. So how does a harness actually run its tools in this &#8220;jail&#8221;?</p><h2>How do sandboxes actually work?</h2><p>In <a href="https://www.decodingai.com/p/the-coding-agent-loop">Lesson 2</a>, we learned that the core tools the agent uses to interact with your computer are <code>read</code>, <code>write</code>, <code>edit</code>, and <code>bash</code>. The rest (<code>web_fetch</code>, <code>todo_write</code>, <code>ask_user</code>, plan mode) never touch the filesystem &#8212; they are meta tools for fetching context and planning. That&#8217;s why, following Pi&#8217;s philosophy, they are optional.</p><p>Thus, our problem reduces to isolating the execution of the core tools from the rest of the harness. There are two main approaches.</p><p>In <strong>option 1,</strong> we run the whole harness in a Docker container or a remote Modal sandbox. It is straightforward and gives complete isolation, but it forces you to work in an environment different from your machine, with little flexibility to isolate specific tasks.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7A90!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7A90!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 424w, https://substackcdn.com/image/fetch/$s_!7A90!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 848w, https://substackcdn.com/image/fetch/$s_!7A90!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 1272w, https://substackcdn.com/image/fetch/$s_!7A90!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7A90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png" width="1200" height="498" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:498,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The one decision that defines the architecture &#8212; put the whole harness in the box, or keep it home and send only its tools across.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The one decision that defines the architecture &#8212; put the whole harness in the box, or keep it home and send only its tools across." title="The one decision that defines the architecture &#8212; put the whole harness in the box, or keep it home and send only its tools across." srcset="https://substackcdn.com/image/fetch/$s_!7A90!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 424w, https://substackcdn.com/image/fetch/$s_!7A90!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 848w, https://substackcdn.com/image/fetch/$s_!7A90!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 1272w, https://substackcdn.com/image/fetch/$s_!7A90!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0a626466-af9c-4245-a046-b7b1c11819cf_1200x498.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The one decision that defines the architecture: Put the whole harness in the sandbox, or keep it local and only execute tools inside the sandbox.</em></figcaption></figure></div><p>In <strong>option 2</strong>, we run the computer-use tools in a sandbox while the harness and the rest of the tools stay on the host. You keep your harness as your control center while executing tools inside the sandbox.</p><p>Option 1 is as simple as SSH-ing into a remote machine and running <code>claude</code>. Option 2 is where the real harness engineering happens.</p><p>The second dimension we have to think about is where the sandbox runs: locally in Docker or remotely on Modal.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7aEX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7aEX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 424w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 848w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 1272w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7aEX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png" width="1200" height="484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Where a bash tool call actually runs &#8212; remote on Modal, locally in Docker, or raw on the host.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Where a bash tool call actually runs &#8212; remote on Modal, locally in Docker, or raw on the host." title="Where a bash tool call actually runs &#8212; remote on Modal, locally in Docker, or raw on the host." srcset="https://substackcdn.com/image/fetch/$s_!7aEX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 424w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 848w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 1272w, https://substackcdn.com/image/fetch/$s_!7aEX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde23dee8-a770-4dd1-9d50-4ea4dfb6a1e9_1200x484.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The core idea behind sandboxing computer-use tools such as bash.</em></figcaption></figure></div><p>Regardless of where the sandbox runs, every computer-use tool call gets wrapped in an <code>inSandbox(command)</code> call. In our educational coding harness, Decode, we defined a <code>CommandExecutor</code> interface with 2 implementations (<code>LocalExecutor</code> for the host, <code>SandboxExecutor</code> for a backend), powered by 2 <strong>sandbox backends</strong>: <code>DockerBackend</code> or <code>ModalBackend</code>.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/sandbox/__init__.py">src/decode/sandbox/__init__.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def select_executor(mode: str) -&gt; CommandExecutor:
    if mode == "docker":
        return SandboxExecutor(DockerBackend())
    if mode == "modal":
        return SandboxExecutor(ModalBackend())
    from decode.tools.exec import LocalExecutor

    return LocalExecutor()</code></pre></div><p>The tool never knows where the command runs. The LLM emits the command, while the harness takes care of executing it in the selected environment. Once we build the right executor, we just call <code>executor.run(command)</code>, completely abstracted away from the sandbox &#8212; which means we can extend it with sandboxes beyond Docker or Modal.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/tools/bash.py">src/decode/tools/bash.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def bash(
    ctx: RunContext[AgentDeps],
    command: str,
    timeout: float | None = None,
) -&gt; str:
    if needs_approval(ctx):
        raise ApprovalRequired  # Permission gate &#8212; before anything runs

    if not command.strip():
        raise ModelRetry("command is empty; provide a shell command to run.")
    timeout_s = _resolve_timeout(timeout)

    executor = await _get_executor() # sandbox (powered by Docker or Modal) or local
    result = await executor.run(command, cwd=ctx.deps.cwd, timeout_s=timeout_s)

    return _render(result, timeout_s=timeout_s)</code></pre></div><p>We adopt a similar strategy for the <code>read</code>, <code>write</code>, and <code>edit</code> tools, plus optional ones such as <code>glob</code> and <code>ls</code>. That way the agent sees a single filesystem: when <code>write</code> creates a file, <code>bash</code> sees it immediately.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uAaO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uAaO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 424w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 848w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 1272w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uAaO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png" width="1200" height="592" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:592,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The executor seam in motion &#8212; the agent loop keeps emitting bash calls on your machine, and each one runs as a command inside the sandbox.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The executor seam in motion &#8212; the agent loop keeps emitting bash calls on your machine, and each one runs as a command inside the sandbox." title="The executor seam in motion &#8212; the agent loop keeps emitting bash calls on your machine, and each one runs as a command inside the sandbox." srcset="https://substackcdn.com/image/fetch/$s_!uAaO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 424w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 848w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 1272w, https://substackcdn.com/image/fetch/$s_!uAaO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1215db45-22b7-45ea-a80d-ce91ae11cda2_1200x592.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The executor logic: The agent loop keeps emitting bash calls on your machine, and each one runs as a command inside the sandbox.</em></figcaption></figure></div><p>Now, let&#8217;s zoom in on how local sandboxes work via Docker.</p><h2>Local sandboxes via Docker</h2><p>Run &#8220;<code>SANDBOX_MODE=docker decode --repo git@github.com:you/project.git"</code> to start a new Decode session inside a Docker sandbox, which contains 5 main steps:</p><ol><li><p><code>DockerBackend</code> launches one long-lived <strong>keeper container</strong> running <code>sleep infinity</code>.</p></li><li><p>Injects all the environment variables from <code>.env</code> into the container.</p></li><li><p>Attaches a local volume at <code>.decode/sandbox</code>.</p></li><li><p>Prepares <strong>the Workspace</strong> by cloning <code>--repo</code> into <code>.decode/sandbox</code> at HEAD.</p></li><li><p>Installs the dependencies by running <code>uv sync</code> on the given <code>--repo</code>.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gae9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gae9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 424w, https://substackcdn.com/image/fetch/$s_!gae9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 848w, https://substackcdn.com/image/fetch/$s_!gae9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 1272w, https://substackcdn.com/image/fetch/$s_!gae9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gae9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png" width="1200" height="309" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:309,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Session start in Docker mode is a straight line &#8212; create the container, inject the env vars, bind the Workspace volume, download the repo, install dependencies.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Session start in Docker mode is a straight line &#8212; create the container, inject the env vars, bind the Workspace volume, download the repo, install dependencies." title="Session start in Docker mode is a straight line &#8212; create the container, inject the env vars, bind the Workspace volume, download the repo, install dependencies." srcset="https://substackcdn.com/image/fetch/$s_!gae9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 424w, https://substackcdn.com/image/fetch/$s_!gae9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 848w, https://substackcdn.com/image/fetch/$s_!gae9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 1272w, https://substackcdn.com/image/fetch/$s_!gae9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbd37a1cb-ef55-4cf9-b5e4-8d823e392358_1200x309.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Docker sandbox lifecycle: Create the container, inject the env vars, bind the Workspace volume, download the repo, install dependencies.</em></figcaption></figure></div><p>Within the <code>DockerBackend</code> class, plugged into <code>SandboxExecutor</code>, we have 2 functions to implement: <code>create</code> and <code>exec</code>. <code>create</code> mostly goes through the 5 steps outlined above. In <code>exec</code>, each <code>bash</code> call translates to a <code>docker exec &lt;command&gt;</code> against its associated container.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/sandbox/docker_backend.py">src/decode/sandbox/docker_backend.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">_WORKSPACE = "/workspace"  # container-side path of the Workspace

class DockerBackend:
    async def create(self, workspace: Path) -&gt; None:
        # once, at session start
        # `workspace` is the host-side clone of your
        # --repo at .decode/sandbox

        args = ["run", "-d", "--rm", "-v", f"{workspace}:{_WORKSPACE}", "-w", _WORKSPACE]
        if sandbox_git_token():
            args += ["-e", GIT_TOKEN_ENV]
        args += ["ghcr.io/astral-sh/uv:python3.12-bookworm-slim", "sleep", "infinity"]
        proc = await asyncio.create_subprocess_exec(
            "docker", *args,
            stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
            env=_run_env(), 
        )
        stdout, _ = await proc.communicate()
        container_id = stdout.decode().strip()  # `docker run -d` prints the container id

    async def exec(self, *args: str, timeout_s: float) -&gt; ExecResult:
        # for every bash tool call &#8212; a fresh exec
        proc = await asyncio.create_subprocess_exec(
            "docker", "exec", "-w", _WORKSPACE, container_id, *args,
            stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE,
            start_new_session=True,  # own process group &#8594; kill as a unit on timeout
        )
        ...  # gather stdout/stderr &#8594; ExecResult</code></pre></div><p>Docker is easy to set up, works out of the box with container tooling, and the same containers can later be hosted remotely via Kubernetes or other orchestrators. As good as that sounds, it isn&#8217;t truly secure. Container processes are <a href="https://www.youtube.com/watch?v=wsFd22SL1s8">native processes on your kernel</a>. As Abhishek Bhardwaj, on OpenAI&#8217;s RL and agent-infrastructure team, puts it, a container process can exploit that boundary and take the host &#8212; a kernel exploit is <a href="https://www.youtube.com/watch?v=OqM67QG_Ikk">&#8220;a New York Times article waiting to happen&#8221;</a>.</p><p>Docker sits on a spectrum:</p><ol><li><p><strong>fork/exec</strong> &#8212; straightforward to implement, no boundary. The command talks straight to your kernel.</p></li><li><p><strong>Containers</strong> &#8592; <strong>we are here.</strong> A namespace-and-cgroup boundary. Shared kernel. Another option is Podman, which doesn&#8217;t use a daemon, saving latency.</p></li><li><p><strong>gVisor</strong> &#8212; a user-space &#8220;sentry&#8221; kernel answers the syscalls, turning a direct kernel exploit into a two-hop chain (sentry &#8594; host kernel). Costs little: near-container performance. It&#8217;s what <a href="https://modal.com/docs/guide/security?source=decodingai&amp;campaign=harnesseng">Modal runs underneath its sandboxes</a>. Not perfect. If the agent gets past the sentry, you&#8217;re back on the shared kernel.</p></li><li><p><strong>microVMs</strong> &#8212; <a href="https://github.com/firecracker-microvm/firecracker">Firecracker</a> or <a href="https://www.cloudhypervisor.org/">Cloud Hypervisor</a> on KVM, the Linux kernel&#8217;s own hypervisor (Linux hosts only). The guest kernel runs in a separate CPU execution context from the host, so even if the agent fully compromises it, it can&#8217;t reach yours. Cheaper than it sounds: <a href="https://github.com/abshkbh/arrakis">Arrakis</a> boots one in under 7s, against ~40s for a traditional VM.</p></li></ol><p><strong>Seatbelt and bubblewrap sit on the same layer as containers.</strong> They are OS jails. They wrap one command instead of the whole machine, deriving the filesystem profile from the permission rules the agent already uses. No image, no daemon. Still sharing your host&#8217;s kernel. That&#8217;s what Claude Code and Codex CLI run locally. Cheaper than Docker, not stronger.</p><p>So which one? If you trust the code and just want your own files safe, go with <strong>containers</strong> (as we did in Decode). Otherwise, for full isolation, go with <strong>microVMs</strong>. Bhardwaj&#8217;s verdict, after building OpenAI&#8217;s sandbox cloud: <a href="https://www.youtube.com/watch?v=OqM67QG_Ikk">&#8220;in the end, everyone always wants a VM&#8230; let me save you the story and two years of grief, just please use microVMs from the start&#8221;</a>.</p><p>To run it on your own machine, follow the <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-running-the-code">&#8220;Running the Code&#8221; setup steps</a> in the course repo, then launch:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">SANDBOX_MODE=docker decode --repo https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course.git</code></pre></div><p>This clones the repo into the isolated Workspace (<code>/workspace</code> &#8801; host <code>.decode/sandbox</code>) and opens a new TUI session wired to the Docker container. To test it out, pick any feature, plan it, ask for a PR, and let Decode do the rest.</p><p>For a quick test, we prepared a demo wrapped as the <code>/demo-5-sandbox-feature-pr</code> skill. It uses Decode to spin up a new sandboxed Decode session and instructs it to implement a small feature from a pool of available ones (e.g. a <code>decode --version</code> CLI command), then open a PR with it. Creating feature PRs is essential when working in sandboxes, as you have no direct access to where the code actually runs.</p><p>The real win, though, is when the box isn&#8217;t on your machine at all.</p><h2>Remote sandboxes via Modal</h2><p><a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a>&#8216;s core primitive is <a href="https://modal.com/docs/guide/sandboxes?source=decodingai&amp;campaign=harnesseng">the sandbox</a> &#8212; an isolated, serverless runtime that starts in under half a second.</p><p>Run &#8220;<code>SANDBOX_MODE=modal decode --repo git@github.com:you/project.git"</code> and here is what happens through Modal&#8217;s 5-event lifecycle:</p><ol><li><p><strong>Created</strong>: <code>ModalBackend</code> requests a sandbox under <code>decode-sandbox-&lt;env&gt;</code>.</p></li><li><p><strong>Scheduled</strong>: Modal finds capacity on its infra.</p></li><li><p><strong>Started</strong>: the container is live and can execute commands (but the app is not ready yet).</p></li><li><p><strong>Ready</strong>: the tar containing the app files is uploaded into <code>/workspace</code> (making the app env ready).</p></li><li><p><strong>In use</strong>: <code>bash</code> and the other computer-use tools exec successfully against the remote.</p></li></ol><p>Modal&#8217;s sandbox infra boots fast. Preparing the app dependencies is what takes a while.</p><p>That&#8217;s why, as you can see in the image below, we mount a volume that already contains the app dependencies, so they are ready when the container starts. On top of that, to avoid the cold start problem &#8212; you want the sandbox ready as soon as the harness starts &#8212; we prepare a sandbox pool modeled as a queue. We populate it with application-agnostic sandboxes and turn them into application-specific ones by attaching a volume. This combination of sandbox pool plus volume mounting gives us application-ready sandboxes on demand. More on this <a href="https://modal.com/blog/unpacking-sandbox-startup-latency?source=decodingai&amp;campaign=harnesseng">here</a>.</p><p>Check <a href="https://modal.com/blog/scaling-to-1-million-concurrent-sandboxes-in-seconds?source=decodingai&amp;campaign=harnesseng">this blog post</a> if you want to learn more about how Modal dropped Kubernetes and built its sandbox architecture from scratch to start 1 million concurrent sandboxes in under a minute.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uvba!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uvba!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 424w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 848w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 1272w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uvba!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png" width="1200" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Modal backend &#8212; the harness stays local, every tool call crosses into a remote sandbox that mounts its repository volume, and sandboxes come pre-provisioned from a pool.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Modal backend &#8212; the harness stays local, every tool call crosses into a remote sandbox that mounts its repository volume, and sandboxes come pre-provisioned from a pool." title="The Modal backend &#8212; the harness stays local, every tool call crosses into a remote sandbox that mounts its repository volume, and sandboxes come pre-provisioned from a pool." srcset="https://substackcdn.com/image/fetch/$s_!Uvba!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 424w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 848w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 1272w, https://substackcdn.com/image/fetch/$s_!Uvba!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6fbbf5d8-c0e6-45ff-95c3-5c9555da65a2_1200x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The Modal backend: The harness stays local, every tool call crosses into a remote sandbox that mounts its repository volume, and sandboxes come pre-provisioned from a pool.</em></figcaption></figure></div><p>The <code>ModalBackend</code> class looks similar to the <code>DockerBackend</code> one. Inside <code>create</code>, we create the sandbox from a pre-built <code>uv</code> Docker image. We inject a git token to get access to our private repositories. Finally, we launch it with the <code>sleep infinity</code> command to keep it running &#8212; now on Modal&#8217;s infrastructure, which takes care of our security concerns.</p><p><strong>Modal puts zero risk on your host.</strong> It&#8217;s remote, and it runs gVisor to intercept syscalls before they reach the kernel. Even when OpenAI&#8217;s agents hacked Hugging Face, as reported <a href="https://www.aljazeera.com/news/2026/7/29/openais-rogue-agent-hacked-an-account-at-a-second-technology-firm-report">here</a>, their code was running on one of Modal&#8217;s sandboxes &#8212; the agent exploited Hugging Face&#8217;s code running there, not the Modal infrastructure itself.</p><p>Within the <code>exec</code> method, we execute the command that comes from the LLM and return the output and exit code.</p><p><em>From <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/src/decode/sandbox/modal_backend.py">src/decode/sandbox/modal_backend.py</a>:</em></p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">class ModalBackend:
    async def create(self, workspace: Path) -&gt; None:
        app = await modal.App.lookup.aio(_app_name(), create_if_missing=True)
        image = modal.Image.from_registry(
            "ghcr.io/astral-sh/uv:python3.12-bookworm-slim"
        ).apt_install("git", "curl", "ca-certificates")
        secrets = []
        if token := sandbox_git_token():
            image = image.run_commands(GIT_CREDENTIAL_HELPER)
            secrets = [modal.Secret.from_dict({GIT_TOKEN_ENV: token})]
        sandbox = await modal.Sandbox.create.aio(
            "sleep", "infinity", app=app, image=image,

        ...  # tar-upload the Workspace into /workspace &#8212; the "Ready" step

    async def exec(self, *args: str, timeout_s: float) -&gt; ExecResult:
        proc = await sandbox.exec.aio(*args, workdir=workdir, timeout=timeout, text=False)
        stdout, stderr = await asyncio.gather(proc.stdout.read.aio(), proc.stderr.read.aio())
        exit_code = await proc.wait.aio()

        ...  # &#8594; ExecResult</code></pre></div><p>From <a href="https://modal.com/pricing?source=decodingai&amp;campaign=harnesseng">Modal&#8217;s pricing page</a> at the time of writing: a CPU sandbox at 2 cores + 4 GiB runs &#8776; 0.38/<em>hr</em>, <em>a</em> <em>B</em>200 <em>GPU</em> <em>bills</em> &#8776;6.25/hr, and an H200 &#8776; $4.54/hr. For pure agentic work, the CPU sandbox gets the job done, while the GPU ones let you run inference or fine-tuning jobs directly from your harness.</p><p>The default is using the CPU sandbox. To configure it with x4 H200 we would do:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">sandbox = await modal.Sandbox.create.aio(
    ...,              # Same parameters as the CPU sandbox
    gpu="H200:4",     # 4&#215; H200 attached to this sandbox
)</code></pre></div><p>As discussed in <a href="https://www.decodingai.com/i/208432780/the-llm-providers">Lesson 2</a> on pay-per-token vs. serverless, for ad-hoc data processing serverless can come out ~80-90% cheaper.</p><p>The trade-offs of a remote sandbox over a local one: network latency, sandbox management, and extra costs.</p><p>You can run the same test as for the Docker sandbox by following the <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-running-the-code">&#8220;Running the Code&#8221; Modal extra setup steps</a> and swapping <code>SANDBOX_MODE=docker</code> for <code>modal</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">SANDBOX_MODE=modal decode --repo https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course.git</code></pre></div><p>After running it, Modal&#8217;s dashboard shows how many sandboxes are live (5 in our case):</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5yvV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5yvV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 424w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 848w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 1272w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5yvV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png" width="1456" height="433" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/db61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:433,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Number of running sandboxes in Modal&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Number of running sandboxes in Modal" title="Number of running sandboxes in Modal" srcset="https://substackcdn.com/image/fetch/$s_!5yvV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 424w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 848w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 1272w, https://substackcdn.com/image/fetch/$s_!5yvV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdb61bc42-9973-4655-8108-40308b5a9a8c_3288x978.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And if you open the sandbox app and click &#8220;Sandboxes&#8221;, you get the full list:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0AC-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0AC-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 424w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 848w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 1272w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0AC-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png" width="1456" height="512" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:512,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The list of running sandboxes inside the Modal sandbox app&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The list of running sandboxes inside the Modal sandbox app" title="The list of running sandboxes inside the Modal sandbox app" srcset="https://substackcdn.com/image/fetch/$s_!0AC-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 424w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 848w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 1272w, https://substackcdn.com/image/fetch/$s_!0AC-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fccdaad8d-8c2a-4918-9513-5cd9abb6c812_3088x1086.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These sandboxes are created when you enter a new Decode session and automatically cleaned up when you exit via the <code>/quit</code> command.</p><h2>The wanted side effects of remote sandboxes</h2><p>Remote sandboxes give you 2 powerful side effects beyond safety.</p><p><strong>The first is compute.</strong> Modal sandboxes accept a <a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng">GPU spec like </a><code>gpu="B200:8"</code><a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng"> at creation</a>, letting you agentically fine-tune models or process large datasets (eg extracting knowledge graphs from 1000+ documents) with open-weight LLMs such as Qwen3.6, Gemma 4, K3, or GLM5.2.</p><p><strong>The second is scale.</strong> An orchestrator agent running directly on the host (no sandbox) can hand work to background agents running on Modal remote sandboxes. Put them on a CPU if you just need a bunch of parallel agents hitting an LLM API to pull tickets from your Linear backlog, or on a GPU if you need to squeeze out more juice.</p><p>In <a href="https://modal.com/blog/how-ramp-built-a-full-context-background-coding-agent-on-modal?source=decodingai&amp;campaign=harnesseng">this case study</a>, Ramp, a fintech company, runs every agent session in its own Modal sandbox with a full dev environment inside. Modal&#8217;s own conclusion from the case study is that with cheap isolation, the bottleneck shifts from &#8220;can the agent write correct code&#8221; to &#8220;how many agents can you run in parallel&#8221;.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Vi-q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Vi-q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 424w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 848w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 1272w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Vi-q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png" width="1200" height="551" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:551,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The scaling shape the seam makes possible &#8212; an unsandboxed orchestrator on your machine fans work out to N background agents, each contained in its own sandbox.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The scaling shape the seam makes possible &#8212; an unsandboxed orchestrator on your machine fans work out to N background agents, each contained in its own sandbox." title="The scaling shape the seam makes possible &#8212; an unsandboxed orchestrator on your machine fans work out to N background agents, each contained in its own sandbox." srcset="https://substackcdn.com/image/fetch/$s_!Vi-q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 424w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 848w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 1272w, https://substackcdn.com/image/fetch/$s_!Vi-q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e446570-e1bb-4559-a85a-e95d6bcb4795_1200x551.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Scaling: An unsandboxed orchestrator on your machine fans work out to N background agents, each contained in its own sandbox.</em></figcaption></figure></div><h2>Next steps</h2><p>Should you sandbox all the time? No. As a Claude Code power user, to keep it simple, I still run directly on my machine in folders versioned by git or Obsidian Sync.</p><p>Sandboxes are non-negotiable for:</p><ul><li><p>24/7 personal assistants that control your whole computer like <a href="https://openclaw.ai/">OpenClaw</a> or Hermes;</p></li><li><p>non-engineers using tools like <a href="https://www.anthropic.com/product/claude-cowork">Claude Cowork</a>;</p></li><li><p>unmonitored remote jobs like <a href="https://openai.com/research/codex">Codex</a>;</p></li><li><p>or when chasing GPUs and parallel scale.</p></li></ul><p>Is this the only way to add sandboxes to your harness? As we are just getting started, surely not. For another perspective, <a href="https://www.youtube.com/watch?v=OqM67QG_Ikk">here is Abhishek Bhardwaj&#8217;s talk</a>, explaining how OpenAI runs agent workloads in a cloud of microVM sandboxes instead of containers.</p><div class="callout-block" data-callout="true"><p>&#129489;&#8205;&#128187; <span>We encourage you to&nbsp;</span><strong>clone our&nbsp;<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">course repo</a></strong><span>, open your terminal, type </span><strong><span data-color="#38761d" style="color: rgb(56, 118, 29);">&#8221;decode&#8221;</span></strong>,<strong> </strong>and test out the coding agent.</p></div><p>In the next lesson, we will explore the key context-engineering techniques that coding harnesses use: memory, compaction, skills, and LSP servers.</p><p>Here is the<strong> course roadmap, </strong>lesson by lesson <em>(<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-course-outline">see all in GitHub</a></em>):</p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a><strong> </strong></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop </a></p></li><li><p><strong>From a Raw Shell to a Sandboxed Coding Agent</strong> <strong>&#8592; </strong><em><strong>you are here</strong></em></p></li><li><p>Context Engineering for Coding Agents <strong>&#8592; </strong><em>Available next week</em></p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Do you run your coding agent raw on your machine, or sandboxed?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/run-coding-agents-safely/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/run-coding-agents-safely/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/run-coding-agents-safely?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/run-coding-agents-safely?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <strong><a href="https://modal.com?source=decodingai&amp;campaign=harnesseng">Modal</a></strong>, <strong><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik (by Comet)</a></strong>, and <strong><a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru (by ZenML)</a></strong> for sponsoring this open-source course and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uq-1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images &amp; videos</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[11 Tips to Run Coding Agents 24/7 on One Subscription]]></title><description><![CDATA[Context engineering techniques to avoid wasting tokens on what doesn't matter]]></description><link>https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens</link><guid isPermaLink="false">https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 04 Aug 2026 11:04:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!-mAQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-mAQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-mAQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-mAQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The archive is enormous. What sits under the lamp is three cards.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The archive is enormous. What sits under the lamp is three cards." title="The archive is enormous. What sits under the lamp is three cards." srcset="https://substackcdn.com/image/fetch/$s_!-mAQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!-mAQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff89ec8d0-4fe0-4c4e-be76-04cb2528a742_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I&#8217;m on vacation, so today I will keep it short.</p><p>Since February 2026, when I got my $200 Anthropic subscription, I maxed it out only once. It happened when Fable was released, and I started using it the way I used previous models such as Opus. After 4-5 queries through my content and software factories, I was running out of tokens.</p><p>Since then, I still use Fable, but only where it&#8217;s worth it. Never hitting my weekly token limit. At least not by surprise. I still have those moments where I am aware that if I press Enter, it will cost me tokens. But sometimes it&#8217;s worth it.</p><p>Anyway, I wanted to share with you 11 context/harness engineering tips that I use in my daily workflows and that work like a charm for me.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Pwe9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Pwe9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 424w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 848w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 1272w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Pwe9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png" width="1200" height="626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/974dd521-5303-4f87-8903-73775563f70a_1200x626.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:626,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The 11 tips at a glance.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The 11 tips at a glance." title="The 11 tips at a glance." srcset="https://substackcdn.com/image/fetch/$s_!Pwe9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 424w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 848w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 1272w, https://substackcdn.com/image/fetch/$s_!Pwe9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F974dd521-5303-4f87-8903-73775563f70a_1200x626.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>1. Progressive disclosure is the foundation everything else sits on</h2><p>I use references in my <code>AGENTS.md</code> files, LLM wikis, and Obsidian to build hierarchies, so the model walks a table of contents and pulls a file only when something resolves to it. Anthropic frames it as a finite <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">attention budget</a>: every token you add competes with every other one.</p><p>OpenAI rebuilt its <code>AGENTS.md</code> into a roughly 100-line table of contents pointing into a linted docs tree, and shipped about a million lines of Codex-written code that way. Quote: <em><a href="https://openai.com/index/harness-engineering-leveraging-codex-in-an-agent-first-world/">&#8220;give Codex a map, not a 1,000-page instruction manual&#8221;</a>.</em></p><h2>2. Plan like crazy, then let a cheaper model execute</h2><p>Token-wise, planning is cheaper than executing. I use the most powerful model available (currently Fable) to produce a plan, then hand it to a cheaper one. I never say &#8220;implement X&#8221;. Instead, I build an extremely detailed plan going through the system design, architecture, components, interfaces and data flow. When a smaller model executes that, it&#8217;s hard to make a mistake.</p><p>I work the plan through 4 dimensions (known knowns, known unknowns, unknown knowns, unknown unknowns) and let the model grill me with questions to surface blind spots.</p><h2>3. For greenfield work, an LLM wiki is the context you point at</h2><p>A wiki lets a plan reference 30 documents without loading 30 documents. When I start working on a new project, I always build one first: a light context layer built via files instead of a database. The plan cites the index that describes the documents, not the corpus, so it stays grounded at near-zero cost. I wrote a <a href="https://www.decodingai.com/p/llm-wiki-agent-memory">full piece</a> on this.</p><h2>4. Send a cheap subagent to read the whole thing</h2><p>The subagent pays the reading cost. You only receive the summary. When I&#8217;m parsing data, I spin up Haiku or Sonnet subagents that hand back only an executive summary to Opus or Fable. A subagent can <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">burn tens of thousands of tokens</a> and return a distilled 1,000-2,000. I clustered my entire Decoding AI archive this way and my main agent&#8217;s context barely grew.</p><h2>5. An ADR and a glossary per feature</h2><p>For every new feature my planning step outputs a task list, an architecture decision record (ADR), and a glossary update. The ADR caches the why behind each decision; the glossary pins down what each term means. Both act as context for later features. OpenAI recommends the same artifact &#8212; <em><a href="https://openai.com/index/harness-engineering-leveraging-codex-in-an-agent-first-world/">&#8220;exec-plans checked into the repo&#8221;</a></em> with progress and decision logs.</p><h2>6. I don&#8217;t graph-index my codebase</h2><p>I don&#8217;t build graphs to index my codebase. The code and the docs drift apart almost immediately, and then you burn tokens keeping an artifact in sync with the thing it describes. That violates clean code principles before it&#8217;s a token problem.</p><p>Note that keeping a glossary and a log of ADRs is different from building a graph out of your code. The glossary and ADRs are orthogonal to the codebase, tracking your domain conventions and design decisions over time. If you change the code, the ADR log doesn&#8217;t need to be changed. It just gets a new entry.</p><p>Worth being precise, because Cursor is a live counterexample: it <a href="https://read.engineerscodex.com/p/how-cursor-indexes-codebases-fast">diffs its embedding index against file hashes every few minutes</a> and re-uploads only what changed. A strategy that adds a lot of complexity. Meanwhile, Claude Code and Codex just parse the codebase at runtime via glob and grep.</p><h2>7. Your modules are already the graph</h2><p>Instead of indexing, I think hard about how to modularize my code, how to shape the interfaces, and how data moves between components. That is your graph, and progressive disclosure parses it really well.</p><p>My sanity check: can I paste this module into another project and have it work?</p><h2>8. Trim the payload you never see</h2><p>Tools like Claude Code become a Swiss army knife that puts a ton of stuff into the system prompt that you never use. They fill it with references to all their features, such as push notifications, remote triggers, scheduling, etc. The logic is simple: for the harness to work with all those features, they need to be mentioned in the system prompt.</p><p>The solution is either to go with a minimalistic approach such as Pi, which ships a bare-bones coding agent you can extend via plugins, or to trim down your Claude Code/Codex harness via a <code>settings.json</code> like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cFex!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cFex!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 424w, https://substackcdn.com/image/fetch/$s_!cFex!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 848w, https://substackcdn.com/image/fetch/$s_!cFex!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 1272w, https://substackcdn.com/image/fetch/$s_!cFex!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cFex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png" width="1456" height="1334" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1334,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!cFex!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 424w, https://substackcdn.com/image/fetch/$s_!cFex!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 848w, https://substackcdn.com/image/fetch/$s_!cFex!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 1272w, https://substackcdn.com/image/fetch/$s_!cFex!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb0b2baeb-57ed-43bc-95b9-689611b7a519_2360x2163.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Inspired by Matt Pocock&#8217;s <a href="https://www.aihero.dev/how-to-kill-the-bloat-in-claude-codes-system-prompt">aihero.dev guide</a></figcaption></figure></div><p>Here is how my context window looks now. Hooked into my content &amp; software factory on a 1M-token window, my payload is 21.4k tokens: 4.3k system prompt, 11.6k system tools, 2.7k across 17 skills, and 46 MCP tools costing literally zero because they load on demand.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X3z4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X3z4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 424w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 848w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 1272w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X3z4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png" width="493" height="490" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3402bf29-a721-4cda-9880-bebe63e085af_493x490.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:490,&quot;width&quot;:493,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;My /context breakdown after trimming &#8212; 21.4k tokens of standing payload, 46 MCP tools at 0 tokens.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="My /context breakdown after trimming &#8212; 21.4k tokens of standing payload, 46 MCP tools at 0 tokens." title="My /context breakdown after trimming &#8212; 21.4k tokens of standing payload, 46 MCP tools at 0 tokens." srcset="https://substackcdn.com/image/fetch/$s_!X3z4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 424w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 848w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 1272w, https://substackcdn.com/image/fetch/$s_!X3z4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3402bf29-a721-4cda-9880-bebe63e085af_493x490.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>9. Turn auto-memory off &#8212; under one condition</h2><p>Auto-memory files, like <code>MEMORY.md</code>, reload into the system prompt every session.</p><p>I set Claude Code&#8217;s auto-memory to false.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HODb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HODb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 424w, https://substackcdn.com/image/fetch/$s_!HODb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 848w, https://substackcdn.com/image/fetch/$s_!HODb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 1272w, https://substackcdn.com/image/fetch/$s_!HODb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HODb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png" width="684" height="251" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba175013-89f9-434c-ab1e-02613800a8dc_684x251.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:251,&quot;width&quot;:684,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Auto-memory switched off in Claude Code's memory panel.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Auto-memory switched off in Claude Code's memory panel." title="Auto-memory switched off in Claude Code's memory panel." srcset="https://substackcdn.com/image/fetch/$s_!HODb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 424w, https://substackcdn.com/image/fetch/$s_!HODb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 848w, https://substackcdn.com/image/fetch/$s_!HODb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 1272w, https://substackcdn.com/image/fetch/$s_!HODb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba175013-89f9-434c-ab1e-02613800a8dc_684x251.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Turning memory off is correct when your continuity already comes from committed artifacts you control (<code>AGENTS.md</code>, ADRs, glossaries, LLM wikis).</p><h2>10. The Caveman plugin</h2><p>I also use the Caveman plugin to cut token usage. LLMs tend to be overly verbose. This plugin transforms the messages from full sentences into &#8220;caveman talk.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Xec!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Xec!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 424w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 848w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 1272w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Xec!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png" width="1456" height="1062" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1062,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Caveman plugin in action.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Caveman plugin in action." title="Caveman plugin in action." srcset="https://substackcdn.com/image/fetch/$s_!8Xec!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 424w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 848w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 1272w, https://substackcdn.com/image/fetch/$s_!8Xec!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F21063347-30a0-436a-92ba-afb5eeb716c5_1750x1276.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Caveman plugin in action. Screenshot from their <a href="https://github.com/juliusbrussee/caveman">GitHub repository</a>.</em></figcaption></figure></div><h2>11. The principles that keep every AGENTS.md small</h2><p>Again, to keep the LLM from being overly verbose and to make it support each instruction with examples, I keep these 3 rules in every <code>AGENTS.md</code> file:</p><blockquote><ul><li><p>Always prefer removing instructions over adding more.</p></li><li><p>Always use minimum words that still achieve goal &#8212; explanations, docs, code.</p></li><li><p>New rule in memory (such as AGENTS.md), resources, skills or other files &#8594; always support with clear, concise explanation + good and bad examples. Good examples: &#8220;a 200-token chunk size&#8221;, &#8220;sub-100ms latency&#8221;. Bad examples: &#8220;a powerful architecture&#8221;, &#8220;a robust pipeline&#8221;.</p></li></ul></blockquote><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>What technique are you using that is not on this list?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/11-context-engineering-tips-cut-coding-agent-tokens?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[The Bare-Bones Coding Agent Loop]]></title><description><![CDATA[One agent loop, 9 tools, and a terminal you can steer.]]></description><link>https://www.decodingai.com/p/the-coding-agent-loop</link><guid isPermaLink="false">https://www.decodingai.com/p/the-coding-agent-loop</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 28 Jul 2026 13:54:35 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!jhJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="callout-block" data-callout="true"><p>In LangChain&#8217;s Terminal-Bench experiment, changing only the harness (with the same model) moved a coding agent from ~30th place into the top 5: the harness, not the model, is what makes a coding agent good.</p><p>In the&nbsp;<strong>open-source course</strong>&nbsp;<strong><a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">Building a Coding Agent From Scratch</a></strong>, you&#8217;ll build that harness from scratch in Python:&nbsp;<strong>Decode</strong>, a complete coding agent that grows lesson by lesson from a bare agent loop into a swarm of remote agents running in parallel in the cloud.</p><p><strong>Why?</strong>&nbsp;You&#8217;ll be able to engineer custom harnesses for your own AI products (the skill behind that leaderboard jump), and you&#8217;ll understand what Claude Code and Codex actually do under the hood, turning you into a power user.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ge05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1446989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Lessons:</strong></p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a><strong> </strong></p></li><li><p><strong>The Bare-Bones Coding Agent Loop</strong> <strong>&#8592; </strong><em><strong>you are here</strong></em></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p>Context Engineering for Coding Agents</p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course&quot;,&quot;text&quot;:&quot;Full open-source course&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course"><span>Full open-source course</span></a></p></div><h1>Lesson 2: The Bare-Bones Coding Agent Loop</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jhJo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jhJo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jhJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The loop runs on its own. The whole trick is staying able to steer it.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The loop runs on its own. The whole trick is staying able to steer it." title="The loop runs on its own. The whole trick is staying able to steer it." srcset="https://substackcdn.com/image/fetch/$s_!jhJo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!jhJo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c58efe-e07c-42af-9fbe-e8a231384e46_1376x768.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When I first tried to implement the code for this course I got greedy. I tried to one-shot the harness in Python: a TUI, an agent, and a handful of tools like bash, read, write, and edit. It worked, until I started adding skills, memory, and compaction. That&#8217;s when everything started to fall apart. No &#8220;fix this &#8220; prompt could have saved it. That&#8217;s when I realized that building a harness for a coding agent is a lot more strategic than just: <em>&#8220;Hey, look at OpenCode&#8217;s open-source code and build a replica for me.&#8221;</em></p><p>So, I took a step back, deleted everything and started researching how Claude Code, OpenCode, Aider and Pi work. Only after I pinned down the whole architecture, with its components, interfaces and data flow I started to build Decode. The coding agent I will teach you how to build in this series.</p><p>In this article, lesson 2 from the <strong>open-source course Building a Coding Agent From Scratch</strong>, we will learn <strong>how to build a bare-bones coding agent from scratch</strong>. At feature parity with the popular <a href="https://github.com/earendil-works/pi">Pi</a> agent harness.</p><p>We will build the coding agent loop. See how the loop decomposes a goal into a plan and executes it. Understand which tools are critical for a coding agent, and which ones are nice to have. Build a TUI. See why naively sending messages from the terminal to the agent can corrupt the loop. For the full architecture of <code>Decode</code>, what we will build throughout this series, we recommend reading <a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Lesson 1</a>.</p><p>On top of that, we will plug in 3 LLM providers (Modal, OpenRouter, and Gemini) and understand when serverless computing such as <a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a> beats token-based APIs. Also, to easily debug the agent, we will integrate trace monitoring via <a href="https://www.comet.com/site/?utm_source=workshop&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a>.</p><p><em>Example of running Decode (our coding agent) powered by Qwen 3.6 35B:</em></p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;0042fe85-84be-40a0-ae28-397aa76ee582&quot;,&quot;duration&quot;:null}"></div><p>Let&#8217;s start with an end-to-end walkthrough of the coding agent harness.</p><h2>One Turn, End to End</h2><p>Our expectations from Decode&#8217;s coding agent loop are similar to any other coding agent you&#8217;re already used to: Claude Code, Codex, Pi, OpenCode, etc. You open it in a repository or any other folder, give it a goal, and let it loop until it completes the goal.</p><p>In our <code>.decode/skills/demo-6-article-kg</code> demo, managed as a skill, we ask Decode to pull data from multiple sources, extract key entities and concepts and render a KG in HTML.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WjR5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WjR5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WjR5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png" width="1456" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;TUI&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="TUI" title="TUI" srcset="https://substackcdn.com/image/fetch/$s_!WjR5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!WjR5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c7cbb63-1eb0-41f3-8479-ea984adb9f4a_1816x855.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The agent kept looping until we got the graph below. Pretty cool, right?</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N80t!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N80t!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 424w, https://substackcdn.com/image/fetch/$s_!N80t!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 848w, https://substackcdn.com/image/fetch/$s_!N80t!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 1272w, https://substackcdn.com/image/fetch/$s_!N80t!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N80t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png" width="1456" height="847" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:847,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The knowledge graph Decode built from three live articles, rendered as one HTML page.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The knowledge graph Decode built from three live articles, rendered as one HTML page." title="The knowledge graph Decode built from three live articles, rendered as one HTML page." srcset="https://substackcdn.com/image/fetch/$s_!N80t!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 424w, https://substackcdn.com/image/fetch/$s_!N80t!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 848w, https://substackcdn.com/image/fetch/$s_!N80t!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 1272w, https://substackcdn.com/image/fetch/$s_!N80t!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F164c2b96-6e40-42f2-bd83-9f546e9195fc_3324x1934.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is a great example where the agent had to break a goal into multiple steps and execute each one independently until the goal is reached.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OA6z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OA6z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 424w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 848w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 1272w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OA6z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png" width="1200" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The interactive mode: one turn's machinery, end to end.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The interactive mode: one turn's machinery, end to end." title="The interactive mode: one turn's machinery, end to end." srcset="https://substackcdn.com/image/fetch/$s_!OA6z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 424w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 848w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 1272w, https://substackcdn.com/image/fetch/$s_!OA6z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1428edd7-7b87-45c8-9d55-149a682ab5c2_1200x686.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The interactive mode</em></figcaption></figure></div><p>More concretely, this is the agent&#8217;s whole lifecycle: <strong>plan &#8594; explore &#8594; apply &#8594; execute &#8594; observe &#8594; next task</strong>, repeated until the goal is met.</p><p>Everything starts with you typing your goal into the TUI and pressing Enter. The request goes into the steering queue and then into a fresh turn, and the loop sends the prompt and tools to the model, a Qwen3.6 served on Modal. It kicks off planning. Via <code>todo_write</code> it records 4 tasks (fetch &#8594; extract &#8594; render &#8594; verify). Via <code>web_fetch</code> Decode fans out in one step and scrapes all the sources. The model reads the scraped output and extracts the KG triplets into a <code>graph.json</code> file via its <code>write</code> tool &#8212; the first call that can change your disk, so the run stops and asks. You type <code>y</code>. Ultimately it generates the HTML code that loads the data from the JSON files and beautifully renders it by calling the <code>write</code> tool to create the <code>kg.html</code> file. Finally, it calls <code>todo_write</code> to update the TODO list and mark the goal as done.</p><p>Based on our <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">open-source GitHub</a>, here are all the components of the agent loop that transform a simple Pydantic AI agent into the foundations of any coding agent you are using out there:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">src/decode/
&#9500;&#9472;&#9472; agent/          # loop.py (the agent loop), factory.py
&#9500;&#9472;&#9472; harness/        # runner.py (single-flight turns), queue.py (steering/follow-up)
&#9500;&#9472;&#9472; tools/          # registry.py, files.py (read/write/edit/glob/grep), bash.py, askuser.py
&#9500;&#9472;&#9472; context/        # session_log.py (append-only JSONL)
&#9500;&#9472;&#9472; observability/  # tracing.py (Opik via OTLP)
&#9492;&#9472;&#9472; tui/            # app.py (prompt_toolkit input), render.py (Rich output)</code></pre></div><p>In this course, we will mostly follow Claude Code/OpenCode&#8217;s design, where we have a larger set of tools, memory and agent features built into the harness. Mostly for educational reasons, to explore all the options out there. But there is also a beautiful, minimalist approach to this, based on the philosophy of Mario Zechner, creator of the Pi harness: strip the agent loop back to its bare bones, keeping only the essential logic, to avoid adding noise into the context window and keep everything observable and in control. If you want more features, you add them explicitly as plugins, instead of getting new &#8220;space ship&#8221; cool-but-useless features with every version. Thus, to understand both perspectives, we will keep drawing parallels to Pi&#8217;s architecture.</p><h2>The Agent Loop</h2><p>In Lesson 1, we said that the agent loop is <em>the good old ReAct pattern</em>. The model reasons, picks a tool, the harness executes it, and the observation feeds the next step &#8212; an agent is just <a href="https://www.anthropic.com/research/building-effective-agents">an LLM using tools on environmental feedback in a loop</a>.</p><p>ReAct in the abstract is reason &#8594; act &#8594; observe. Give it a set of tools it can operate on a codebase and voil&#224;, it becomes a coding agent.</p><p><strong>Plan</strong>: <code>todo_write</code> the task list before touching anything.<br><strong>Explore</strong>: <code>read</code>, <code>glob</code>, <code>grep</code> the codebase.<br><strong>Apply</strong>: <code>write</code> and <code>edit</code>, stopping for your verdict.<br><strong>Execute</strong>: <code>bash</code> the tests, the linter.<br><strong>Observe</strong>: a failure is the next observation, and the repair is another Apply &#8594; Execute pass on the same task. Tick it off, re-enter.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KVlk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KVlk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KVlk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92b11633-a282-4fec-9129-e573664754a4_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The coding agent loop: one goal, one repeating cycle, until the goal is achieved.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The coding agent loop: one goal, one repeating cycle, until the goal is achieved." title="The coding agent loop: one goal, one repeating cycle, until the goal is achieved." srcset="https://substackcdn.com/image/fetch/$s_!KVlk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!KVlk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92b11633-a282-4fec-9129-e573664754a4_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In Claude Code&#8217;s leaked source the core loop is ~150 lines. To emphasize the harness around the agent, we will use Pydantic AI for the &#8220;core agent&#8221; and focus on everything around it (from <code>build_agent</code> in <code>src/decode/agent/factory.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def build_agent(*, model: str | None = None) -&gt; Agent[AgentDeps, str | DeferredToolRequests]:
    built_model = _build_model(model=model)
    agent = Agent(
        built_model,
        deps_type=AgentDeps,                       # cwd, task store, event emitter &#8212; the harness state
        output_type=[str, DeferredToolRequests],   # a step ends in text &#8212; or pauses on approvals
        output_retries=3,                          # empty / thinking-only turns get another attempt
        tool_retries=5,                            # only resets on success &#8212; the plan-survival budget
    )
    register_tools(agent)                          # the coding tool set
    _register_instructions(agent)                  # ONE merged system prompt

    return agent</code></pre></div><p>The <code>Agent</code> owns one step: one model request, the tool executions it triggers as &#8220;actions&#8221;, and the results it gets back as &#8220;observations&#8221;, ending in either text or <code>DeferredToolRequests</code>. <strong>The agent loop</strong> is operated by the <code>AgentTurnHandler</code> (<code>src/decode/agent/loop.py</code>) class chaining steps together through <code>agent.iter</code>.</p><p><code>AgentTurnHandler.__call__</code> is an async generator that streams tokens in real time via Python generators. It runs a <code>while True</code> loop with two boundaries: <code>yield Boundary.MODEL_REQUEST</code> and <code>yield Boundary.WOULD_STOP</code>. Via <code>Boundary.MODEL_REQUEST</code>, we can inject (steer) new messages into the loop before it finishes reaching its goals.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">class AgentTurnHandler:

    ...                 # ONE instance per session; owns the turn + history

    async def __call__(self, ctx: TurnContext) -&gt; AsyncGenerator[Boundary, list[str]]:
        while True:
            steering = yield Boundary.MODEL_REQUEST
            if pending_results is not None:
                self._append_steering(steering)
                output = await self._run_turn(ctx, deferred_results=pending_results)
                pending_results = None
            else:
                output = await self._run_turn(
                    ctx, prompt=self._compose_prompt(next_prompt, steering)
                )
            if isinstance(output, DeferredToolRequests):
                pending_results = await self._resolve_deferred(ctx, output)
                continue
            self._persist_turn()
            follow_ups = yield Boundary.WOULD_STOP
            if not follow_ups: return
            next_prompt = "\n".join(follow_ups)</code></pre></div><p>The whole action happens inside the <code>self._run_turn</code> method, which makes the actual model call, and based on the results from the model, via the <code>run</code> object, it either emits answers from the model or executes a tool request.</p><p>In more detail, this is what happens:</p><ol><li><p>A fresh step passes <code>prompt</code>, a resumed step passes <code>deferred_tool_results</code>, never both.</p></li><li><p>The <code>async for</code> streams each node to the TUI as an event, so you watch tokens arrive live.</p></li><li><p>The <code>finally</code> carries <code>run.all_messages()</code> forward, so a step that dies keeps everything it accomplished in memory.</p></li></ol><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">class AgentTurnHandler:

    ...                         # ...same class as above

    async def _run_turn(self, ctx, *, prompt=None, deferred_results=None) -&gt; str | DeferredToolRequests:
        async with self._agent.iter(
            prompt,
            deps=self._deps,
            message_history=self.message_history,
            deferred_tool_results=deferred_results,
        ) as run:
            try:
                async for node in run:
                    if Agent.is_model_request_node(node):
                        await self._stream_model_node(ctx, node, run)
                    elif Agent.is_call_tools_node(node):
                        await self._stream_tool_node(ctx, node, run)
            finally:
                self.message_history = run.all_messages()
                self._last_input_tokens = _leg_input_tokens(self.message_history)
        return run.result.output</code></pre></div><blockquote><p>&#128161; The loop has no max-steps knob, based on Pi&#8217;s principles: <em>&#8220;the loop just loops until the agent says it&#8217;s done.&#8221;</em> A cap is a guess about how many steps a task needs, and the model already signals completion by returning text instead of a tool call. The signal you should be careful about is the context window.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qpse!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qpse!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 424w, https://substackcdn.com/image/fetch/$s_!qpse!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 848w, https://substackcdn.com/image/fetch/$s_!qpse!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 1272w, https://substackcdn.com/image/fetch/$s_!qpse!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qpse!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png" width="1200" height="725" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:725,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;One turn's lifecycle: steps, pauses, and the two boundaries.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="One turn's lifecycle: steps, pauses, and the two boundaries." title="One turn's lifecycle: steps, pauses, and the two boundaries." srcset="https://substackcdn.com/image/fetch/$s_!qpse!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 424w, https://substackcdn.com/image/fetch/$s_!qpse!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 848w, https://substackcdn.com/image/fetch/$s_!qpse!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 1272w, https://substackcdn.com/image/fetch/$s_!qpse!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca03aacb-f307-4302-b341-d40d28b90b6c_1200x725.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>A turn as a chain of steps</em></figcaption></figure></div><p>The first thing every step does is call a model, and picking that model should always be a one-line config choice.</p><h2>The LLM Providers</h2><p>It&#8217;s an architectural mistake to couple your design to a single provider. The loop shouldn&#8217;t know whether it talks to Gemini, <a href="https://openrouter.ai/">OpenRouter</a>, <a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a>, or whatever comes next.</p><p>All provider knowledge lives in <code>_build_model()</code> in <code>src/decode/agent/factory.py</code>. You pick the provider by setting the <code>LLM_PROVIDER</code> environment variable, which is picked by your Pydantic settings object from <code>src/decode/config/settings.py</code>.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def _build_model(*, model: str | None = None) -&gt; Model:
    provider = settings.llm_provider                     # explicit LLM_PROVIDER env var
    if provider == "gemini":
        return GoogleModel(
            model or settings.gemini_model,
            provider=GoogleProvider(api_key=_provider_api_key("gemini"))
        )
    if provider == "openrouter":
        return OpenAIChatModel(
            model or settings.openrouter_model,
            provider=OpenRouterProvider(api_key=_provider_api_key("openrouter"))
        )
    if provider == "modal":
        client = AsyncOpenAI(
            base_url=f"{settings.modal_endpoint_url}/v1",
            api_key=token_secret,
            default_headers={"Modal-Key": token_id, "Modal-Secret": token_secret}
        )
        return OpenAIChatModel(
            model or settings.modal_endpoint_model,
            provider=OpenAIProvider(openai_client=client)
        )
        
    raise ValueError(f"unsupported llm_provider: {provider!r}")</code></pre></div><p>So from all the options out there (we know there are tons), why these 3? And no OpenAI or Anthropic. Because between them they cover the three tiers of the build vs. buy decision: Gemini is proprietary (you buy the model), OpenRouter is open weights bought as a service (you buy the serving), and Modal is open weights you serve yourself.</p><p>We choose <strong><a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a></strong> as our default option for 3 reasons. <strong>You pay for GPU compute, not tokens</strong>: agentic bursts fit <a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng">GPU-time pricing</a>. Serverless open-source models supported by Modal that we deployed are Qwen3.6 35B, Kimi K3, and GLM-5.2 via <a href="https://modal.com/blog/introducing-auto-endpoints?source=decodingai&amp;campaign=harnesseng">Modal Endpoints</a>. If you want to use a fine-tuned model, you can easily swap it in with 0 changes on the harness side. Because it&#8217;s serverless, it <strong>scales to zero</strong>: you pay only when the agent is working.</p><p>This combination makes it ideal for intermittent periods of extremely high compute demand. For example, if you want to process 1000 documents, instead of paying for each token, which is what&#8217;s typical of all the APIs out there, you just pay for the compute time. To make testing Decode extremely affordable, for most of our tests we used <code>Qwen3.6 35B</code>, which runs on a single <code>H200</code> GPU at <code>$4.54 / h</code>.</p><p>But going back to our 1000 documents example, if these 1000 documents translate to 1000 * 30000 tokens, that's 30M input tokens, plus ~500 output tokens per document. If we wanted to process all these tokens with Sonnet, that would translate to: <code>30M / 1M x 3 (input) + 500k / 1M x 15 (output) ~= $97</code>. And prompt caching doesn't save us here &#8212; every document is a different prefix, so there's nothing to reuse across calls. Considering we could process this data with Modal at ~3000 tokens/second batched, that's under 3 hours of GPU time, which would have cost only ~$13. Modal <a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng">benchmarked the same tradeoff</a> and found that giving up interactivity, from ~200ms to ~4s end-to-end, provided an x8 throughput increase on identical hardware. If we do this multiple times per day, it quickly adds up. This is just napkin math, but you get the idea.</p><p>Now, on the other side of the spectrum, let's assume Decode sits idle while it waits on a &#8220;y&#8221; confirmation the agent asked for. If that happens overnight, you can easily add 10 hours of idle time to your GPU billing, an extra ~$45.</p><p>Alongside the pay-per-token model, which quickly becomes inefficient at high <span>volumes,&nbsp;</span><strong><span>another dimension to</span> consider is serverless vs. reserved GPU time</strong>. When you reserve GPUs, you have to reserve your peak. If your peak needs 40 GPUs on Friday afternoon and 2 on Sunday night, you sign for 40 &#8212; and you keep paying for 40 all weekend, all month, all year. With serverless, the meter follows the demand curve, so the total cost is just the rate <code>R_s</code> times whatever you actually used at each moment. The reservation instead charges you rate <code>R_r</code> times the peak, times the entire length of the contract <code>T</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2Fua!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2Fua!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 424w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 848w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 1272w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2Fua!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png" width="1456" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Serverless vs. reserved GPU cost&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Serverless vs. reserved GPU cost" title="Serverless vs. reserved GPU cost" srcset="https://substackcdn.com/image/fetch/$s_!2Fua!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 424w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 848w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 1272w, https://substackcdn.com/image/fetch/$s_!2Fua!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9c92b0f8-5161-491d-adf4-59d5a5538f04_1498x578.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Formula to check the costs of serverless vs. reserved infrastructure (<a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng">source</a>)</figcaption></figure></div><p>In other words, if reserving is <code>5x</code> cheaper than serverless, but your peak is <code>5x</code> higher than your average, then you break even. And the further your peak climbs above that price advantage, the better off you are paying for serverless. For the full math, <a href="https://modal.com/blog/how-to-price-serverless?source=decodingai&amp;campaign=harnesseng">see this blog post</a>.</p><p><strong>OpenRouter</strong> is the most popular gateway to every hosted model: closed source (Claude, OpenAI, Gemini) or open-source (Kimi K3, Z GLM-5.2, Gemma 4, etc.) behind one key. Thanks to their huge aggregated pool of models, they also have some free defaults, such as <code>qwen/qwen3-coder:free</code>, which we used in this course. Having them integrated into your app is a powerful way to easily experiment with different models without worrying about the underlying infrastructure.</p><p>We picked <strong>Gemini</strong> mostly due to their generous free tier, to provide you a third option to run Decode without any cost. Their models are rarely the best, but relative to other API-based models, especially OpenAI &amp; Anthropic, they&#8217;re cheap and good enough to get most jobs done.</p><p>We recommend starting with <a href="https://modal.com/blog/introducing-auto-endpoints?source=decodingai&amp;campaign=harnesseng">Modal Endpoints</a>, powered by <code>Qwen3.6 35B</code> by default, that spins up in a couple of minutes a configurable <code>SGLangEndpoint</code>. <code>SGLang</code> is the right default here because it and <code>vLLM</code> land in <a href="https://modal.com/llm-almanac/summary?source=decodingai&amp;campaign=harnesseng">roughly the same place on throughput</a>, but <code>SGLang</code> boots in ~1 minute against vLLM&#8217;s ~5 for small models, which is everything when your endpoint scales to zero. Modal&#8217;s $30 in free credits each month covers ~6.5 hours of <code>H200</code> time, enough to run the whole course at no cost. And while <code>Qwen3.6 35B</code> is small next to GLM-5.2 740B or even GPT OSS 120B, it&#8217;s well tested with Decode and works well enough for our examples.</p><p>After you&#8217;ve completed the basic setup on Modal, you can start a new endpoint just by running:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">modal endpoint create --model Qwen/Qwen3.6-35B-A3B-FP8 --env main</code></pre></div><p>While trying it out, to avoid the cold start problem, we recommend setting the autoscaling limits to a minimum of 1 container:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;c4cab325-9438-4644-8a2f-8422259d4991&quot;,&quot;duration&quot;:null}"></div><blockquote><p>&#129489;&#8205;&#128187; Find the full setup docs in our <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">GitHub repo</a>.</p></blockquote><p>But between Modal and OpenRouter, you can easily swap between hundreds of models. You can try out whatever you&#8217;re interested in. The only requirement is that it supports tool calling.</p><h2>The System Prompt</h2><p>The entire base system prompt is one paragraph:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">You are Decode, a terminal coding agent that helps a developer in their working
directory. You are concise and precise: answer directly, prefer running the work
over describing it, and never invent file contents or command output you have not
seen. When you do not have a tool for something yet, say so plainly rather than
pretending.</code></pre></div><p>The team behind Pi started this minimalist mentality, where you keep your system prompts, tools, and features to a minimum, to avoid filling your context window with noise that confuses the model more than it helps. This also makes maintaining and understanding the prompts, for us as humans, a lot easier. In the past months, OpenAI and Anthropic followed, trimming their system prompts by up to 70%, as more and more functionality around coding gets baked directly into the model&#8217;s weights.</p><p>Still, this paragraph is only the baseline. Pydantic AI builds a schema from every tool&#8217;s signature, which is added to the system prompt. Thus, each tool comes with a cost, meaning that the more tools you use, the more context window you consume, and the model becomes more confused about which one to pick. This becomes even more problematic when we start adding memory and skills into the mix, as we will see in future lessons.</p><p>Whichever model answers, it can only touch your repo through the tools.</p><h2>The Core Tools</h2><p>In reality, the tools are 90% of why this is a coding agent and not any other kind of AI agent. The agent needs to <a href="https://mitchellh.com/writing/my-ai-adoption-journey">read files, execute programs, make HTTP requests</a>. <a href="https://github.com/earendil-works/pi">Pi</a> ships exactly <code>read</code>, <code>write</code>, <code>edit</code>, and <code>bash</code> &#8212; under 1,000 tokens of prompt plus definitions, <a href="https://mariozechner.at/posts/2025-11-30-pi-coding-agent/">still respectable &#8212; top 10 on Terminal-Bench 2.0</a>.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">read   path, offset?, limit?   &#8594; file contents; first 2,000 lines by default
write  path, content           &#8594; create or overwrite; makes parent dirs
edit   path, oldText, newText  &#8594; exact-match surgical replace (whitespace included)
bash   command, timeout?       &#8594; run it in the cwd; returns stdout + stderr</code></pre></div><p>On top of these 4 core tools, we have more specialized I/O tools such as <code>glob</code> and <code>grep</code>. Then there&#8217;s <code>todo_write</code>, used to decompose the goal into a plan of TODOs, <code>web_fetch</code> to fetch web pages, and <code>ask_user</code> to interact with the user.</p><blockquote><p>&#128161; Pi doesn&#8217;t have a <code>todo_write</code> tool because it considers that the best way to store your plan is directly in a Markdown file, not in an in-memory TODO list the agent has to keep track of &#8212; <a href="https://mariozechner.at/posts/2025-11-30-pi-coding-agent/">a PLAN.md on disk beats an in-memory list</a>.</p></blockquote><p>Every snippet below opens with <code>ctx: RunContext[AgentDeps]</code>. <code>RunContext</code> is Pydantic AI&#8217;s per-run context object: the framework injects it as every tool&#8217;s first parameter and hides it from the model&#8217;s tool schema. The model calls <code>edit(path, old_string, new_string)</code> and never knows <code>ctx</code> exists.</p><p><code>AgentDeps</code> is in our harness. We declare it once as <code>deps_type=AgentDeps</code> in <code>build_agent</code>, pass it into <code>agent.iter(deps=...)</code>, and Pydantic AI hands it to every tool call. <code>RunContext[AgentDeps]</code> reads as &#8220;this run&#8217;s context, whose <code>.deps</code> is an <code>AgentDeps</code>.&#8221; It is the harness state, arriving by injection (from <code>src/decode/agent/deps.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">@dataclass(slots=True)
class AgentDeps:                                   # every tool's ctx.deps &#8212; the harness, injected
    cwd: Path                                      # the jail: file tools + bash resolve paths here
    emit: EventSink                                # push an event &#8594; the TUI renders it
    gate: PermissionGate                           # the allow / ask / deny policy (Section 6)
    resolve_permission: PermissionResolver         # a gate "ask" &#8594; the human's verdict, awaited
    resolve_user_question: UserQuestionResolver    # ask_user's answer, on the SAME channel
    task_store: list[Task] = field(default_factory=list)      # what todo_write rewrites in place</code></pre></div><p><code>emit</code>, <code>resolve_permission</code>, and <code>resolve_user_question</code> are used for dependency injection, so tools reach the terminal without importing the TUI, and they make this code easily testable by swapping in a different <code>AgentDeps</code>.</p><p>To keep things short and sweet, I will skip how <code>read</code> and <code>write</code> work and go straight to <code>edit</code> (see them at <code>src/decode/tools/files.py</code>). <code>edit</code> is a find-and-replace with one rule: load the file&#8217;s text, find <code>old_string</code> inside it, dump <code>new_string</code> into that exact spot, write the file back. But the devil is in the details. To make this replace work, it first needs to normalize away the invisible formatting the model was never shown &#8212; a file&#8217;s line-ending convention, a leading byte-order mark &#8212; so a match never fails on characters the model had no way to guess. Then it looks for <code>old_string</code>, and only when that misses does it retry with whitespace collapsed on both sides. Either way, the match must be <strong>unique</strong>: 0 hits returns <code>not found</code>, 2+ returns <code>ambiguous, N matches</code>, and both end up with <code>ModelRetry</code>:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def edit(ctx: RunContext[AgentDeps], path: str, old_string: str, new_string: str) -&gt; str:
    if needs_approval(ctx):
        raise ApprovalRequired
    target = _resolve_in_cwd(ctx.deps.cwd, path)
    raw = target.read_bytes().decode("utf-8")
    final = _apply_edit(raw, old_string, new_string)
    _atomic_write_bytes(target, final.encode())

    return f"Edited {path!r} (replaced 1 occurrence)."</code></pre></div><p>Within <code>todo_write</code>, the model sends the <strong>full</strong> desired list on every call and the tool overwrites the whole list &#8212; which is exactly what stops the plan from drifting out of the context window. The overwrite is in place (<code>[:] = tasks</code>, not a rebind) so the loop and the TUI keep pointing at the same list object, and every item is validated by the <code>Task</code> Pydantic model on the way in. It then emits one <code>TaskListUpdated</code> event carrying pre-rendered checklist lines: the tool maps <code>pending / in_progress / completed</code> to <code>[ ] / [~] / [x]</code> itself, so the renderer never has to learn the status vocabulary. The store is in-memory and per-run &#8212; nothing about the task list outlives the process (from <code>src/decode/tools/tasks.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def todo_write(ctx: RunContext[AgentDeps], tasks: list[Task]) -&gt; str:
    if needs_approval(ctx):
        raise ApprovalRequired
    ctx.deps.task_store[:] = tasks
    ctx.deps.emit(events.TaskListUpdated(tasks=_checklist_lines(tasks)))

    return f"Updated task list ({len(tasks)} task(s))."</code></pre></div><p>That <code>emit</code> line is the harness&#8217;s entire UI protocol. <code>events</code> is the <code>decode.entities.events</code> module of frozen dataclasses (<code>TurnStarted</code>, <code>ToolCallStarted</code>, <code>ToolResult</code>, <code>TaskListUpdated</code>, ...) joined into one union known by the renderer.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">Event = (
    TurnStarted
    | TurnFinished
    | AssistantTextDelta
    | ThinkingDelta
    | ToolCallStarted
    | ToolResult
    | PermissionRequested
    | AskUserRequested
    | TaskListUpdated
    | ContextCompacted
    | ContextMicrocompacted
    | AgentError
)</code></pre></div><p><code>ctx.deps.emit</code> is a synchronous event-based sink, injected into the harness to communicate with outer layers, in this case the TUI. This is clean architecture 101. The tool describes what happened as a typed value, and the TUI decides how to draw it.</p><p><code>web_fetch</code> makes an async httpx GET request. What comes back is filtered twice before the model sees it &#8212; non-text content types are refused outright, and the decoded body is hard-capped at 2 MB, so an enormous page can never eat your entire context window. HTML is then mapped to Markdown keeping mostly the body and other metadata such as the title. Every failure path &#8212; non-2xx, timeout, connection error, wrong content type, HTML nested too deep to parse &#8212; throws a <code>ModelRetry</code> error, so a bad fetch is an observation the model has to handle explicitly and not ignore (from <code>src/decode/tools/web.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def web_fetch(ctx: RunContext[AgentDeps], url: str) -&gt; str:
    if needs_approval(ctx):
        raise ApprovalRequired
    _validate_url(url)
    response = await _get(url)
    body = _render_body(response, _decode_body(response))

    return f"HTTP {response.status_code} {response.url}\n\n{body}"</code></pre></div><p><code>ask_user</code> lets the agent request input from the user. It emits <code>AskUserRequested</code> so the TUI renders the question, then awaits <code>ctx.deps.resolve_user_question</code>. Two things can go wrong: the agent loop can run in headless mode, where there is no interactive user at all, or the question can be dismissed (turn aborted, REPL shutting down). Both become <code>ModelRetry</code> text telling the model plainly to proceed without an answer (from <code>src/decode/tools/askuser.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def ask_user(ctx: RunContext[AgentDeps], question: str) -&gt; str:
    ctx.deps.emit(events.AskUserRequested(question=question))
    try:
        return await ctx.deps.resolve_user_question(question)
    except NoInteractiveUserError as exc:
        raise ModelRetry(str(exc)) from exc</code></pre></div><p><code>bash</code> is the most powerful. Via <code>bash</code> the agent can execute any shell command such as <code>ls</code>, <code>cd</code>, <code>mkdir</code>, <code>rm</code>, <code>cp</code>, <code>mv</code>, and <code>echo</code>. Plus, piping and everything else you can run in a terminal. Which means that via <code>bash</code> the agent can run Python, TypeScript, Rust, or any other language. Via <code>bash</code> it can manipulate all the CLIs you give it access to.</p><blockquote><p><em>Via </em><code>bash</code><em> it gets that magical feeling of being able to interact with the operating system and run any command.</em></p></blockquote><p>But this also makes it the most dangerous one. <code>rm -rf ~/</code> is always <a href="https://modal.com/llm-almanac/summary?source=decodingai&amp;campaign=harnesseng">only a few tokens away</a>. That&#8217;s why running your agent in a sandbox environment becomes so important. In a future lesson, we will get into the executor and how to run commands in local Docker and remote <a href="https://modal.com/docs/guide/sandboxes?source=decodingai&amp;campaign=harnesseng">Modal containers</a>.</p><p>Bash plus code execution is a big step toward <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">giving the model a computer</a> (from <code>src/decode/tools/bash.py</code>):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">async def bash(ctx: RunContext[AgentDeps], command: str, timeout: float | None = None) -&gt; str:
    if needs_approval(ctx):
        raise ApprovalRequired
    timeout_s = _resolve_timeout(timeout)
    result = await _get_executor().run(command, cwd=ctx.deps.cwd, timeout_s=timeout_s)

    return _render(result, timeout_s=timeout_s)</code></pre></div><p>As we&#8217;ve seen at the beginning, the lifecycle of the agent is based on running these tools in order: <code>todo_write</code> plans, <code>read</code> / <code>glob</code> / <code>grep</code> explore, <code>write</code> / <code>edit</code> apply, <code>bash</code> executes (<code>bash</code>&#8216;s exit code is the observation that starts the next pass).</p><p>When running <code>.decode/skills/demo-6-article-kg</code> that asks the agent to scrape 3 web pages and build a knowledge graph, the agent creates a 4-step plan, keeps track of it via <code>todo_write</code>, fetches the data via <code>web_fetch</code>, extracts the KG triplets directly, then via <code>write</code> saves them to <code>graph.json</code>. Next, it writes the HTML and CSS code that displays the KG triplets into <code>kg.html</code>. Ultimately, via <code>bash</code> it checks that the HTML code renders correctly. If not, the model <code>edit</code>s the code and retries.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!h25c!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!h25c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 424w, https://substackcdn.com/image/fetch/$s_!h25c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 848w, https://substackcdn.com/image/fetch/$s_!h25c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 1272w, https://substackcdn.com/image/fetch/$s_!h25c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!h25c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png" width="1456" height="877" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:877,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Opik Plan&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Opik Plan" title="Opik Plan" srcset="https://substackcdn.com/image/fetch/$s_!h25c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 424w, https://substackcdn.com/image/fetch/$s_!h25c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 848w, https://substackcdn.com/image/fetch/$s_!h25c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 1272w, https://substackcdn.com/image/fetch/$s_!h25c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F794bbda3-92ab-43cf-9988-b5680507589f_2874x1732.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Adding Tracing to Understand What Is Going On</h2><p>We&#8217;ve seen above how the agent calls the <code>todo_write</code> tool to bake the plan into its state. The trace is logged via <a href="https://www.comet.com/site/?utm_source=workshop&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a>. Let&#8217;s see how easy it is to plug it into your own code.</p><p>Debugging your agent via the terminal is terrible. Not only is reading the full traces hard, sometimes it&#8217;s impossible, as you just don&#8217;t have access to all the spans, plus other essential metadata such as configs, token counts, tool inputs and outputs &#8212; and the list goes on. That&#8217;s why you need to plug in an observability tool like Opik from day 0 to get visibility into your agent&#8217;s behavior.</p><p>As we use Pydantic AI, it has native support for tracing via Logfire, the observability tool made by Pydantic. Logfire, like most observability tools, supports OpenTelemetry (OTLP) out of the box, which is the standard wire protocol for tracing. Thus, hooking up Opik is as easy as defining the <code>OTLPSpanExporter</code> to point to Opik&#8217;s managed servers via the <code>endpoint</code> parameter, plus authentication headers. As Opik is open-source, this would work exactly the same if you were hosting it yourself (from <code>src/decode/observability/tracing.py</code>).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def init_tracing() -&gt; bool:
    key = settings.opik_api_key.get_secret_value()
    if not key:
        return False

    exporter = OTLPSpanExporter(
        endpoint=f"{base}/v1/traces",
        headers={"Authorization": key, "Comet-Workspace": settings.opik_workspace,
                 "projectName": settings.opik_project_name})
    logfire.configure(send_to_logfire=False, console=False,
        additional_span_processors=[BatchSpanProcessor(CostAnnotatingExporter(exporter))])
    logfire.instrument_pydantic_ai()

    return True</code></pre></div><p>You can find the full setup on how to get started with Opik in our <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course/blob/main/running_the_code/install_and_usage.md">GitHub repository</a>. Opik is optional to get through the course, but note that it has a generous freemium plan with 25k spans/month free. You can run the whole course for free.</p><p>In the GIF below, you can see an end-to-end trace of how the agent executed the <code>.decode/skills/demo-6-article-kg</code> skill that builds the KG from 3 articles. It consists of 47 spans, covering 6 steps, 15 model calls, and 18 tool executions over ~6m.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;e926026d-53d7-4f4f-b61e-fd291b72afe2&quot;,&quot;duration&quot;:null}"></div><p>With the following token usage (no cost per token as we ran it via Modal):</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">cache_read.input_tokens: 631424
completion_tokens: 19781
details.cache_read_tokens: 631424
details.reasoning_tokens: 2912
prompt_tokens: 655624
total_tokens: 675405</code></pre></div><h2>The TUI and the Queues</h2><p>You can build a TUI in <a href="https://mariozechner.at/posts/2025-11-30-pi-coding-agent/">2 ways</a>. <strong>Full-screen</strong> takes over the terminal&#8217;s viewport as a grid of cells (Amp, OpenCode): total layout control, but you lose scrollback, search and have to implement a bunch of features from scratch. <strong>Append-to-scrollback</strong> writes like an ordinary CLI (Claude Code, Codex, Pi). Decode takes the second approach.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3VGC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3VGC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3VGC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;TUI&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="TUI" title="TUI" srcset="https://substackcdn.com/image/fetch/$s_!3VGC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!3VGC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9441cf15-4eb2-4376-9ee6-3f6c6031b696_1815x986.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>As Python packages, we use <code>prompt_toolkit</code> to read the input and <code>Rich</code> to render output in append-style. Below you can see the loop that takes events from the harness and renders them on the TUI (from <code>src/decode/tui/app.py</code>).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">with patch_stdout(raw=True):
    while True:
        submitted = await session.prompt_async(_PROMPT)   # one pinned input line
        intent, text = _interpret(submitted)              # Enter / Alt+Enter / Esc
        if decisions.pending:                             # mid-turn question? answer it
            decisions.resolve(text)
            continue
        await runner.submit(text, intent)</code></pre></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sVk_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sVk_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 424w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 848w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 1272w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sVk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png" width="1456" height="829" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:829,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Decode TUI on startup &#8212; the Modal-served model in the banner, Opik tracing on, and the footer naming all three input modes.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Decode TUI on startup &#8212; the Modal-served model in the banner, Opik tracing on, and the footer naming all three input modes." title="The Decode TUI on startup &#8212; the Modal-served model in the banner, Opik tracing on, and the footer naming all three input modes." srcset="https://substackcdn.com/image/fetch/$s_!sVk_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 424w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 848w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 1272w, https://substackcdn.com/image/fetch/$s_!sVk_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67513ce7-f3d1-4d72-9116-d8965e52021e_1815x1033.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>But what happens when you type a new command mid-turn, while the agent is still running your previous one? Injecting it instantly would corrupt the current tool call. Thus, you need to buffer your input on arrival and inject it only at boundaries, such as after a tool finishes running or a whole turn ends.</p><p>The input can arrive in 3 modes.</p><ul><li><p><strong>Steering</strong> (plain <code>Enter</code>): the Runner executes it within a model turn, between tool calls.</p></li><li><p><strong>Follow-up</strong> (<code>Alt+Enter</code>): the Runner holds it until the turn stops, then runs it as one more step.</p></li><li><p><strong>Cooperative abort</strong> (<code>Esc</code>): sets a flag to stop the agent turn at the next boundary. Next, it clears both queues. This avoids corrupting the history.</p></li></ul><p>As seen within the <code>InteractionQueues</code> class, for steering and follow-ups we use two different in-memory queues (from <code>src/decode/harness/queue.py</code>).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">@dataclass(slots=True)
class InteractionQueues:
    steering: asyncio.Queue[str] = field(default_factory=asyncio.Queue)
    follow_up: asyncio.Queue[str] = field(default_factory=asyncio.Queue)
    def drain_steering(self) -&gt; list[str]:  return _drain(self.steering)
    def drain_follow_up(self) -&gt; list[str]: return _drain(self.follow_up)
    def clear(self) -&gt; None:                # on abort: drop everything pending
        _drain(self.steering)
        _drain(self.follow_up)</code></pre></div><p>This loop belongs to the <code>Runner</code>, which is the facade between the TUI and the agent. Its job is to keep the agent alive as long as the TUI session is running. It also takes care of draining the queues at the right moments and sending them to the agent (from <code>src/decode/harness/runner.py</code>).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">class Runner:

    ...                 # single-flight: one turn in flight, ever

    async def _run_turn(self, turn_id: int, prompt: str) -&gt; None:
        agen = self._turn_handler(ctx)
        boundary = await agen.asend(None)
        while True:
            if self._abort:
                aborted = True
                break                                 # Esc: stop at the boundary, keep history
            if boundary is Boundary.MODEL_REQUEST:
                sent = self.queues.drain_steering()   # steering: before every model call
            elif boundary is Boundary.WOULD_STOP:
                sent = self.queues.drain_follow_up()  # follow-up: only when the turn would end
            try:
                boundary = await agen.asend(sent)     # resume the loop; get the next boundary
            except StopAsyncIteration:
                break</code></pre></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vDAk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vDAk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 424w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 848w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 1272w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vDAk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png" width="1200" height="665" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:665,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Two queues, two drain boundaries, one safe turn.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Two queues, two drain boundaries, one safe turn." title="Two queues, two drain boundaries, one safe turn." srcset="https://substackcdn.com/image/fetch/$s_!vDAk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 424w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 848w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 1272w, https://substackcdn.com/image/fetch/$s_!vDAk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F293cd381-1a60-4553-8c55-5a9b147f1815_1200x665.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Buffer instantly, inject only at boundaries</em></figcaption></figure></div><p>This is the approach implemented in Pi. Another option, implemented in OpenCode, is to keep track of the session in your database, which means you can use your database as the queue as well. But that also means that you need to complicate your solution with a database. Which raises the question, how do we keep track of sessions?</p><h2>The Session Log</h2><p>In the interactive mode the conversation is the working state. To keep track of sessions, we create a <strong>session log</strong> &#8212; an append-only JSONL file per session under <code>.decode/sessions/</code>. This simple approach kills the need for a database entirely. This is how Claude Code implements their session management.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">.decode/sessions/
&#9500;&#9472;&#9472; 20260620T132411Z_d710a5b9-28af-418b-9a15-936942a8db12.jsonl
&#9500;&#9472;&#9472; 20260620T132419Z_058cddc8-1d0f-406d-a754-098703c07cb5.jsonl
&#9500;&#9472;&#9472; 20260622T110408Z_7114fe38-d294-4c78-bbc3-c454be57082b.jsonl
&#9500;&#9472;&#9472; 20260622T111609Z_4bbf140e-3495-4d69-9a88-c7014fd77742.jsonl
&#9500;&#9472;&#9472; 20260625T152011Z_7594e9b0-6c62-421a-ad74-9918c4d0291e.jsonl
&#9492;&#9472;&#9472; ...</code></pre></div><p>Every completed turn appends one <code>messages</code> line to the log. An aborted or crashed turn persists what it finished (from <code>src/decode/context/session_log.py</code>).</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">def append_turn(self, new_messages: list[ModelMessage]) -&gt; None:
    if not new_messages:
        return

    payload = json.loads(ModelMessagesTypeAdapter.dump_json(new_messages))
    entry = {"type": "messages", "messages": payload}
    with self.path.open("a", encoding="utf-8") as handle:
        handle.write(json.dumps(entry) + "\n")</code></pre></div><p>Based on the knowledge-graph example, here is how the log entries look:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">{"type": "session", "version": 1, "session_id": "48900d84&#8230;", "cwd": "&#8230;/building-a-coding-agent-from-scratch-course", "created_at": "2026-07-16T19:32:01Z"}
{"type": "messages", "messages": [
    {"role": "user", "content": "The hardcore one: turn three live articles into a knowledge graph&#8230;"},
    {"role": "tool", "name": "web_fetch", "content": "HTTP 200 &#8230;/keep-knowledge-graph-clean\n\nHow to Keep a Knowledge Graph Clean&#8230;"},
    {"role": "tool", "name": "bash", "content": "Exit code: 0.\n\nstdout:\nNode count: 28 (should be 20-35)\nEdge count: 29&#8230;"},
    {"role": "assistant", "content": "## Knowledge Graph Visualization &#8212; Complete&#8230;"}]}</code></pre></div><p>To resume the state, you can run <code>decode --resume &lt;session_id&gt;</code> to kick off a new TUI from an existing session log.</p><h2>Next Steps</h2><p>In this lesson, we&#8217;ve implemented a bare-bones version of the coding agent, adding the right tools, a TUI, and a way to manage sessions. More or less, at this point, we are at feature parity with Pi.</p><p>But as a course on harness engineering, we want to push it further. Any agent needs a headless mode (along with running it from the terminal), essential context engineering features such as memory, compaction, skills and guardrails such as the permission layer and sandboxes. That&#8217;s essentially harness engineering. So far we&#8217;ve built the agent loop. Now the real harness engineering begins.</p><div class="callout-block" data-callout="true"><p>&#129489;&#8205;&#128187; <span>We encourage you to&nbsp;</span><strong>clone our&nbsp;<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">course repo</a></strong><span>, open your terminal, type </span><strong><span data-color="#38761d" style="color: rgb(56, 118, 29);">decode</span> </strong>and test out the coding agent.</p></div><p>In the next lesson, we&#8217;ll build the sandbox layer locally via Docker and remotely via Modal.</p><p>Here is the<strong> course roadmap, </strong>lesson by lesson <em>(<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-course-outline">see all in GitHub</a></em>):</p><ol><li><p><a href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design">Building a Coding Agent From Scratch</a></p></li><li><p><strong>The Bare-Bones Coding Agent Loop</strong> &#8592; <strong>You are here</strong></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p>Context Engineering for Coding Agents</p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p>Or the <strong>video</strong> lecture <strong>supporting</strong> <strong>the</strong> <strong>first two lessons</strong>:</p><div id="youtube2-sJpop1juVBQ" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;sJpop1juVBQ&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/sJpop1juVBQ?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><strong>From your perspective, as we&#8217;ve been using Claude Code, Codex, etc. for general productivity stuff, what makes a general-purpose agent a coding agent?</strong></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/the-coding-agent-loop/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/the-coding-agent-loop/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/the-coding-agent-loop?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/the-coding-agent-loop?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <strong><a href="https://modal.com?source=decodingai&amp;campaign=harnesseng">Modal</a></strong>, <strong><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik (by Comet)</a></strong>, and <strong><a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru (by ZenML)</a></strong> for sponsoring this open-source course and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uq-1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images &amp; Videos</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Building a Coding Agent From Scratch]]></title><description><![CDATA[Designing the harness around the model, from the agent loop to a remote swarm.]]></description><link>https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design</link><guid isPermaLink="false">https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Wed, 22 Jul 2026 11:04:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FPSt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F82861d6d-5603-4f6d-b98c-1af4a96d69df_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="callout-block" data-callout="true"><p>In LangChain&#8217;s Terminal-Bench experiment, changing only the harness (with the same model) moved a coding agent from ~30th place into the top 5: the harness, not the model, is what makes a coding agent good.</p><p>In the&nbsp;<strong>open-source course</strong>&nbsp;<strong><a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">Building a Coding Agent From Scratch</a></strong>, you&#8217;ll build that harness from scratch in Python:&nbsp;<strong>Decode</strong>, a complete coding agent that grows lesson by lesson from a bare agent loop into a swarm of remote agents running in parallel in the cloud.</p><p><strong>Why?</strong>&nbsp;You&#8217;ll be able to engineer custom harnesses for your own AI products (the skill behind that leaderboard jump), and you&#8217;ll understand what Claude Code and Codex actually do under the hood, turning you into a power user.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ge05!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1446989,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ge05!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 424w, https://substackcdn.com/image/fetch/$s_!ge05!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 848w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1272w, https://substackcdn.com/image/fetch/$s_!ge05!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F27ba7d81-6547-41ad-9370-e9df2dd960e1_1200x630.gif 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Lessons:</strong></p><ol><li><p><strong>Building a Coding Agent From Scratch &#8592; </strong><em><strong>you are here</strong></em></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop</a></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p>Context Engineering for Coding Agents</p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course&quot;,&quot;text&quot;:&quot;Full open-source course&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course"><span>Full open-source course</span></a></p></div><h1>Lesson 1: Building a Coding Agent From Scratch</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yVLk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yVLk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yVLk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The model is the smallest part. The machine around it is what you're about to build.&quot;,&quot;title&quot;:&quot;The model is the smallest part. The machine around it is what you're about to build.&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The model is the smallest part. The machine around it is what you're about to build." title="The model is the smallest part. The machine around it is what you're about to build." srcset="https://substackcdn.com/image/fetch/$s_!yVLk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!yVLk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15bedf6a-82c7-467b-a260-9a084c6d2b5a_1376x768.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In a <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">test run by LangChain on Terminal-Bench</a>, changing only the harness (same model throughout) moved a coding agent from roughly 30th place into the top 5. The model isn&#8217;t what makes a coding agent good. The harness is. So that&#8217;s what we&#8217;ll build from scratch. A coding agent harness.</p><p>When I first started digging into coding agents, I couldn&#8217;t tell where the agent ended and the harness began. I wanted past that black box, so in the past months I&#8217;ve researched how the most popular coding agent tools work under the hood: Claude Code (via its leaked source), <a href="https://github.com/anomalyco/opencode">OpenCode</a>, <a href="https://github.com/earendil-works/pi">Pi</a>, and <a href="https://github.com/aider-ai/aider">Aider</a>.</p><p>That harness is the only layer you can actually engineer. And that&#8217;s why I think building your own coding agent harness from scratch is the best way to understand both how to better use coding agents to become a power user and how to build your own custom harnesses for AI agents.</p><p><em>During my research, I&#8217;ve built my own replica: <strong>&#8220;Decode: The Coding Agent&#8221;</strong>. Now, I want to <strong>show you how to build your own.</strong></em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!a09O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!a09O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!a09O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!a09O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!a09O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!a09O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:211061,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!a09O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!a09O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!a09O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!a09O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc0acc2c8-d4bb-4730-88d1-9fa2db966e6f_1815x986.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Decode: The Coding Agent - Planning</figcaption></figure></div><p>I don&#8217;t mean a simple LLM with some tools in a loop, which is just the good old ReAct pattern. I mean building the whole coding harness from scratch. Build a coding agent once, and you&#8217;re equipped to build a custom agent for any use case.</p><p>The truth is that to add custom business logic to existing open-source harnesses such as <a href="https://github.com/earendil-works/pi">Pi</a>, <a href="https://github.com/langchain-ai/deepagents">DeepAgents</a> by LangChain, or <a href="https://github.com/pydantic/pydantic-ai-harness">Pydantic AI Harness</a> is not that hardcore. But to know what to add based on the internals of these harnesses is extremely important. That&#8217;s fundamentals. The secret sauce that still makes AI Engineers valuable.</p><p>In this <strong>8-lesson series</strong>, you&#8217;ll build a complete coding agent called <strong>Decode</strong>, from scratch, in Python. It runs as a CLI via <code>decode</code> for interactive use, or as a remote headless agent that lets you run a swarm of agents in parallel on a cloud platform for automation such as picking up tasks from the backlog or PR reviews.</p><p>You&#8217;ll learn how to implement all of that in 3 escalating phases. First, build: the agent loop via Pydantic AI, powered by open-source models on <a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a> or <a href="https://openrouter.ai/">OpenRouter</a>.</p><p>Then building the harness around the loop: durable execution with <a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru</a>, context engineering, memory, the permission layer, sandboxing in Docker and Modal, and the agent catalog of planners, builders, explorers, and subagents. All the good stuff.</p><p>Finally, the boring stuff that makes you a senior AI engineer: a custom benchmark similar to <a href="https://www.tbench.ai/leaderboard">Terminal-Bench</a>, AI Evals for regressions, observability via <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a>, and deployment to GCP running a swarm of agents in parallel.</p><p>Before getting into the implementation, I want to kick off this lesson with the most fun part: <strong>the system design of the coding agent.</strong></p><p>Let&#8217;s trace the architecture end to end, following one request through every component.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5g74!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5g74!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!5g74!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!5g74!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!5g74!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5g74!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png" width="1456" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:160059,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5g74!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!5g74!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!5g74!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!5g74!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc58beb8-0171-4fe3-a109-c13ddd5f0145_1816x855.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Decode: The Coding Agent - Demos as <strong>.decode/skills</strong> you can run yourself</figcaption></figure></div><h2>The High-Level System Design</h2><p>You pass a coding agent a request &#8212; &#8220;fix the bugs that make the unit tests fail&#8221; &#8212; and it loops: explore the codebase, run the tests, read the feedback, edit the code, repeat. The input is your request, while the repository is the state of the codebase. The output is tested changes done to the repo. Everything in between is the harness.</p><p>We are pretty familiar with this process. <strong>But how does it work?</strong></p><p>At the center sits the headless harness: no interface of its own. It exposes a module that interfaces connect to. At the core, it runs the agent loop every harness shares: the LLM picks an action (a tool call &#8212; run the failing test suite), the tool executes and returns an observation (2 failing tests, expected vs actual), and the loop feeds it back. Everything reads from and writes to the context window (the state of the LLM).</p><p>To highlight that the harness is independent from the LLM, we wanted to implement multiple LLM providers. The loop is powered by an LLM provider module that to support open-source models we implemented it with Modal (for self-hosting) and OpenRouter (for APIs). Also, we added support for Gemini for their free tier. <a href="https://modal.com/?source=decodingai&amp;campaign=harnesseng">Modal</a> is the most interesting as it allows us to either host standard open-source models or easily host our own fine-tuned models on top of their serverless infrastructure.</p><p>That cycle lets the agent correct itself: implement the code, run or compile it, read the error, fix it &#8212; or catch the mistake before anything runs, with a Language Server Protocol (LSP) server flagging broken syntax the moment an edit happens. The tighter these feedback loops, the faster the agent converges on working code. The LSP server (we used ty - made by Astral&#8217;s - the guys behind uv and ruff) is the cheapest way to get feedback on code changes.</p><p>Along with the LLM providers and LSP server, the harness contains 4 more essential modules: Memory, Skills, Sandbox, and Permissions. Essential for context engineering and security.</p><p>The context window of the LLM is a budget. The conversation accumulates in the window until it stops fitting or performance degrades. Remember that too much context confuses the model, known as context decay. Every observation the loop feeds back <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">spends from the same finite budget</a>. Hence, the harness needs to implement compaction techniques such as summarization, truncation, or just clearing the window.</p><p>How do we interact with the headless harness? It has two core interfaces: interactive mode, a terminal user interface (TUI) wired to one live session, and remote mode, where an agent runtime (<a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru</a>) runs N headless harnesses in parallel on a server.</p><p>On top of everything, we have the AI evals &amp; observability layer, powered by <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a>, that records every model call and tool call, and turns a bad prompt tweak into a failing regression score before your users feel it in production.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!89g-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!89g-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!89g-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!89g-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!89g-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!89g-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:154657,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!89g-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!89g-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!89g-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!89g-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff098d70e-2956-40be-9311-7c133d096cf6_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The architecture of a coding-agent harness</figcaption></figure></div><p>Here is how all the components fit together:</p><p>You type the request into the TUI. The input goes into the steering queue through the priority gate into the session&#8217;s context window. The loop sends the window (with the available tools) to the model through the LLM provider. The model answers with an action &#8212; grep for the failing assertion, then edit <code>stats.py</code>. Permissions checks if it can execute the tool, the tool executes inside the Sandbox, and the observation is added back into the context window. The loop repeats until the model stops calling tools. During the loop execution, events are streaming back to your terminal in real-time via an async generator (or SSE for remote streaming events).</p><p>Next, let&#8217;s zoom into the agent loop, where the agent ends and the harness begins, the boundary that defines this entire series.</p><h2>The Headless Harness &amp; The Agent Loop</h2><p>The agent itself is a Pydantic AI agent. A ~20 line definition that composes the model, the tools, the output type and iterates until the model stops calling them. The snippet below is the distilled version of Decode&#8217;s loop:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;python&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-python">from dataclasses import dataclass
from pydantic_ai import Agent, DeferredToolRequests

@dataclass
class AgentDeps:                # the harness state injected into every tool call
    cwd: Path                   # the repo the tools operate on
    emit: EventSink             # streams events to whatever interface is attached
    gate: PermissionGate        # allow / ask / deny, per tool call
    resolve_permission: PermissionResolver  # asks the human when the gate says "ask"

agent = Agent(
    build_model(settings.llm_provider),       # gemini | openrouter | modal
    deps_type=AgentDeps,
    output_type=[str, DeferredToolRequests],   # a turn ends as a final answer (str),
)                                              # or as tool calls paused for approval
register_tools(agent)                          # read, edit, bash, grep, ...

async with agent.iter(prompt, message_history=history) as run:
    async for node in run:                     # model request &#8594; tool calls &#8594; repeat
        stream_events(node)                    # everything else is the harness</code></pre></div><p>Through the <code>AgentDeps</code> dataclass we inject harness related components into the loop. The tools are never aware of the interface: TUI or headless. This is what I like to call &#8220;a practical clean architecture&#8221;, where you are obsessive about separating the serving and infrastructure layers from your core business logic via interfaces and composition.</p><p><code>output_type</code> names the only 2 ways a turn can end: a final answer, or tool calls suspended mid-turn waiting for human input.</p><p>We will go into all the details about the agent loop, explaining how we hook multiple closed-source/open-source models, the tools and other deps into the loop, in the next article.</p><p>These ~20 lines are the <em>entire</em> tool-calling LLM agent. The thing people call &#8220;the agent&#8221; ends here. Everything we build on top of it across 8 lessons is the <strong>coding harness</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IJV9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IJV9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 424w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 848w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 1272w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IJV9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png" width="1400" height="828" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:828,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The boundary: a tiny tool-calling agent inside a much larger harness.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The boundary: a tiny tool-calling agent inside a much larger harness." title="The boundary: a tiny tool-calling agent inside a much larger harness." srcset="https://substackcdn.com/image/fetch/$s_!IJV9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 424w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 848w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 1272w, https://substackcdn.com/image/fetch/$s_!IJV9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0db84995-d395-4854-a4c0-65be5f8915c5_1400x828.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Pydantic AI is a thin layer over the model APIs: typed tool definitions, streaming, structured outputs, with no heavy framework between us and our own logic. What makes this a <em>coding</em> agent is the tools: read and edit files, run bash, search the codebase, manage a task list, fetch the web, ask the user a question, and spawn subagents. Plus, the LLM specializes in coding. Anthropic is well known for continually optimizing their models for coding tasks. That&#8217;s why with every release their models get worse and worse at writing, while better and better at coding.</p><p>Still, almost everyone already uses coding agents such as Claude Code or Codex for completely different use cases (including myself): productivity, content creation, finance, sales, marketing. The line between a coding agent and a general-purpose agent is blurry, as any agent needs to natively interact with your computer. How would a harness specialized in writing look? Other than making the LLM sound better. Which is not the harness!</p><p>On top of the agent loop, we have 6 modules + compaction that transform the agent loop into a headless harness.</p><h3>The Six Modules + Compaction</h3><p><strong>LLM Providers</strong> &#8212; Decode ships with 3: Modal to serve any type of open-source models (pre-configured or your own fine-tuned version), deployed as <strong><a href="https://modal.com/docs/guide/endpoints?source=decodingai&amp;campaign=harnesseng">Modal endpoints</a></strong> &#8212; serverless GPU web endpoints that put the model behind a URL the harness calls like any hosted API, OpenRouter to reach any hosted model behind one API, and Gemini for Google&#8217;s free tier for following along. Also, by implementing three providers we can showcase how to swap the model only with a config change, not a rewrite. The loop should never know which model is powering the harness. Clean architecture, remember?</p><p><strong>Sandbox</strong> &#8212; an agent that runs bash can break things. We wrap the bash and file-I/O tools to execute inside a sandbox (Docker locally, <strong><a href="https://modal.com/docs/guide/sandboxes?source=decodingai&amp;campaign=harnesseng">Modal Sandboxes</a></strong> remotely) instead of on your machine.</p><p><strong>Permissions</strong> &#8212; the permission layer is the most important guardrail: it asks you before running every action, or only the risky ones, depending on the mode. For example, it pauses before a destructive bash command like <code>rm -rf</code> and waits for your approval. This is similar to Claude Code&#8217;s default, edit, and auto modes.</p><p><strong>Memory</strong> &#8212; the iconic AGENTS.md that carries your project instructions plus a MEMORY.md that encodes what the agent learns (e.g. &#8220;run the tests with <code>pytest -x</code>, never the full suite&#8221;). Plain files, deliberately no memory database and no codebase index: the repo is explored dynamically with grep. Just-in-time reads beat a stale heavy index.</p><p><strong>Skills</strong> &#8212; the omnipresent skills feature that encodes reusable workflows loaded only when invoked, so the context window doesn&#8217;t get bloated with all your instructions at once. The repo already ships a set of skills under <code>.decode/skills/</code> that you can try out of the box.</p><p><strong>LSP Server</strong> &#8212; a key component of a coding agent. It keeps an index of all your variables and functions. The loop gets syntax and semantic information about the codebase through 2 channels instead of brute-forcing through it or waiting for the code to run. On demand, the model asks where a symbol is defined, who calls it, what its real contract is, and what&#8217;s broken in a file. The model gets 1 precise <code>file:line</code> answer. After each edit, a fast syntax checker feeds its findings back into the loop. The agent fixes a type error in the same turn, before running/compiling any code. The cheapest feedback loop in the system.</p><p><strong>Compaction</strong> &#8212; not a module but a behavior of the harness itself that helps keep the context window as small as possible. The most iconic strategy is to compact the window once it goes over a threshold, squashing the window&#8217;s old head into a summary + keeping the recent interactions fresh: <code>[summary, *tail]</code>. You can also call this manually via <code>/compact</code> or simply clean the whole context window via <code>/clear</code>.</p><p>That&#8217;s the headless harness. Now, let&#8217;s plug it into the interfaces you use every day.</p><h2>The Interactive Mode</h2><p>The first is the <strong>TUI</strong>: the interactive mode, a terminal interface wired directly to one live session of the headless harness, in memory, in the same process.</p><p>We built it in Python, where <code>prompt_toolkit</code> handles input and <code>Rich</code> handles output of the terminal experience. It&#8217;s append-style, like a conversation log, rather than a full-screen app. Keystrokes go in, and the session&#8217;s event stream comes back in real-time via Python generators: streamed text, tool calls, approval prompts.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GNsc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GNsc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GNsc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png" width="1456" height="791" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:791,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The TUI: an append-style conversation log streamed live from one harness session.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The TUI: an append-style conversation log streamed live from one harness session." title="The TUI: an append-style conversation log streamed live from one harness session." srcset="https://substackcdn.com/image/fetch/$s_!GNsc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 424w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 848w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 1272w, https://substackcdn.com/image/fetch/$s_!GNsc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46cc8b77-6896-405b-ad08-feac403ea3b7_1815x986.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The TUI that we will build</em></figcaption></figure></div><p><strong>Why Python?</strong> To be honest, we picked it mostly for teaching purposes.</p><p>From my recent poll, I realized that all my audience knows Python. So this makes it accessible to you. But if I were to ship this for real, I&#8217;d reach for TypeScript (the language claude-code, OpenCode, and Pi chose) or Go, which compiles to one tidy binary. Still, Aider proves Python can carry a serious coding agent.</p><p>And in this series we will focus on the &#8220;why&#8221;, the design and architecture decisions. Thus, the programming language is not that important and you can easily swap it out for another language.</p><h3>The steering queue</h3><p>What happens when you send a new command and the agent is already mid-task?</p><p>Injecting it the moment it&#8217;s sent would corrupt a tool call already in flight. Ignoring it makes the agent unsteerable. Every serious harness hits this: Pi drains steering messages mid-turn but follow-ups only at the turn boundary, and claude-code ranks queued input so user messages never starve.</p><p>Decode&#8217;s answer is the <strong>steering queue + priority gate</strong>. Input is buffered the instant it arrives into the steering queue and injected only at a safe boundary: before the next model call, never mid-tool-call. The gate decides how to process the messages from the queue: steer now, answer later, or abort.</p><p>The steering queue can be a simple in memory FIFO queue. No need for a complex queue infrastructure like RabbitMQ.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_MJf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_MJf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 424w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 848w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 1272w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_MJf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png" width="1456" height="510" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:510,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Mid-turn input: buffered in the steering queue, injected only at a safe boundary.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Mid-turn input: buffered in the steering queue, injected only at a safe boundary." title="Mid-turn input: buffered in the steering queue, injected only at a safe boundary." srcset="https://substackcdn.com/image/fetch/$s_!_MJf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 424w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 848w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 1272w, https://substackcdn.com/image/fetch/$s_!_MJf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f58d9ed-d1d9-4550-a8ae-bb08f071e682_2100x735.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Steering without corruption</em></figcaption></figure></div><p>You can already clone the <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">Decode repository</a> and try it out for yourself.</p><p>You have all the setup instructions in the repo. There are 0 <em>costs</em> <em>to</em> <em>try</em> <em>it</em> <em>out</em>. <em>We</em> <em>recommend</em> <em>starting</em> <em>it</em> <em>with</em> <em>Modal</em>, <em>which</em> <em>offers</em>30 in free credit every month.</p><p>The experience is similar to what you already know: you run <code>decode</code> in any repo and the TUI opens as a fresh session.</p><p>We bundled together a few demo&#8217;s as skills under <code>.decode/skills/</code>, so you can easily try out the coding agent with 0 friction:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TsnR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TsnR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TsnR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png" width="1456" height="686" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The demo skills bundled under .decode/skills/, listed inside the TUI.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The demo skills bundled under .decode/skills/, listed inside the TUI." title="The demo skills bundled under .decode/skills/, listed inside the TUI." srcset="https://substackcdn.com/image/fetch/$s_!TsnR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 424w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 848w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 1272w, https://substackcdn.com/image/fetch/$s_!TsnR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F92c62af5-78c3-4009-99f3-759c7beba3ed_1816x855.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The demo skills bundled under </em><code>.decode/skills/</code><em>, listed inside the TUI.</em></figcaption></figure></div><p>Such as creating a snake game:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!irfj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!irfj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 424w, https://substackcdn.com/image/fetch/$s_!irfj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 848w, https://substackcdn.com/image/fetch/$s_!irfj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 1272w, https://substackcdn.com/image/fetch/$s_!irfj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!irfj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png" width="854" height="819" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:819,&quot;width&quot;:854,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The snake game skill, built and running from a single prompt.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The snake game skill, built and running from a single prompt." title="The snake game skill, built and running from a single prompt." srcset="https://substackcdn.com/image/fetch/$s_!irfj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 424w, https://substackcdn.com/image/fetch/$s_!irfj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 848w, https://substackcdn.com/image/fetch/$s_!irfj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 1272w, https://substackcdn.com/image/fetch/$s_!irfj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa73cc86c-8e1c-4c1c-ac42-7299fb9cede9_854x819.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Fetching data from a GitHub repo and rendering a web page:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!4v2q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!4v2q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 424w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 848w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 1272w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!4v2q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png" width="1456" height="1190" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1190,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;GitHub repo data fetched by the agent and rendered into a web page.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="GitHub repo data fetched by the agent and rendered into a web page." title="GitHub repo data fetched by the agent and rendered into a web page." srcset="https://substackcdn.com/image/fetch/$s_!4v2q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 424w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 848w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 1272w, https://substackcdn.com/image/fetch/$s_!4v2q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff9fe14a6-8adb-4c85-ac6f-8aafbc64ae9e_2328x1902.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Or something more complex like scraping data from the internet, extracting a knowledge graph of entities and topics and rendering them into a cool visualization:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c6fZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c6fZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 424w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 848w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 1272w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c6fZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png" width="1456" height="847" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:847,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A knowledge graph of entities and topics, scraped from the web and rendered into a visualization.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A knowledge graph of entities and topics, scraped from the web and rendered into a visualization." title="A knowledge graph of entities and topics, scraped from the web and rendered into a visualization." srcset="https://substackcdn.com/image/fetch/$s_!c6fZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 424w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 848w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 1272w, https://substackcdn.com/image/fetch/$s_!c6fZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa0abc6ad-61e0-4594-84c2-2f289327f8a1_3324x1934.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>What if we want to run the agent remotely?</p><h2>The Remote Mode</h2><p>Remote mode keeps the harness headless and runs it on a server through an agent runtime. We use <strong><a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru</a></strong>, the agent runtime built by ZenML, which provides durability, replay and distributed HITL features. Then we ship the Kitaru control plane to GCP via its open-source option. From there, it orchestrates and scales the remote agents, which run on Modal.</p><p>This setup lets you run background jobs, scheduled tasks, and full automation pipelines: grab a ticket from Linear, launch 5 to 10 implementations in parallel (each with its own PR), and let a frontier foundation model judge the candidates and rank them for you.</p><p>A runtime gives the headless harness <a href="https://docs.zenml.io/kitaru/core-concepts/harness-runtime-platform?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=docs">a control plane</a>: deploy it once, then trigger, monitor, and feed it input remotely, without building any of that plumbing yourself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HGOX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HGOX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 424w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 848w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 1272w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HGOX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png" width="1456" height="844" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:844,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Kitaru runtime &#8212; the control plane that orchestrates the remote headless agents.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Kitaru runtime &#8212; the control plane that orchestrates the remote headless agents." title="The Kitaru runtime &#8212; the control plane that orchestrates the remote headless agents." srcset="https://substackcdn.com/image/fetch/$s_!HGOX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 424w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 848w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 1272w, https://substackcdn.com/image/fetch/$s_!HGOX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F72c126ea-2eeb-480c-89fd-7397a81b6ade_3344x1938.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The Kitaru runtime: the control plane that orchestrates the remote headless agents.</em></figcaption></figure></div><p>The infrastructure&#8217;s moving pieces can get confusing. There are 3 main pieces:</p><ul><li><p><strong>The Control Plane</strong>: The runtime that coordinates the headless agents. Powered by Kitaru. Super similar to orchestrators such as ZenML, Prefect or Temporal. That&#8217;s why ZenML created Kitaru, specialized in running agentic workflows. Using Kitaru&#8217;s open-source Docker image, we will deploy it to GCP.</p></li><li><p><strong>The Execution</strong>: Where the headless agents run: Python environment (local) and Modal (remote).</p></li><li><p><strong>The Sandbox</strong>: Where the tools execute: Docker (local) and Modal (remote).</p></li></ul><p>The runtime <a href="https://docs.zenml.io/kitaru/core-concepts/how-it-works?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=docs">records the run&#8217;s progress step by step</a>, so when a sandbox dies mid-task, the run resumes from its last recorded step instead of restarting.</p><p>Same reasoning for human input: <a href="https://docs.zenml.io/kitaru/core-concepts/wait-and-input?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=docs">the run freezes at a question</a>, consuming no compute while it waits, and resumes the moment you answer, hours later or from another terminal.</p><p>Because every step is recorded, a finished run can be <strong><a href="https://docs.zenml.io/kitaru/core-concepts/harness-runtime-platform?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=docs">replayed</a></strong> with one thing changed (a different model, a fixed prompt) against the original as the baseline.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!888f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!888f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 424w, https://substackcdn.com/image/fetch/$s_!888f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 848w, https://substackcdn.com/image/fetch/$s_!888f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 1272w, https://substackcdn.com/image/fetch/$s_!888f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!888f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png" width="987" height="609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:609,&quot;width&quot;:987,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:84712,&quot;alt&quot;:&quot;The three planes of a remote run: control, progress record, execution.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The three planes of a remote run: control, progress record, execution." title="The three planes of a remote run: control, progress record, execution." srcset="https://substackcdn.com/image/fetch/$s_!888f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 424w, https://substackcdn.com/image/fetch/$s_!888f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 848w, https://substackcdn.com/image/fetch/$s_!888f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 1272w, https://substackcdn.com/image/fetch/$s_!888f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fce1c73-27d4-4b0d-aca4-1f54916bc228_987x609.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em> The runtime split</em></figcaption></figure></div><h3>Try it out</h3><p>You can run the remote version by going to the <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">course repo</a>, typing <code>decode run &lt;your_command&gt;</code> in your terminal, and opening Kitaru to watch the agent work.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uDnx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uDnx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 424w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 848w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 1272w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uDnx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png" width="1456" height="836" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:836,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Watching a remote run step by step in Kitaru after decode run.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Watching a remote run step by step in Kitaru after decode run." title="Watching a remote run step by step in Kitaru after decode run." srcset="https://substackcdn.com/image/fetch/$s_!uDnx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 424w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 848w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 1272w, https://substackcdn.com/image/fetch/$s_!uDnx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F36c8a3a2-9a7a-4871-b037-8baa7d6dd1ee_3330x1912.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Watching a remote run step by step in Kitaru after </em><code>decode run</code><em>.</em></figcaption></figure></div><p>Two modes, one core. That raises the obvious question: why not both at once?</p><h2>All the Modes, One Message Bus</h2><p>We keep Decode simple by keeping the headless harness as the core business logic that can be served in two modes: local and remote.</p><p>But you can take this further. OpenCode uses a message bus between the headless harness and every interface to synchronize sessions across their TUI, IDE, WhatsApp, web app, mobile clients. So they all drive the <em>same</em> live session: when one interface publishes a message, all the other ones are instantly synced.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JnP3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JnP3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 424w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 848w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 1272w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JnP3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png" width="1400" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;One remote session, many interfaces, one message bus.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="One remote session, many interfaces, one message bus." title="One remote session, many interfaces, one message bus." srcset="https://substackcdn.com/image/fetch/$s_!JnP3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 424w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 848w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 1272w, https://substackcdn.com/image/fetch/$s_!JnP3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03e2a9fb-ca73-42c3-a243-33753a725abc_1400x640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The topology we explained, but won&#8217;t build: one remote session behind a bus, every interface a thin subscriber.</em></figcaption></figure></div><p>Whichever mode runs it, one question decides whether any of this is real engineering: can you prove the agent works?</p><h2>The Observability and AI Evals Layer</h2><p>The evals layer answers 3 questions, each with its own mechanism.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_f1O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_f1O!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 424w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 848w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 1272w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_f1O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png" width="1200" height="395" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0300419f-aac0-4e7e-b532-d81835784777_1200x395.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:395,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Three questions, three eval mechanisms, one timeline.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Three questions, three eval mechanisms, one timeline." title="Three questions, three eval mechanisms, one timeline." srcset="https://substackcdn.com/image/fetch/$s_!_f1O!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 424w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 848w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 1272w, https://substackcdn.com/image/fetch/$s_!_f1O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0300419f-aac0-4e7e-b532-d81835784777_1200x395.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The evals layer answers three different questions</em></figcaption></figure></div><p>Internal benchmarks answer <em>does it work?</em> These are the metrics you try to beat with every new feature. You can use public benchmarks such as <a href="https://github.com/harbor-framework/terminal-bench">Terminal-Bench</a> to compare your agent&#8217;s performance against others. But the real deal is to build a custom benchmark suite from your own tasks that optimizes for your specific use case.</p><p>Each case is a task instruction, a fresh sandboxed environment, and a hidden oracle test that decides pass or fail. One example case is <em>&#8220;add a </em><code>--json</code><em> flag to </em><code>decode run</code><em>&#8220;</em>, with a hidden pytest asserting the output parses. It&#8217;s the same pattern <a href="https://github.com/swe-bench/SWE-bench">SWE-bench</a> applies to real GitHub issues and <a href="https://github.com/harbor-framework/terminal-bench">Terminal-Bench</a> applies to terminal tasks.</p><p>Your own tasks predict your agent&#8217;s usefulness better than any leaderboard.</p><p>Regression tests answer <em>does it still work?</em> Every new feature re-runs a regression suite and compares scores against the baseline, so a prompt tweak or a new tool can&#8217;t silently make the agent worse.</p><p>Production evals answer <em>does it keep working?</em> Every session is traced with <strong><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik</a></strong>, Comet&#8217;s open-source LLM observability platform: each model call, tool call, and token count is a trace, while the conversation is logged as a thread. Live scoring tracks quality in production, where you run a bunch of AI Evals metrics on sampled traces to detect unwanted behavior to create warnings or alarms.</p><p>We will also use Opik as our evaluation harness to track our eval datasets and run a coding agent on all the scenarios from the benchmark and regression tests.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AKa3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AKa3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 424w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 848w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 1272w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AKa3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png" width="1456" height="858" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:858,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Opik threads &#8212; every session logged as a thread, every model and tool call as a trace.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Opik threads &#8212; every session logged as a thread, every model and tool call as a trace." title="Opik threads &#8212; every session logged as a thread, every model and tool call as a trace." srcset="https://substackcdn.com/image/fetch/$s_!AKa3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 424w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 848w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 1272w, https://substackcdn.com/image/fetch/$s_!AKa3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40da9e96-3e12-46f9-97eb-4651da6e3e46_3262x1922.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Next Steps</h2><p>You&#8217;ve seen a bird&#8217;s-eye view of what a coding agent looks like: one headless core, a small tool-calling agent inside a much larger harness, 2 modes, and an evals layer that measures performance.</p><div class="callout-block" data-callout="true"><p>&#129489;&#8205;&#128187; We encourage you to <strong>clone our <a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course">course repo</a></strong>, open your terminal, type <strong><span data-color="#38761d" style="color: rgb(56, 118, 29);">decode</span> </strong>and test out the coding agent.</p></div><p>In the next lesson, we get into the code and start building the agent loop hooked into the TUI.</p><p>Here is the<strong> course roadmap, </strong>lesson by lesson <em>(<a href="https://github.com/decodingai-magazine/building-a-coding-agent-from-scratch-course#-course-outline">see all in GitHub</a></em>):</p><ol><li><p><strong>Building a Coding Agent From Scratch &#8592; </strong><em><strong>you are here</strong></em></p></li><li><p><a href="https://www.decodingai.com/p/the-coding-agent-loop">The Bare-Bones Coding Agent Loop</a></p></li><li><p><a href="https://www.decodingai.com/p/run-coding-agents-safely">From a Raw Shell to a Sandboxed Coding Agent</a></p></li><li><p><span>Context Engineering for Coding Agents</span></p></li><li><p>Agents Catalog, Subagents &amp; Parallel Fan-out</p></li><li><p>Remote Headless Mode &amp; Durability</p></li><li><p>AI Evals Foundations: Benchmarks, Regression and Online</p></li><li><p>AI Evals on Steroids via Replays</p></li></ol><p>Or the <strong>video</strong> lecture <strong>supporting</strong> <strong>the</strong> <strong>first two lessons</strong>:</p><div id="youtube2-sJpop1juVBQ" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;sJpop1juVBQ&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/sJpop1juVBQ?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Which part of your daily coding agent is still a black box to you: the loop, the sandbox, the memory, or something else?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/building-a-coding-agent-from-scratch-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <strong><a href="https://modal.com?source=decodingai&amp;campaign=harnesseng">Modal</a></strong>, <strong><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&amp;utm_content=coding_agent_course">Opik (by Comet)</a></strong>, and <strong><a href="https://www.zenml.io/product/kitaru?utm_source=decodingai&amp;utm_medium=referral&amp;utm_campaign=coding-agent-course&amp;utm_content=brand">Kitaru (by ZenML)</a></strong> for sponsoring this open-source course and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uq-1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69533,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/207400663?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Uq-1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 424w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 848w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1272w, https://substackcdn.com/image/fetch/$s_!Uq-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98999460-8389-40b0-9dda-73f934bbf55a_1200x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Agent Memory From Scratch]]></title><description><![CDATA[Ingest, query, and serve a unified memory from a single database.]]></description><link>https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch</link><guid isPermaLink="false">https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 14 Jul 2026 05:01:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Cr9k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Cr9k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Cr9k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Cr9k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Many sources. One record. That is what a unified memory buys you.Many sources. One record. That is what a unified memory buys you.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Many sources. One record. That is what a unified memory buys you.Many sources. One record. That is what a unified memory buys you." title="Many sources. One record. That is what a unified memory buys you.Many sources. One record. That is what a unified memory buys you." srcset="https://substackcdn.com/image/fetch/$s_!Cr9k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!Cr9k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8b3401e-0a72-4e13-ba67-9a2863a387a2_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Agent memory is one of the hottest problems in AI engineering right now, with Graphiti, mem0, HydraDB, and cognee all racing to solve it. A race this crowded means one thing: nobody has cracked it yet.</p><p>But if you&#8217;re thinking of jumping straight into an agent memory tool without understanding how it works under the hood, read this first.</p><blockquote><p>Here is what happened in one of my tests: LangChain&#8217;s <code>MongoDBGraphStore</code> gave me a knowledge graph (KG) in 10 minutes, and from 5 documents it invented 17 node types and 34 relationship types, where <code>part_of</code>, <code>Part Of</code>, and <code>part of</code> were three different ways to express the same relationship.</p></blockquote><p>That&#8217;s why it&#8217;s incredibly important to <strong>understand how the memory layer works under the hood</strong>, so you know its limitations, how to properly configure it for your data, and how to plug it into your agent.</p><p>Or even decide if <strong>you need a unified memory at all, and if so, which tool to use.</strong></p><p>Claude Code comes with a built-in memory layer powered by files. Is this enough for you or not?</p><p>Then, if you move to a more powerful solution, should you use a vector database, a graph database, or a combination of both? Do you need temporality or versioning?</p><p>And ultimately, how should you serve your memory layer to your agent? Through an MCP server, a CLI, or plain skills?</p><p>The reality is that there is no blueprint on how to build your own unified memory layer. Too many choices, too many trade-offs.</p><p>But that&#8217;s why I want to show you how to build a unified agent memory from scratch, in the most complicated way possible: via knowledge graphs (KGs). Plus all the other moving pieces: ingestion, querying, and serving.</p><p><strong>Why?</strong> Because all the popular vendors (cognee, Graphiti, Neo4j&#8217;s agent memory, etc.) go in this direction. Plus, if you know how this works, it will be incredibly easy for you to build simpler solutions.</p><p>So, I am not saying that KGs are always the way to go. They are not. But they are definitely something you need to understand. At least to know when to stay away from them.</p><p>Let&#8217;s go!</p><h2>A Session With a Unified Memory</h2><p>First, here is what I expect a unified memory plugged into a harness to do.</p><p>I open Claude Code and ask what I need to do today. The memory already knows: building a coding agent for my next open source project.</p><p>I ask it to gather everything relevant I have on building a coding agent: Obsidian notes, Readwise highlights, starred repos, all ingested long ago. Then to build an LLM wiki on top of that as my agent memory while I implement the plan.</p><p>When I&#8217;m done, the conversation is ingested too, so the next session already knows all my decisions around the project.</p><p>Nothing in that session lived in the harness. Claude Code was just the interface.</p><p>So how do I implement a unified memory that supports this? Let&#8217;s kick off with the architecture.</p><h2>The Architecture, End to End</h2><p>Sources in, subgraphs out. In between sit 4 pieces: an ontology, a write path, one collection, and a serving layer.</p><p>The whole database layer is powered by <a href="https://www.mongodb.com/">MongoDB</a>: a document warehouse plus a knowledge-graph store doing text, vector, and graph search in one collection. Because we use a single database, lineage is free: nodes hold references to their source documents, not copies from a separate source. This works incredibly well at 2-3 hops at query time.</p><p>OG databases such as MongoDB scale really well up to millions of documents via sharding and replicas.</p><p>Writes are 2 durable pipelines. A data pipeline normalizes each source into the warehouse. A memory pipeline cleans, chunks, extracts, normalizes, embeds, and writes the knowledge-graph objects. Both pipelines are powered by an orchestrator, such as Prefect or DBOS, to serve them, scale them, and make them durable.</p><p>On the read side, we offer multiple ways to interact with the unified memory: standard graph search encoded directly into the tool, agentic search where the agent writes its own MongoDB query, and a deep-search primitive that creates an on-demand LLM wiki for exploring larger subgraphs via progressive disclosure. Reads never touch the orchestrator, as they need to be fast and don&#8217;t benefit from the orchestrator&#8217;s durability or scheduling features.</p><p>The memory is reachable only through a FastMCP server exposing agent-shaped primitives (query, deep-search, ingest), never raw database operations. The MCP server should never be an API wrapper, but directly expose business logic to the harness. A hook fires the conversation ingestion as the session runs, so what the agent learns flows back into the memory &#8212; a process known as &#8220;continual learning.&#8221;</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qby_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qby_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 424w, https://substackcdn.com/image/fetch/$s_!qby_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 848w, https://substackcdn.com/image/fetch/$s_!qby_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 1272w, https://substackcdn.com/image/fetch/$s_!qby_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qby_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png" width="600" height="600" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:600,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The full dataflow &#8212; data pipeline, memory pipeline, one MongoDB engine, the MCP server, and the harness with its skills.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The full dataflow &#8212; data pipeline, memory pipeline, one MongoDB engine, the MCP server, and the harness with its skills." title="The full dataflow &#8212; data pipeline, memory pipeline, one MongoDB engine, the MCP server, and the harness with its skills." srcset="https://substackcdn.com/image/fetch/$s_!qby_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 424w, https://substackcdn.com/image/fetch/$s_!qby_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 848w, https://substackcdn.com/image/fetch/$s_!qby_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 1272w, https://substackcdn.com/image/fetch/$s_!qby_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb4ba4d2e-41d4-4847-b2ce-f95abe5ff76f_600x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The most interesting part is not the database, the ingestion, or the query logic, but the ontology that makes everything possible.</p><h2>The Ontology Is the Contract</h2><p>An ontology is a contract between the writer and the reader. The LLM extracts against it. The query layer reads against it. Define it once as Pydantic, serialize with <code>model_json_schema()</code>, and dump that JSON into both writing and reading system prompts. 1 artifact, 2 consumers, no drift.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k41v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k41v!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 424w, https://substackcdn.com/image/fetch/$s_!k41v!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 848w, https://substackcdn.com/image/fetch/$s_!k41v!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!k41v!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k41v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png" width="1200" height="1006" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1006,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The unified memory's three layers, with the POLE+O ontology at the core of the long-term graph.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The unified memory's three layers, with the POLE+O ontology at the core of the long-term graph." title="The unified memory's three layers, with the POLE+O ontology at the core of the long-term graph." srcset="https://substackcdn.com/image/fetch/$s_!k41v!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 424w, https://substackcdn.com/image/fetch/$s_!k41v!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 848w, https://substackcdn.com/image/fetch/$s_!k41v!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 1272w, https://substackcdn.com/image/fetch/$s_!k41v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0df98727-adf0-400d-ae27-3e6dd3cd5177_1200x1006.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>One memory, three layers</em></figcaption></figure></div><p>The ontology defines what the knowledge graphs look like. All the KG instances are extracted by passing the input data and the ontology schema to an LLM.</p><p>The memory is 3 layers. The long-term layer is the knowledge graph: the POLE+O entities plus <code>preference</code> and <code>fact</code>. A short-term layer holds the dialogue as <code>conversation</code> and <code>session</code> nodes. A reasoning layer records the agent&#8217;s work as <code>agent</code>, <code>tool_call</code>, and <code>memory</code> nodes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iXbI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iXbI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iXbI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png" width="1200" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The ontology as a contract &#8212; data plus the POLE+O ontology go into extraction, and knowledge-graph instances come out.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The ontology as a contract &#8212; data plus the POLE+O ontology go into extraction, and knowledge-graph instances come out." title="The ontology as a contract &#8212; data plus the POLE+O ontology go into extraction, and knowledge-graph instances come out." srcset="https://substackcdn.com/image/fetch/$s_!iXbI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 424w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 848w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 1272w, https://substackcdn.com/image/fetch/$s_!iXbI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F923ca4d3-e1fc-44d4-bdc3-c1fae8391130_1200x630.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The ontology is the contract the extractor reads. The same POLE+O nouns, preferences, and facts on the left; the graph they produce on the right.</em></figcaption></figure></div><p>One powerful ontology design is based on the 5 POLE+O nouns from law-enforcement analysis: Person, Object, Location, Event, Organization, which Neo4j Labs writes up as the <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">POLE+O data model</a>. Each noun carries an optional subtype used to further refine the ontology within a specific domain. For gaming, this can look like:</p><ul><li><p>Person: Player, Character</p></li><li><p>Object: Item, Quest</p></li><li><p>Event: Raid, Battle</p></li></ul><p>Because the agent memory is often used for a personal assistant, you also need to plug <code>preference</code> and <code>fact</code> nodes into the ontology. A <strong>fact</strong> is an atomic subject-predicate-object triplet, an island no edge may touch, reachable only by similarity. A <strong>preference</strong> is the personalization layer with typed slots.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">nodes: person &#183; organization &#183; location &#183; event &#183; object
       preference &#183; fact
edges: related_to, with semantic_type &#8712; {
         knows, member_of, employed_by,
         owns, uses, located_at, resides_at,
         alias_of, has_task, ... 
       }</code></pre></div><p>Now, on top of the KG instances extracted by the LLM, we can also have structured nodes that are directly inferred via code.</p><p>Such as:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">nodes: document &#183; chunk
edges: part_of &#183; next &#183; mentions &#183; referenced &#183; has &#183; same_as &#183; superseded_by</code></pre></div><p>There is a lot more to talk about ontologies. I have a <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">full article</a> just on this.</p><p>With the contract fixed, let&#8217;s see how we can ingest KG objects into the unified memory based on the ontology schema.</p><h2>The Write Path</h2><p>There are 7 stages in one direction. Chunk the document (512-token chunks, 64 overlap). Extract nodes and edges with an LLM. Validate. Resolve names. Embed. Deduplicate. Upsert into the MongoDB unified memory.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vN7D!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vN7D!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 424w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 848w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 1272w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vN7D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png" width="1200" height="1009" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1009,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The extraction pipeline feeding the per-entity normalization algorithm &#8212; resolution, then deduplication, with the score thresholds that govern each.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The extraction pipeline feeding the per-entity normalization algorithm &#8212; resolution, then deduplication, with the score thresholds that govern each." title="The extraction pipeline feeding the per-entity normalization algorithm &#8212; resolution, then deduplication, with the score thresholds that govern each." srcset="https://substackcdn.com/image/fetch/$s_!vN7D!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 424w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 848w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 1272w, https://substackcdn.com/image/fetch/$s_!vN7D!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6298cf69-c546-42e4-8702-f0f5347ddf9b_1200x1009.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The write path. Deduplication &#8212; the &#8805;0.95 merge / &#8805;0.85 flag / else new-node branch</em></figcaption></figure></div><p>During the LLM extraction, we pass in a chunk and we receive a JSON response with nodes and edges, the same shape Neo4j Labs lands on in <a href="https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/">How Entity Extraction Works</a>.</p><p>The model sees one chunk and nothing else. It receives no IDs and no prior state. It returns JSON. Every edge endpoint points to a node&#8217;s <code>name</code> in the same record. This allows us to scale the extraction pipeline through batching to process large documents of 1,000,000+ units.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Qssu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Qssu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 424w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 848w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 1272w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Qssu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png" width="1456" height="1398" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1398,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!Qssu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 424w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 848w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 1272w, https://substackcdn.com/image/fetch/$s_!Qssu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf5826f4-ab01-4d78-b2a8-8e562f1e38fe_2120x2035.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Validation is done via Pydantic. We load the JSON response into a Pydantic model and validate it against the schema.</p><p>Name resolution only checks whether two canonical names match. It&#8217;s done purely on the name and its aliases: alias, exact, fuzzy 0.85, semantic 0.80, filtered by type.</p><p>But there is a next step, where we actually check if an entity is the same instance as another that already exists in the graph.</p><p>Deduplication runs on embeddings computed on the whole node content: &#8805;0.95 cosine merges, &#8804;0.85 makes a new node, and the gap writes a <code>same_as</code> edge for a human to judge.</p><p>So why two steps?</p><p>Name resolution simply helps us group entities by their canonical name. For example, &#8220;Demis Hassabis&#8221; and &#8220;Demis Hassabis, CEO&#8221; would both be resolved to &#8220;Demis Hassabis&#8221;. Or &#8220;Apple&#8221; and &#8220;Apple Inc.&#8221; would both be resolved to &#8220;Apple&#8221;. Super powerful for analytics and human curation.</p><p>Deduplication is the sensitive one &#8212; it decides what actually merges. It shouldn&#8217;t flag &#8220;Apple&#8221; and &#8220;Apple Inc.&#8221; as duplicates, as they are different entities with different meanings.</p><p>A wrong merge is the only unrecoverable mistake. That&#8217;s why, when the similarity score has low confidence, between 0.85 and 0.95, we don&#8217;t merge the nodes automatically, as the operation can be irreversible.</p><p>I break the full algorithm down in <a href="https://www.decodingai.com/p/keep-knowledge-graph-clean">Keep Your Knowledge Graph Clean</a>.</p><p>Which leaves the question that decides your RAM bill: once the triplets are extracted, how do we store them in the unified memory?</p><h2>Append-Only Logs vs. a Single Knowledge Graph Collection</h2><p>There are 3 designs, and the winner? Well... It depends... As always.</p><p>An <strong>append-only log plus a materialized view</strong> buys versioning and soft-delete for free, but you pay for it. <strong>Nested relationships</strong> duplicate edges and make them awkward to query. <strong>Separate edge docs</strong> give queryable edges, no duplication, and the cheapest footprint, at the cost of built-in temporal history and versioning.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pc0N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pc0N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 424w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 848w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 1272w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pc0N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png" width="1200" height="934" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:934,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Three ways to store the same graph in MongoDB, and what each one costs you.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Three ways to store the same graph in MongoDB, and what each one costs you." title="Three ways to store the same graph in MongoDB, and what each one costs you." srcset="https://substackcdn.com/image/fetch/$s_!pc0N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 424w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 848w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 1272w, https://substackcdn.com/image/fetch/$s_!pc0N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab164d43-00b7-4a1c-83cb-8457cb5cf35d_1200x934.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Append-only log, nested relationships, or edges as first-class documents.</em></figcaption></figure></div><p>Because the graph is a projection of the append-only log, a bad extraction is fixed by invalidating its event. You can change the materialization logic and replay it without re-extracting a single source. Also, full-graph temporality belongs to the log alone.</p><p>The log&#8217;s real cost: a vector index is at least as large as the data it covers. Indexing both the log and the view inflates ~10 GB of data toward ~40 GB of RAM. Index only the view, leave the log cold on disk, and it collapses back toward ~10 GB. But the idea is that adding an append-only log brings a lot of engineering effort you then have to maintain.</p><p>So think three times before you sign up for it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2XrE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2XrE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 424w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 848w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 1272w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2XrE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png" width="1200" height="1031" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1031,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The two data models behind the log design &#8212; the append-only immutable log and the materialized view it projects into.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The two data models behind the log design &#8212; the append-only immutable log and the materialized view it projects into." title="The two data models behind the log design &#8212; the append-only immutable log and the materialized view it projects into." srcset="https://substackcdn.com/image/fetch/$s_!2XrE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 424w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 848w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 1272w, https://substackcdn.com/image/fetch/$s_!2XrE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F98a7e08c-bd36-4811-9dc2-446e780ace5f_1200x1031.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The view is a projection of the log &#8212; dedup is one aggregation that squashes events by entity ID (an early run: 244 log entries &#8594; 70 nodes + 104 edges). Roadmap, not shipped; the build writes separate edge docs instead.</em></figcaption></figure></div><p>At query time, the agents see the materialized view, not the log itself. Given the RAM cost, reach for the log only when versioning or the time dimension is core to your business logic. Otherwise, keep it simple and stick to a single knowledge graph collection.</p><p>Within the data model, Node IDs are <code>{user_id}:{type}:{name}</code>. Edge IDs are <code>{source}|{type}|{target}</code>. Because the key is content-derived, every write is idempotent.</p><p>The reality? You can get temporality even without a dedicated append-only log. Preferences and facts carry <code>valid_from</code> / <code>valid_until</code>, and a superseding preference writes a <code>superseded_by</code> edge.</p><h2>Three Ways to Read the Memory</h2><p>The 3 retrieval methods below are the serving layer&#8217;s search primitives, the tools the MCP server exposes to the agent.</p><p><strong>Graph search</strong> is the default retrieval, baked into a single function. It runs <code>$vectorSearch</code> and <code>$text</code> in parallel over the KG collection. Fuse the <em>ranks</em> with <a href="https://cormack.uwaterloo.ca/cormacksigir09-rrf.pdf">Reciprocal Rank Fusion (RRF)</a>. Keep the fused top 10 as seed nodes, then expand with a bidirectional <code>$graphLookup</code> at 2 hops by default. That multi-hop step is the entire difference between RAG and GraphRAG.</p><p><strong>Deep search</strong> widens the walk to 3 hops and persists the result to disk as a memory wiki the agent can access via progressive disclosure. The LLM wiki is a mini-graph of its own: you keep the (entity, relationship, entity) triplets by cross-referencing files, where each file is an entity. You can see it as a local cache that is either discarded between sessions or kept in sync with the KG collection.</p><p><strong>NL query</strong> is agentic search that lets the LLM write its own MongoDB queries based on the ontology. Here you have to validate that the query is syntactically correct, and especially guard it against harmful intents such as deleting or modifying data. It&#8217;s safer to use this mode purely for read operations.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LJc3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LJc3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 424w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 848w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LJc3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png" width="1245" height="1036" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1036,&quot;width&quot;:1245,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The three retrieval methods &#8212; graph search, deep search, and NL query &#8212; plugged into the agent through the MCP server.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The three retrieval methods &#8212; graph search, deep search, and NL query &#8212; plugged into the agent through the MCP server." title="The three retrieval methods &#8212; graph search, deep search, and NL query &#8212; plugged into the agent through the MCP server." srcset="https://substackcdn.com/image/fetch/$s_!LJc3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 424w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 848w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!LJc3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cf6f9b0-9519-4135-b923-c88bd051390d_1245x1036.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Three ways in: graph search fuses then walks one hop; deep search walks three hops and writes a wiki; NL query lets the LLM author the aggregation against the ontology.</em></figcaption></figure></div><p>RRF replaces a reranker (a second model that re-scores the retriever&#8217;s top candidates) you don&#8217;t need yet. It is 20 lines of Python, needs no model, and runs in microseconds. Reach for a cross-encoder (a heavier model that compares the query against each candidate) when you search millions of heterogeneous documents.</p><p><strong>When do you need to switch from a single database (MongoDB) to a graph database (Neo4j)?</strong> Past 4 hops, past ~100M to 1B vectors, when graphs <em>are</em> your business logic, or purely to visualize them: that is where you leave MongoDB for Neo4j. It&#8217;s common to use a single database in production (MongoDB) and a graph database as an internal tool for data exploration and analysis (Neo4j). This is a powerful combo, because for an internal tool you don&#8217;t care that much about 99.99% SLAs, while you can fully leverage Neo4j&#8217;s Cypher query language to explore and analyze your graph data.</p><h2>Open, Closed, and Small</h2><p>Extraction (from ingestion) and query translation (from agentic search) use <code>gemini-3.1-flash-lite</code>. Embeddings are Voyage <code>voyage-3.5</code> at 1024 dimensions. Both are closed APIs.</p><p>You can take this further and fine-tune an open-source SLM (such as the Liquid family of models) as an extractor, query translator, or embedding model on your own data.</p><p>The issue with SLMs is that without fine-tuning they perform poorly on new data. But the beautiful part about them is that after fine-tuning they perform as well as a frontier model on a scoped task, while being much cheaper and faster to run.</p><p>I won&#8217;t go too much into fine-tuning here, but the idea is that at first you always want to start with an API that quickly gets stuff done, and then slowly replace the most important parts with your own fine-tuned models. You usually have to decide this based on cost, latency, performance, data privacy, or other dimensions important to your use case.</p><h2>Build vs Buy: When Not To Build This</h2><p>Everything above assumed you build everything yourself. But in reality, there are 3 levels to choose from.</p><p><strong>Level 1:</strong> build the memory, the logic, and the serving layer yourself on one database.</p><p><strong>Level 2:</strong> keep only the business logic and serving layer on top of a memory SDK, such as <a href="https://github.com/getzep/graphiti">Graphiti</a>, <code>neo4j-labs/agent-memory</code>, or <a href="https://github.com/mem0ai/mem0">mem0</a>.</p><p><strong>Level 3:</strong> run an off-the-shelf engine, such as <a href="https://github.com/topoteretes/cognee">cognee</a>, managed <a href="https://www.getzep.com/">Zep</a>, or <a href="https://hydradb.com/">HydraDB</a>.</p><p>This is a problem about owning your context layer, which I have a <a href="https://www.decodingai.com/p/the-context-layer">full article</a> on.</p><p>Buy when you don&#8217;t care that much about customization. Build when you want <em>your</em> own solution. But since building everything yourself usually isn&#8217;t worth it (or you just don&#8217;t have the time to do it &#8212; even with Claude Code), the best solution is <strong>Level 2</strong>, where you own the business logic and can customize the serving layer to your needs.</p><p>But honestly, because things move so fast and I am lazy, my long-term memory still lives in Obsidian, Readwise, and Google Drive, plus a serving layer that creates scoped LLM wikis per project as agent memory. This way, you create mini-graphs for one specific problem, powered purely by .md files, without any infrastructure hassle. The reality is that this works for personal use only, and not so much for shipping a production-ready solution. I write about that approach in <a href="https://www.decodingai.com/p/llm-wiki-agent-memory">LLM Wikis as Agent Memory</a>.</p><p>Still, I am applying the strategy based on KGs and ontologies to build <strong>Pulse</strong>, a data mining tool that runs the exact same strategy presented above on a knowledge-work ontology to extract the top 0.1% signal from the AI industry. I want it custom because I want it to be super light, powered by LadybugDB, and to leverage my Claude subscription for the extraction and deduplication part, built as a hybrid between skills and Python modules.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>If you keep dumping everything into the unified memory, where do you draw the line between what your agent should remember forever and what it should be allowed to forget?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/how-to-implement-a-unified-memory-from-scratch?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <a href="https://www.mongodb.com/">MongoDB</a> for sponsoring this article and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://www.mongodb.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48258,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:&quot;https://www.mongodb.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/203854945?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Explore Next</h2><ol><li><p>Iusztin, P. (n.d.). Own Your Context Layer: Portable AI Agent Memory. Decoding AI. <a href="https://www.decodingai.com/p/the-context-layer">https://www.decodingai.com/p/the-context-layer</a></p></li><li><p>Iusztin, P. (n.d.). Ship a Knowledge Graph Ontology in 5 Minutes. Decoding AI. <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes</a></p></li><li><p>Iusztin, P. (n.d.). How to Keep Your AI Agent&#8217;s Knowledge Graph Clean. Decoding AI. <a href="https://www.decodingai.com/p/keep-knowledge-graph-clean">https://www.decodingai.com/p/keep-knowledge-graph-clean</a></p></li><li><p>Iusztin, P. (n.d.). LLM Wikis as Living Memory for AI Agents. Decoding AI. <a href="https://www.decodingai.com/p/llm-wiki-agent-memory">https://www.decodingai.com/p/llm-wiki-agent-memory</a></p></li><li><p>Neo4j Labs. (n.d.). Why Neo4j? Graph-Native Memory Architecture. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">https://neo4j.com/labs/agent-memory/explanation/graph-architecture/</a></p></li><li><p>Neo4j Labs. (n.d.). POLE+O Data Model. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">https://neo4j.com/labs/agent-memory/explanation/poleo-model/</a></p></li><li><p>Neo4j Labs. (n.d.). How Entity Extraction Works. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/">https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Your Second Brain Is a Graveyard. Make It Agent Memory.]]></title><description><![CDATA[Turn dead notes into a living LLM wiki your AI agents can query, maintain, and grow]]></description><link>https://www.decodingai.com/p/llm-wiki-agent-memory</link><guid isPermaLink="false">https://www.decodingai.com/p/llm-wiki-agent-memory</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 07 Jul 2026 05:01:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qTKJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qTKJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qTKJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qTKJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Ten thousand notes sit in the dark. The handful you need light up and come to you.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Ten thousand notes sit in the dark. The handful you need light up and come to you." title="Ten thousand notes sit in the dark. The handful you need light up and come to you." srcset="https://substackcdn.com/image/fetch/$s_!qTKJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!qTKJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc983d19b-d99e-442f-9a41-3418aea2dc4c_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I spent 18 months turning my second brain into my living research memory. My digital life contains 10,994 notes: over 5,000 in Obsidian, another 5,000 in Readwise, plus more in Notion and Google Drive, growing by roughly 250 a month.</p><p>The reality is that most of my notes and bookmarks transformed into a graveyard. When I start a new article or open a codebase, I can&#8217;t recall the high-signal notes I already have, so I work without them or burn an hour digging.</p><p>The reflex is to reach for Codex or NotebookLM. But those are harnesses: they sit on top of your work, and the moment the chat ends, the context window loses all of it.</p><p>More context isn&#8217;t the fix. You re-paste the same links and re-explain the same project every session, while past research sits inert in a vault your agents can&#8217;t reach.</p><p>So <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Louis-Fran&#231;ois Bouchard&quot;,&quot;id&quot;:130571458,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!f-b9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c5d976-f699-4595-8b6d-6ffa3e42a5e5_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;e78edcc8-a889-48fd-81a9-fefde2398454&quot;}" data-component-name="MentionToDOM"></span>, CTO of Towards AI, and I built the alternative, and we&#8217;ll show you how: your own <strong>AI Research OS</strong>. It&#8217;s a memory layer that sits <em>between</em> your second brain and any harness (Codex, Claude Code, or your own). It runs deep research across your notes and the open web, and stores what it finds as an LLM wiki you can query, maintain, and grow.</p><p>We first touched on this subject in a talk at the AI Engineer World&#8217;s Fair. After we saw that people loved it (it was published as a keynote in the online tracks - out of 82 videos - and is the 2nd most popular one), I decided to write an article about it as well.</p><p>By the end you&#8217;ll learn how to turn your 10,994 notes into a queryable LLM wiki that your AI agents can use as their agent memory, useful for research, coding and content creation.</p><p>You will build an LLM wiki as in the image below, where the payoff already compounds with just 12 sources:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LflI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LflI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 424w, https://substackcdn.com/image/fetch/$s_!LflI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 848w, https://substackcdn.com/image/fetch/$s_!LflI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 1272w, https://substackcdn.com/image/fetch/$s_!LflI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LflI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png" width="1456" height="772" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/de064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:772,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The payoff up front: a queryable wiki combining repos, personal notes, and web sources into one graph. Just 12 sources, and the memory already earns its keep.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The payoff up front: a queryable wiki combining repos, personal notes, and web sources into one graph. Just 12 sources, and the memory already earns its keep." title="The payoff up front: a queryable wiki combining repos, personal notes, and web sources into one graph. Just 12 sources, and the memory already earns its keep." srcset="https://substackcdn.com/image/fetch/$s_!LflI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 424w, https://substackcdn.com/image/fetch/$s_!LflI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 848w, https://substackcdn.com/image/fetch/$s_!LflI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 1272w, https://substackcdn.com/image/fetch/$s_!LflI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fde064b5c-a1fd-4f12-a210-84b70ef625c1_1614x856.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Or go crazier with a larger wiki:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!USVl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!USVl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 424w, https://substackcdn.com/image/fetch/$s_!USVl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 848w, https://substackcdn.com/image/fetch/$s_!USVl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 1272w, https://substackcdn.com/image/fetch/$s_!USVl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!USVl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png" width="1456" height="823" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:823,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A bigger project wiki of ~100 notes, distilled into 73 concepts and 18 entities, that still draws on a 10,000+ note second brain. Why it stays this small and this cheap comes together by the end.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A bigger project wiki of ~100 notes, distilled into 73 concepts and 18 entities, that still draws on a 10,000+ note second brain. Why it stays this small and this cheap comes together by the end." title="A bigger project wiki of ~100 notes, distilled into 73 concepts and 18 entities, that still draws on a 10,000+ note second brain. Why it stays this small and this cheap comes together by the end." srcset="https://substackcdn.com/image/fetch/$s_!USVl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 424w, https://substackcdn.com/image/fetch/$s_!USVl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 848w, https://substackcdn.com/image/fetch/$s_!USVl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 1272w, https://substackcdn.com/image/fetch/$s_!USVl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f1500bb-8910-4222-a8c1-0d396fa71d3c_1602x906.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By the end, you will also see why the wikis don&#8217;t contain all my 10,994 notes to keep ingestion costs low. Let&#8217;s go.</p><div class="callout-block" data-callout="true"><h2>Want your AI work featured across three platforms?</h2><p>I'm looking for one builder to co-create a customer story on how you used Opik to solve a real-world problem in your AI product.</p><p>Here's what you get: from a 1-hour interview where you show off what you built, I'll produce a <strong>co-authored article, a YouTube video, and a run of social posts</strong>, all spotlighting your work. Distributed across both Decoding AI and Opik (by Comet) channels to 200,000+ AI engineers and decision-makers.</p><p>Here are the last two:</p><ul><li><p><a href="https://www.decodingai.com/p/how-evaluation-driven-development-works">How Evaluation-Driven Development (EDD) Works</a></p></li><li><p><a href="https://www.decodingai.com/p/ship-rag-with-weave-cli">What Held Up at 3 AM: One Engineer&#8217;s RAG Case Study</a></p></li></ul><p>If you want to collaborate, email me at <em>pauliusztin@decodingai.com</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;mailto:pauliusztin@decodingai.com?subject=Opik%20Customer%20Story%20Collaboration&quot;,&quot;text&quot;:&quot;Email me&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="mailto:pauliusztin@decodingai.com?subject=Opik%20Customer%20Story%20Collaboration"><span>Email me</span></a></p><p><em>Fine print:</em> your product or project must use Opik. This is a collaboration between Decoding AI and Opik (by Comet). </p></div><h2>Why a Bigger Context Window Won&#8217;t Save You</h2><p>Most research doesn&#8217;t need this system. If you want a quick answer or a one-off, Google it, or reach for Codex and Claude Code. You need this only when the research has to <em>stick</em> and an agent has to reuse those sources later.</p><p>You don&#8217;t need a giant vault either. This is about topic density, not size. It already pays off on a topic-sized cluster: around 20 notes on one subject, or 2 or 3 repos, like coding agents such as Pi, OpenCode, and Aider. Louis-Fran&#231;ois runs it on a few hundred notes, not my 10,000+, and it still earns its keep.</p><p>Why not NotebookLM? It&#8217;s great at digesting sources, but you don&#8217;t own it, you can&#8217;t personalize it deeply, it isn&#8217;t agent-native, and it&#8217;s weak for coding since it&#8217;s browser-bound.</p><p>Why not a vector-database RAG pipeline? That&#8217;s the right call at production scale, but it&#8217;s infrastructure. It&#8217;s hard to inspect or edit by hand, and overkill for a personal tool you open every day.</p><p>So you build it yourself: a personalized research assistant that uses an LLM wiki knowledge base that&#8217;s light and human-friendly as its agent memory. The perfect context engineering technique as an interface between the human and the AI agent.</p><p>Now, I want to go over, step by step, how we reached our final deep research + LLM wiki design, with the &#8220;why&#8221; and &#8220;how&#8221; in mind.</p><h2>The Deep-Research Loop, Version 1: Mining the Public Web</h2><p>A year ago, building the Agent Engineering course, we scoped the loop tightly: give it a topic plus a few hand-picked <strong>golden links</strong>, and get back a single static <code>research.md</code>.</p><p>The deep research algorithm first scrapes the golden links for seed context. Knowing them up front lets the agent frame better questions. Then it runs query rounds: one <strong>orchestrator</strong> generates the questions, and a <strong>sub-agent per question</strong> searches (Gemini grounded in Google) and returns links plus a summary, which the orchestrator aggregates so the context never explodes.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FbGR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FbGR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 424w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 848w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 1272w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FbGR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png" width="1456" height="443" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:443,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Version 1 in one line: topic + golden links &#8594; deep-research algorithm &#8594; one static research.md.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Version 1 in one line: topic + golden links &#8594; deep-research algorithm &#8594; one static research.md." title="Version 1 in one line: topic + golden links &#8594; deep-research algorithm &#8594; one static research.md." srcset="https://substackcdn.com/image/fetch/$s_!FbGR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 424w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 848w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 1272w, https://substackcdn.com/image/fetch/$s_!FbGR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a02e318-e3d9-43f6-a2a5-7429e48b19c0_2400x731.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Version 1 in one line: topic + golden links &#8594; deep-research algorithm &#8594; one static research.md.</em></figcaption></figure></div><p>Three rounds of 6 queries surface 40&#8211;50 links, which is too noisy to keep whole. A <strong>ranking</strong> step scores each source against the topic. Only the top-K get fully scraped, the rest are kept as summaries, and everything is compiled into one flat <code>research.md</code>. That version generated 35 course lessons fast.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y6mp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y6mp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 424w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 848w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 1272w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y6mp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png" width="1456" height="581" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:581,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The deep-research algorithm unpacked: orchestrator, six sub-agents per round, three rounds, ranking, then top-K full scrapes into research.md.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The deep-research algorithm unpacked: orchestrator, six sub-agents per round, three rounds, ranking, then top-K full scrapes into research.md." title="The deep-research algorithm unpacked: orchestrator, six sub-agents per round, three rounds, ranking, then top-K full scrapes into research.md." srcset="https://substackcdn.com/image/fetch/$s_!Y6mp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 424w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 848w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 1272w, https://substackcdn.com/image/fetch/$s_!Y6mp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F792be5b5-ea26-4bfb-829d-d861596cb62f_2400x957.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The deep-research algorithm unpacked: orchestrator, six sub-agents per round, three rounds, ranking, then top-K full scrapes into research.md.</em></figcaption></figure></div><p>It worked for the course, but it was aimed at the generic public web, with every golden link hand-picked from our own second brain.</p><h2>Version 2: Point the Loop at Your Second Brain</h2><p>Same loop, new target: aim it at your own sources instead of the public web, where you&#8217;ve already filtered what matters. Your second brain <em>is</em> a curated set of golden links, so the input shrinks to just a topic and the loop finds the rest.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!txf7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!txf7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 424w, https://substackcdn.com/image/fetch/$s_!txf7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 848w, https://substackcdn.com/image/fetch/$s_!txf7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 1272w, https://substackcdn.com/image/fetch/$s_!txf7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!txf7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png" width="1456" height="530" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Version 2's core move: take the same loop and aim it at your own sources instead of the open web.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Version 2's core move: take the same loop and aim it at your own sources instead of the open web." title="Version 2's core move: take the same loop and aim it at your own sources instead of the open web." srcset="https://substackcdn.com/image/fetch/$s_!txf7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 424w, https://substackcdn.com/image/fetch/$s_!txf7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 848w, https://substackcdn.com/image/fetch/$s_!txf7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 1272w, https://substackcdn.com/image/fetch/$s_!txf7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6dce886a-e409-47a9-aba5-cff5a95bc51c_2400x873.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Version 2&#8217;s core move: take the same loop and aim it at your own sources instead of the open web.</em></figcaption></figure></div><p>You plug in Obsidian, Readwise, NotebookLM, and GitHub Stars, then extend with Gemini Deep Research, YouTube, Google Drive, or Notion. Code is a special case: a GitHub sub-agent clones a repo and builds a high-level architecture note.</p><p>The token-efficiency trick lives in the reranker. It scores each candidate from 0 to 1 against your question using only its metadata and summary, never the full text, then passes only the top-K to the model.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1AwG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1AwG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 424w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 848w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 1272w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1AwG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png" width="1456" height="489" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:489,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The loop over your own sources: topic-only input, personal sources plugged in, same rank-and-scrape tail.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The loop over your own sources: topic-only input, personal sources plugged in, same rank-and-scrape tail." title="The loop over your own sources: topic-only input, personal sources plugged in, same rank-and-scrape tail." srcset="https://substackcdn.com/image/fetch/$s_!1AwG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 424w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 848w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 1272w, https://substackcdn.com/image/fetch/$s_!1AwG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe6164947-9d0d-4ed7-82a3-022984668b97_2400x806.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The loop over your own sources: topic-only input, personal sources plugged in, same rank-and-scrape tail.</em></figcaption></figure></div><p>The new problem is that the output is frozen. You still end up with a static <code>research.md</code>, and real research isn&#8217;t static. You want another question answered, or part of it goes stale, and re-running the loop from scratch is expensive in tokens and time. The fix is a new layer that sits on top of the raw data: the LLM wiki.</p><h2>Version 3: From a Static Pile to a Living Wiki</h2><p>The pivot came from Andrej Karpathy&#8217;s idea of <strong>LLM-maintained knowledge-base wikis</strong> <a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f">[1]</a>. Instead of re-deriving knowledge from raw documents on every query, which is the RAG pattern, the LLM incrementally builds and maintains a persistent, interlinked wiki between you and your sources.</p><p><strong>Since I realized the power of LLM wikis, I started to use them for all my personal setups as my agent memory. It&#8217;s simple, powerful and beautiful.</strong></p><p>Since giving this talk, we found that Google had published its <strong><a href="https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing">Open Knowledge Format (OKF)</a></strong>, an open spec that &#8220;formalizes the LLM-wiki pattern into a portable, interoperable format&#8221; <a href="https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing">[2]</a>. It&#8217;s built on the very blocks you&#8217;ll see below: plain markdown with YAML frontmatter, an index, a log, and links that form a graph. When Google independently ships the same architecture as a standard, you know the direction is right.</p><p>During ingestion it generates, as a byproduct, derivatives over your raw sources: entities and concepts, comparisons between them, notes tied to your questions, open questions, and a synthesis:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qxOx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qxOx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 424w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 848w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 1272w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qxOx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png" width="1456" height="1486" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1486,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!qxOx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 424w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 848w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 1272w, https://substackcdn.com/image/fetch/$s_!qxOx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffe7b23f3-fd42-4087-87b1-d17f4562fe68_2120x2163.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Storing each finding as an individual raw file, instead of one flat <code>research.md</code>, is the one change that makes everything downstream queryable and growable. Sources can include Obsidian, GitHub, Google Drive, even custom URLs (plain curl for simple sites, Bright Data for bot-walled ones).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K5GT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K5GT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 424w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 848w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 1272w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K5GT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png" width="1456" height="497" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/30565fb3-2384-4103-aa3a-172461647681_2400x820.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:497,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Sources &#8594; deep research &#8594; store raw files &#8594; index &#8594; generate wiki &#8594; query. The version-3 pipeline end to end.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Sources &#8594; deep research &#8594; store raw files &#8594; index &#8594; generate wiki &#8594; query. The version-3 pipeline end to end." title="Sources &#8594; deep research &#8594; store raw files &#8594; index &#8594; generate wiki &#8594; query. The version-3 pipeline end to end." srcset="https://substackcdn.com/image/fetch/$s_!K5GT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 424w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 848w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 1272w, https://substackcdn.com/image/fetch/$s_!K5GT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F30565fb3-2384-4103-aa3a-172461647681_2400x820.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Sources &#8594; deep research &#8594; store raw files &#8594; index &#8594; generate wiki &#8594; query. The version-3 pipeline end to end.</em></figcaption></figure></div><p>The natural fear is that &#8220;index + wiki + query&#8221; means vector databases and knowledge graphs. It doesn&#8217;t, and that&#8217;s the surprising part.</p><h2>A Memory Layer Built From Plain Files and No Database</h2><p>Vector databases, knowledge graphs, and semantic and text search all add real complexity, too much for a personal research OS. So drop that infrastructure and build the whole thing on files and references: no database, just a simple index rooted in how your filesystem already works.</p><p>The index is the retrieval layer. An agent reads a single <code>index.yaml</code> first, a catalog with a summary and metadata for each source (original file, origin, title, authors, date).</p><p>There are 3 layers. A <code>raw</code> folder holds the immutable source data, a <code>wiki</code> folder holds the LLM-generated derivatives, and the <code>index</code> points to all of it. A real example is an <code>index.yaml</code> cataloging 10 sources and 38 wiki pages.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OJ0b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OJ0b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 424w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 848w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 1272w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OJ0b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png" width="1456" height="387" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:387,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!OJ0b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 424w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 848w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 1272w, https://substackcdn.com/image/fetch/$s_!OJ0b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76c82d98-b000-496f-a6fa-8f1f93bb0da1_2120x563.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xLVZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xLVZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 424w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 848w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 1272w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xLVZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png" width="1456" height="673" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:673,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The index is the retrieval layer: one YAML catalog the agent reads first, pointing to everything else.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The index is the retrieval layer: one YAML catalog the agent reads first, pointing to everything else." title="The index is the retrieval layer: one YAML catalog the agent reads first, pointing to everything else." srcset="https://substackcdn.com/image/fetch/$s_!xLVZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 424w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 848w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 1272w, https://substackcdn.com/image/fetch/$s_!xLVZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdad1e1cc-58c1-4df9-bc93-93a94480e689_2400x1110.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The index is the retrieval layer: one YAML catalog the agent reads first, pointing to everything else.</em></figcaption></figure></div><p>You even get a knowledge graph for free. Because everything is Obsidian-flavored markdown with references, Obsidian&#8217;s local graph renders the connections out of the box: entities like OpenCode or MCP linked to concepts like tool registry, context compaction, and sandboxing, and the sources they touch.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jvI7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jvI7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 424w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 848w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 1272w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jvI7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png" width="1456" height="1242" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1242,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;claude code entity&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="claude code entity" title="claude code entity" srcset="https://substackcdn.com/image/fetch/$s_!jvI7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 424w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 848w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 1272w, https://substackcdn.com/image/fetch/$s_!jvI7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5d11c98e-271b-41b5-a728-adc37e38024e_2112x1802.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Obsidian is only a viewer, though. The whole system runs from any working directory through Codex or Claude Code, so the graph is a bonus on top.</p><h2>Querying the Wiki, and Why It Never Freezes</h2><p>The agent queries through progressive disclosure. It starts at the <code>index.yaml</code> summaries. If it needs more, it opens the <strong>source wiki page</strong> (an expanded summary), and often stops there.</p><p>If not, it follows references into the <strong>derivatives</strong> (entities, concepts, comparisons, notes). Only as a last resort does it read the <strong>raw source</strong>. Summaries are computed once, at ingestion, so the context window stays small.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y3Kw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 424w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 848w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png" width="1456" height="703" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:703,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The query drill-down: each level answers most questions, so the agent rarely touches raw sources and context stays small.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The query drill-down: each level answers most questions, so the agent rarely touches raw sources and context stays small." title="The query drill-down: each level answers most questions, so the agent rarely touches raw sources and context stays small." srcset="https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 424w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 848w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 1272w, https://substackcdn.com/image/fetch/$s_!Y3Kw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd45a4434-b833-4be1-be5c-cd3fd702c2ac_2400x1158.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The query drill-down: each level answers most questions, so the agent rarely touches raw sources and context stays small.</em></figcaption></figure></div><p>The wiki is also alive. Ask a question and the LLM can spawn a new concept, note, or comparison, and each question is written to a log. So the wiki evolves as you <em>talk</em> to it, not only when you ingest data.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DbRB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DbRB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 424w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 848w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 1272w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DbRB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png" width="1456" height="484" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:484,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Every question leaves a trace: new notes and comparisons accrete, and the log tracks the whole history.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Every question leaves a trace: new notes and comparisons accrete, and the log tracks the whole history." title="Every question leaves a trace: new notes and comparisons accrete, and the log tracks the whole history." srcset="https://substackcdn.com/image/fetch/$s_!DbRB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 424w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 848w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 1272w, https://substackcdn.com/image/fetch/$s_!DbRB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd62a4de4-10b1-452f-b73c-0fbd9ee2ddef_2400x798.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Every question leaves a trace: new notes and comparisons accrete, and the log tracks the whole history.</em></figcaption></figure></div><p>It&#8217;s never frozen, and it grows 3 ways: ingest a new custom link, run another deep-research round, or let it create derivatives purely from your questions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QyOU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QyOU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 424w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 848w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 1272w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QyOU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png" width="1456" height="859" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:859,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The wiki grows three ways: new links, new research rounds, and new derivatives born from your questions.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The wiki grows three ways: new links, new research rounds, and new derivatives born from your questions." title="The wiki grows three ways: new links, new research rounds, and new derivatives born from your questions." srcset="https://substackcdn.com/image/fetch/$s_!QyOU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 424w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 848w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 1272w, https://substackcdn.com/image/fetch/$s_!QyOU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dc23955-1cf8-4cc0-ad10-47d0539c3249_2400x1416.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The wiki grows three ways: new links, new research rounds, and new derivatives born from your questions.</em></figcaption></figure></div><p>One design choice makes this safe to run against a decade of notes: the wiki never sits directly on your whole second brain.</p><h2>Scope It to a Project With PARA</h2><p>Your second brain stays an immutable snapshot. I organize everything with the <strong>PARA method</strong>: Projects, Areas, Resources, Archive <a href="https://fortelabs.com/blog/para/">[3]</a>. Sources are piped into Resources as a flat list, then referenced into Projects and Areas. So Obsidian stays read-only; I don&#8217;t want the LLM editing notes I write by hand.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Hom-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Hom-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 424w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 848w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Hom-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png" width="1456" height="757" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:757,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;PARA keeps your global second brain an immutable, read-only snapshot the LLM never writes to.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="PARA keeps your global second brain an immutable, read-only snapshot the LLM never writes to." title="PARA keeps your global second brain an immutable, read-only snapshot the LLM never writes to." srcset="https://substackcdn.com/image/fetch/$s_!Hom-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 424w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 848w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 1272w, https://substackcdn.com/image/fetch/$s_!Hom-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9e096d-bde9-4394-8e57-af70ea9b5215_2400x1248.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>PARA keeps your global second brain an immutable, read-only snapshot the LLM never writes to.</em></figcaption></figure></div><p>The wiki is scoped per project, not global. When you start something new, you reference that snapshot <em>through</em> the deep-research loop and scope it down to the project, running the loop or ingesting specific repos, articles, and notes via skills plugged into a harness.</p><p>Scoping is a scale choice as much as a safety one: plain files stay fast and inspectable at project size, but a whole-vault wiki of thousands of documents is exactly where a vector or graph database finally earns its place.</p><p>That&#8217;s the ~100-note wiki from the top, kept small by scoping to one project, yet reaching my entire 10,000+ note second brain through the loop.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j4il!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j4il!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 424w, https://substackcdn.com/image/fetch/$s_!j4il!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 848w, https://substackcdn.com/image/fetch/$s_!j4il!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 1272w, https://substackcdn.com/image/fetch/$s_!j4il!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j4il!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png" width="1456" height="521" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:521,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Scope the snapshot down into a project wiki, then let an agent turn that research into the actual work.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Scope the snapshot down into a project wiki, then let an agent turn that research into the actual work." title="Scope the snapshot down into a project wiki, then let an agent turn that research into the actual work." srcset="https://substackcdn.com/image/fetch/$s_!j4il!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 424w, https://substackcdn.com/image/fetch/$s_!j4il!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 848w, https://substackcdn.com/image/fetch/$s_!j4il!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 1272w, https://substackcdn.com/image/fetch/$s_!j4il!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8fb1f960-b375-4943-8d4d-07f9e637778a_2400x859.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Scope the snapshot down into a project wiki, then let an agent turn that research into the actual work.</em></figcaption></figure></div><p>The mental model is that the project is the work and the second brain is the research. A project is anything where you turn research into work: an article, a video, a set of slides (this talk was built this way), or a whole codebase. That&#8217;s the whole architecture, and the fastest way to see why it matters is to watch it run.</p><h2>See It Run: Three Demos</h2><p>Everything ships as one open-source Claude Code plugin you can clone and run on your own notes (<a href="https://github.com/iusztinpaul/ai-research-os-workshop">https://github.com/iusztinpaul/ai-research-os-workshop</a>), tweakable for any harness.</p><p>It&#8217;s four skills: <code>/research</code> (build or query the wiki), <code>/research-distill</code> (a per-piece <code>research.md</code>), <code>/research-lint</code> (health-checks), and <code>/research-render</code> (slides or a brief).</p><p><strong>Demo 1</strong> is research from a brain dump around &#8220;agentic harnesses&#8221;. You point the research skill at a file of notes plus a few must-include references. It scrapes those for seed context and picks a depth: <strong>fast</strong> (1 round of 3 queries), <strong>light</strong> (2 rounds, 3 then 2), or <strong>deep</strong> (3 rounds of 3). Out come the raw files + the LLM wiki:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m3dw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m3dw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 424w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 848w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 1272w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m3dw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png" width="1456" height="1062" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1062,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Demo 1 output: a topic's worth of research rendered as a live Obsidian graph, the index at its center.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Demo 1 output: a topic's worth of research rendered as a live Obsidian graph, the index at its center." title="Demo 1 output: a topic's worth of research rendered as a live Obsidian graph, the index at its center." srcset="https://substackcdn.com/image/fetch/$s_!m3dw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 424w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 848w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 1272w, https://substackcdn.com/image/fetch/$s_!m3dw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd63cc833-a7f5-45e8-9da0-b04a9609955d_1482x1081.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Demo 2</strong> is ingesting and comparing GitHub repos. You give it 3 harness repos (OpenCode, Pi, Hermes), no deep research, scoped to architecture, sub-agents, memory, and the permission flow. It clones each, writes per-repo notes, then builds cross-repo comparisons.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0gs0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0gs0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 424w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 848w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 1272w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0gs0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png" width="1145" height="822" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:822,&quot;width&quot;:1145,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Demo 2 output: three harnesses ingested straight from code, with the cross-repo comparison notes generated automatically.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Demo 2 output: three harnesses ingested straight from code, with the cross-repo comparison notes generated automatically." title="Demo 2 output: three harnesses ingested straight from code, with the cross-repo comparison notes generated automatically." srcset="https://substackcdn.com/image/fetch/$s_!0gs0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 424w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 848w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 1272w, https://substackcdn.com/image/fetch/$s_!0gs0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F347becea-b19b-45a9-8512-a7d3c7417e3a_1145x822.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Demo 3</strong> is ad-hoc links on GraphRAG, then questions to create notes. You hand it 3 arbitrary links to build a wiki, then ask how agentic GraphRAG differs from a plain knowledge graph. It answers off the wiki <em>and</em> updates it in place.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jzx2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jzx2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 424w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 848w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 1272w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jzx2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png" width="976" height="740" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:740,&quot;width&quot;:976,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Demo 3 output: a wiki built from three raw links that keeps growing as you query it.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Demo 3 output: a wiki built from three raw links that keeps growing as you query it." title="Demo 3 output: a wiki built from three raw links that keeps growing as you query it." srcset="https://substackcdn.com/image/fetch/$s_!Jzx2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 424w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 848w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 1272w, https://substackcdn.com/image/fetch/$s_!Jzx2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F20818c5f-397a-477f-9606-c6c66e2ca1f6_976x740.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It was super hard to show the full demos here. You can find the full examples within the <a href="https://github.com/iusztinpaul/ai-research-os-workshop">Examples</a> section of the repo or watch me go over them in Obsidian and Zed in the <a href="https://www.youtube.com/watch?v=ZRM_TfEZcIo">full video</a>.</p><h2>Where This Is Going</h2><p>Some connectors are missing on purpose (Google Drive, Notion, Slack) &#8212; the point is for <em>you</em> to add what you need. Louis-Fran&#231;ois added YouTube transcript ingestion in seconds with one prompt to Codex.</p><p>Two weaknesses stand out. The byproducts are often poorly written, fixable with the article writing profiles I already use. And as data grows, the LLM makes subtle errors: <strong>concept confusion</strong> (comparing Claude Code and OpenCode, it merged how each handles tool calls into one explanation) and <strong>superficiality</strong> (the Claude Code queuing system took many follow-ups to get right).</p><p>The fix is constant linting, which is what <code>/research-lint</code> does: it sweeps the wiki for orphan sources, broken links, stale claims, and contradictions.</p><h2>What&#8217;s Next</h2><p>Everything you saw here is open source. <strong>Clone the repo</strong> (or install it as a Claude Code plugin) and run it on your own notes today: <a href="https://github.com/iusztinpaul/ai-research-os-workshop">https://github.com/iusztinpaul/ai-research-os-workshop</a></p><p>If you&#8217;d rather see the whole system in action first, watch the full talk <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Louis-Fran&#231;ois Bouchard&quot;,&quot;id&quot;:130571458,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!f-b9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0c5d976-f699-4595-8b6d-6ffa3e42a5e5_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;9c3ede7f-d61e-4f65-a625-08e3bc850048&quot;}" data-component-name="MentionToDOM"></span> and I gave at the <strong>AI Engineer World&#8217;s Fair</strong>:</p><div id="youtube2-ZRM_TfEZcIo" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;ZRM_TfEZcIo&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/ZRM_TfEZcIo?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>And if you want to go beyond a workshop repo, such as <strong>building a deep-research-plus-writing multi-agent system</strong> from <strong>scratch</strong> and <strong>shipping</strong> it to <strong>production</strong> with AI evals and an observability layer on top, that&#8217;s exactly what we teach in our <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems course</a></strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uql0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uql0!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!Uql0!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The multi-agent system built during the <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems course</a></strong></figcaption></figure></div><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/llm-wiki-agent-memory?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/llm-wiki-agent-memory?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Explore Next</h2><ol><li><p>Karpathy, A. (n.d.). LLM Wiki: A pattern for building personal knowledge bases using LLMs. GitHub. <a href="https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f">https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f</a></p></li></ol><ol><li><p>Google Cloud. (n.d.). How the Open Knowledge Format can improve data sharing. Google Cloud Blog. <a href="https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing">https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing</a></p></li><li><p>Forte, T. (n.d.). The PARA Method: The Simple System for Organizing Your Digital Life. Forte Labs. <a href="https://fortelabs.com/blog/para/">https://fortelabs.com/blog/para/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[From Harness Lock-In to Portable Context Layer]]></title><description><![CDATA[Build a unified memory (knowledge graph or an LLM wiki) and serve it over MCP servers or skills, so any agent, open or closed, plugs in within minutes.]]></description><link>https://www.decodingai.com/p/the-context-layer</link><guid isPermaLink="false">https://www.decodingai.com/p/the-context-layer</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 30 Jun 2026 08:20:17 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!k7bK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!k7bK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!k7bK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!k7bK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Your memory is the one thing you carry from one machine to the next.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Your memory is the one thing you carry from one machine to the next." title="Your memory is the one thing you carry from one machine to the next." srcset="https://substackcdn.com/image/fetch/$s_!k7bK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!k7bK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34e5ac29-e4cc-447f-b4c5-b25cefcce8b2_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Models are commoditizing fast. Harnesses already have. What you care about is your research, your notes, your conversations, your tasks, your preferences, and your domain knowledge.</p><blockquote><p>&#8220;Free&#8221; open-source harnesses don&#8217;t make you free. What you want to own is the <em>context layer</em>. Every agent is the same model + runtime + harness underneath, rebuildable on an open stack <a href="https://youtube.com/watch?v=BEYEWw1Mkmw">[1]</a>.</p></blockquote><p>I hit this myself. The deeper I built into a single harness, the clearer it got how much I&#8217;d lose the day I had to leave. The loss comes in 3 forms.</p><p><strong>Failure 1 &#8212; You start from scratch.</strong> You&#8217;ve run Claude Code for 6 months. You switch to an open model and every past conversation, every preference the agent learned about you, is gone. You begin again from zero.</p><p><strong>Failure 2 &#8212; Your skills are hostage.</strong> The harder lock-in is your business logic. If your skills and workflows are coupled to one harness&#8217;s features and keywords, switching doesn&#8217;t just lose chat history &#8212; your custom logic breaks or quietly performs worse on the next tool.</p><p><strong>Failure 3 &#8212; You&#8217;re billed at their mercy.</strong> The plan you depend on can be pulled, suddenly gated behind expensive pay-as-you-go, restricted from the latest models (e.g., the Fable story), or repriced from 200 <em>to </em>1,000 overnight. With high switching friction, you can&#8217;t leave. You never know how the AI world can change. But for sure it won&#8217;t stay as is now.</p><blockquote><p><em>So what do you do?</em></p></blockquote><p>Keep your context layer detached from the harness. Any harness, any model (open or closed), plugs in and within ~5 minutes knows who you are, what you&#8217;re working on, what matters to you and how you like things to get done.</p><p>Everything that follows is based on the two projects I am working on: Scrabble, my own context layer anchored into my Obsidian notes, Readwise library, Notion, and Google ecosystem; and Tree, the project I am working on with <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Maxime Labonne&quot;,&quot;id&quot;:31453795,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17e73529-4d58-4477-b896-6d1e1f5c9796_896x896.png&quot;,&quot;uuid&quot;:&quot;6a62bff0-f52e-4d91-9880-7e3c5fe1eddb&quot;}" data-component-name="MentionToDOM"></span> for our next book, where we teach how to build a personal AI assistant from scratch.</p><h2>The Architecture of Your Context Layer</h2><p>A context layer is made out of 3 core components. First, a <strong>unified memory</strong> that holds everything you know. Second, a <strong>serving layer</strong> (MCP server or skills) that is the interface to that memory and the <strong>business logic</strong> that defines how the memory is used. The harness sits on top and is deliberately disposable.</p><p>The unified memory fuses what used to be separate systems: a filesystem, keyword search (BM25), semantic vector search, and a knowledge graph of typed POLE+O nouns (Person, Organization, Location, Event, Object), all in one place. The goal is a memory that belongs to you.</p><p>What I always preach is to try your best to build your unified memory on top of a single database that supports text, semantic, and graph search (such as <a href="https://www.mongodb.com/">MongoDB</a>). Start simple and add complexity only when your use case demands it.</p><p>The serving layer has 2 angles. The first is an MCP server, surfacing Tools, Resources, Prompts, Skills, and even MCP Apps (e.g. a graph visualizer) <a href="https://www.youtube.com/watch?v=v3Fr2JR47KA">[2]</a>. It wraps the business logic for how memory is queried and updated. That&#8217;s what makes it portable.</p><p>The second form skips the server entirely, which is based on skills shipped straight on the filesystem (an <code>AGENTS.md</code> plus a folder of skills). Skills are an interface too. They&#8217;re leaner, with nothing to run, but more tied to a given harness&#8217;s conventions. It&#8217;s how Scrabble&#8217;s wiki layer gets consumed.</p><p>In practice the strongest setups do both: a portable MCP server for memory access, skills layered on top for higher-level workflows <a href="https://www.youtube.com/watch?v=v3Fr2JR47KA">[2]</a>. To avoid fragmenting your business logic, host the skills directly on your MCP servers, coupling them with the rest of the server&#8217;s business logic.</p><p>In Tree, where I am building a unified memory powered by knowledge graphs, everything is discovered as ordinary MCP tools. That is exactly why &#8220;swap the harness, keep the memory&#8221; is a one-line config change, not a migration.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l99G!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l99G!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!l99G!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!l99G!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!l99G!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l99G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/af894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The context layer &#8212; interchangeable harnesses over an MCP-server interface over one unified memory you own.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The context layer &#8212; interchangeable harnesses over an MCP-server interface over one unified memory you own." title="The context layer &#8212; interchangeable harnesses over an MCP-server interface over one unified memory you own." srcset="https://substackcdn.com/image/fetch/$s_!l99G!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!l99G!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!l99G!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!l99G!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faf894e06-e355-4ae6-95b5-45f3b84ec6dd_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The context layer: Interchangeable harnesses over an MCP-server interface over one unified memory you own.</em></figcaption></figure></div><p><em>Here is what happens when you interact with the context layer:</em></p><p>You enter a prompt into the harness, which becomes an MCP tool call to the server. The server queries the unified memory, and results flow back into the agent&#8217;s context. Nothing crazy so far.</p><p>The interesting part happens when you start adding stuff to your memory. It&#8217;s where continual learning happens.</p><h2>Building a Unified Memory for Continual Learning</h2><p>At a high level, the pipeline is simple. Ingest data into the unified memory &#8594; extract entities and relationships into a graph &#8594; index for hybrid and graph retrieval &#8594; expose everything through an MCP server &#8594; connect it to a harness like Claude Code or OpenCode. Building the knowledge graph was the easy part. Designing how the agent interacts with it was the hard part.</p><p>Don&#8217;t expose raw database operations. Agents struggle with them. Instead, design the server around how agents actually search and write, giving them high-leverage primitives they can compose like LEGOs inside skills. In Tree that&#8217;s 6 tools: 3 to search, 3 to write.</p><p>There are 3 search tools. <code>nl_query_memory</code> is the default &#8212; an LLM maps a natural-language (NL) question into a MongoDB hybrid-search + graph query. <code>query_memory</code> is the deterministic fallback for structured filters when NL fails. <code>deep_search_memory</code> handles large result sets (50+ docs) via progressive disclosure: it writes intermediate results to a YAML index creating a localized LLM wiki on the fly.</p><p>The distinction between <code>nl_query_memory</code> / <code>query_memory</code> and <code>deep_search_memory</code> is important because when retrieving chunks from the unified memory, you need to further compress them before adding them into the context window to avoid exploding your costs. But that means you lose a lot of information. Thus, creating a wiki on the fly trades latency for performance and lower costs.</p><p>There are also 3 write tools: <code>ingest_url</code>, <code>ingest_file</code>, and <code>ingest_conversation</code>.</p><p>The last is auto-triggered by a hook that ingests incrementally every ~10 conversation turns and finalizes when the conversation ends. That hook is what makes the learning loop continual: the system writes back what it just learned without you asking, so it gets smarter the more you use it.</p><p>And &#8220;smarter&#8221; is concrete. Across tens of thousands of notes, it finds links between things you&#8217;d long forgotten you had, connections you&#8217;d never have made by hand. It&#8217;s how you finally harvest your own past work and your graveyard of bookmarks.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6ZNy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6ZNy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 424w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 848w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 1272w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6ZNy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png" width="1232" height="1065" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1065,&quot;width&quot;:1232,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:159550,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/203854945?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6ZNy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 424w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 848w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 1272w, https://substackcdn.com/image/fetch/$s_!6ZNy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d4eef9e-3825-4125-95e4-a6827be4dfe8_1232x1065.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The continual-learning loop: The agent queries the graph through the MCP tools, and every conversation is ingested back into the unified memory.</figcaption></figure></div><p>Now, let&#8217;s see how to actually build the unified memory layer.</p><h2>Build It Three Ways</h2><p>You&#8217;re implementing 3 pieces: the unified memory, your custom business logic, and the serving layer. How much you build yourself is also split into 3 levels of effort, which translates to a build vs. buy discussion.</p><p><strong>Level 1: Build all three from scratch</strong> on a database that supports everything at once (such as <a href="https://www.mongodb.com/">MongoDB</a>), implementing the memory and the MCP serving layer yourself. Maximum control, maximum effort.</p><p><strong>Level 2: Build only the business logic and serving layer</strong>, on top of an SDK that already implements the memory layer: <a href="https://github.com/getzep/graphiti">Graphiti</a>, a bi-temporal entity/fact/episode graph; Neo4j-Labs&#8217; <a href="https://github.com/neo4j-labs/agent-memory">agent-memory</a>, a graph-native POLE+O store; or <a href="https://github.com/mem0ai/mem0">mem0</a>, a vector-first layer that stores facts as rows.</p><p><strong>Level 3: Off-the-shelf</strong> memory engines you mostly just run: <a href="https://github.com/topoteretes/cognee">cognee</a>, an Extract-Cognify-Load pipeline of typed nodes that are graph + vector at once; or managed services like <a href="https://www.getzep.com/">Zep</a> (temporal context graphs on the open-source Graphiti engine) and <a href="https://hydradb.com/">HydraDB</a> (a graph DB on tiered object storage, pitched as &#8220;own your memory, no data leaving your stack&#8221;). Lowest effort, least control over the data model, and a vendor dependency. Cognee can import and export memory across Mem0, Zep, and Graphiti if you need to switch.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dGWD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dGWD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dGWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Agentic GraphRAG Architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Agentic GraphRAG Architecture" title="Agentic GraphRAG Architecture" srcset="https://substackcdn.com/image/fetch/$s_!dGWD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!dGWD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F68892c6f-9124-46c5-805a-e3b9adfe0282_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Version 1 (from scratch): The full agentic GraphRAG pipeline from raw sources to MCP tools.</em></figcaption></figure></div><p>Now zoom into Level 1, the from-scratch path. Building the memory yourself splits into 2 versions. <strong>Version 1 (more complex)</strong>, such as Tree, the agent memory I am building, which is a GraphRAG system whose retrieval fuses vector and keyword search with knowledge-graph traversal. It contains a POLE+O ontology, the index (graph + vector + text), the data and memory pipelines that ingest into it, and the query algorithms that read it.</p><p>POLE+O is a popular data model for building ontologies, borrowed from law-enforcement and intelligence analysis. Its beauty is that it&#8217;s perfectly balanced. It&#8217;s not too shallow, nor too deep. Perfect for an LLM to extract KG triplets from your data. Here it is as a thin <code>StrEnum</code> of the 5 node types:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZojL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZojL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 424w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 848w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 1272w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZojL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png" width="1456" height="410" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:410,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!ZojL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 424w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 848w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 1272w, https://substackcdn.com/image/fetch/$s_!ZojL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9eee1cf0-da6a-46be-a4a4-0bb896b6a262_2911x819.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In case you want more granularity over your POLE+O model, you can introduce subclasses, such as:</p><ul><li><p><strong>Person</strong>: individual, alias, persona</p></li><li><p><strong>Organization</strong>: company, nonprofit, government, ...</p></li><li><p><strong>Location</strong>: address, city, region, country, ...</p></li><li><p><strong>Event</strong>: meeting, transaction, communication, ...</p></li><li><p><strong>Object</strong>: device, software, document, task, topic, project</p></li></ul><p>To learn more, I have a full article on <a href="https://www.decodingai.com/p/agentic-graphrag">agentic GraphRAG</a> and another one on <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">designing an ontology for your context layer</a>.</p><p><strong>Version 2</strong>, the lighter one, is based on LLM wikis, such as Scrabble, my current agent memory. Markdown files with YAML frontmatter and cross-references, sitting directly on top of your existing infrastructure (Obsidian, Notion, Google Drive) &#8212; exactly how Scrabble runs over my own second brain. Google recently formalized this pattern as the Open Knowledge Format (OKF), a vendor-neutral directory of markdown + YAML whose only required field is <code>type</code> <a href="https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing">[3]</a>. The filesystem is the state; no database required.</p><p><strong>Which do you pick?</strong> It depends on how much control over the data model you want and your technical depth. Personally, I use both: Scrabble for everyday research across my second brain, and I plan to use Tree when I need precision at scale. Such as mining high-signal knowledge from 10,000+ documents.</p><p>Still, when it comes to implementing a unified memory layer on top of a knowledge graph, I keep getting asked one question: is a single database (MongoDB) enough? Why not throw in a specialized graph database like Neo4j or a vector database like Pinecone?</p><h2>Is MongoDB Enough?</h2><p>The simplest system that works wins. Instead of 3 databases (a SQL/NoSQL store, a vector DB, and a graph DB), you want one store that does all three. The payoff is concrete: far less operational overhead (one production DB, not three), less deep expertise required (being a power user of one engine beats being mediocre at three), and the ability to join documents, vectors, and graph in a single query. That last point matters most for memory: a single-store join is faster, cheaper, and lower-latency.</p><p><a href="https://www.mongodb.com/">MongoDB</a> is a good example, because it&#8217;s schema-less, supports all indexing operations, and has a huge ecosystem around it, with both an open-source version and their self-managed Atlas version. Another option I&#8217;ve tried that works well, but with more developer friction, is Postgres.</p><p>Also, as the cherry on top, you get lineage for free. Which is essential for adding references, understanding where each node came from, or simply preparing for an audit. You keep references on each knowledge-graph node instead of copying all data onto it: the document(s) a node was extracted from, the user who owns it, other metadata. That gives you easy lineage and versioning, and lets your memory connect to the rest of your system with no cross-database sync tax.</p><p><strong>Now what about scale?</strong> For personal assistants, where you have only 100-10,000 documents, a single MongoDB cluster is more than enough. But even for medium to big enterprises, you can easily scale to millions of documents by adding more clusters (aka horizontal scaling).</p><p>After a conversation with a principal MongoDB engineer I understood that the real bottleneck is RAM. RAM is the most expensive component from your database cluster and you want to keep it as low as possible.</p><p>So index only what you query. Your memory holds 2 snapshots of the same knowledge: an append-only log (the immutable record of everything ingested) and a materialized view (the queryable graph rebuilt from that log). Vector indexes are inverted indexes &#8805; the data they cover, so indexing both blows ~10 GB of data up toward ~40 GB of RAM.</p><p>Keep the log on disk (no vector index) and index only the materialized view, and it collapses back toward ~10 GB with the same data, at a quarter of the RAM.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NMXo!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NMXo!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 424w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 848w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 1272w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NMXo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png" width="1400" height="618" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:618,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Vector-indexing both snapshots inflates ~10 GB of data toward ~40 GB of RAM; index only the materialized view and it collapses back toward ~10 GB.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Vector-indexing both snapshots inflates ~10 GB of data toward ~40 GB of RAM; index only the materialized view and it collapses back toward ~10 GB." title="Vector-indexing both snapshots inflates ~10 GB of data toward ~40 GB of RAM; index only the materialized view and it collapses back toward ~10 GB." srcset="https://substackcdn.com/image/fetch/$s_!NMXo!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 424w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 848w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 1272w, https://substackcdn.com/image/fetch/$s_!NMXo!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff370b6c4-e1ce-4802-98b9-f5da8230fbf9_1400x618.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Vector-indexing both snapshots inflates ~10 GB of data toward ~40 GB of RAM; index only the materialized view and it collapses back toward ~10 GB.</em></figcaption></figure></div><p><strong>When does it make sense to use a specialized graph DB like Neo4j?</strong> The reality is that for most use cases, you will do only 2-3 hops traversals. Such as getting all the preferences of a user, and the documents/conversations they were extracted from. In these cases, a single database that does it all is amazing. But there are cases when you should reach for a specialized graph DB like Neo4j. For example, when you need to do 3+ hop traversals, your whole business logic relies on graphs or simply as an internal visualization tool. You could sync your MongoDB production database to Neo4j, just for exploration reasons, as their Cypher engine + visualization ecosystem is stronger.</p><h2>Using Your Context Layer With Any Agent</h2><p>The wiki version is the simplest to switch between agents. If your context layer is shipped as an LLM wiki, switching harnesses is just handing the new harness a path. For this article, I literally pointed the harness at the research wiki folder from my Second Brain. Without any fancy skills or plugins in place.</p><p>Or a step further, is to point it at my entire second brain &#8212; that&#8217;s Scrabble &#8212; whose <code>AGENTS.md</code> explains how to navigate it and which CLI tools and skills to use. It works out of the box because it&#8217;s just files.</p><p>The MCP version is a bit more work, but not much. Serving memory over an MCP server means re-pointing one config entry from one harness to the next &#8212; switch from Claude Code to Codex by configuring the path to your MCP server, and your whole memory moves with almost zero friction, regardless of harness or model.</p><p>Each MCP server ships its own tools (read tools and write tools), and the tool descriptions are the contract the agent reads. It gets especially interesting on the write side, where the tools decide when to persist (e.g. parsing a whole conversation into memory when it ends).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Qrw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Qrw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 424w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 848w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Qrw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png" width="1200" height="1034" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1034,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The MCP server serves the same memory, skills, and UI to any harness and any interface.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The MCP server serves the same memory, skills, and UI to any harness and any interface." title="The MCP server serves the same memory, skills, and UI to any harness and any interface." srcset="https://substackcdn.com/image/fetch/$s_!8Qrw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 424w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 848w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 1272w, https://substackcdn.com/image/fetch/$s_!8Qrw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F74b95bcc-d207-4f47-95ba-03311f4500ae_1200x1034.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em> The MCP server serves the same memory, skills, and UI to any harness and any interface.</em></figcaption></figure></div><p>Skills are where the leverage compounds. On top of this memory, you can write deep-research, writing, or coding-agent skills that remember your preferences. A few of mine, all part of Scrabble:</p><ul><li><p><code>/research</code>, which runs deep research on a topic and produces a localized wiki (I have an open-source version in my latest <a href="https://github.com/iusztinpaul/ai-research-os-workshop">ai-research-os-workshop</a> talk made for the AI Engineer World&#8217;s Fair SF - <a href="https://www.youtube.com/watch?v=ZRM_TfEZcIo">full video</a>);</p></li><li><p><code>/article-guideline</code>, which expands a brain dump into an article plan anchored in a wiki;</p></li><li><p><code>/squid:plan</code>, part of my <a href="https://github.com/iusztinpaul/squid">Squid</a> software factory, which plans a feature from my spec, codebase, and memory &#8212; injecting my personal takes on how I write software.</p></li></ul><h2>What&#8217;s Next</h2><p>Agent memory is an unsolved, fast-moving topic. These designs work, but they&#8217;re far from perfect, and your data is still segregated across Obsidian, Notion, local files, and messages in ways that are hard to unify. In practice, I lean on the lighter wiki-based approach. One per project does the job. I reserve Tree&#8217;s heavy knowledge-graph memory for the few high-precision cases that earn its cost.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Your data can move between harnesses, but can your skills? I have this issue with Claude Code&#8217;s workflows and agents embedded into my skills.</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/the-context-layer/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/the-context-layer/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/the-context-layer?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/the-context-layer?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><p><em>Special thanks to <a href="https://www.mongodb.com/">MongoDB</a> for sponsoring this article and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://www.mongodb.com/" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg" width="1200" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48258,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:&quot;https://www.mongodb.com/&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/203854945?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!c1Gm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!c1Gm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F143757ba-2cb8-4d2f-be0e-dbd29fcbb7d0_1200x400.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Explore Next</h2><ol><li><p>LangChain. (n.d.). Open Models, Open Runtime, Open Harness &#8212; Building Your Own AI Agent With LangChain and Nvidia. YouTube. <a href="https://youtube.com/watch?v=BEYEWw1Mkmw">https://youtube.com/watch?v=BEYEWw1Mkmw</a></p></li><li><p>Soria Parra, D. (n.d.). The Future of MCP. YouTube. <a href="https://www.youtube.com/watch?v=v3Fr2JR47KA">https://www.youtube.com/watch?v=v3Fr2JR47KA</a></p></li><li><p>McVeety, S., &amp; Hormati, A. (n.d.). Introducing the Open Knowledge Format. Google Cloud.<a href="http://The MCP server serves the same memory, skills, and UI to any harness and any interface."> https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing</a></p></li><li><p>getzep. (n.d.). Graphiti. GitHub. <a href="http://The MCP server serves the same memory, skills, and UI to any harness and any interface.">https://github.com/getzep/graphiti</a></p></li><li><p>Neo4j Labs. (n.d.). agent-memory. GitHub. <a href="https://github.com/neo4j-labs/agent-memory">https://github.com/neo4j-labs/agent-memory</a></p></li><li><p>mem0ai. (n.d.). mem0. GitHub. <a href="https://github.com/neo4j-labs/agent-memory">https://github.com/mem0ai/mem0</a></p></li><li><p>topoteretes. (n.d.). cognee. GitHub. <a href="https://github.com/topoteretes/cognee">https://github.com/topoteretes/cognee</a></p></li><li><p>getzep. (n.d.). Zep. <a href="https://www.getzep.com/">https://www.getzep.com/</a></p></li><li><p>HydraDB. (n.d.). HydraDB. <a href="https://www.getzep.com/">https://hydradb.com/</a></p></li><li><p>Iusztin, P. (n.d.). ai-research-os-workshop. GitHub. <a href="https://github.com/iusztinpaul/ai-research-os-workshop">https://github.com/iusztinpaul/ai-research-os-workshop</a></p></li><li><p>Iusztin, P. (n.d.). squid. GitHub. <a href="https://github.com/iusztinpaul/squid">https://github.com/iusztinpaul/squid</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[How Evaluation-Driven Development (EDD) Works]]></title><description><![CDATA[Turn every AI agent change into a measured experiment you compare before and after to detect regressions and measure performance.]]></description><link>https://www.decodingai.com/p/how-evaluation-driven-development-works</link><guid isPermaLink="false">https://www.decodingai.com/p/how-evaluation-driven-development-works</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 23 Jun 2026 08:57:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!opgq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!opgq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!opgq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!opgq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!opgq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!opgq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!opgq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Hold the before and the after up to the light &#8212; and don't open the gate until you know which ray went dark.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Hold the before and the after up to the light &#8212; and don't open the gate until you know which ray went dark." title="Hold the before and the after up to the light &#8212; and don't open the gate until you know which ray went dark." srcset="https://substackcdn.com/image/fetch/$s_!opgq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!opgq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!opgq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!opgq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fca8875b3-6a98-444f-9b68-0085006c19f1_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The scariest AI failures are the silent ones.</p><p>You ship a change to your agent on a branch &#8212; a new feature, a prompt fix, a quick refactor. No errors. No complaints. Everything <em>looks</em> fine. But does it still work, or did you quietly break something that worked yesterday?</p><p>As Alejandro Aboy puts it: <em>&#8220;the fact that they&#8217;re not complaining doesn&#8217;t mean there&#8217;s no issue going on.&#8221;</em> A quiet user is not a happy user. Usually, it&#8217;s the opposite.</p><blockquote><p>The more Alejandro and I talked about AI evals and EDD, the more his struggles sounded like mine. A story from builders to builder.</p></blockquote><p><strong>1. You can break what already worked.</strong> Change a prompt, refactor a tool, and an old feature quietly regresses. Alejandro lived it: cleaning noisy instructions out of his agent&#8217;s system prompt made it start fabricating IDs it used to get right. You only catch that by running the same tests before and after the change, and comparing.</p><p><strong>2. The feature is brand new, so you have nothing to test it on.</strong> No dataset, no historical traces, no ground truth. Yet you still need to know whether it works, and how well. So how do you generate realistic test data fast, then feed it to evaluators that turn it into hard performance numbers?</p><p>This is the case study that gives you a plan of attack for both: <strong>Evaluation-Driven Development (EDD)</strong></p><p>How to prove a new feature works, and didn&#8217;t regress, <em>before</em> you merge. It comes from a recent conversation with <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Alejandro Aboy&quot;,&quot;id&quot;:22949723,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/82b06564-e92e-44ba-80d7-0a45455d7ab7_1003x1003.png&quot;,&quot;uuid&quot;:&quot;8ebabe2d-0981-4315-8d99-d44100e5187a&quot;}" data-component-name="MentionToDOM"></span>, a senior data and AI engineer at Workpath who owns the entire data stack, built the Workpath AI Companion, and writes <em>The Pipe and The Line</em> Substack.</p><p>And we won&#8217;t keep it abstract. Every example comes from one real product: <strong>Workpath</strong>, a strategy-execution SaaS that keeps large companies&#8217; OKRs and initiatives aligned. (OKRs &#8212; Objectives and Key Results &#8212; are the goal-setting framework teams use to name what they want to achieve and the measurable results that prove they&#8217;re getting there.) Its AI-native feature is the <strong>Workpath AI Companion</strong>: an agent that scans a company&#8217;s strategy and OKR data end-to-end to keep enterprise teams aligned. It&#8217;s the exact system Alejandro runs EDD on every day.</p><p>So when we say <em>developing a new feature</em>, picture shipping a change to that Companion and proving, before you merge, that it works and didn&#8217;t regress.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AcZy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AcZy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 424w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 848w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 1272w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AcZy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png" width="1200" height="832" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:832,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The moving parts &#8212; Claude Code drives a headless agent, Agno enriches its trace, and Opik stores and scores everything.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The moving parts &#8212; Claude Code drives a headless agent, Agno enriches its trace, and Opik stores and scores everything." title="The moving parts &#8212; Claude Code drives a headless agent, Agno enriches its trace, and Opik stores and scores everything." srcset="https://substackcdn.com/image/fetch/$s_!AcZy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 424w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 848w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 1272w, https://substackcdn.com/image/fetch/$s_!AcZy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1ec3350d-e9cb-45f1-a7b7-d95a966fc5e5_1200x832.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The moving parts</em></figcaption></figure></div><h2>The Develop-a-Feature Workflow</h2><p>Imagine. You start working on a new feature, branch, and develop the change. But before you merge, you have to answer 2 questions:</p><ol><li><p>What&#8217;s the performance of my new feature?</p></li><li><p>Did my change introduce any regressions into the existing codebase?</p></li></ol><p>Only when both look good you accept the pull request. EDD helps you answer those 2 questions.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jIGa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jIGa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 424w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 848w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 1272w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jIGa!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png" width="984" height="331.74857142857144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:472,&quot;width&quot;:1400,&quot;resizeWidth&quot;:984,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;EDD is the offline gate between developing a change and merging it &#8212; it answers \&quot;does it work?\&quot; and \&quot;did it regress?\&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="EDD is the offline gate between developing a change and merging it &#8212; it answers &quot;does it work?&quot; and &quot;did it regress?&quot;" title="EDD is the offline gate between developing a change and merging it &#8212; it answers &quot;does it work?&quot; and &quot;did it regress?&quot;" srcset="https://substackcdn.com/image/fetch/$s_!jIGa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 424w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 848w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 1272w, https://substackcdn.com/image/fetch/$s_!jIGa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1813e19e-2dd7-42ca-a4f1-24ae965d54b6_1400x472.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>EDD is the offline validation gate between developing a change and merging it</em></figcaption></figure></div><p>Every feature is hypothesis-first. As Alejandro frames it, <em>&#8220;I have a hypothesis... and everything should lie around that.&#8221;</em> Every change starts as a stated hypothesis on a branch.</p><p>Based on that hypothesis, EDD runs a simulation and scores the results to answer the 2 questions.</p><p>Every feature ends in a PR, backed by an experiment, with clear traces and metrics. Framing the eval results as an experiment allows you to compare current results to previous ones, detecting regressions or tracking improvements.</p><p>This is how you can compare two experiments in Opik:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MJ44!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MJ44!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 424w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 848w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png" width="1456" height="594" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Comparing two experiments in Opik&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Comparing two experiments in Opik" title="Comparing two experiments in Opik" srcset="https://substackcdn.com/image/fetch/$s_!MJ44!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 424w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 848w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Comparing two experiments in Opik</em></figcaption></figure></div><p>What about the process that happens between starting a new feature and its experiment?</p><h4>From an architectural perspective, we have:</h4><ul><li><p>The <strong>AI application</strong>, which can be an AI agent, workflow or a simple chatbot. In Alejandro&#8217;s case, it&#8217;s an AI agent built with Agno. More precisely, it&#8217;s the Workpath AI Companion he is building. But due to data privacy reasons, during the demo, he could share only a mock of the data.</p></li><li><p>A <strong>headless evaluation harness</strong>, powered by Claude Code.</p></li><li><p>An <strong>AI observability and evaluation platform</strong> responsible for capturing traces, managing eval datasets and evaluators, running experiments and comparing results. Alejandro is using <a href="https://github.com/comet-ml/opik">Opik</a>. The tool is open-source, but for ease of use, you can also try out their managed platform for free <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">here</a> for 25k spans/month.</p></li></ul><p>Now... how do we generate data for these experiments? How do we get the traces? How do we populate the evaluation harness with the right context? We will see how all of that falls into place, where everything starts with two modes.</p><h2>Two Modes: Manual Quick Check vs. Automated Experiments</h2><p>The two modes are modeled by the <code>/edd</code> skill, which has two inputs: Mode and Aggression.</p><p><strong>Mode 1</strong> is a quick, manual check. You fire around 30 fresh traces, let Claude Code read them back from Opik one by one, and trigger a judge by hand only if you want a score. As Alejandro describes it, <em>&#8220;it won&#8217;t trigger automatic evaluations; you trigger them manually.&#8221;</em> No dataset, no experiment, ephemeral, minutes. His favorite for a small change: his Substack Author Agent kept over-asking for the publication URL on every new trace. A tiny, targeted fix, exactly what Mode 1 is for.</p><p><strong>Mode 2</strong> automates the judgment. When you touch a lot or ship new functionality, you turn the traces into a dataset and run an experiment, both Opik objects, where the judges score every item automatically and produce an experiment you can compare across runs. This is the only way to catch a subtle regression, because you compare 2 experiments.</p><p>Both modes start from a hypothesis on a branch, emit fresh simulated traces, and can use the same evaluators. The mode only changes whether the evaluation is done by hand or automatically.</p><p>The <strong>Aggression setting</strong> controls how adversarial the simulated traces get, from happy-path up to fully adversarial. As you turn up the knob, simulated traces get more aggressive, finding harder and harder corner cases to break the agent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JD2l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JD2l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 424w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 848w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 1272w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JD2l!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png" width="1008" height="647.28" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:899,&quot;width&quot;:1400,&quot;resizeWidth&quot;:1008,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The skill's decision flow &#8212; a small change takes the quick Mode 1 path; new functionality takes the Mode 2 dataset-and-experiment path.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="The skill's decision flow &#8212; a small change takes the quick Mode 1 path; new functionality takes the Mode 2 dataset-and-experiment path." title="The skill's decision flow &#8212; a small change takes the quick Mode 1 path; new functionality takes the Mode 2 dataset-and-experiment path." srcset="https://substackcdn.com/image/fetch/$s_!JD2l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 424w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 848w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 1272w, https://substackcdn.com/image/fetch/$s_!JD2l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9266d723-6f23-405c-8dcb-bf71c5493ace_1400x899.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The skill&#8217;s decision flow: A small change takes the quick Mode 1 path, while new functionality takes the Mode 2 dataset-and-experiment path.</em></figcaption></figure></div><p>The secret sauce of Alejandro&#8217;s EDD approach is in how he uses Claude Code to simulate fresh traces.</p><h2>Scope the Change and Simulate Its Traces</h2><p>Remember. Our goal is to simulate relevant traces to test the performance of our feature. To do that, we use Claude Code to read the agent&#8217;s source code, especially the code around the new feature. After, we retrieve old traces (stored in Opik) that are relevant to our current code. </p><p>Based on these two signals, we generate ~30 traces targeting the new feature&#8217;s functionality.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!uUqd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!uUqd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 424w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 848w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 1272w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!uUqd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png" width="1400" height="508" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:508,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The evals can only see what the trace carries &#8212; so the trace has to carry the whole harness, not just the answer.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The evals can only see what the trace carries &#8212; so the trace has to carry the whole harness, not just the answer." title="The evals can only see what the trace carries &#8212; so the trace has to carry the whole harness, not just the answer." srcset="https://substackcdn.com/image/fetch/$s_!uUqd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 424w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 848w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 1272w, https://substackcdn.com/image/fetch/$s_!uUqd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F276950ac-3f87-4242-ae76-7d5ebef0c393_1400x508.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The evals can only see what the trace carries. So the trace has to carry the whole harness, not just the answer.</em></figcaption></figure></div><p>The traces need to be high signal and as diverse as possible. The goal is to find holes within our system and fix them, not to validate what currently works. </p><p>To achieve that, the traces are generated based on 2 dimensions:</p><ul><li><p><em>Regression evals</em> (what worked still works) vs. <em>capability evals</em> (can do it on new things</p></li><li><p><em>Happy path</em> (easy: testing the core logic) vs. <em>adversarial</em> (hard: finding edge cases, such as missing data, faulty tool descriptions or guardrails)</p></li></ul><p>During generation, we can configure these parameters. For example, if we go full adversarial, the probability of finding errors increases. Which isn't necessarily a good thing, as you don&#8217;t want to overoptimize in advance either. You want to make the system as good as possible on the hot path. You don&#8217;t want to waste time on scenarios that might never happen. That&#8217;s why anchoring your trace generation to existing traces is an essential step for properly understanding the user&#8217;s behavior and which components to target when generating the traces.</p><blockquote><p>&#9888;&#65039; <strong>Important!</strong> Even if we simulate the data, we still want REAL traces and outputs to evaluate on.</p></blockquote><p><strong>This is what we have to do.</strong> The pipeline starts from the data, not from invented inputs. Claude Code analyzes the current traces to learn what inputs are worth generating, so we <strong>simulate only the inputs, NOT the outputs or internal state.</strong></p><p>That&#8217;s the whole point. Synthesize the outputs too and you hit Alejandro&#8217;s problem: <em>&#8220;every time I try synthetic datasets, I was losing everything the agent was doing beyond the response.&#8221;</em> Grade the final answer alone and a wrong tool call stays invisible.</p><p>To get there, we send each simulated input to a headless copy of the agent, which runs for real: selecting tools, calling the staging backend, handling whatever comes back. As it runs, Agno records the full tool-call history and outputs into its OpenTelemetry trace, and the agent emits it to Opik.</p><p>Using this strategy, we simulate the inputs, run the agent, and record the trace with real values produced by the agent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GXvk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GXvk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 424w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 848w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 1272w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GXvk!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png" width="1010" height="706.1675824175824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:1018,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1010,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!GXvk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 424w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 848w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 1272w, https://substackcdn.com/image/fetch/$s_!GXvk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc7ca37f6-6b19-4678-a857-081ca79038ed_2428x1698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>A single simulated trace in Opik</em></figcaption></figure></div><p>A simulated trace is only as trustworthy as the state the agent was in when it ran, and recreating that state is the hardest part.</p><h2>Context Population: Mocking Production State</h2><p>The hardest part of agentic evals is getting the agent into the right state, so it passes or fails for reasons that actually relate to your hypothesis. A trace generated from the wrong state is a useless trace.</p><p>In Alejandro&#8217;s use case, roughly 90% of the agent&#8217;s tools are API calls, so Claude Code gets a token and hits the real internal backend through a staging mocked account that already holds data. For the happy path, it pulls real goals, OKRs, and teams. To go adversarial, it forces errors and asks for data that doesn&#8217;t exist.</p><p>The reusable trick is where the context gets injected. Before the agent boots, Claude Code calls the API and injects the user&#8217;s context into dedicated system-prompt sections. So the agent greets you with <em>&#8220;Hi Paul, want to check goals from the coding AI team?&#8221;</em> It runs <em>&#8220;as if for real.&#8221;</em></p><p>Alejandro is explicit that this is not pytest-style fixtures, but <em>&#8220;the prompt is the only thing the LLM sees.&#8221;</em> A faithful prompt-level state is a faithful enough production proxy. You mock at the system-prompt layer and stop worrying about reproducing the whole backend.</p><p>So instead of using the standard way of using fixtures to populate the backend, you can bypass everything and directly inject the context into the system prompt. From the LLM&#8217;s perspective, it&#8217;s the same thing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QxfE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QxfE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 424w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 848w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 1272w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QxfE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png" width="1073" height="559" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:1073,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Mock the state at the system-prompt level, hit a real staging backend, and the agent runs as if in production.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Mock the state at the system-prompt level, hit a real staging backend, and the agent runs as if in production." title="Mock the state at the system-prompt level, hit a real staging backend, and the agent runs as if in production." srcset="https://substackcdn.com/image/fetch/$s_!QxfE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 424w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 848w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 1272w, https://substackcdn.com/image/fetch/$s_!QxfE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a74f723-8dbb-43f3-9594-6555739931e4_1073x559.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Mock the state at the system-prompt level, hit a real staging backend, and the agent runs as if in production.</em></figcaption></figure></div><p>The last step is to transform the traces into an evals dataset.</p><h2>On-Demand Datasets</h2><p>You want two types of eval datasets:</p><ol><li><p>A persistent, hand-built evaluation set that tests the core business logic. Useful for catching regressions.</p></li><li><p>An on-demand, synthetic dataset used to evaluate the feature you are working on.</p></li></ol><p>We are interested here in the second option.</p><p>Via the <code>/edd</code> skill Claude Code assembles an Opik dataset, on the fly, from the branch-tagged simulated traces. The dataset is tagged so a later run can filter straight to it, then kept or thrown away.</p><p>Before committing to a big sample, Alejandro fires a couple of runs as smoke checks, <em>&#8220;to catch anything awful&#8221;</em> before spending tokens. Then he checks that the dataset&#8217;s coverage is good enough to be worth running an experiment against. Small, cheap, and it saves the expensive mistake.</p><p>Because the dataset is cheap to regenerate and scoped to one change, it&#8217;s disposable. Optionally, you might promote a couple of high signal traces into the persistent regression set.</p><p>A dataset is only useful once you&#8217;ve decided what metrics to use &#8212; aka the judges.</p><h2>Define the Judge</h2><p>You want to support 2 evaluator types.</p><p><strong>Code metrics</strong> score the structural things deterministically, server-side, free, no LLM, like whether it called the tool or whether the format is right. Always try to evaluate a given metric via code metrics if possible.</p><p><strong>LLM judges</strong> score the subjective things, like completeness, accuracy, and ranking quality.</p><p>Both evaluators are designed as binary classifiers: verified, or not. The urge to introduce 1-5 likert scales is huge. But the thing is that it&#8217;s incredibly difficult to get it right. What&#8217;s the difference between 2 and 3 or 4 and 5? Even when using multiple human annotators, the labels are inconsistent. With binary labels, the decision is clear: it&#8217;s correct or not. Which makes it incredibly easy for the LLM to get it right.</p><p>To get some nuance, on top of the binary labels, you want to add a critique that explains in 2-3 sentences why the output is correct or not.</p><p>The judge model is deliberately a different model than the agent, so the two don&#8217;t share blind spots and the judge can&#8217;t rubber-stamp its own family&#8217;s mistakes.</p><p>But here is the trick! The evaluators are static, carefully defined and calibrated up front from the codebase. The loop regenerates traces and datasets, not the metrics. When implementing LLM judges, it&#8217;s extremely important to align them with the domain expert. Once they are working well, you can use them for inference, which we are doing here on the dynamic datasets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zrh6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zrh6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 424w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 848w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zrh6!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png" width="1044" height="455.3159340659341" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:635,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1044,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!zrh6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 424w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 848w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 1272w, https://substackcdn.com/image/fetch/$s_!zrh6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F620b20f7-a725-445e-bc36-18d4b9be1753_2936x1280.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Opik&#8217;s Insights view turns each judge into a per-dimension score profile for the run.</em></figcaption></figure></div><p>The judges are configured within Opik, using their API to call the model to score each sample from the dataset.</p><p>In the image below, you can see the evaluators Alejandro configured for each experiment:</p><ul><li><p>Content Completeness</p></li><li><p>Metric Accuracy</p></li><li><p>Ranking Quality</p></li><li><p>Relative Grounding</p></li><li><p>Response Directness</p></li><li><p>Semantic Search Accuracy</p></li><li><p>Skill Selection</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CNQw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CNQw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 424w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 848w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CNQw!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png" width="1096" height="388.4175824175824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:516,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1096,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!CNQw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 424w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 848w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 1272w, https://substackcdn.com/image/fetch/$s_!CNQw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17033b01-aa15-49d7-a6e6-d504048eced4_2926x1036.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The evaluator suite Alejandro runs on every experiment. One judge per dimension, scoring the whole dataset.</em></figcaption></figure></div><p>With the dataset built and the judges defined, you run the experiment. And you run it twice.</p><h2>Run and Compare Experiments</h2><p>The experiment runs in Opik, scoring the dataset against all the judges to produce a score distribution.</p><p>In a feature Alejandro was working on, he cleaned all the noisy instructions out of his agent&#8217;s system prompt, <em>&#8220;hygiene before&#8221;</em> vs. <em>&#8220;hygiene after,&#8221;</em> and ran 2 experiments over the same scope in Opik&#8217;s comparison view.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mWkj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mWkj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 424w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 848w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 1272w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mWkj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png" width="1456" height="589" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:589,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Run the same scope twice and the regression you introduced shows up as one short bar.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Run the same scope twice and the regression you introduced shows up as one short bar." title="Run the same scope twice and the regression you introduced shows up as one short bar." srcset="https://substackcdn.com/image/fetch/$s_!mWkj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 424w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 848w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 1272w, https://substackcdn.com/image/fetch/$s_!mWkj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F445836b8-2b99-4d09-a10a-c5393dfd0cf2_1760x712.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Run the same scope twice and the regression you introduced shows up as one short bar.</em></figcaption></figure></div><p>The <em>after</em> had regressed on one judge: tool-call parameter inference. The agent should remember which ID to pass to a tool, but the cleanup made it <em>&#8220;get lost and fabricate IDs.&#8221;</em> EDD caught his own change before it shipped.</p><p>Comparison matters because failure hides where a single trace can&#8217;t show it. Trace-level evals are usually fine, but problems surface across 5, 10, or 20-message conversations. Around the 10th message, the model slides into a <em>&#8220;context rot zone&#8221;</em>: a request that earlier earned a cooperative <em>&#8220;let&#8217;s work with this&#8221;</em> now gets <em>&#8220;what do you mean by that?&#8221;</em></p><p>A user asks the agent to <em>&#8220;scan 50 teams, get me all the OKRs.&#8221;</em> It pushes back and offers to go progressively, returning 17 copy-pasteable tables. But by trace 21 of a 20-message conversation, you&#8217;re at 200k total tokens, paying heavily without caching.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MJ44!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MJ44!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 424w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 848w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png" width="1456" height="594" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!MJ44!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 424w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 848w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1272w, https://substackcdn.com/image/fetch/$s_!MJ44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F63c347d8-ed96-4989-8bd8-8f61587a0b2c_2974x1214.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The same scope, before vs after, overlaid in Opik. One regressed dimension can&#8217;t hide across the judges.</em></figcaption></figure></div><p>These are the kinds of errors proper evals protect you from! Not only performance, but also latency and cost issues that can blow up your infrastructure overnight.</p><h2>Don&#8217;t Run Online Evals</h2><p>Everything so far ran offline, on a branch, before the merge. The expensive default everyone reaches for instead is always-on online evals. That&#8217;s the trap.</p><p>Alejandro made the same mistake.</p><p>He thought running online evaluations on all the traces was essential for production. Until the bill! It was on credits, not cash, but it would have been around $2k a month just from triggering a few evaluations: <em>&#8220;the bill just pops in &#8212; in one second you have thousands of dollars in debt.&#8221;</em></p><p>So you recalibrate. What&#8217;s the actual risk of evaluating whether the agent leaked an ID to the user? Low. So you sample or look for a pattern, run the heavy judges offline, and cap spend first: <em>&#8220;consume an amount you know you can afford.&#8221;</em></p><blockquote><p><strong>The good news?</strong> The whole <code>/edd</code> skill and headless harness implemented by Alejandro via Opik is now an <a href="https://github.com/aboyalejandro/eval-driven-development">installable open-source Claude Code plugin</a>. You can also create a free account on <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Opik</a> with <em>25k spans/month</em> to try out this EDD strategy on your own project.</p></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nQe4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nQe4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 424w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 848w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nQe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png" width="1456" height="546" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:546,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Opik Dataset&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Opik Dataset" title="Opik Dataset" srcset="https://substackcdn.com/image/fetch/$s_!nQe4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 424w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 848w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 1272w, https://substackcdn.com/image/fetch/$s_!nQe4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F24590605-5526-432d-a9d3-fd49543a10c3_3358x1260.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The offline eval dataset</em></figcaption></figure></div><div><hr></div><div class="callout-block" data-callout="true"><h4>&#127909; Watch the full conversation between Alejandro Aboy and me</h4><div id="youtube2-1zuGTgHQGcM" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;1zuGTgHQGcM&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/1zuGTgHQGcM?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div></div><div><hr></div><h2>Final Thoughts</h2><blockquote><p>You&#8217;re already driving one AI process with another. Would you hand the whole thing over to an agent that reads the traces, understands the agent&#8217;s mistakes, gets the signal from the evaluators and writes the code changes itself?<br>&#8212; Paul</p></blockquote><p>Alejandro would want exactly that, on one condition. He&#8217;s tried prompt-only optimizers and doesn&#8217;t trust them, because they change the prompt but never test the agent&#8217;s full harness. Until then, the human stays in the loop, and every change earns its pull request.</p><blockquote><p>Opik has been shipping exactly that: Test Suites, Agent Configuration and Playground. Where does your hand-rolled loop go from here?<br>&#8212; Paul</p></blockquote><p>Because they tackle the prompt-only-optimization gap, Alejandro is bullish on adopting them &#8212; he expects they&#8217;ll close the whole agentic loop: analyze the code &amp; failures &#8594; generate inputs &#8594; call the agent &#8594; build a dataset &#8594; evaluate each sample &#8594; fix the code &#8594; repeat, all in one place.</p><p>Try out Alejandro&#8217;s EDD code on <a href="https://github.com/aboyalejandro/eval-driven-development">GitHub</a>, while leveraging <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Opik&#8217;s free tier</a> as the observability platform.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Where do you draw the line between online and offline evals? What do you actually run always-on in production, and how do you cap the spending?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-evaluation-driven-development-works/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/how-evaluation-driven-development-works/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-evaluation-driven-development-works?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/how-evaluation-driven-development-works?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><p><em>Thanks again to <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Opik</a> for sponsoring this case study and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oSDm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oSDm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 424w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 848w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1272w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png" width="1456" height="364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:364,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Opik Banner&quot;,&quot;title&quot;:&quot;Opik Banner&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Opik Banner" title="Opik Banner" srcset="https://substackcdn.com/image/fetch/$s_!oSDm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 424w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 848w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1272w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Try Opik for free here</a> (25k spans/month free)</figcaption></figure></div><p><strong>If you want to monitor, evaluate and optimize your AI workflows and agents:</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&quot;,&quot;text&quot;:&quot;Try Opik for free&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul"><span>Try Opik for free</span></a></p><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Build, Configure, or Use As-Is: The Agentic Harness]]></title><description><![CDATA[A component-by-component teardown of an agentic harness, from tools and skills to memory, sandbox, and permissions.]]></description><link>https://www.decodingai.com/p/agentic-harness-system-design</link><guid isPermaLink="false">https://www.decodingai.com/p/agentic-harness-system-design</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 09 Jun 2026 05:00:28 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!qdmn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qdmn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qdmn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qdmn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1466419,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/200891005?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qdmn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!qdmn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc4bb167-4683-4bec-b335-e44e6efafa57_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Maxime Labonne&quot;,&quot;id&quot;:31453795,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F17e73529-4d58-4477-b896-6d1e1f5c9796_896x896.png&quot;,&quot;uuid&quot;:&quot;191ae76b-9f08-4ecb-978b-b953476cb01b&quot;}" data-component-name="MentionToDOM"></span> and I were planning our upcoming book when we kept hitting the same realization. Just as LLMs got commoditized, the harness around them is commoditizing too, hardening into a handful of standardized, batteries-included frameworks. Once it&#8217;s a commodity, the hard question flips. It stops being &#8220;how do I get an agent running&#8221; and becomes &#8220;for each piece, do I build, configure, or just use it?&#8221; And that line is blurry.</p><p>Overbuild, and you burn weeks reimplementing a tool loop, a permission system, and a sandbox that is already available for free. Under-build, and you lean on the defaults forever, never building the one layer that&#8217;s actually yours, your context layer, your moat, so you stay a renter of someone else&#8217;s system.</p><p>The harnesses fall along a spectrum, from tool-like ones you customize as a user (Claude Code, Codex, OpenCode) through framework-type ones you build with, like Pydantic AI in Python or pi in TypeScript.</p><p>This article hands you that system design: the ~80% blueprint that&#8217;s conceptually the same across Claude Code, OpenCode, Codex, and pi, walked component by component, with one conclusion per piece.</p><p>We start with the big-picture architecture, the shape almost every harness shares, then walk it component by component: the tools the model calls, the catalog of agents, how subagents spawn and stay contained, how skills load cheaply, where memory really lives, how sandboxes both protect and scale you, and the permission layer with almost no AI in it. Each one closes on a verdict that fills in the map.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Build the Layer That&#8217;s Actually Yours (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YHdS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YHdS!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YHdS!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!YHdS!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!YHdS!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F221368fb-6f12-4684-9807-e738c255c22e_1200x1200.gif 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This article shows the system design of a harness, the commoditized part. The real value is the business layer you build on top of it. That&#8217;s what my <a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent AI Engineering course</a> teaches, built with Towards AI: only what you need to deliver value, not how to rebuild the harness.</p><p>35 lessons. 3 end-to-end portfolio projects. A certificate. And a Discord community with direct access to industry experts and me.</p><p>Built for software, data engineers or scientists transitioning into AI engineering.</p><p><em>Rated 5/5 by 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p></div><h2>The 80% Every Harness Shares</h2><p>Roughly 80% of a harness&#8217;s blueprint is identical regardless of the tool or framework, because every harness solves the same problems with different techniques. That shared 80% is exactly the part you mostly <em>use as-is</em>. The decisions about what to <em>configure</em> or <em>build</em> live in the remaining slice. At the highest level: a user message goes in, an answer comes out, and everything between is the harness.</p><p>In between, here are the 5 core layers:</p><p>The <strong>Agent</strong> is the innermost piece: the agentic loop (the ReAct loop, where the model reasons then acts) wrapping an LLM plus its tools. The LLM can be closed (Gemini, Anthropic, OpenAI) or open-source served over the OpenAI protocol on Modal, RunPod, GCP, or TogetherAI, or run locally with Ollama or llama.cpp. This loop is the core: strip away compaction, task budgets, and thinking and it&#8217;s roughly 150 lines.</p><p>The <strong>Harness</strong> is everything wrapped around the agent: a message queue with a priority gate, the sandbox, hooks, services (LLM gateway, memory, LSP servers, MCP client), skills, the permission system, an agents catalog, and subagents, with context engineering sprinkled everywhere.</p><p>The <strong>Runtime</strong> is the durable execution layer the whole harness runs inside: Prefect, Temporal, Kitaru. It gives you non-blocking human-in-the-loop, scheduling, durability and caching, and a credentials proxy.</p><p>The <strong>Presentation layer</strong> is how you talk to the harness, whether TUI, web, mobile, WhatsApp, or Telegram. The interesting question is how the <em>same</em> agent serves many front-ends, and there are 2 real patterns. One is a pub/sub bus, OpenCode style, where a headless server streams events to TUI, web, and desktop clients over HTTP+SSE so many clients observe 1 live session. The other is custom services bridging into 1 in-process loop, the Claude Code style.</p><p>The <strong>Observability layer</strong> is tracing, logging, metrics and evals sitting across everything, with tools like Opik, Langfuse, or Braintrust.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2QwS!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2QwS!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 424w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 848w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 1272w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2QwS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png" width="1456" height="614" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:614,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The layered anatomy of an agentic harness &#8212; the agentic loop at the core, wrapped by harness services, all running inside a durable runtime, with presentation and observability spanning the stack.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The layered anatomy of an agentic harness &#8212; the agentic loop at the core, wrapped by harness services, all running inside a durable runtime, with presentation and observability spanning the stack." title="The layered anatomy of an agentic harness &#8212; the agentic loop at the core, wrapped by harness services, all running inside a durable runtime, with presentation and observability spanning the stack." srcset="https://substackcdn.com/image/fetch/$s_!2QwS!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 424w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 848w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 1272w, https://substackcdn.com/image/fetch/$s_!2QwS!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fae792e86-7aa3-4a27-b515-9ce157ac0c19_2676x1129.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The layered anatomy of an agentic harness: The agentic loop at the core, wrapped by harness services, all running inside a durable runtime, with presentation and observability spanning the stack.</em></figcaption></figure></div><p>To see how the components connect, let&#8217;s follow a single message down the happy path: user &#8594; TUI &#8594; message queue &#8594; wait for the agent to be free &#8594; agent &#8594; LLM &#8594; tool &#8594; LLM &#8594; tool &#8594; &#8230; &#8594; LLM &#8594; answer &#8594; TUI &#8594; user.</p><p>Meanwhile, The TUI sends and receives over SSE. The priority gate decides when to inject a new message <em>between</em> loops rather than interrupting mid-loop. When the context window nears its limit (tokens &#8805; contextWindow &#8722; reserve), compaction runs, keeping the window as [system prompt] + [summary] + [recent tail]. And a single tool call can fan out into hooks, sandboxes, services, and permission gates.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Q7I0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Q7I0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 424w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 848w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 1272w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Q7I0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png" width="1400" height="656" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:656,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A user message buffered by the priority gate, run through the agentic loop's stream&#8594;check&#8594;tool&#8594;append&#8594;recurse cycle, then streamed back to the TUI as the answer &#8212; with compaction ([system prompt]+[summary]+[recent tail]) kicking in as the context window fills.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A user message buffered by the priority gate, run through the agentic loop's stream&#8594;check&#8594;tool&#8594;append&#8594;recurse cycle, then streamed back to the TUI as the answer &#8212; with compaction ([system prompt]+[summary]+[recent tail]) kicking in as the context window fills." title="A user message buffered by the priority gate, run through the agentic loop's stream&#8594;check&#8594;tool&#8594;append&#8594;recurse cycle, then streamed back to the TUI as the answer &#8212; with compaction ([system prompt]+[summary]+[recent tail]) kicking in as the context window fills." srcset="https://substackcdn.com/image/fetch/$s_!Q7I0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 424w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 848w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 1272w, https://substackcdn.com/image/fetch/$s_!Q7I0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc2553bc0-4c0e-4564-bf21-43e7f4773b22_1400x656.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>A user message buffered by the priority gate, run through the agentic loop&#8217;s stream&#8594;check&#8594;tool&#8594;append&#8594;recurse cycle, then streamed back to the TUI as the answer.</em></figcaption></figure></div><p>This skeleton, the loop, the queue, the runtime wiring, the message journey, is the commoditized 80%. As there is a ton going on on top of the basic agentic loop, let&#8217;s explore all the core components of the harness to get an intuition on what can be customized or built on top of it.</p><h2>The Tools</h2><p>The set of tools the LLM can call inside the agentic loop is the most visible part of a harness. Everything the model can invoke conforms to a single shape, a name, an input schema, and an <code>execute</code> method behind a flat registry.</p><p>Ground that in what a real harness ships. Claude Code organizes ~40 built-ins into 10 families, and these are what you get for free:</p><ul><li><p><strong>File I/O:</strong> <code>FileRead</code>, <code>FileWrite</code>, <code>FileEdit</code>, <code>Glob</code>, <code>Grep</code>. The model&#8217;s hands on your files. Read one, write a new one, edit in place, find files by name pattern with <code>Glob</code>, and search their contents with <code>Grep</code>.</p></li><li><p><strong>Execution:</strong> <code>Bash</code>. A single tool to run shell commands. The most powerful tool available that allows an agent to run shell, Python, TypeScript or in general interact with your machine.</p></li><li><p><strong>Orchestration:</strong> <code>EnterPlanMode</code> / <code>ExitPlanMode</code>, <code>Sleep</code>, <code>Agent</code> (spawn a subagent), <code>EnterWorktree</code> / <code>ExitWorktree</code>. These shape the work itself. Plan mode gates edits behind a read-only planning pass, <code>Sleep</code> pauses the loop, <code>Agent</code> spawns a subagent, and the worktree pair carves out an isolated branch to edit without touching the main tree.</p></li><li><p><strong>Tasks:</strong> <code>TaskCreate</code> / <code>Update</code> / <code>Get</code> / <code>List</code> / <code>Output</code> / <code>Stop</code>. A task state machine that lets the agent track a to-do list and run long jobs that outlive a single turn.</p></li><li><p><strong>Web:</strong> <code>WebSearch</code>, <code>WebFetch</code>. The window outward. Search the web, then pull a specific URL&#8217;s contents into context.</p></li><li><p><strong>MCP:</strong> an MCP tool factory + <code>ToolSearch</code>, <code>ListMcpResources</code>, <code>ReadMcpResource</code>, <code>MCPAuth</code>. This is how external tool servers plug in. The factory mints 1 tool per each tool from the MCP server to flatten out the tool discovery logic into a single tool set (e.g., <code>/mcp__brown__edit_content_prompt</code>). <code>ToolSearch</code> surfaces the right one when hundreds are attached, and the rest list resources, read them, and handle auth.</p></li><li><p><strong>Scheduling and misc:</strong> <code>ScheduleCron</code>, <code>RemoteTrigger</code>, <code>Skill</code> (a dispatcher, 1 tool with N skills by argument), <code>LSP</code>, <code>AskUser</code>. The odds and ends. Schedule a run on a cron, trigger one remotely, dispatch a skill by argument, query a language server with <code>LSP</code>, and hand a question back to the human with <code>AskUser</code>.</p></li></ul><p>The built-in tool families are the commoditized surface. The customizer&#8217;s job is to <strong>configure</strong> which tools each agent may call. The architect&#8217;s is to <strong>build</strong> new domain tools as MCP servers plugged into the same registry. That&#8217;s where your product&#8217;s actual capabilities live.</p><p>Tools are <em>what</em> the model can do. The agents&#8217; catalog is <em>who</em> does it.</p><h2>The Agent Catalog Is Just a Config File</h2><p>Each harness ships a set of predefined agents, and the version worth copying defines them as config, not code, because that makes them discoverable and pluggable without touching the loop. The format varies: a markdown file with YAML frontmatter, where the body is the prompt, in pi and Claude Code, or plain YAML or JSON in OpenCode. I reach for YAML, but the point is the same. The core fields are small: <code>name</code>, <code>mode</code>, <code>model</code>, <code>tools</code>, <code>disallowedTools</code>, and <code>permission</code>.</p><p>When you open Claude Code, you chat directly with the primary agent, the primary process. The trickiest part to understand is that both the primary and subagents can wear multiple hats. The agent catalog distcribes these hats, these modes the agent can take on.</p><p>A catalog worth copying looks like this, synthesized across the references (the <code>mode: primary | subagent | all</code> axis is OpenCode&#8217;s, while <code>Plan</code>, <code>Explore</code>, and <code>General Purpose</code> ship in Claude Code):</p><ul><li><p><strong>Build</strong> (mode: primary), the default agent.</p></li><li><p><strong>Plan</strong> (mode: primary), read-only.</p></li><li><p><strong>General Purpose</strong> (mode: subagent), the fallback when no specific agent fits.</p></li><li><p><strong>Explore</strong> (mode: subagent), read-only search and locate, running on a cheap model.</p></li><li><p><strong>Code Reviewer</strong> (mode: subagent), read-only and git/diff-aware.</p></li></ul><p>The <code>code-reviewer</code> subagent (in Claude Code) <code>tools</code> allowlist grants <code>FileRead</code>, <code>Grep</code>, <code>Glob</code>, and <code>Bash(git *)</code>, while its <code>disallowedTools</code> denylist blocks <code>FileEdit</code>, <code>FileWrite</code>, and <code>Bash(rm *)</code>. So it can read the tree and run git, but it can never edit a file or shell out to delete one. That dual allowlist/denylist, with rule syntax like <code>Bash(git *)</code>. The safety trick is that the scope is <em>narrowing only</em>. OpenCode enforces it by deriving a child&#8217;s permissions from its parent&#8217;s, so a delegated agent can never out-permission the one that spawned it.</p><p>Use the bundled agents as-is for everyday work, then author your own as YAML or markdown files. You rarely need to build a custom agent. That usually happens when you build your custom application. For example, I did it only for my deep research and writing skills, which required a ton of customization. Ultimately, ending up as completely apps covered as a skill.</p><p>To get the full picture, let&#8217;s understand how subagents work.</p><h2>A Subagent Is a New Loop</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!weZT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!weZT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 424w, https://substackcdn.com/image/fetch/$s_!weZT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 848w, https://substackcdn.com/image/fetch/$s_!weZT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 1272w, https://substackcdn.com/image/fetch/$s_!weZT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!weZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png" width="1087" height="351" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:351,&quot;width&quot;:1087,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A main orchestrator spawns a subagent through the Agent tool; the subagent runs its own loop, and only a compressed summary of its output is re-injected into the parent.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A main orchestrator spawns a subagent through the Agent tool; the subagent runs its own loop, and only a compressed summary of its output is re-injected into the parent." title="A main orchestrator spawns a subagent through the Agent tool; the subagent runs its own loop, and only a compressed summary of its output is re-injected into the parent." srcset="https://substackcdn.com/image/fetch/$s_!weZT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 424w, https://substackcdn.com/image/fetch/$s_!weZT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 848w, https://substackcdn.com/image/fetch/$s_!weZT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 1272w, https://substackcdn.com/image/fetch/$s_!weZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3acbea4f-ba49-4915-8860-1b83ae76c6e8_1087x351.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>A main orchestrator spawns a subagent through the Agent tool; the subagent runs its own loop, and only a compressed summary of its output is re-injected into the parent.</em></figcaption></figure></div><p>Most harnesses support subagents, though some, like pi, do it via plugins instead of natively. The hard part is keeping orchestrator and child communicating without the child&#8217;s full context polluting the parent loop and ensuring the orchestrator, &#8220;orchestrates&#8221; the subagents as expected. Remember that the orchestrator is an agent, not a workflow encoded in code, which means it can easily go off track and forget a step.</p><p>In Claude Code a subagent is <em>not new code</em>. It&#8217;s the same loop re-entered with a cloned context and a restricted tool list, and only a condensed summary flows back. A periodic ~30-second summarizer fork produces a live progress label plus a bounded final summary. The lesson to steal: a subagent is your existing loop, narrowed, with a summary on the return path. Only recently they started introducing subagents as new processes.</p><p>Harnesses almost never support swarm architectures where every agent talks to every other. They support a master&#8211;slave orchestrator topology where one main agent tracks the children.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TacJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TacJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 424w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 848w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 1272w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TacJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png" width="791" height="386" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:386,&quot;width&quot;:791,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Parent and subagent talk over a channel that sits outside the isolation boundary &#8212; here a queue the parent awaits, with the child's output compressed before it folds back into the loop.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Parent and subagent talk over a channel that sits outside the isolation boundary &#8212; here a queue the parent awaits, with the child's output compressed before it folds back into the loop." title="Parent and subagent talk over a channel that sits outside the isolation boundary &#8212; here a queue the parent awaits, with the child's output compressed before it folds back into the loop." srcset="https://substackcdn.com/image/fetch/$s_!TacJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 424w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 848w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 1272w, https://substackcdn.com/image/fetch/$s_!TacJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3cb62ab-55e5-42e2-aa0f-f2a8dfed9b29_791x386.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Parent and subagent talk over a channel that sits outside the isolation boundary.</em></figcaption></figure></div><p>Spawning is half the problem. The parent and child still have to talk, and there are three channels, ordered by how far apart the two run.</p><p>Cheapest is <strong>in-process</strong>: the child is a nested call, so its output is just a return value handed back to the caller. A <strong>queue</strong> sits one step out. The parent drops work on a message queue, the child consumes it, and the parent <em>awaits</em> a result event. Because the queue is a shared bus, other clients can watch the same exchange live, the way OpenCode streams a subagent&#8217;s events to many observers. Most decoupled are <strong>shared JSON files</strong>: a lock-serialized mailbox, one file per recipient, that agents in separate processes or worktrees write and poll. pi&#8217;s one-way subprocess, streaming JSON lines back to the parent, is the same idea narrowed to a pipe.</p><p>For most builders this is <strong>use-as-is, lightly configured</strong>. The spawn mechanism and orchestrator topology come standard, and all you configure is each subagent&#8217;s tool and permission scope and which agent it spawns. You only <strong>build</strong> when you need exotic isolation, like pi&#8217;s out-of-process model for untrusted children. That&#8217;s a rare need.</p><p>Now let&#8217;s see how skills fit into the picture.</p><h2>Skills</h2><p>A skill is one of the simplest implementations to understand yet one of the highest-impact things in the whole harness. It&#8217;s essentially a markdown recipe, instructions plus an allowed-tool set, that the model pulls in on demand.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ujpr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ujpr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 424w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 848w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 1272w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ujpr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png" width="1456" height="424" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:424,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Skills from three sources (bundled, user-defined, MCP prompts) are merged, capped at ~1% of the context window, assembled into a skills context, and injected as a system reminder.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Skills from three sources (bundled, user-defined, MCP prompts) are merged, capped at ~1% of the context window, assembled into a skills context, and injected as a system reminder." title="Skills from three sources (bundled, user-defined, MCP prompts) are merged, capped at ~1% of the context window, assembled into a skills context, and injected as a system reminder." srcset="https://substackcdn.com/image/fetch/$s_!ujpr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 424w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 848w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 1272w, https://substackcdn.com/image/fetch/$s_!ujpr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F915659a5-a406-4169-b9f4-d10cd3ac7214_1610x469.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Skills from three sources (bundled, user-defined, MCP prompts) are merged, capped at ~1% of the context window, assembled into a skills context, and injected as a system reminder.</em></figcaption></figure></div><p>Concretely, skills come from 3 sources merged together: bundled skills shipped with the harness (e.g. <code>src/skills/bundled</code>), defined skills dropped into <code>.agents/skills</code>, and MCP server prompts. The pipeline is short. A <code>GetSkills</code> step collects all 3 sources, caps the total at ~1% of the context window, assembles a single skills context, and wraps it as a <code>&lt;system_reminder&gt;</code>.</p><p>That 1% cap is the whole trick, and it works because of progressive disclosure. Skills are surfaced by name and description only, so the agent sees a cheap menu of capabilities and reads a skill&#8217;s body on demand, which is why the always-loaded skills context can be hard-capped at ~1% and still scale to dozens of skills. pi takes the same spirit further, surfacing its skills via prompt injection rather than as tools.</p><p>This is pure <strong>configure</strong>, or really authoring, and it&#8217;s the single best return on effort for the user and customizer tiers. Writing a markdown skill is the cheapest way to teach the harness a new workflow, and the 1% cap means you can pile on dozens.</p><p>Skills, tools, and subagents all hang off the loop, and they&#8217;re mostly things you configure. Memory is different. It&#8217;s the one component where you actually build your own layer.</p><h2>Memory Is the Layer You Actually Build</h2><p>In most harnesses, out-of-the-box memory is loaded directly into context, not via a tool. The model never calls a tool to &#8220;remember.&#8221; Relevant memories are read off disk and prepended to the system prompt <em>before</em> the turn runs, and new memories are extracted <em>after</em> the turn by a separate process.</p><p>A file-backed design, Claude Code-style, is worth grounding concretely. The store splits into 2 kinds of files. User-defined <code>.md</code> files come first: <code>AGENTS.md</code> is always loaded, and <code>**/AGENTS.md</code> is loaded dynamically per directory, on demand. LLM-extracted <code>.md</code> files come second: <code>MEMORY.md</code> is an always-loaded index, hard-capped at ~200 lines / 25 KB, while <code>logs/YYYY-MM-DD.md</code> is an append-only daily log where only the <em>relevant</em> logs are loaded. A small-model side-query ranks topic files from the log by their frontmatter description, not embeddings, and picks the top few to inject, which is debuggable and needs no vector store.</p><p>By default a forked extractor updates <code>MEMORY.md</code> live after each turn. A daily-log variant runs a nightly <code>/dream</code> distillation instead: a small LLM extracts the conversation into <code>logs/YYYY-MM-DD.md</code>, then a second distills those logs into <code>MEMORY.md</code>. In other words the pipeline looks like this: raw conversation &#8594; daily logs &#8594; durable memory.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!81Pd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!81Pd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!81Pd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png" width="1400" height="1380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1380,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Three out-of-the-box memory designs &#8212; file-backed, SQLite-backed, and an append-only session tree &#8212; plus the custom MCP-server memory layer that sits above all of them.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Three out-of-the-box memory designs &#8212; file-backed, SQLite-backed, and an append-only session tree &#8212; plus the custom MCP-server memory layer that sits above all of them." title="Three out-of-the-box memory designs &#8212; file-backed, SQLite-backed, and an append-only session tree &#8212; plus the custom MCP-server memory layer that sits above all of them." srcset="https://substackcdn.com/image/fetch/$s_!81Pd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!81Pd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6f2b5f4c-a07d-4241-ae41-aae257087452_1400x1380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Three out-of-the-box memory designs: file-backed, SQLite-backed, and an append-only session tree. Plus the custom MCP-server memory layer that sits above all of them.</em></figcaption></figure></div><p>Most harnesses use a file-based system for memory. Which is good enough for uses cases such as coding. Other tools, like Cursor or OpenClaw, build a vector index over your memory instead. That&#8217;s why many people report better memory from OpenClaw. As instead of parsing your whole memory as append only logs or forgetting context when building the <code>MEMORY.md</code> index, OpenClaw builds a vector index over your memory.</p><p>Here&#8217;s the heart of the build/configure/use thread, though. The defaults get you started and <code>AGENTS.md</code> is worth configuring, but the highest-leverage move is a <strong>custom memory layer behind an MCP server</strong>, a database exposed through an MCP server with your own read/write logic. Because it&#8217;s harness-independent, you jump from Claude Code to Cursor to anything and the agent instantly picks up who you are.</p><p>Real independence means owning your own context layer.</p><p>This is the one place to <strong>build</strong>, and it pays off for every tier that&#8217;s serious. The context layer behind an MCP server is the moat. It&#8217;s harness-portable, fully yours, and the thing that makes the assistant <em>your</em> assistant.</p><p>Owning your context is about <em>what</em> the agent knows. The next layer is about <em>where</em> its code runs, sandboxing, which protects you and, surprisingly, lets 1 harness scale to many jobs.</p><h2>The Sandbox: One Jail, Many Remote Workers</h2><p>The obvious reason for a sandbox comes first: it keeps the agent in a controlled environment with no direct access to your machine. Establish the key separation early.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!J4Lc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!J4Lc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 424w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 848w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 1272w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!J4Lc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png" width="1456" height="411" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:411,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;When the model issues a Bash command, the harness decides where it runs &#8212; remotely on Modal, locally in a sandbox (Docker/Firecracker), or directly &#8212; with the OS jail co-located with execution.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="When the model issues a Bash command, the harness decides where it runs &#8212; remotely on Modal, locally in a sandbox (Docker/Firecracker), or directly &#8212; with the OS jail co-located with execution." title="When the model issues a Bash command, the harness decides where it runs &#8212; remotely on Modal, locally in a sandbox (Docker/Firecracker), or directly &#8212; with the OS jail co-located with execution." srcset="https://substackcdn.com/image/fetch/$s_!J4Lc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 424w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 848w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 1272w, https://substackcdn.com/image/fetch/$s_!J4Lc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F87958c6d-55fa-4b3f-926c-4be4be8edb19_2162x611.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>When the model issues a Bash command, the harness decides where it runs:  remotely on Modal, locally in a sandbox (Docker/Firecracker), or directly on the host</em></figcaption></figure></div><p>Sandboxing lives at the Bash and PowerShell tool layer, not the UI. When the model issues a <code>Bash</code> tool call, a decision runs about where it executes. If remote, the command runs in a sandbox such as Modal. If local, the harness asks whether to use a sandbox at all: yes means it runs inside a local sandbox (Docker, Firecracker, &#8230;). No means it runs directly on your machine.</p><p>The enforcement detail worth stealing, the way Claude Code does it, is that the jail is derived from the same permission rules the agent already uses, and it always denies writes to its own settings file.</p><p>On top of security sandboxes can change how we define software architecture. Reframe sandboxes as workers from classic distributed systems: each sandbox is a worker that runs jobs in parallel, and 1 harness can manage and scale many of them. So the same harness that protects you locally can fan out dozens of remote jobs. Depending on your sandbox type, you can run data ingestion jobs or even training jobs if the VM has a GPU. Everything from your harness. Codex is a harness that is all in on remote sandboxing.</p><p>Now, let&#8217;s wrap up the article with the most important component: the permission layer.</p><h2>The Permission Layer Has Almost No AI in It</h2><p>The permission system is the hardest part to reason about, and the strange thing is it has essentially no AI in it, yet it&#8217;s what makes the whole system safe to run. Its job is narrow: for every tool call, decide to (a) run it, (b) ask the user, or (c) deny it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3SHl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3SHl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 424w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 848w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 1272w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3SHl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;For every tool call the harness resolves a decision &#8212; allow it, ask the user, or deny it &#8212; combining agent modes with user-defined permission rules.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="For every tool call the harness resolves a decision &#8212; allow it, ask the user, or deny it &#8212; combining agent modes with user-defined permission rules." title="For every tool call the harness resolves a decision &#8212; allow it, ask the user, or deny it &#8212; combining agent modes with user-defined permission rules." srcset="https://substackcdn.com/image/fetch/$s_!3SHl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 424w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 848w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 1272w, https://substackcdn.com/image/fetch/$s_!3SHl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc43c0d55-93a7-489c-8d9d-493acace2235_1945x972.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>For every tool call, the harness resolves a decision: allow it, ask the user, or deny it</em></figcaption></figure></div><p>The structure has 2 flavors. Agent modes change default behavior: <code>default</code>, <code>acceptEdits</code>, <code>bypassPermissions</code>, and <code>plan</code>. User-defined rules live in config, in <code>.agents/settings.json</code> and <code>.agents/settings.local.json</code>, where you declare what the agent can and cannot run, including wildcard rules like <code>Bash(git *)</code>. The harness combines mode metadata and user rules at runtime to resolve each call.</p><p>The <em>&#8220;Can use tool?&#8221;</em> question has 3 outcomes.</p><p><strong>Allow</strong> calls the tool. <strong>Ask</strong> surfaces it to the user, and on allow it calls the tool, while on deny it synthesizes a denial tool-result and continues. <strong>Deny</strong> synthesizes the denial directly.</p><p>When deciding what to do, the harness runs tool filter &#8594; user settings &#8594; mode.</p><p>Here&#8217;s the counterintuitive payoff. &#8220;Bypass everything&#8221; is not total. Plan mode is enforced <em>prompt-side</em>, via a system reminder telling the model to only edit the plan file.</p><p>Which shows how fragile these mechanisms still are, as we just hope for the best that the model will pick up the instruction.</p><p>You almost never build this. But it&#8217;s incredebly important to properly configure it. It&#8217;s probably the most important part to configure right to ensure it has just enough access to your data and machine.</p><h2>What&#8217;s Next</h2><p>These are just the core components that almost any agentic harness needs and has.</p><p>But there is more to it.</p><p>Worktrees for parallel isolated edits, multiprocessing subagents for true parallelism, and a plugin system for extending the harness without forking it. Which I will address in future articles.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Which component did you decide to build rather than configure? Was owning it worth it, or did you reinvent something the harness already had?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/agentic-harness-system-design/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/agentic-harness-system-design/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/agentic-harness-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/agentic-harness-system-design?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[How to Keep Your AI Agent's Knowledge Graph Clean]]></title><description><![CDATA[The resolution, deduplication, and review pipeline that keeps agent memory usable as it grows.]]></description><link>https://www.decodingai.com/p/keep-knowledge-graph-clean</link><guid isPermaLink="false">https://www.decodingai.com/p/keep-knowledge-graph-clean</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 02 Jun 2026 05:00:53 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!p5lm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p5lm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p5lm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p5lm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1382657,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/199956327?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!p5lm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!p5lm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F71377412-24c1-4531-883e-22f3a5057aa5_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Two months ago, I started building unified memory layers on top of knowledge graphs. One question kept coming back from readers. How do you handle entity resolution and deduplication without corrupting the graph?</p><p>Rather than guessing, I spent serious time studying how mem0, cognee, and Neo4j actually solve it. The recurring question exposes a confusion almost everyone shares. People treat entity resolution and deduplication as the same step.</p><p>That confusion is exactly what corrupts graphs. People collapse naming and identity into 1 fuzzy check.</p><p>Also, if the merging step is not properly designed, 2 different real-world entities can silently merge, corrupting your graph.</p><p>Resulting in losing the trust in your graph that made it worth building. The graph quietly rots. Nobody trusts it, and the entire memory layer you invested in goes unused.</p><p>The failure is invisible until it becomes expensive to undo. The fix is to separate naming from identity.</p><p>We will walk through the end-to-end pipeline. This includes LLM extraction, entity resolution for naming, embedding the full node and deduplication for identity. Plus, the 2 safety nets most tutorials skip.</p><p>We covered the full <a href="https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system">memory-system design</a> and the <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">ontology design</a> in prior articles. This piece focuses only on keeping the graph clean. By the end, you will be able to design a graph that stays clean and usable as it grows.</p><div class="callout-block" data-callout="true"><h2><a href="https://www.youtube.com/watch?v=BtY6hqNpMNk">Why We Killed RAG in Production (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://www.youtube.com/watch?v=BtY6hqNpMNk" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ciWB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ciWB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://www.youtube.com/watch?v=BtY6hqNpMNk&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!ciWB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ciWB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F026e9a22-c706-4acb-a74d-7aa50c5173db_1280x720.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This article shows how to keep a graph memory layer clean. In a recent podcast, I covered the decision that comes before it: whether you need retrieval at all.</p><p>I explain why we killed RAG for a financial advisor product. All of an advisor&#8217;s data summed to 64,000 tokens, so loading the full context beat RAG&#8217;s zigzag retrieval loop. The formula I use: your data-to-context-window ratio.</p><p>We also get into regretting MCP everywhere, treating vibe-coded output as a compilation step, and why AI evals become the real job once the model writes the code.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.youtube.com/watch?v=BtY6hqNpMNk&quot;,&quot;text&quot;:&quot;Watch the episode&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.youtube.com/watch?v=BtY6hqNpMNk"><span>Watch the episode</span></a></p></div><h2>One Pipeline, Five Steps</h2><p>In goes a document or a conversation turn. Out comes a set of canonical, deduplicated nodes correctly wired into the existing graph. Everything between is about making sure each new node is named and identified right.</p><p>First, an LLM extractor reads the text and emits entities and relationships connected by <code>(entity, relationship, entity)</code> triplets. It anchors within the POLE+O, Facts, and Preferences ontology. This ensures it only extracts the entity types you actually care about, as we explained in depth <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">in this article</a>.</p><p>For example, a sentence about a person working at a company becomes a <code>(Person)-[:WORKS_AT]-&gt;(Organization)</code> triplet. The ontology told the extractor those are the types that matter.</p><p>If using only LLMs for extraction becomes too costly, you can use a cost-tiered cascade here, starting with fast statistical models like spaCy for common entities, moving to zero-shot models like GLiNER for domain-specific types, and falling back to an LLM for complex cases.</p><p>Before touching the graph, we must decide what this new entity should be called. The system normalizes its name against existing nodes of the same type. This is the finding-the-canonical-name step, and no merges happen yet.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qe_I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qe_I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 424w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 848w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 1272w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qe_I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png" width="1200" height="1009" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1009,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;From raw documents to a clean graph node: extraction, resolution, embedding, deduplication, then the merge/flag/add decision.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="From raw documents to a clean graph node: extraction, resolution, embedding, deduplication, then the merge/flag/add decision." title="From raw documents to a clean graph node: extraction, resolution, embedding, deduplication, then the merge/flag/add decision." srcset="https://substackcdn.com/image/fetch/$s_!qe_I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 424w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 848w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 1272w, https://substackcdn.com/image/fetch/$s_!qe_I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9ae16fdb-fca4-480b-b88a-c43f8b35a461_1200x1009.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>From raw documents to a clean graph node: extraction, resolution, embedding, deduplication, then the merge/flag/add decision.</em></figcaption></figure></div><p>Next, we compute an embedding over the entity&#8217;s full context. This includes its name, type, and attributes. We embed more than just its bare name. This is what later lets deduplication compare identity rather than spelling.</p><p>We compare the embedded node against existing nodes. This decides whether it is the same real-world entity as one already in the graph.</p><p>Based on the deduplication outcome, the system makes a final routing decision. It either merges into an existing node, flags the pair for human review, or adds a brand-new node.</p><p>A new mention of a company gets extracted as a typed entity. The resolution step normalizes it to a canonical name. Then, it gets embedded with its full context so we capture its semantic meaning. It is compared against existing same-type nodes to verify its identity. Finally, it gets added, merged, or flagged for review.</p><p>Resolution and deduplication are 2 distinct decisions doing 2 distinct jobs. Let&#8217;s zoom in on each one.</p><h2>Entity Resolution: &#8220;What Should We Call This?&#8221;</h2><p>During resolution we find the canonical name for each entity. It answers <em>&#8220;what should we call this?&#8221;</em>.</p><p>It handles typos, acronyms, and surface-form similarity. These are the noisy ways humans and documents write the same thing. It uses exact, fuzzy, and semantic matching in a short-circuit chain.</p><p>The short-circuit chain passes the entity to the next matcher only if no confident match is found. If exact match fails, it tries fuzzy match. If fuzzy match fails, it tries semantic match (using light embeddings only on the name).</p><p>But it matches only against the names of existing nodes of the same type. You never compare a <code>PERSON</code> name against an <code>ORGANIZATION</code> name.</p><p>&#8220;NYC&#8221; resolves to &#8220;New York City&#8221;. &#8220;JP Morgan&#8221; resolves to &#8220;JPMorgan Chase&#8221;. The 3 forms <code>"John Smith "</code>, <code>"john smith"</code>, and <code>"Jon Smith"</code> all collapse to 1 canonical &#8220;John Smith&#8221;.</p><p>This happens because resolution absorbs whitespace, casing, and typo variations. Fuzzy string matching uses token-based comparison to handle word order and partial matching for abbreviations. At this stage the system only updates the node&#8217;s <code>canonical_name</code> property. No graph merges happen yet.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p1qh!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p1qh!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 424w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 848w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 1272w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p1qh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png" width="1400" height="536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:536,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:558276,&quot;alt&quot;:&quot;Resolution chains exact &#8594; fuzzy &#8594; semantic matching against same-type names to assign a canonical name &#8212; without ever merging nodes.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Resolution chains exact &#8594; fuzzy &#8594; semantic matching against same-type names to assign a canonical name &#8212; without ever merging nodes." title="Resolution chains exact &#8594; fuzzy &#8594; semantic matching against same-type names to assign a canonical name &#8212; without ever merging nodes." srcset="https://substackcdn.com/image/fetch/$s_!p1qh!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 424w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 848w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 1272w, https://substackcdn.com/image/fetch/$s_!p1qh!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F37cc7c05-b7d4-4317-a222-5b4fa3ac46ea_1400x536.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Resolution chains exact &#8594; fuzzy &#8594; semantic matching against same-type names to assign a canonical name (without ever merging nodes).</em></figcaption></figure></div><p>Often, you also keep track of a list of aliases for each node. Whenever you find a new hit via fuzzy or semantic match that doesn&#8217;t match the current <code>canonical_name</code>, you add it to the list of aliases. Like this, in future checks you can speed up matching by checking the alias list first.</p><p>Similar names are not strong enough evidence that 2 entities are identical. This is the line most people blur. Blurring it is what causes silent corruption.</p><p>Apple the company is not Apple the fruit. They have different types, so type-gating already separates them. A harder example is Jensen Huang the CEO of NVIDIA versus a doctor in Taipei with the same name.</p><p>They have the same name and the same type. Yet they are 2 different real-world people. Naming similarity alone would happily fuse them.</p><p>Still, canonical names are extremely useful for GROUP BY operations where, during querying and visualizations, we can quickly understand the data. During human review, we can even spot duplicates and resolve them manually.</p><p>That is why identity is a separate decision. Resolution has told us what to call the node. It has deliberately not told us whether the node is a duplicate.</p><p>That second, riskier question belongs to deduplication.</p><h2>Deduplication: &#8220;Is This the Same Entity?&#8221;</h2><p>Deduplication is the identity layer. It answers the harder question: <em>&#8220;is this the same real-world entity?&#8221;</em>. It is the step where merges actually happen <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">[5]</a>.</p><p>In goes 1 embedded node. Out comes a single routing decision: merge into an existing node, flag it for review, or create a new node.</p><p>The system embeds the full entity context. It compares it against existing nodes using semantic and fuzzy similarity across that full context. The richer signal is what lets it distinguish 2 same-named, same-type entities that resolution could not.</p><p>By the context of a node, we refer to the entity&#8217;s attributes such as its text, image, video content or even its metadata properties such as a person&#8217;s email or date of birth. Or an object&#8217;s model or manufacturer. Still, you don&#8217;t want to embed everything, such as identifier, but per each ontology type pick the fields that contain the highest signal.</p><p>The combined deduplication score is an explicit weighted blend. It uses the embedding score multiplied by 0.7 and the fuzzy score multiplied by 0.3. Based on a similarity score from 0 to 1, we have 3 bands.</p><p>High confidence (&#8805;0.95) triggers an auto-merge. Medium confidence (0.85&#8211;0.95) flags the pair for human review. Low confidence (&lt;0.85) creates a new node.</p><p>Near-certain identity is allowed to merge automatically. The uncertain middle is escalated. Weak evidence just becomes a fresh node.</p><p>False merges silently corrupt the graph. The corruption is invisible until it is expensive. Take the Paris example: 2 <code>LOCATION</code> nodes both named &#8220;Paris&#8221;.</p><p>One is the capital of France, and the other is Paris, Texas. They have the same name, the same type, and very similar bare-name embeddings. But they are 2 different places.</p><p>The dangerous part is the middle band, the gray area. This is where the system is not sure and a human has to step in.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HtX8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HtX8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 424w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 848w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 1272w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HtX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png" width="1400" height="785" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:785,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Deduplication scores full-context similarity, then routes to auto-merge, human review, or a new node &#8212; stronger evidence earns more irreversible action.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Deduplication scores full-context similarity, then routes to auto-merge, human review, or a new node &#8212; stronger evidence earns more irreversible action." title="Deduplication scores full-context similarity, then routes to auto-merge, human review, or a new node &#8212; stronger evidence earns more irreversible action." srcset="https://substackcdn.com/image/fetch/$s_!HtX8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 424w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 848w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 1272w, https://substackcdn.com/image/fetch/$s_!HtX8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cbddf49-7c66-407a-946e-57baa4d3c128_1400x785.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Deduplication scores full-context similarity, then routes to auto-merge, human review, or a new node.</em></figcaption></figure></div><h2>When Confidence Lands in the Gray Zone</h2><p>When a deduplication score lands in the medium band (0.85&#8211;0.95), the system deliberately does not merge. It flags the pair for a human to decide, as merging is a dangerous operation we should be really deliberate about.</p><p>The source node gets tombstoned, meaning it is kept queryable for forensics but skipped from future matching. Actually undoing a merge means re-ingesting the source data. That reversibility cost is the whole reason for the gray zone.</p><p>Whenever a new entity is flagged for human review, a new node is created and a <code>(:Entity)-[:SAME_AS {status:'pending', confidence}]-&gt;(:Entity)</code> edge is added inside the graph itself. The human review step transitions that <code>status</code> to <code>confirmed</code> or <code>rejected</code>. The review queue is just a Cypher query over pending <code>SAME_AS</code> edges, ordered by confidence.</p><p>For each flagged pair, the reviewer answers 1 question. Is this actually a duplicate, a new node, or neither?</p><p>This usually happens to entities that are related but not identical. The Codex model and the Codex CLI are related, but not the same object. The same applies to Jensen Huang the CEO versus a same-named doctor in Taipei.</p><p>This is hardest at the start of an entity&#8217;s lifecycle. When metadata is scarce, similarity spikes, and you risk polluting 1 node with another&#8217;s attributes.</p><p>Human review catches the uncertain pairs the live pipeline surfaces. But some duplicates never get surfaced at all. That is the gap the dream pipeline closes.</p><h2>Cleaning the Graph While It Sleeps</h2><p>While the system ingests documents, data often flows through in parallel. If 2 entities are processed at the same time, the resolution and deduplication steps never get to compare them against each other.</p><p>The system would never check whether Claude Code from Conversation X and Claude Code from Document Y are the same entity, because neither existed in the graph when the other was written.</p><p>You run a dream pass every night. It re-runs the deduplication pass on recently ingested nodes only. Otherwise, you will have to loop through all nodes in the graph. Which as the graph grows, becomes increasingly expensive.</p><p>It does not run the full resolution chain. Because the embeddings were already computed at ingest time, this is a light operation. It is primarily database reads and writes, not fresh model calls. Since it mostly adds I/O pressure, run it when organic traffic is low, which is usually during the night, hence the name <code>the dream pipeline</code>.</p><h2>What&#8217;s Next</h2><p>I&#8217;ve spent the past 4 months building unified memory layers on top of knowledge graphs, and I learned that keeping them clean is the hardest part. Keeping your knowledge graph clean is the maintenance step that decides whether the graph ever gets used. A graph full of noise, fragments, and false merges will not be trusted or queried.</p><p>In case you want to learn more, remember that we also covered the full <a href="https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system">memory-system architecture via knowledge graphs</a> and the <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">ontology design</a> in prior articles.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>What are the core strategies you&#8217;ve used to keep your knowledge graph clean and usable? Something close to our approach here, or something completely different?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/keep-knowledge-graph-clean/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/keep-knowledge-graph-clean/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/keep-knowledge-graph-clean?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/keep-knowledge-graph-clean?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Iusztin, P. (n.d.). Understanding the Neo4j Graph Agent Memory System. Decoding AI Magazine. <a href="https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system">https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system</a></p></li><li><p>Iusztin, P. (n.d.). Ship a Knowledge Graph Ontology in 5 Minutes. Decoding AI Magazine. <a href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes">https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes</a></p></li><li><p>POLE+O Data Model. (n.d.). Neo4j Labs. <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">https://neo4j.com/labs/agent-memory/explanation/poleo-model/</a></p></li><li><p>How Entity Extraction Works. (n.d.). Neo4j Labs. <a href="https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/">https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/</a></p></li><li><p>Entity Resolution and Deduplication. (n.d.). Neo4j Labs. <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Stop Chasing the Perfect Ontology]]></title><description><![CDATA[Start with a fixed, generic base and extend only when your data demands it.]]></description><link>https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes</link><guid isPermaLink="false">https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 26 May 2026 05:00:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!HeOr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HeOr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HeOr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HeOr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1173447,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/198955243?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HeOr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!HeOr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc87b2d2f-a13e-458f-8014-2d574171418c_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>For a while now I&#8217;ve been trying to build a proper memory layer on top of my research, writing, and content creation. Today it all lives in my Second Brain in Obsidian, where the primitives are files like notes, videos, and articles.</p><p>What I actually want is to shift those primitives from files to entities and relationships, such as people, locations, objects, topics, preferences, and facts. I want the memory to get closer to reality so I can watch how things evolve over time. I want a knowledge graph.</p><p>Everyone agrees knowledge graphs and GraphRAG provide a more performant substrate for a unified agent memory layer than plain RAG. But kicking one off is far harder. The resistance always collapses to the same wall: how you model your data. Your ontology is the hardest part of the system.</p><p>If you can&#8217;t define your ontology properly for your domain, the graph won&#8217;t represent the reality you want. The right entities and relationships simply aren&#8217;t there. As a result, GraphRAG ends up performing worse than the simple RAG you were trying to beat.</p><p>This translates straight to a memory layer. There&#8217;s no dodging it. Even if you stay file-only (a &#8220;virtual knowledge graph,&#8221; like an LLM knowledge base over your notes), you still hit the same data-modelling question: which primitives, and which entities, do you even extract?</p><p>The instinctive reaction is to design the perfect, complete ontology upfront. That&#8217;s exactly the trap that freezes the project.</p><p>The strategy is a not-overkill ontology. You need something flexible enough to kick off with almost no friction before you really know your domain, extending it with domain-specific detail as you explore your data.</p><p>Concretely, you use a small, fixed, generic, but extendable noun data model, known as POLE+O. Plus two core primitives, Preferences and Facts, for everything that doesn&#8217;t fit into the nouns.</p><p>You ship something that works, then add subtypes as a lightweight data-exploration step shows you where the generic types clash with your real data.</p><p>This approach lets you stand up a knowledge-graph memory layer for your own assistant without burning weeks on schema design. To build this, we first need to understand what an ontology actually is and why targeted models beat exhaustive ones.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Start Your Transition Into AI Engineering (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!XTiA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!XTiA!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 424w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 848w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 1272w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!XTiA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png" width="463" height="488.3527827648115" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1175,&quot;width&quot;:1114,&quot;resizeWidth&quot;:463,&quot;bytes&quot;:null,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!XTiA!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 424w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 848w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 1272w, https://substackcdn.com/image/fetch/$s_!XTiA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F977ee5b6-01a9-4bf9-a923-d092a8f5ac28_1114x1175.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This article showed how to design the ontology your knowledge-graph memory needs. My <a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a> shows the harness around it. I just released a free preview to build and run a working agent in 5 minutes.</p><p>You build a multi-agent system with two MCP servers (Research Agent + Writing Workflow), a deep research algorithm, an evaluator-optimizer loop, observability, and LLM-as-judge evals. Patterns required to ship AI.</p><p>Built for software, data engineers or scientists transitioning into AI engineering.</p><p>7 free lessons, 2 MCP agents ready for your GitHub portfolio. Part of our 35-lesson course. Rated 5/5 by 300+ students.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start the free preview &#8594;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start the free preview &#8594;</span></a></p></div><h2>What Is an Ontology?</h2><p>An ontology is the formal answer to 1 question. When you read the world, what do you write down as nodes, and what do you draw as edges? It specifies the kinds of things that exist in your domain, their properties, and how they relate to each other.</p><p>The ontology&#8217;s job is to map a targeted slice of the real world into the digital world. A good ontology is highly targeted to the problem you actually want to solve. If you over-model, you drown in noise and never ship. Plus, it get&#8217;s extremely expensive to extract and maintain the knoweldge graph. If you under-target, the graph doesn&#8217;t reflect the reality you care about.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!shkp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!shkp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 424w, https://substackcdn.com/image/fetch/$s_!shkp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 848w, https://substackcdn.com/image/fetch/$s_!shkp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 1272w, https://substackcdn.com/image/fetch/$s_!shkp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!shkp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png" width="1400" height="1202" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1202,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;An ontology is a deliberately narrow funnel from the real world into a queryable graph.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="An ontology is a deliberately narrow funnel from the real world into a queryable graph." title="An ontology is a deliberately narrow funnel from the real world into a queryable graph." srcset="https://substackcdn.com/image/fetch/$s_!shkp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 424w, https://substackcdn.com/image/fetch/$s_!shkp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 848w, https://substackcdn.com/image/fetch/$s_!shkp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 1272w, https://substackcdn.com/image/fetch/$s_!shkp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6da9e68c-1cec-4f99-afe9-ada0003fd270_1400x1202.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>An ontology is a deliberately narrow funnel from the real world into a queryable graph.</em></figcaption></figure></div><p>Look at concrete, shipped ontologies for real-world proof. The <a href="https://create-context-graph.dev/docs/reference/domain-catalog">create-context-graph</a> domain catalog made by Neo4j publishes 22 ready-made domain ontologies. Every single one lands at exactly 10 to 12 entity types. They use a shared 5-noun base plus only 5 to 7 domain-specific nouns.</p><p>For example, the Personal Knowledge domain models the world as Note, Contact, Project, Topic, Bookmark, and JournalEntry. The Agent Memory uses Agent, Conversation, Memory, ToolCall, and Session. The lesson here is that real ontologies are small on purpose. They capture only the entities required to answer the questions the system is designed for.</p><p>So if targeted and small is the goal, why does everyone &#8212; me included &#8212; reach for big and perfect first? That&#8217;s the trap.</p><h2>The Overkill Trap: Why My Knowledge Graphs Never Shipped</h2><p>When I first encountered the ontology concept, I assumed I had to study my domain in depth. I thought I needed to model all of finance, for example, and design the ideal ontology before working with any real data. You can&#8217;t actually do that before you have a system running and data to look at. You just pile up assumptions that mostly turn out wrong.</p><p>I got frozen. Every knowledge-graph solution I started stayed on my laptop and never got used, because I was waiting on an ideal ontology I could never reach. Without understanding the ontology, I couldn&#8217;t even write a decent extraction step to populate it. I was deadlocked, bringing 0 value.</p><p>The breakthrough was realizing I need a couple of models that let me start generic and extend over time. As I get more data, analyze it, and actually understand my problem, the schema evolves. Let&#8217;s meet the base model that lets you start in 5 minutes instead of 5 weeks.</p><h2>The POLE+O Data Model</h2><p>POLE+O is a tiny, fixed, top-level vocabulary that can classify almost anything you pull out of text. It stands for Person, Object, Location, Event, and Organization <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">[2]</a>. It originated in law-enforcement and intelligence analysis. The Organization type was added for general-purpose entity extraction. The point of a fixed base is queryability. There are always exactly 5 base nouns to filter on, so the graph stays answerable no matter how it grows underneath.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wK0q!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wK0q!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 424w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 848w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 1272w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wK0q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png" width="1400" height="1159" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1159,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;5 fixed base nouns, each extensible with optional subtypes &#8212; the base never changes, so every refinement is additive.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="5 fixed base nouns, each extensible with optional subtypes &#8212; the base never changes, so every refinement is additive." title="5 fixed base nouns, each extensible with optional subtypes &#8212; the base never changes, so every refinement is additive." srcset="https://substackcdn.com/image/fetch/$s_!wK0q!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 424w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 848w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 1272w, https://substackcdn.com/image/fetch/$s_!wK0q!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F34af01f1-f989-43ca-a1ca-f0e76cfa57fd_1400x1159.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>5 fixed base nouns, each extensible with optional subtypes</em></figcaption></figure></div><p>Person covers people, aliases, and personas. Object covers physical or digital things. Location covers places, addresses, and regions. Event covers meetings, transactions, and incidents. Organization covers companies, teams, and institutions. Two or three of these catch the overwhelming majority of what a personal assistant needs.</p><p>Here are POLE+O&#8217;s five base types and the default subtypes each one ships with:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yyhn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yyhn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 424w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 848w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 1272w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yyhn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png" width="1456" height="670" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:670,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;table&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="table" title="table" srcset="https://substackcdn.com/image/fetch/$s_!yyhn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 424w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 848w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 1272w, https://substackcdn.com/image/fetch/$s_!yyhn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7cc57663-f5d0-4f97-b81a-60c1bf2c34b9_1920x883.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here&#8217;s the beauty of this approach. You extend the base nouns with your own subtypes, and that&#8217;s how you tailor a generic ontology to your specific domain. It works exactly like object-oriented programming. You start from base classes you adopt without thinking. Then you subclass into specifics as your use case clarifies.</p><p>You can kick off with nothing extended and add concrete types only as you understand your data better. Neo4j&#8217;s <a href="https://github.com/neo4j-labs/agent-memory">agent-memory</a> library uses precisely this approach. POLE+O is its default, swappable ontology.</p><p>The data-exploration workflow runs in a simple loop. First, kick off with generic POLE+O. Second, run an exploration extraction over your real data. Forget production reliability. You only care about understanding what&#8217;s there. Third, inspect the graph for clashes where the generic model lies about your data. Fourth, add or rename subtypes to fix each clash. Finally, repeat the process. You won&#8217;t get it perfect, and that&#8217;s the point. You iterate like any other AI app instead of freezing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pksj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pksj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 424w, https://substackcdn.com/image/fetch/$s_!pksj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 848w, https://substackcdn.com/image/fetch/$s_!pksj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 1272w, https://substackcdn.com/image/fetch/$s_!pksj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pksj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png" width="1400" height="1351" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1351,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;You don't theorize subtypes &#8212; you discover them by watching where generic POLE+O mislabels your real data, then patch the clash and loop.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="You don't theorize subtypes &#8212; you discover them by watching where generic POLE+O mislabels your real data, then patch the clash and loop." title="You don't theorize subtypes &#8212; you discover them by watching where generic POLE+O mislabels your real data, then patch the clash and loop." srcset="https://substackcdn.com/image/fetch/$s_!pksj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 424w, https://substackcdn.com/image/fetch/$s_!pksj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 848w, https://substackcdn.com/image/fetch/$s_!pksj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 1272w, https://substackcdn.com/image/fetch/$s_!pksj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3cbabfc9-cba1-433b-8ed2-b5d593ef3c81_1400x1351.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>You discover subtypes by watching where generic POLE+O mislabels your real data, then patch the clash and loop.</em></figcaption></figure></div><p>Look at named examples from real extraction runs. Claude Code comes back tagged as a Person when it&#8217;s clearly an Object. The &#8220;AI Engineer&#8221; conference lands as an Event when you wanted an Organization. DeepSeek is tagged a Person, not an Object.</p><p>Portugal and New York both get a flat Location label even though one&#8217;s a country and one&#8217;s a city. An agentic harness shows up as a generic Object when, for knowledge work, you&#8217;d rather have a Topic type. Each clash is a signal to add 1 subtype, not to redesign the whole schema.</p><p>POLE+O nouns and their subtypes cover the things in your world. But to fill in the gaps there are two specials tricks we have to go over.</p><h2>Preferences: The Things a Noun Likes</h2><p>Preferences are the second family of entities you attach to the graph. They are things a noun likes or dislikes. A Preference is a characteristic of an entity. It represents a stance. The canonical case is a person who likes, prefers, or dislikes something.</p><p>Concretely, a Preference entity looks like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3KUZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3KUZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3KUZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png" width="1456" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!3KUZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!3KUZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3a9cbc22-bb97-4bd4-99fa-a86ad59e6c60_2120x819.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><code>category</code> groups the preference, <code>preference</code> is the statement itself, and <code>context</code> optionally records when or where it applies. <code>confidence</code> runs from 0 to 1. The <code>embedding</code> makes it semantically searchable.</p><p>Make it concrete. &#8220;Loves Italian food&#8221;, &#8220;prefers dark mode&#8221;, and &#8220;dislikes long meetings&#8221; are clear examples. Each is a stable stance the assistant should remember and adapt to.</p><p>By default, a Preference hangs off the Person. That&#8217;s the most common and useful case. You can extend preferences to other objects, like an Organization&#8217;s policies, a car&#8217;s settings, or an Event&#8217;s dress code.</p><p>Because I&#8217;m building a personal assistant, I start by attaching Preferences only to the Person. This keeps the graph clean, low-noise, and small. I&#8217;ll extend it later only when a concrete use case demands it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hSPb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hSPb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 424w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 848w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 1272w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hSPb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png" width="1400" height="879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:879,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Start simple &#8212; preferences attached only to the user; the dotted edges are extensions you add only when you need them.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Start simple &#8212; preferences attached only to the user; the dotted edges are extensions you add only when you need them." title="Start simple &#8212; preferences attached only to the user; the dotted edges are extensions you add only when you need them." srcset="https://substackcdn.com/image/fetch/$s_!hSPb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 424w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 848w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 1272w, https://substackcdn.com/image/fetch/$s_!hSPb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F76d5574d-28fd-47a0-94e4-4a735f05dbd4_1400x879.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Preferences attached only to the user. The dotted edges are extensions you add only when you need them.</em></figcaption></figure></div><p>Preferences are the personalization layer. They act as the memory of the user&#8217;s stances. They are the &#8220;sweet sauce&#8221; that makes every future response feel tailored.</p><p>There is one issue. Plenty of useful knowledge is just an atomic fact. Forcing all of that into the ontology is how graphs explode in complexity. The fix is a deliberately generic primitive.</p><h2>Facts: The Trick You Haven&#8217;t Thought Of</h2><p>The Facts entity is the fallback for everything that doesn&#8217;t cleanly fit a noun or a Preference. You drop the claim into a generic Fact. This is the move that keeps the ontology small and stops you from over-thinking the schema.</p><p>A Fact is the closest thing to a classic-RAG chunk. An LLM produces each Fact during extraction. Each Fact holds a single, atomic concept which works like a charm via semantic search.</p><p>The beauty is that with facts you avoid the usual chunking errors, such as splits mid-thought, mixed concepts, and arbitrary boundaries. In reality, a Fact is a triplet. A subject, predicate, and object like &#8220;Eiffel Tower / is / 330m tall&#8221; gets embedded and stored as 1 granular unit.</p><p>Here is the shape of a Fact entity:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g51f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g51f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!g51f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!g51f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!g51f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g51f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png" width="1456" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!g51f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!g51f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!g51f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!g51f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa162972e-7ad0-4275-94ec-4a9e654d287a_2120x819.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The triplet &#8212; <code>subject</code>, <code>predicate</code>, <code>object</code> &#8212; is the whole fact. <code>valid_from</code> and <code>valid_until</code> give it optional bi-temporal validity. The <code>embedding</code>, computed over the concatenated triplet, is what makes the fact retrievable by semantic search.</p><p>It&#8217;s confusing that we have a triplet stored as a node. But this is what it makes it flexible. We don&#8217;t worry about modeling these one-off triplets directly into the ontology, but the LLM extracts them as-is from the text.</p><p>Facts are usually wired to nothing. They have no relationships to other entities. They are retrieved only via semantic search and text search. A Fact stays in the graph but is independent of it. This works because a graph store runs vector search and graph traversal in the same query engine <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">[4]</a>. Which means facts are retrieved only via semantic/text search.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Wtw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Wtw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 424w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 848w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 1272w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Wtw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png" width="1400" height="1138" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1138,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Facts are atomic triplets retrieved by similarity and wired to nothing; POLE+O entities are reached by walking the graph. Same store, two retrieval modes.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Facts are atomic triplets retrieved by similarity and wired to nothing; POLE+O entities are reached by walking the graph. Same store, two retrieval modes." title="Facts are atomic triplets retrieved by similarity and wired to nothing; POLE+O entities are reached by walking the graph. Same store, two retrieval modes." srcset="https://substackcdn.com/image/fetch/$s_!-Wtw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 424w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 848w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 1272w, https://substackcdn.com/image/fetch/$s_!-Wtw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc37ed613-1a16-40f7-9607-2ed492a787cb_1400x1138.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Facts are atomic triplets retrieved by similarity and wired to nothing; POLE+O entities are reached by walking the graph. Same store, two retrieval modes.</em></figcaption></figure></div><p>Facts let you ship a memory layer before you have the perfect ontology. Anything you can&#8217;t yet model degrades gracefully into a searchable atomic node instead of blocking the build. Early on, you lean on Facts. As the graph matures, claims migrate toward typed entities and edges. It costs nothing to schema and nothing to maintain when entities merge or get deleted.</p><h2>What&#8217;s Next</h2><p>The takeaway is the posture. An ontology is a living artifact you bootstrap from a fixed generic base and grow through a data-exploration loop, exactly like any other AI application.</p><p>If you want to see the whole strategy implemented, the fastest path is to play with Neo4j&#8217;s <a href="https://github.com/neo4j-labs/agent-memory">agent-memory</a> SDK or its MCP server. It uses POLE+O as a swappable default, subtypes as cheap extensions, and Preferences and Facts as first-class primitives. Studying it is what made all of this finally click for me.</p><p>I&#8217;m actively migrating my own Obsidian Second Brain toward the POLE+O, Preferences, and Facts primitives. This turns thousands of files into a graph I can actually traverse, visualize, and watch evolve over time.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>If you worked with Knowledge Graphs, what was your process in discovering your own ontology?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/ship-a-knowledge-graph-ontology-in-5-minutes?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Create Context Graph. (n.d.). Domain Catalog. create-context-graph. https://create-context-graph.dev/docs/reference/domain-catalog</p></li><li><p>Neo4j Labs. (n.d.). POLE+O Data Model. Neo4j Agent Memory. https://neo4j.com/labs/agent-memory/explanation/poleo-model/</p></li><li><p>Neo4j Labs. (n.d.). Neo4j Agent Memory. GitHub. https://github.com/neo4j-labs/agent-memory</p></li><li><p>Neo4j Labs. (n.d.). Why Neo4j? Graph-Native Memory Architecture. Neo4j Agent Memory. https://neo4j.com/labs/agent-memory/explanation/graph-architecture/</p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Inside Neo4j's Agent Memory]]></title><description><![CDATA[The knowledge-graph patterns that turn one-shot conversations into compounding intelligence.]]></description><link>https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system</link><guid isPermaLink="false">https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 19 May 2026 08:55:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5ypW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5ypW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5ypW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5ypW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1355267,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/197969180?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5ypW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!5ypW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F282bfce7-31ad-4a52-b320-b917b2696020_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I already have a second brain setup based on Obsidian, Readwise, NotebookLM, and Claude Code. I dump all my notes, research, and highlights there. Whenever I want to create content, I create a scoped wiki targeted toward the topic. I gather information from my second brain using a deep research algorithm on top of my private data and external resources via NotebookLM. The wiki is structured like the LLM Knowledge Base presented by Andrej Karpathy.</p><p>This setup fails to extract and maintain shared entities, preferences, and facts across the wiki as the knowledge base grows. For example, if the topic &#8220;Claude Code&#8221; is mentioned in 10 documents, I want to extract all the metadata about it into its dedicated folder. I want to see what other entities it relates to, such as Anthropic, San Francisco, Codex, or Gemini CLI. I also want to see how many documents mention it to rank frequency. You can do that with a pure file-based system and Obsidian, but performance degrades when your data scales past 50 documents.</p><p>The same concept applies to any unstructured knowledge base. You need a way to extract and connect knowledge from your conversations, documents, and images. This becomes essential between conversations so your agent doesn&#8217;t forget you. Instead, it provides a personalized experience. It&#8217;s also critical for context engineering to inject the right context at the right time and keep the LLM focused on relevant facts.</p><p>Most teams default to one of two memory approaches. Both collapse under real use. A file system gives you append-only logs that the agent re-reads from scratch, which fragments and rots context.</p><p>A vector index gives you fuzzy semantic recall but no merge, no identity, and no way to know if this is the same Karpathy you knew yesterday. Durable AI memory requires a structured graph to track identity and relationships <a href="https://www.linkedin.com/posts/tonyseale_this-week-anthropic-dropped-claude-sonnet-activity-7379787334398926848-iVOE/">[1]</a>. Without this structure, the assistant forgets past interactions and fails to build compounding intelligence.</p><p>Knowledge-graph memory is the next step on the arc from Retrieval-Augmented Generation (RAG) to agentic RAG to agent memory <a href="https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html">[2]</a>. Building a unified knowledge-graph memory system is hard, so most teams skip it.</p><p>During my research, I stumbled upon <code>neo4j-labs/agent-memory</code>. It&#8217;s a masterpiece. Who knows more about knowledge graphs (KGs) than Neo4j?</p><p>After I spent 2 days playing with it and understanding the codebase, I realized it was the perfect mental model for any agent memory system powered by KGs.</p><p>In this article, I&#8217;ll walk through the core architectural patterns of <code>neo4j-labs/agent-memory</code>. It features 1 graph, 3 memory tiers, the POLE+O ontology, a 3-stage extraction pipeline, a composite resolver, and the SAME_AS pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cxdW!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cxdW!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 424w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 848w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cxdW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png" width="1456" height="1167" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1167,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:390376,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/197969180?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cxdW!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 424w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 848w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!cxdW!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F44a2dc7c-3947-44f5-88fd-1a5aef196b8d_1744x1398.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>By the end, you&#8217;ll have a concrete mental model. You can ship on top of their Software Development Kit (SDK) or hook it into your agent via their Model Context Protocol (MCP) server. Alternatively, you can steal the patterns and ship the same architecture on Postgres or MongoDB if a full graph database in production doesn&#8217;t make sense for your use case.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Start Your Transition Into AI Engineering (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!BjfO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!BjfO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 424w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 848w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 1272w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!BjfO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png" width="1285" height="1074" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1074,&quot;width&quot;:1285,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:225430,&quot;alt&quot;:&quot;Build and run a working agent in 5 minutes &#8212; free preview of the Agentic AI Engineering course&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Build and run a working agent in 5 minutes &#8212; free preview of the Agentic AI Engineering course" title="Build and run a working agent in 5 minutes &#8212; free preview of the Agentic AI Engineering course" srcset="https://substackcdn.com/image/fetch/$s_!BjfO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 424w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 848w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 1272w, https://substackcdn.com/image/fetch/$s_!BjfO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe5d0b9ec-af0d-4a21-9110-f5a7d1c4a742_1285x1074.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This article shows the memory layer your agent needs. My <a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a> shows the harness around it, and I just released a free preview that lets you build and run a working agent in 5 minutes.</p><p>You build a multi-agent system with two MCP servers (Research Agent + Writing Workflow), a deep research algorithm, an evaluator-optimizer loop, observability, and LLM-as-judge evals. The production patterns behind agents that actually ship.</p><p>Built for software, data engineers or scientists transitioning into AI engineering.</p><p>7 free lessons, 2 MCP agents ready for your GitHub portfolio. Part of the 35-lesson course. Rated 5/5 by 300+ students.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start the free preview &#8594;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start the free preview &#8594;</span></a></p></div><h2>What&#8217;s Inside <code>neo4j-labs/agent-memory</code></h2><p>The SDK takes natural-language interactions on the write side and returns a fused memory context on the read side. Everything anchors to a single Neo4j graph. For our scoped wiki, notes and Readwise highlights about Claude Code flow in. A structured pull of what the agent knows about Claude Code, how it relates to Anthropic, and its frequency across 50 documents comes out.</p><p>At its core, there is 1 graph and 3 memory tiers joined by typed edges: short-term conversations, long-term typed entities, and reasoning traces. They&#8217;re stitched together by <code>:MENTIONS</code>, <code>:TOUCHED</code>, and <code>:INITIATED_BY</code> relationships <a href="https://neo4j.com/labs/agent-memory/explanation/memory-types/">[3]</a>.</p><p>The architecture contains 8 small, single-responsibility modules. The <code>models/</code> module holds Pydantic schemas. The <code>schema/</code> module handles Cypher migrations. The <code>extraction/</code> module runs the Named Entity Recognition (NER) pipeline. The <code>resolution/</code> module holds the composite resolver. The <code>dedup/</code> module manages the SAME_AS pattern. The <code>core/</code> module provides <code>MemoryClient.get_context()</code>. The <code>mcp/</code> module runs the FastMCP server with 15 tools. The <code>integrations/</code> module holds 9 framework adapters for tools like LangChain and LlamaIndex.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z_M-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z_M-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 424w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 848w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 1272w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z_M-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png" width="1400" height="1311" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1311,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The 8 modules sit between an MCP / framework interface and a single Neo4j graph that holds all three memory tiers.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The 8 modules sit between an MCP / framework interface and a single Neo4j graph that holds all three memory tiers." title="The 8 modules sit between an MCP / framework interface and a single Neo4j graph that holds all three memory tiers." srcset="https://substackcdn.com/image/fetch/$s_!Z_M-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 424w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 848w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 1272w, https://substackcdn.com/image/fetch/$s_!Z_M-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb76b9b07-fb46-40c4-81a1-61e5aff42cc0_1400x1311.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>The 8 modules sit between an MCP / framework interface and a single Neo4j graph that holds all three memory tiers.</em></figcaption></figure></div><p>Consider an end-to-end scenario. You drop a Readwise highlight about Claude Code into your scoped wiki. The <code>extraction/</code> module pulls Claude Code as an Object, Anthropic as an Organization, and Codex as an Object. The <code>resolution/</code> module canonicalizes each against existing nodes. The <code>dedup/</code> module checks vector similarity and either auto-merges or flags a pending <code>:SAME_AS</code> edge. The <code>schema/</code> module commits <code>:MENTIONS</code> edges from the note to each entity.</p><p>Later, <code>MemoryClient.get_context()</code> pulls fused context across the same graph in one call. This matters concretely for the scoped-wiki agent. You can ask what you discussed last session, what you know about Claude Code, and why the agent surfaced a Codex comparison last Tuesday. The SDK answers all three against the same graph. It uses the same Cypher dialect with no cross-store join logic.</p><h2>Short-Term, Long-Term, Reasoning Memory</h2><p>The SDK splits memory into three layers that all live on the same Neo4j graph <a href="https://neo4j.com/labs/agent-memory/explanation/memory-types/">[3]</a>. Short-term memory is the linear message sequence. It uses ordered <code>:Message</code> nodes chained by <code>:NEXT</code> edges, scoped to a <code>:Conversation</code>. Long-term memory is the typed entity graph. It uses deduplicated <code>:Entity</code> nodes with vector embeddings and arbitrary domain relationships.</p><p>Reasoning memory is a tree per agent run. It uses a <code>:ReasoningTrace</code> root with child <code>:ReasoningStep</code> nodes capturing thoughts and tool calls. For the scoped-wiki agent, short-term memory holds your current chat. Long-term memory holds the canonical Claude Code entity plus its relations to Anthropic, San Francisco, Codex, and Gemini CLI. Reasoning memory holds the trace of how the agent picked those specific notes to answer you.</p><p>Three relationships do the entire stitching. The <code>:MENTIONS</code> edge joins short-term to long-term memory. The <code>:INITIATED_BY</code> edge joins reasoning to short-term memory. The <code>:TOUCHED</code> edge joins reasoning to long-term memory. These three edges make provenance a one-hop query rather than a log-reconstruction project.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_7Cv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_7Cv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 424w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 848w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 1272w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_7Cv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png" width="1400" height="1370" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1370,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Three tiers, one graph &#8212; the typed edges make every cross-tier question a one-hop query.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Three tiers, one graph &#8212; the typed edges make every cross-tier question a one-hop query." title="Three tiers, one graph &#8212; the typed edges make every cross-tier question a one-hop query." srcset="https://substackcdn.com/image/fetch/$s_!_7Cv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 424w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 848w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 1272w, https://substackcdn.com/image/fetch/$s_!_7Cv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcbbcbfc0-e8bd-484a-8ec6-eb4105fcc620_1400x1370.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Three tiers, one graph &#8212; the typed edges (</em><code>:MENTIONS</code><em>, </em><code>:INITIATED_BY</code><em>, </em><code>:TOUCHED</code><em>) make every cross-tier question a one-hop query.</em></figcaption></figure></div><p>Reasoning memory is the novelty from this architecture. By storing past successful or failed thinking patterns into the memory, the agent can one-shot future similar requests or at least know not to repeat similar mistakes. Intuitively, it&#8217;s similar to Reinforcement Learning (RL), but instead of baking the optimizations into the weights, you do it at the database level.</p><p>The most important part of this architecture is the ontology.</p><h2>The Ontology</h2><p>The long-term memory uses a closed five-type vocabulary for its ontology known as POLE+O. It uses Person, Object, Location, Event, and Organization, borrowed from intelligence-analysis taxonomies <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">[5]</a>. Every entity is exactly one of these five types. Subtypes are open, but the top-level vocabulary is fixed.</p><p>In the personal assistant, Karpathy is a Person. Claude Code is an Object. Anthropic is an Organization. Your Tuesday deep-research run is an Event. San Francisco is a Location.</p><p>Type and subtype materialize as multi-tier Neo4j labels. The query builder sanitizes and PascalCases them into labels like <code>:Entity:Person:Individual</code>. You can search by type or subtype, making this solution highly efficient.</p><p>Using this strategy, you can extend each core type from POLE+O with your own custom domain. Other defaults are: <code>:Entity:Location:City</code>, <code>:Entity:Event:Concert</code>, <code>:Entity:Organization:Company</code>, etc. <a href="https://create-context-graph.dev/docs/reference/domain-catalog">Here</a> is a catalog of over 20 domains such as Data Journalism, Gaming, Personal Knowledge, and Product Management.</p><p>Entities modeled via POLE+O are nouns. The SDK adds 2 other node types beyond entities.</p><p><code>:Fact</code> nodes hold every claim mentioned in the text. They&#8217;re intentionally generic so the ontology doesn&#8217;t get over-specified. They serve as a fallback when nothing else fits. You can intuitively see them as chunks of text that contain only 1 concept.</p><p>Then there are <code>:Preference</code> nodes that store user preferences via a <code>SUPERSEDED_BY</code> relationship. As agent memory is user-centric, this provides the WOW effect where the agent remembers past preferences and learns from them over time.</p><p>For the scoped wiki, &#8220;Anthropic developed Claude Code&#8221; is an edge. &#8220;Claude Code 1.0 shipped in 2025&#8221; is a <code>:Fact</code>. &#8220;I prefer agent-harness comparisons over pure benchmarks&#8221; is a <code>:Preference</code>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!m-oO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!m-oO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 424w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 848w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 1272w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!m-oO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png" width="1400" height="1357" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1357,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A scoped-wiki graph built from the five POLE+O types.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A scoped-wiki graph built from the five POLE+O types." title="A scoped-wiki graph built from the five POLE+O types." srcset="https://substackcdn.com/image/fetch/$s_!m-oO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 424w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 848w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 1272w, https://substackcdn.com/image/fetch/$s_!m-oO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F96ae330f-3585-4cc7-9dc5-831f2c778da4_1400x1357.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>A scoped-wiki graph built from the five POLE+O types &#8212; every node is exactly one of Person, Object, Location, Event, Organization, and every typed relationship is a </em><code>:RELATED_TO</code><em> edge with the semantic name carried as a property.</em></figcaption></figure></div><h2>Extraction: From Raw Text to Typed Entities</h2><p>The SDK runs entity extraction as a speed-versus-accuracy ladder. It uses spaCy for fast statistical NER. It uses GLiNER and GLiREL for zero-shot extraction. It uses an LLM stage for cases that need real semantics and to extract the relationships between them <a href="https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/">[6]</a>.</p><p>Each stage maps its outputs back to POLE+O types. It uses explicit merge strategies when 2 extractors disagree. When you drop a Readwise highlight about Claude Code into your scoped wiki, spaCy lifts proper nouns like Anthropic and San Francisco. GLiNER catches domain entities like Claude Code and Gemini CLI. The LLM stage only fires when the previous 2 stages leave ambiguity, or when the model needs to extract relationships.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!sw5N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!sw5N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 424w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 848w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 1272w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!sw5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png" width="1400" height="1369" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1369,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;From raw text to a clean graph &#8212; the three-zone SAME_AS pattern is what stops the same entity from becoming three nodes.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="From raw text to a clean graph &#8212; the three-zone SAME_AS pattern is what stops the same entity from becoming three nodes." title="From raw text to a clean graph &#8212; the three-zone SAME_AS pattern is what stops the same entity from becoming three nodes." srcset="https://substackcdn.com/image/fetch/$s_!sw5N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 424w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 848w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 1272w, https://substackcdn.com/image/fetch/$s_!sw5N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3ad32c39-16d8-4231-b576-69087bff7511_1400x1369.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em> From raw text to a clean graph &#8212; the three-zone SAME_AS pattern is what stops the same entity from becoming three nodes.</em></figcaption></figure></div><p>Routing every mention through an LLM would multiply extraction cost massively for marginal recall on rare entities. The ladder pushes high-confidence cases to cheap models. It escalates only ambiguous mentions to the zero-shot models and reserves the LLM stage for when real semantics matter.</p><p>The real problem is at the normalization step.</p><h2>When Two Mentions Are the Same Entity (And When They Aren&#8217;t)</h2><p>Resolution and deduplication are 2 different problems. Resolution sets a canonical string property on an existing reference. Deduplication decides whether a new node gets created at all. Conflating them is how graphs end up with 3 Anthropic nodes that none of your queries find together <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">[7]</a>.</p><p>Resolution runs 3 strategies on the name field in cost order. Exact matches existing canonical strings. Fuzzy uses RapidFuzz string similarity for surface variants like &#8220;A. Karpathy&#8221; and &#8220;Karpathy, Andrej&#8221;. Semantic falls back to embedding similarity for cases like &#8220;the founder of Eureka Labs&#8221;. It only matches between nodes of the same type, meaning a Person only resolves against Person candidates.</p><p>After resolution runs, two mentions like &#8220;Apple&#8221; and &#8220;Apple Inc.&#8221; end up with different surface names but the same canonical name. That&#8217;s why a second step is needed. Deduplication looks at the semantics, not just the name.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!joRt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!joRt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 424w, https://substackcdn.com/image/fetch/$s_!joRt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 848w, https://substackcdn.com/image/fetch/$s_!joRt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 1272w, https://substackcdn.com/image/fetch/$s_!joRt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!joRt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png" width="1400" height="1363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1363,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Same name, three outcomes &#8212; high similarity auto-merges, the middle band defers to a human, and low similarity creates two nodes that share a canonical name but live as separate referents.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Same name, three outcomes &#8212; high similarity auto-merges, the middle band defers to a human, and low similarity creates two nodes that share a canonical name but live as separate referents." title="Same name, three outcomes &#8212; high similarity auto-merges, the middle band defers to a human, and low similarity creates two nodes that share a canonical name but live as separate referents." srcset="https://substackcdn.com/image/fetch/$s_!joRt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 424w, https://substackcdn.com/image/fetch/$s_!joRt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 848w, https://substackcdn.com/image/fetch/$s_!joRt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 1272w, https://substackcdn.com/image/fetch/$s_!joRt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2f4cbb67-cf5c-481b-b0e9-f7fa3f45eb1a_1400x1363.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Same name, three outcomes: High similarity auto-merges, the middle band defers to a human, and low similarity creates 2 nodes that share a canonical name but live as separate referents.</em></figcaption></figure></div><p>For deduplication, the SDK uses vector and fuzzy similarity across the entire node content. This ensures the node is actually the same, not just a name coincidence. In other words, this avoids false positives. Using vector and fuzzy search, the SDK computes a score.</p><p>Scores at or above 0.95 trigger an auto-merge. Scores below 0.85 create a new node. Scores between 0.85 and 0.95 don&#8217;t silently merge. Instead, they create a <code>:SAME_AS</code> edge with a pending status. This flags the edge for a human or downstream agent to resolve later. This pattern stops &#8220;Jensen Huang the NVIDIA CEO&#8221; from merging with &#8220;Jensen Huang the Taipei dermatologist&#8221; just because their embeddings landed 0.91 apart <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">[7]</a>.</p><p>A false merge is silent and unrecoverable. A false split is noisy but recoverable. You can&#8217;t undo a false merge without re-ingesting from the raw source data. That&#8217;s why you should leave uncertainty to a human.</p><h2>Zooming into the Retrieval Algorithm</h2><p>Because all three tiers live on one graph, a single retrieval can compose vector similarity over <code>:Entity</code> embeddings, multi-hop expansion over typed relationships, time-ordered <code>:NEXT</code> conversation walks, and reasoning-trace lookups via <code>:INITIATED_BY</code> and <code>:TOUCHED</code> joins. All of these run as steps in the same Cypher query. Neo4j 5.20 introduces <code>db.index.vector.queryNodes</code>, making vector similarity a first-class graph operation <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">[4]</a>.</p><p>When you ask what you know about Claude Code, how it relates to Codex and Gemini CLI, and why you looked at it last week, the agent fuses three things in one pull. It uses vector similarity over your Readwise highlights to surface relevant passages. It uses a multi-hop traversal of <code>:DEVELOPED_BY</code> and <code>:COMPETES_WITH</code> edges to bring in Anthropic and Codex neighbors. Finally, it uses an <code>:INITIATED_BY</code> jump back to the prior conversation that discussed agent harnesses. There&#8217;s no cross-store join logic and no orchestrator.</p><p>From our tests, the library leaves the context construction to the user of the SDK. In other words, you get the whole output from the graph, and it&#8217;s your responsibility to further compress it before passing it to the LLM.</p><h2>What&#8217;s Next</h2><p>The <a href="https://github.com/neo4j-labs/agent-memory">neo4j-labs/agent-memory</a> architecture is more complex than what this article covers, but this is the core idea behind it. I&#8217;ll cover other components in more depth in future articles, including designing the ontology and keeping your knowledge graph clean over time.</p><p>I think this open-source repository is a perfect blueprint you can take to build your own agent memory solution, even with Postgres or MongoDB, to avoid keeping multiple databases in production. Still, Neo4j is probably the best choice for data mining and exploration.</p><p>For small to medium-scale projects with thousands of nodes and short hop traversals, I&#8217;d probably build my own agent memory solution from scratch on top of Postgres or MongoDB. I&#8217;d reach for Neo4j as an internal tool within my organization, or when the scale or complexity becomes too large for Postgres or MongoDB.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>How are you handling agent memory today? Flat files, a vector index, a knowledge graph, or something stranger?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/understanding-neo4j-graph-agent-memory-system?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Seale, T. (n.d.). This week Anthropic dropped Claude Sonnet 4.5. LinkedIn. <a href="https://www.linkedin.com/posts/tonyseale_this-week-anthropic-dropped-claude-sonnet-activity-7379787334398926848-iVOE/">https://www.linkedin.com/posts/tonyseale_this-week-anthropic-dropped-claude-sonnet-activity-7379787334398926848-iVOE/</a></p></li><li><p>Monigatti, L. (n.d.). The Evolution From RAG to Agentic RAG to Agent Memory. Leonie Monigatti. <a href="https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html">https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html</a></p></li><li><p>Neo4j Labs. (n.d.). Understanding the Three Memory Types. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/memory-types/">https://neo4j.com/labs/agent-memory/explanation/memory-types/</a></p></li><li><p>Neo4j Labs. (n.d.). Why Neo4j? Graph-Native Memory Architecture. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">https://neo4j.com/labs/agent-memory/explanation/graph-architecture/</a></p></li><li><p>Neo4j Labs. (n.d.). POLE+O Data Model. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/poleo-model/">https://neo4j.com/labs/agent-memory/explanation/poleo-model/</a></p></li><li><p>Neo4j Labs. (n.d.). How Entity Extraction Works. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/">https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/</a></p></li><li><p>Neo4j Labs. (n.d.). Entity Resolution and Deduplication. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[From Vibe Coding to a Real Engineering Team]]></title><description><![CDATA[My Claude Code agentic coding setup that ships features end-to-end]]></description><link>https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026</link><guid isPermaLink="false">https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 12 May 2026 11:04:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!5s3I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5s3I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5s3I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5s3I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b2577418-f25c-4206-a924-4dc119729cd3_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1362362,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/196997194?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!5s3I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!5s3I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb2577418-f25c-4206-a924-4dc119729cd3_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I needed a TypeScript harness for my latest book code. It required a Terminal User Interface (TUI), an agent loop, tools, Model Context Protocol (MCP) support, skills, and slash commands. I will be honest with you. I first tried to vibe code this project.</p><p>As I knew what I was looking for, it worked. Until it didn&#8217;t. The code was working until you started looking more closely at the details. Only the first 20 characters were rendering inside the TUI, and the skills weren&#8217;t invoked by the agent loop.</p><p>So I deleted the whole code base and started over with a new strategy.</p><p>The cost of vibe coding isn&#8217;t abstract. It&#8217;s the next feature you can&#8217;t ship because you&#8217;re debugging a slash-command renderer that looked finished. This is what most people get wrong. Output that compiles and looks done breaks the moment you reach for the rough edges.</p><p>I divided the harness into tasks. I one-shotted the barebones version, which was just a TUI plus an agent loop with <code>bash</code>, <code>grep</code>, and a todo tool. Then I layered MCP, skills, and slash commands as separate features.</p><p>You can&#8217;t one-shot whole applications. You can one-shot big features if you scope them right and run them through a real engineering process.</p><p>This is known as agentic coding. Not vibe coding. You&#8217;re using agents to write the whole codebase, but you are still the mastermind behind everything.</p><p>But I wanted more. I wanted to automate this process. But with a single constraint in mind: &#8220;the code should HAS to be good&#8221;.</p><p>That&#8217;s why I built Squid. It&#8217;s an opinionated six-agent Claude Code setup available at <a href="https://github.com/iusztinpaul/squid">iusztinpaul/squid</a>. It ships features the way a real software team ships them.</p><p>Squid has already shipped our content-automation tool, expanding it from articles to posts, notes, threads, and messages. It shipped the book&#8217;s code data pipelines and TypeScript harness.</p><p>In this article I will show you how it works.</p><p>The concrete blueprint relies on a specialized team and an e2e lifecycle.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Start Your Transition Into AI Engineering (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2YEV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2YEV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2YEV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png" width="1400" height="1380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1380,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Multi-agent free lesson architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Multi-agent free lesson architecture" title="Multi-agent free lesson architecture" srcset="https://substackcdn.com/image/fetch/$s_!2YEV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!2YEV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef20e0ae-d28f-4cbf-bb86-675b4a0ab84a_1400x1380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Squid applies the multi-agent pattern to coding. My <a href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a> applies it to writing, and I just released a free hands-on lesson that distills the whole system.</p><p>You build a multi-agent system composed of two FastMCP servers (Deep Research + LinkedIn Writer) orchestrated by a harness, plus an observability and evals layer on top. The shift from classic backend/frontend stacks to MCP servers and harnesses is the pattern shaping modern agentic AI.</p><p>Built for software and data engineers moving into agentic AI engineering.</p><p><em>Part of the 35-lesson course. Rated 5/5 by 300+ students. First 7 lessons free.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start the free lesson &#8594;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/pages/free-lesson-offer-2?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start the free lesson &#8594;</span></a></p></div><h2>The Six Agents Engineering Team</h2><p>The system contains six agents. No agent both writes code and decides whether the code is correct.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9yS9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9yS9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 424w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 848w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9yS9!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png" width="1200" height="1031.1258278145694" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:1038,&quot;width&quot;:1208,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The six-agent team&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="The six-agent team" title="The six-agent team" srcset="https://substackcdn.com/image/fetch/$s_!9yS9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 424w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 848w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 1272w, https://substackcdn.com/image/fetch/$s_!9yS9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fecde9a6b-b62d-4f38-a010-6c8af2e9728e_1208x1038.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">My Agentic Engineering Team</figcaption></figure></div><p>The <strong>product manager agent</strong> manages the tasks and ensures the feature adheres to the software architect&#8217;s specifications. It takes a raw feature specification, writes or updates an Architecture Decision Record (ADR) for non-obvious choices, and splits the feature into ordered tasks. It also maintains the Domain-Driven Design (DDD) glossary so vocabulary stays consistent between the business and engineering.</p><p>Note how, because Claude can easily handle both PM and software architecture work, we decided to merge these roles together. We did this to avoid fragmenting the context just to follow a standard human process. Ultimately, planning should be closely aligned with the software architect&#8217;s vision. In human processes, dividing these two responsibilities often created more issues than solutions.</p><p>The <strong>software engineer agent</strong> uses red-green Test-Driven Development (TDD). It writes the failing test, writes the minimal code to pass it, and then refactors. The software engineer uses direct command-line interfaces (CLIs) like <code>git</code>, <code>mongosh</code>, and <code>gh</code>. It never uses MCP wrappers. CLIs are more flexible because they tap directly into the power of bash. Plus, LLMs have seen considerably more bash code than MCP wrappers during training.</p><p>The <strong>tester agent</strong> specializes in the adversarial end-to-end edge-case pass. It catches false-confidence claims where the software engineer says the tests pass. It does this by reading every acceptance criterion against concrete evidence, like the test name, file lines, and command output.</p><p>The <strong>pull request reviewer agent</strong> performs a diff-only review. It looks for dead code, duplication, missing test coverage, and documentation adherence. It does a narrow performance review on hot paths only. It&#8217;s explicitly told not to micro-optimize one-off scripts.</p><p>The <strong>on-call agent</strong> loops on the Continuous Integration (CI) pipeline until it passes. In an earlier iteration, the CI check lived inside the software engineer and tester loop, and it got skipped constantly. Promoting it to a dedicated agent invoked by the orchestrator increased the probability the step runs.</p><p>The <strong>self-improve agent</strong> is an optional meta agent. After the feature is done, while looking over the results, the human can run the self-improve agent to scan the run for high-signal lessons and propose updates to the agentic coding layer that consists of <code>CLAUDE.md</code>, skills and subagents. This is a double-edged sword. It can constantly improve your workflow or quickly degrade it if you are not careful. That&#8217;s why it&#8217;s incredibly important that this step is gated by a human.</p><p>The secret sauce is in anchoring the agents into your own documentation.</p><h2>Keeping Up With Documentation: ADRs &amp; DDD Glossary</h2><p>The ADR directory acts as compressed architectural memory across runs. Every non-obvious choice regarding the datastore, synchronization defaults, authentication boundaries, or dependency lock-in ships with an ADR. These records include the status, context, decision, and consequences at <code>docs/adr/&lt;NNNN_title&gt;.md</code>. The product manager reads the directory before grooming a new feature, so decisions stay consistent across feature branches.</p><p>The DDD glossary gives shared vocabulary between the business and engineering at <code>docs/glossary.md</code>. It enforces one canonical name per concept. Code identifiers, OpenAPI schemas, database columns, and customer-facing interfaces all use the term exactly as it appears there. This gives Claude Code business context, not just code context, properly anchoring your code in your domain. The software engineer, tester, and pull request reviewer all reason about the same domain.</p><p>I have an honest caveat. The agents still under-use both the ADRs and the glossary. The spine exists, but I am still working on getting the agents to lean on it consistently.</p><p>Now the agents have the context they need to execute a feature from a raw specification all the way to a merged pull request.</p><h2>The Night Skill. The End-To-End Workflow.</h2><p>The <code>/night</code> skill takes one input, which is a feature specification written by the human, and produces one output, which is a merged pull request with green CI. Everything in this section sits between those two endpoints.</p><p>The <code>/night</code> pipeline is a long-running lifecycle. That&#8217;s why it&#8217;s called the &#8220;night&#8221; skill. It&#8217;s scoped to run for hours at a time, often with multiple pipelines in parallel.</p><p>It has two human checkpoints and five retry caps, while everything else is automated. The orchestrator acts as a manager. It never writes code itself, never runs tests itself, and never reviews the diff itself. It launches agents and enforces human validation.</p><p>After a human carefully writes a detailed feature specification, it calls the <code>/night</code> skill, which creates a new branch and worktree. The product manager reads the glossary and ADR directory, updates or writes a new ADR if needed, and splits the feature into a task plan.</p><p>Then we hit the first human gate. The user approves the plan, optionally sharpened by the <code>/grill-me</code> skill. The <code>/grill-me</code> skill is inspired by Matt Pocock&#8217;s work, which forces the agent to ask sharp questions back about anything fuzzy in the plan, such as interfaces, modularization, or new tools. This conversation is the line between vibe coding and agentic coding.</p><p>Next is the inner loop per task. The software engineer implements the code, the tester verifies it, and failures route back to the software engineer. This loop is capped at 5 attempts. Convergence is mostly mechanical through a run, fail, fix, and run cycle.</p><p>The product manager then performs an acceptance review on the whole feature from the user&#8217;s perspective. Rejections are packed into a single task back into the inner loop. This is capped at 3 attempts, because judgment-call loops are where Claude Code spirals.</p><p>Next, we repeat a similar loop using the PR reviewer agent, which looks at the diff, with a maximum of 3 attempts to avoid perfectionism. Adding a maximum number of attempts here is critical, because during review an LLM almost always has something else to say.</p><p>After the push, the on-call agent watches CI with a maximum of 5 attempts, routing failures back to the software engineer.</p><p>When the CI is green, we notify the user (e.g., via Slack) that the PR is ready for review. Optionally, based on any potential issues found while running the <code>/night</code> skill, we run <code>self-improve</code> to propagate that into your memory.</p><p> The /night lifecycle. Two human gates, five retry caps, everything else automated.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8VWO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8VWO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 424w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 848w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 1272w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8VWO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png" width="1200" height="965" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:965,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The /night lifecycle. Two human gates, five retry caps, everything else automated.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The /night lifecycle. Two human gates, five retry caps, everything else automated." title="The /night lifecycle. Two human gates, five retry caps, everything else automated." srcset="https://substackcdn.com/image/fetch/$s_!8VWO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 424w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 848w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 1272w, https://substackcdn.com/image/fetch/$s_!8VWO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5775bbe9-c91b-46fe-94ef-1a819be0bce8_1200x965.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">My Agentic Coding Setup</figcaption></figure></div><p>Beautiful! With this process I one-shot most of the features I am working on. And when it&#8217;s not a one-shot, I&#8217;m typically 95&#8211;99% there by the time I review the PR.</p><h2>How the Tester Stopped Re-Running What the SWE Already Ran</h2><p>The biggest problem with the e2e workflow above is that it&#8217;s slow and redundant. I preferred that over generating AI slop that I have to manually review and fix.</p><p>Still, there are a few tweaks that we can make to the workflow to improve speed and efficiency.</p><p>For example, when the tester re-ran the linter, type checker, formatter, and the happy-path suite that the software engineer had already run, we paid for everything twice. This was the number-one source of having a system that works but is too slow to use.</p><p>To fix this, the tester now accepts the software engineer&#8217;s reports for formatting and happy-path tests. It only runs the adversarial end-to-end edge-case pass itself. This covers the part the software engineer can&#8217;t credibly self-verify. Trust is bounded. Intuitively, I realized I&#8217;d started shifting the <code>Tester</code> toward QA-style practices, rather than just running simple tests.</p><p>I am still iterating on optimizations. For example, I want to route some subagents to Claude Sonnet models instead of Claude Opus. I also plan to narrow toolsets per role to reduce reasoning failures.</p><p>Also, depending on what you are working on, you might want to use the system more as a fast, snappy assistant than as a long-running workflow that prioritizes correctness above all.</p><h2>Day vs. Night: Two Orchestrators, One Team</h2><p>That&#8217;s why we have two pipelines running the same agents. The <code>/night</code> skill is the full lifecycle. It&#8217;s long-running, set-and-forget, has two human gates, and runs while you are away from the keyboard or working in parallel.</p><p>The <code>/day</code> skill is the lean inner loop. It runs the software engineer, the tester, and human commits for surgical edits. It skips product manager grooming, the pull request reviewer, and the on-call agent.</p><p>There is a concrete use case for the <code>/day</code> skill. When I read a merged pull request and find code I don&#8217;t like, the <code>/day</code> skill runs the stripped software engineer and tester loop to apply targeted edits. Then the on-call agent cleans up any CI fallout. This is the surgery that keeps the system from becoming a black box.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2bZF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2bZF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 424w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 848w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 1272w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2bZF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png" width="1200" height="965" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:965,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Day vs. Night &#8212; same agent team, two orchestrators tuned for different workloads.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Day vs. Night &#8212; same agent team, two orchestrators tuned for different workloads." title="Day vs. Night &#8212; same agent team, two orchestrators tuned for different workloads." srcset="https://substackcdn.com/image/fetch/$s_!2bZF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 424w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 848w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 1272w, https://substackcdn.com/image/fetch/$s_!2bZF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1143ede6-93a8-4c72-ac85-3f12071bd61b_1200x965.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Day vs. Night: Same agent team, two orchestrators tuned for different workloads.</figcaption></figure></div><p>Both pipelines have one thing in common. The human is in the loop on purpose, not as a fallback.</p><h2>Why Code Templates Are a Waste of Time in 2026</h2><p>Most teams are still scaffolding from cookiecutter templates that were outdated the day they were committed. This is a maintenance tax disguised as productivity. Squid stops paying that tax. Technology moves fast enough that any frozen template&#8217;s frameworks, tooling, interfaces, and opinions all need their own maintenance pipeline. That&#8217;s only worth it if one template fans out across dozens of projects.</p><p>A Copier or cookiecutter template isn&#8217;t free. I tried scaling one across Python, TypeScript, and Go. I watched the project balloon into a maintenance burden where most files would never be used. Maintaining a template engine to support multiple stacks is a full-time job.</p><p>Asking Claude Code to copy from the last project fails too. It propagates the technical debt baked into the source codebase. You inherit the mess, not the ideal state.</p><p>The real shift relies on markdown, not Jinja. I call these <strong>agentic templates</strong>.</p><p>You encode good practices as skills and <code>CLAUDE.md</code> files. Fundamentals like clean architecture, CI/CD discipline, testing patterns, and development cycles rarely change. When they do change, you edit prose instead of regenerating from a template engine that quickly slides into dependency hell.</p><p>Tooling stays dynamic. You don&#8217;t pin framework versions inside a template. You keep a decision tree of allowed choices and let the agent pull the latest interfaces on demand via Context7 at scaffold time.</p><p>Project structure can&#8217;t be templatized. The anti-pattern organizes by type, putting files into <code>agents/</code>, <code>nodes/</code>, <code>schemas/</code>, and <code>tools/</code> directories. One business module&#8217;s logic ends up scattered across four folders, forcing both humans and the agent&#8217;s context window to thrash.</p><p>The correct pattern organizes by actionability, keeping one bounded context per directory. Each domain owns its own types, store, Application Programming Interface (API), and prompts. That&#8217;s locally readable, easier to maintain, and easier for the agent to reason about.</p><p>Because we describe the structure in Markdown files instead of cookiecutter templates, we can define it like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bhZj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bhZj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 424w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 848w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 1272w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bhZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png" width="1456" height="946" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:946,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!bhZj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 424w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 848w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 1272w, https://substackcdn.com/image/fetch/$s_!bhZj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F83fcb967-260a-49e3-af0c-b1a7f0181e01_2737x1779.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Avoid global dumping grounds like <code>utils/</code> or <code>helpers/</code>. Avoid a root-level <code>types.py</code> grab bag. Avoid grouping tests by type.</p><p>The <code>/scaffold</code> skill acts as an interactive bootstrap. An <code>AskUserQuestion</code> prompt drives a tight decision tree covering project identity, layout, components, backend, frontend framework, infrastructure, agent team, tracker, ADR and glossary opt-ins, and external services. A deterministic table picks only the matching specifications from the specification library. Unused categories never enter the context. The skill writes a tailored <code>CLAUDE.md</code> brief, lays down an empty folder skeleton, and hands off.</p><p>Then, based on the agentically generated template, you can use <code>/night</code> or <code>/day</code> to start writing real code.</p><h2>Open-Sourcing Squid</h2><p>I don&#8217;t want to keep Squid for myself. I want to share it with the community to learn from and contribute to.</p><p>Thus, <strong>I am open-sourcing <a href="https://github.com/iusztinpaul/squid">Squid</a>.</strong></p><p>You can install it as a Claude Code plugin:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">/plugin marketplace add iusztinpaul/squid
/plugin install squid@squid</code></pre></div><p>I want you to try it, build something awesome with it, and if you like it, contribute back:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/iusztinpaul/squid&quot;,&quot;text&quot;:&quot;Check the full codebase&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/iusztinpaul/squid"><span>Check the full codebase</span></a></p><p><em>Still, here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>What is your agentic coding setup? How is Squid different from your own approach?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/squid-my-agentic-coding-setup-may-2026?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Building Agentic GraphRAG Systems]]></title><description><![CDATA[From knowledge graphs and ontologies to a unified memory as an MCP server for your AI agent.]]></description><link>https://www.decodingai.com/p/agentic-graphrag</link><guid isPermaLink="false">https://www.decodingai.com/p/agentic-graphrag</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 05 May 2026 05:01:08 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!tLfe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tLfe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tLfe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tLfe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1412283,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/196226897?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tLfe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!tLfe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1b0a301c-6d75-4ba0-a8e6-97d72a1f7674_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I gave this talk twice in one month: at O&#8217;Reilly&#8217;s Context Engineering Event and at Abi Aryan&#8217;s Maven course on LLM inference at scale. After being blasted with questions, I realized something: GraphRAG isn&#8217;t a retrieval algorithm, it&#8217;s a data modeling problem.</p><p>Powering agents with knowledge graphs (KGs) and ontologies is still an unsolved problem. All the engineers I spoke to want GraphRAG, but don&#8217;t know how to implement it.</p><p>But at its core, we should ask a different question. Why do we even need GraphRAG in the first place? Why complicate our solution over a simple RAG system?</p><p>There are three core reasons.</p><p>First, you face context rot. As the context window fills, the signal-to-noise ratio collapses. The LLM degrades.</p><p>You pay for this degradation in quality, cost, and latency <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">[1]</a>.</p><p>Second, you face data fragmentation. In the agent era, your data lives in silos most builders share: documents, notes, research, emails, and text messages. We are no longer lucky enough to have all the data nicely stored in a single database.</p><p>Third, the agent&#8217;s unified memory naturally maps to a knowledge graph (KG). People have preferences and experiences. They went into specific locations, met with other people, or have a list of items to do. Things get trickier when <em>&#8220;Arthur told Felix that his favorite coffee shop is in the center of Timisoara&#8221;</em>, but after two months <em>&#8220;it moved to Lisbon&#8221;</em>. You need to start tracking relationships between people, locations, and most especially how these relate in time.</p><p>GraphRAG solves all three.</p><p>This is a data modeling problem, not a retrieval algorithm. It took a painful LangChain detour and a hard MongoDB RAM conversation to settle that for me. You need an ontology.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K9Ds!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Agentic GraphRAG Architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Agentic GraphRAG Architecture" title="Agentic GraphRAG Architecture" srcset="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 2: The full GraphRAG system architecture.</figcaption></figure></div><p>By the end of this article, you will learn about ontology-first design, the three extraction modes, append-only data models, and hybrid retrieval joined by Reciprocal Rank Fusion (RRF). Finally, you will see how to expose the GraphRAG engine as a unified memory layer via an MCP server to power your agents. In other words, <strong>how to do agentic GraphRAG</strong>.</p><p>Before walking through the architecture, let&#8217;s understand why the story has to start from the ontology.</p><div class="callout-block" data-callout="true"><h2><a href="https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop">Build Your Own Multi-Agent System Free Workshop (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!erqJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!erqJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png" width="1400" height="1380" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1380,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Multi-agent workshop architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Multi-agent workshop architecture" title="Multi-agent workshop architecture" srcset="https://substackcdn.com/image/fetch/$s_!erqJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 424w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 848w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 1272w, https://substackcdn.com/image/fetch/$s_!erqJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c792e04-46a4-4edf-8c7f-bf7d370cabde_1400x1380.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This article shows what an MCP-served unified memory looks like end to end. If you want to actually build agentic systems with MCP servers like this, I open-sourced a hands-on workshop for that.</p><p>Two MCP servers from scratch: a Deep Research Agent (Gemini + Google Search grounding) and a Writing Workflow with an evaluator-optimizer loop.</p><p>Packaged with slides, a ~2-hour video, runnable reference code, and an &#8220;implement-it-yourself&#8221; skeleton via agentic coding best practices (25 tickets, one orchestrator skill, and two agents: SWE and tester).</p><p>Originally presented at the AI Engineering Conference Europe. 200+ stars on GitHub. Free.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop&quot;,&quot;text&quot;:&quot;Go to workshop &#8594;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/iusztinpaul/designing-real-world-ai-agents-workshop"><span>Go to workshop &#8594;</span></a></p></div><h2>Why the Story Starts From the Ontology</h2><p>Whenever you need to connect dots across a corpus of multiple documents rather than find the most relevant paragraph, you go for GraphRAG. Knowledge is stored as entities and edges.</p><p>You traverse connections rather than find similar text.</p><p>An ontology is a collection of classes and the relationships allowed between them. If you come from object-oriented programming, you already have the right intuition.</p><p>Throughout this article, we will build a digital twin. My favorite example. We will define a Global Ontology of six entity types organized into two sub-ontologies.</p><p>The data pipeline deterministically constructs the Document Ontology. It contains <code>DOCUMENT</code> and <code>CHUNK</code> nodes. It uses <code>PART_OF</code>, <code>NEXT</code>, <code>REFERENCED</code>, and <code>MENTIONS</code> edges.</p><p>The LLM extracts the Person Ontology. It contains <code>PERSON</code>, <code>TASK</code>, <code>EPISODE</code>, and <code>PREFERENCE</code> nodes. It uses <code>RELATED_TO</code>, <code>TODO</code>, <code>EXPERIENCED</code>, and <code>HAS</code> edges.</p><p>The schema is flexible. You define it for your business case. Every section after this one assumes these exact node and edge labels.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6-9A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6-9A!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 424w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 848w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 1272w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6-9A!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png" width="1200" height="416.2087912087912" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:505,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;ontology_example&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="ontology_example" title="ontology_example" srcset="https://substackcdn.com/image/fetch/$s_!6-9A!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 424w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 848w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 1272w, https://substackcdn.com/image/fetch/$s_!6-9A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F69db60bc-3ff8-438a-a432-cfedf2ad3622_2586x897.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 3: Left shows the Global Ontology split into a Document Ontology and a Person Ontology. Right shows an instantiated KG with nodes wired together via the eight typed edges.</figcaption></figure></div><p>Skipping the ontology carries a heavy cost. I tried LangChain&#8217;s <code>MongoDBGraphStore</code>, which lets the LLM extract entity and relationship types freely. Five documents produced 17 node types and 34 relationship types.</p><p>This included <code>part_of</code>, <code>Part Of</code>, and <code>part of</code> as three separate types. The underlying data model does not enforce a schema at the storage layer.</p><p>With an ontology, the LLM can only extract what you defined. The constrained scope also allows you to use cheaper extractor models.</p><p>That&#8217;s why GraphRAG is the right tool when you have a clearly defined schema. It works when you need to identify relationships.</p><p>It reduces hallucination on complex queries that span interconnected facts. Domains where knowledge graphs naturally fit are legal, medical, financial, business operations, productivity tools and in my opinion, the crown jewel: personal assistants. With a KG, you can naturally build the unified memory of your personal assistant to properly remember what you like, what you did, and what you have to do, all anchored in time.</p><p>For example, Palantir built its empire using ontologies. Google uses KG to power its search, and Microsoft uses it in its internal ops tools.</p><p>With the ontology defined, the next architectural choice is the shape of the graph itself and how to extract those entities from raw text.</p><h2>RDF vs. Property Graphs, and the Three Extraction Modes</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GtoY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GtoY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 424w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 848w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GtoY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png" width="1400" height="1342" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1342,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;RDF vs. Labeled Property Graph on the same Arthur fact. RDF explodes every property into its own triplet. Property Graphs attach properties to the node. Agent stacks use property graphs in practice.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="RDF vs. Labeled Property Graph on the same Arthur fact. RDF explodes every property into its own triplet. Property Graphs attach properties to the node. Agent stacks use property graphs in practice." title="RDF vs. Labeled Property Graph on the same Arthur fact. RDF explodes every property into its own triplet. Property Graphs attach properties to the node. Agent stacks use property graphs in practice." srcset="https://substackcdn.com/image/fetch/$s_!GtoY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 424w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 848w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 1272w, https://substackcdn.com/image/fetch/$s_!GtoY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F05040c7c-d947-454a-ae93-a39e52ef86fb_1400x1342.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: RDF vs. Labeled Property Graph on the same Arthur fact. RDF explodes every property into its own triplet. Property Graphs attach properties to the node. Agent stacks use property graphs in practice.</em></figcaption></figure></div><p>Every graph is structured as a collection of (entity, relationship, entity) triplets. But there are two ways to attach data to each entity or relationship instance, known as Resource Description Framework (RDF) and labeled property graphs.</p><p>RDF attaches each piece of metadata as another triplet. The graph explodes in size. Property graphs attach metadata as JSON on the entity or relationship.</p><p>In practice, GraphRAG and agents use property graphs <a href="https://www.manning.com/books/knowledge-graphs-and-llms-in-action">[3]</a>.</p><p>Now, during <strong>extraction</strong>, where we actually map data into our (entity, relationship, entity) triplets, plus their corresponding data, we have three core methods.</p><p><strong>Structured</strong> extraction is schema-guided. The LLM outputs entities per the Person Ontology.</p><p><strong>Semi-structured</strong> extraction uses metadata and lineage without an LLM. You parse the email&#8217;s links and attachments.</p><p><strong>Unstructured</strong> extraction uses an LLM without a schema. The LLM invents its own labels. This is useful for discovery, not for grounded retrieval. In other words, we use the LLM to extract triplets without an ontology. Exactly what we said to avoid in the previous section.</p><p>Here is the data-source mapping for the Person Ontology of the digital twin:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!B24g!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!B24g!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 424w, https://substackcdn.com/image/fetch/$s_!B24g!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 848w, https://substackcdn.com/image/fetch/$s_!B24g!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 1272w, https://substackcdn.com/image/fetch/$s_!B24g!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!B24g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png" width="1456" height="629" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:629,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;table&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="table" title="table" srcset="https://substackcdn.com/image/fetch/$s_!B24g!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 424w, https://substackcdn.com/image/fetch/$s_!B24g!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 848w, https://substackcdn.com/image/fetch/$s_!B24g!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 1272w, https://substackcdn.com/image/fetch/$s_!B24g!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2d668c23-2d2e-4e89-a677-7b5110ce6dd9_1920x830.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Table 1: Data-source mapping for the digital twin.</figcaption></figure></div><p>The Document Ontology can be completely done through semi-structured mechanics, since we already know what document each chunk comes from, the author of each document, and the references between them.</p><blockquote><p> &#128161; A student asked about open-domain extraction. Exploratory extraction is great early on when you are figuring out what ontology makes sense for your data. You can use zero-shot Named Entity Recognition (NER) models like GLiNER for that exploratory phase <a href="http://(https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/)">[4]</a>. Which you can easily run locally without having powerful inference hardware. Without that discipline, the output becomes unusable noise within tens of documents. A constrained scope lets you swap the frontier model for a small fine-tuned extractor like Gemini Flash Lite, Claude Haiku or even better, use Liquid open-source models fine-tuned on your ontology.</p></blockquote><p>These extraction modes feed directly into a five-component system that turns raw documents into queryable memory.</p><h2>The Five-Component Architecture</h2><p>The input consists of heterogeneous documents scattered across multiple silos. The output is a single queryable knowledge graph. The agent can search and write back to it via two tools.</p><p>Everything in between is plumbing built to serve that one job.</p><p>The data pipeline gathers from URIs, notes, emails and Google Drive. It normalizes everything into a document collection written to a warehouse.</p><p>The memory pipeline turns documents into knowledge-graph objects and writes them into the unified memory modeled as a KG.</p><p>The KG is the queryable artifact. The agent communicates with the knowledge graph via an MCP server that exposes search and write tools. If you are building in Python, choose FastMCP over the native MCP SDK, as it&#8217;s much easier to use and offers a better developer experience.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!YdlO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!YdlO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!YdlO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;the-five-component-architecture.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="the-five-component-architecture.png" title="the-five-component-architecture.png" srcset="https://substackcdn.com/image/fetch/$s_!YdlO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!YdlO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F796f1448-9394-405d-9c74-2a20c2c8b782_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 5: The five-component architecture. Sources flow through the data and memory pipelines into the materialized knowledge graph. The agent talks to it through two MCP-exposed tools.</figcaption></figure></div><p>The <code>search_memory</code> family of tools brings only the slice the agent needs into the context window. The <code>write_memory</code> tools run the same data + memory pipelines on demand on a conversation or URI instead of running them in batch mode <a href="https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html">[5]</a>.</p><p>Ultimately, we connect the MCP server to a harness such as Claude Code or Codex, where we inject custom business logic on how the tools should be used through a family of <code>assistant-memory</code> and <code>assistant-learn</code> skills.</p><p>For 2-3 hop traversals, Postgres or MongoDB handle documents, vectors, and graph-lookup in a single piece of infrastructure <a href="https://www.youtube.com/watch?v=JhfClrHIwG0">[7]</a>.</p><p>Reach for Neo4j only when deep traversals or specialized graph algorithms are core to the product <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">[8]</a>. Or a good trade-off is to use it internally just for data exploration. Do not design for Google scale when you are processing thousands of documents.</p><p>The memory pipeline sits at the core of this architecture, transforming raw documents into the exact triplets the rest of the system queries.</p><h2>The Memory Pipeline</h2><p>The memory pipeline cleans the incoming document.</p><p>Next is optional chunking. If you can avoid chunking, avoid it. It introduces problems and is more about RAG-era reflexes than a necessity. You always have to customize the solution based on your data and try to introduce as little complexity as possible.</p><p>Next, the graph extractor emits triplets. You should use Pydantic-style schema descriptors so the LLM knows how each field should look.</p><p>Normalization is the most important step. You track the evolution of a single entity over time. Do not allow multiple versions of the same person to exist. The system re-uses the same canonical ID across extractions. New metadata and new relationships layer on top <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">[9]</a>.</p><p>Finally, you embed the relevant fields for semantic search.</p><p>Now, let&#8217;s look at the core ways of data models you can use to store your KG.</p><h2>Single Mutable Collection vs. Append-Only Log Data Models</h2><p>There are two main approaches on how you can model your collections: as an append-only log or as a single mutable collection. Both have their pros and cons.</p><p>The append-only log consists of two collections: an append-only log and a queryable materialized view.</p><p>The system appends every event to an immutable log. A periodic materialization step squashes all events for the same ID into one canonical record.</p><p>You get versioning, temporality, and reversibility for free. You pay in RAM and operational complexity. As RAM is the most scarce and costly piece of hardware for hosting databases, this quickly translates into larger compute costs.</p><p>The single mutable collection approach drops the log. Each extraction directly upserts into the queryable collection.</p><p>You get simpler ops and real-time visibility, but the temporal audit trail is gone. Pick the single collection if operational simplicity and reduced costs beat time-travel.</p><p>Pick the two-collection append-only approach if you genuinely need an audit trail. Append-only collections never delete and never update. The same ID can appear multiple times across extractions, reflecting updates of an entity or relationship instance across the KG.</p><p>You can replay history up to a point in time, soft-delete, and revert a bad extraction. Materialization squashes all logs sharing an ID into one canonical entity.</p><p>An intuitive way of comparing the two methods is that the single mutable collection option is the same as the materialized view of the append-only option. Thus, one option comes with an append-only log, which comes with versioning and temporality, while the other doesn&#8217;t.</p><h3>How Would This Look Within the Digital Twin?</h3><p>Each log event lands with an auto-generated <code>ObjectId</code> plus a single <code>chunk_id</code> and <code>source_document_id</code> pinning it to one origin, with no embedding because nothing has been merged yet into the final instance. Materialization groups events by <code>(name, type)</code> for nodes and by the <code>(source, kind, target)</code> triplet for edges, swapping the <code>ObjectId</code> for a deterministic composite ID that <em>is</em> the merge key, unioning every contributing document into a <code>sources</code> array, and embedding each canonical entity once.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zNQp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zNQp!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 424w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 848w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 1272w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zNQp!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png" width="1200" height="752.4725274725274" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:913,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;data_model_append_only_log&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="data_model_append_only_log" title="data_model_append_only_log" srcset="https://substackcdn.com/image/fetch/$s_!zNQp!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 424w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 848w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 1272w, https://substackcdn.com/image/fetch/$s_!zNQp!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c4d1233-69a5-4efc-96c1-9e853d3b78a6_2087x1309.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 6: The two-collection MongoDB shape. Left column shows the append-only log node and edge. Right column shows the materialized node and materialized edge.</figcaption></figure></div><p>Nodes and edges share a single collection, separated only by a <code>kind</code> discriminator. So within our MongoDB implementation, <code>$graphLookup</code> walks <code>source_node_id &#8594; target_node_id</code> recursively without joining across collections.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!E-qQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!E-qQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 424w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 848w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 1272w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!E-qQ!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png" width="1200" height="636.2637362637363" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:772,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;data_model_one_collection&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="data_model_one_collection" title="data_model_one_collection" srcset="https://substackcdn.com/image/fetch/$s_!E-qQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 424w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 848w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 1272w, https://substackcdn.com/image/fetch/$s_!E-qQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe4ed1b3f-7ca3-4e9c-9e47-a74252a3189a_2292x1215.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 7: The one-collection MongoDB shape. Nodes and edges coexist in a single collection, both keyed by deterministic string IDs.</figcaption></figure></div><p> A student asked about community detection and isolated nodes. Once materialization runs, the system computes communities over the canonical node collection. An isolated node is just a singleton community. Filter or keep it based on your use case. Postgres and MongoDB handle hundreds of millions of small records. They can also scale vertically easily through sharding by partitioning on the entity and relationship IDs.</p><p>Now, let&#8217;s finally understand how we can query the KG and plug it into an agent.</p><h2>Finally...Let&#8217;s Understand the Retrieval Algorithm</h2><p>During retrieval, we use a hybrid index.</p><p>Text search uses exact keywords. Semantic search is meaning-based. Graph search is a multi-hop traversal across the typed edges.</p><p>Communities are an optional fourth index for topical clusters.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nriB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nriB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!nriB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!nriB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!nriB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nriB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Retrieval Example&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Retrieval Example" title="Retrieval Example" srcset="https://substackcdn.com/image/fetch/$s_!nriB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!nriB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!nriB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!nriB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9f1d6313-13fa-49b8-9098-8a52d8995da4_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 8: Top-down retrieval example for the query: &#8220;Create a presentation on GraphRAG for O&#8217;Reilly&#8221;.</em></figcaption></figure></div><p>GraphRAG retrieval is a two-stage move <a href="https://towardsdatascience.com/how-to-build-a-graph-rag-app-b323fc33ba06/">[10]</a>.</p><p>Stage 1 runs text and semantic search. It merges results with Reciprocal Rank Fusion (RRF). Apply a cutoff to get your entry points <a href="https://substack.com/@jeremyarancio/note/c-205294494">[11]</a>.</p><p>Stage 2 walks 2-3 hops across the typed edges to expand the result set.</p><p>During retrieval, GraphRAG&#8217;s addition over RAG is this multi-hop step, after the RRF merge, which is standard for most RAG systems.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p-rw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p-rw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 424w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 848w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p-rw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png" width="1399" height="1254" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1254,&quot;width&quot;:1399,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Two-stage retrieval. Text and semantic search feed RRF for entry points. From there, 2-3 hop graph traversal expands the result set.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Two-stage retrieval. Text and semantic search feed RRF for entry points. From there, 2-3 hop graph traversal expands the result set." title="Two-stage retrieval. Text and semantic search feed RRF for entry points. From there, 2-3 hop graph traversal expands the result set." srcset="https://substackcdn.com/image/fetch/$s_!p-rw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 424w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 848w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 1272w, https://substackcdn.com/image/fetch/$s_!p-rw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc07f92e0-5a0b-46a8-b96d-f3ea887de28d_1399x1254.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 9: Two-stage retrieval. Text and semantic search feed RRF for entry points. From there, 2-3 hop graph traversal expands the result set.</em></figcaption></figure></div><p>Still, there are two important details to highlight. There&#8217;s bottom-up, which expands entities for depth, while top-down hops across communities for a high-level overview <a href="https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/">[2]</a>. This translates to a trade-off between context size, latency and performance.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LuE-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LuE-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LuE-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png" width="1024" height="1024" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1024,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Bottom-up vs. top-down GraphRAG. Both start at text and semantic search. Bottom-up expands entities for depth. Top-down hops across communities for a high-level overview.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Bottom-up vs. top-down GraphRAG. Both start at text and semantic search. Bottom-up expands entities for depth. Top-down hops across communities for a high-level overview." title="Bottom-up vs. top-down GraphRAG. Both start at text and semantic search. Bottom-up expands entities for depth. Top-down hops across communities for a high-level overview." srcset="https://substackcdn.com/image/fetch/$s_!LuE-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 424w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 848w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 1272w, https://substackcdn.com/image/fetch/$s_!LuE-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb70ad9e2-6d9a-4cf7-b66d-ae7bb7b49214_1024x1024.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 10: Bottom-up vs. top-down GraphRAG. Both start at text and semantic search. Bottom-up expands entities for depth. Top-down hops across communities for a high-level overview.</em></figcaption></figure></div><p>Now, to close the loop, let&#8217;s connect everything to an agent.</p><h2>The Cherry on Top: Agentic GraphRAG</h2><p>GraphRAG becomes agentic when an agent gets to write to and search the knowledge graph autonomously <a href="https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html">[5]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K9Ds!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Agentic GraphRAG Architecture&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Agentic GraphRAG Architecture" title="Agentic GraphRAG Architecture" srcset="https://substackcdn.com/image/fetch/$s_!K9Ds!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 424w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 848w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!K9Ds!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffefc6b09-62e0-4a2f-93b6-ad8c2ce773db_1200x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 11: Agentic GraphRAG via MCP. The agent calls search and write tools exposed by an MCP server.</em></figcaption></figure></div><p>The agent dynamically writes queries against the materialized knowledge graph using a family of <code>search_memory</code> tools. The <code>write_memory</code> family of tools runs the data and memory pipelines on the current conversation or any other type of document. These tools are exposed to the agent via the MCP server, implemented in FastMCP.</p><p>This differs from the five-component architecture explained earlier: this time, the agent decides when to search/write to memory.</p><p>The search tools can directly implement the text + semantic + graph-search algorithm programmatically, or let the agent write the query code on-demand, which gives more flexibility at the cost of potentially less optimal code.</p><p>As for the write tools, allowing the agent to ingest the current conversation ensures continual learning by dynamically tracking the user&#8217;s preferences, to-dos, experiences and more.</p><p>At the moment, harnesses such as Claude Code use the filesystem to implement the memory layer. But as the data grows, gets more complex, or we have to operate under strict cost/latency requirements, we will need more powerful solutions than just hoping the agent will figure it out through progressive disclosure.</p><h2>What&#8217;s Next</h2><p>In this piece, I presented only the high-level architecture and strategies around GraphRAG.</p><p>The issue is that when you start diving into each component, such as normalization, extraction, embedding or data modeling, you will realize that everything is extremely custom to your own data and use case.</p><p>This is especially true because GraphRAG is still in its early days, where there is no clear plan of attack.</p><p>That&#8217;s why I am actively working on a new book on how to implement a personal assistant from scratch (yes, together with Maxime Labonne!), where we will explore building a memory layer stage by stage: RAG, then GraphRAG, with an AI Evals layer on top to measure the actual gain in performance when introducing GraphRAG. As soon as I have more details on this, I will let you know.</p><p><em>But here is what I&#8217;m wondering:</em></p><blockquote><p><em><strong>Are you using a single database (Postgres / MongoDB) or splitting graph and vector workloads across specialized systems (Neo4j + Pinecone)?</strong></em></p></blockquote><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/agentic-graphrag/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/agentic-graphrag/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/agentic-graphrag?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/agentic-graphrag?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Anthropic. (n.d.). Effective Context Engineering for AI Agents. Anthropic. <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents</a></p></li><li><p>Larson, J. (2024, April 2). GraphRAG: Unlocking LLM Discovery on Narrative Private Data. Microsoft Research. <a href="https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/">https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/</a></p></li><li><p>Negro, A., Kus, V., Futia, G., &amp; Montagna, F. (n.d.). Knowledge Graphs and LLMs in Action. Manning. <a href="https://www.manning.com/books/knowledge-graphs-and-llms-in-action">https://www.manning.com/books/knowledge-graphs-and-llms-in-action</a></p></li><li><p>Neo4j Graph Data Platform. (n.d.). How Entity Extraction Works. Neo4j Agent Memory. <a href="https://www.manning.com/books/knowledge-graphs-and-llms-in-action">https://neo4j.com/labs/agent-memory/explanation/extraction-pipeline/</a></p></li><li><p>Monigatti, L. (n.d.). The Evolution From RAG to Agentic RAG to Agent Memory. Leonie Monigatti. <a href="https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html">https://www.leoniemonigatti.com/blog/from-rag-to-agent-memory.html</a></p></li><li><p>Govindarajan, V. (n.d.). OpenClaw Architecture - Part 3: Memory and State Ownership. The Agent Stack. <a href="https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory">https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory</a></p></li><li><p>Iusztin, P., &amp; Rodrigues, J. (n.d.). <a href="https://www.decodingai.com/p/building-vertical-ai-agents-case-study-1">How We Killed Our RAG Pipeline.</a></p></li><li><p>Neo4j Graph Data Platform. (n.d.). Why Neo4j? Graph-Native Memory Architecture. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/graph-architecture/">https://neo4j.com/labs/agent-memory/explanation/graph-architecture/</a></p></li><li><p>Neo4j Graph Data Platform. (n.d.). Entity Resolution and Deduplication. Neo4j Agent Memory. <a href="https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/">https://neo4j.com/labs/agent-memory/explanation/resolution-deduplication/</a></p></li><li><p>Hedden, S. (n.d.). How to Build a Graph RAG App. Towards Data Science. <a href="https://towardsdatascience.com/how-to-build-a-graph-rag-app-b323fc33ba06/">https://towardsdatascience.com/how-to-build-a-graph-rag-app-b323fc33ba06/</a></p></li><li><p>Arancio, J. (n.d.). Comment on Hybrid RRF Retrieval Pipeline. Substack. <a href="https://substack.com/@jeremyarancio/note/c-205294494">https://substack.com/@jeremyarancio/note/c-205294494</a></p></li><li><p>Liu, J. (2025, May 19). There Are Only 6 RAG Evals. jxnl. <a href="https://jxnl.co/writing/2025/05/19/there-are-only-6-rag-evals/">https://jxnl.co/writing/2025/05/19/there-are-only-6-rag-evals/</a></p></li><li><p>Zhang, B. (2026, January 22). Scaling PostgreSQL to Power 800 Million ChatGPT Users. OpenAI. <a href="https://openai.com/index/scaling-postgresql/">https://openai.com/index/scaling-postgresql/</a></p></li><li><p>Govindarajan, V. (n.d.). OpenClaw Architecture - Part 2: Concurrency, Isolation, and the Invariants That Keep Agents Sane. The Agent Stack. <a href="https://theagentstack.substack.com/p/openclaw-architecture-part-2-concurrency">https://theagentstack.substack.com/p/openclaw-architecture-part-2-concurrency</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[What Held Up at 3 AM: One Engineer's RAG Case Study]]></title><description><![CDATA[You iterate. You evaluate. Weave CLI unifies 11 vector databases into one workflow.]]></description><link>https://www.decodingai.com/p/ship-rag-with-weave-cli</link><guid isPermaLink="false">https://www.decodingai.com/p/ship-rag-with-weave-cli</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Wed, 29 Apr 2026 11:04:33 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SPcK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SPcK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SPcK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SPcK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1350466,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/195449428?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SPcK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!SPcK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3f2b8d15-142e-443d-88c0-086a37bf2051_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Most AI demos work. Most AI products don&#8217;t. This series is a collection of interviews with engineers who shipped AI agents to production, covering the stacks they chose, the architectures they regretted, and what actually held up at 3 am.</p><p>This is an interview with <a href="https://www.linkedin.com/in/drmaximilien/">Michael Maximilien</a>, former CTO and Distinguished Engineer at IBM and Chairperson of the Board of the NodeJS Foundation. Now, the founder and CEO of ClawMax.ai, an AI agent orchestration platform powered by OpenClaw and the creator of <a href="https://github.com/maximilien/weave-cli/tree/main">weave-cli</a>, an open-source tool for shipping Retrieval-Augmented Generation (RAG) systems.</p><p><em>Watch our full interview on YouTube</em> &#8595;</p><div id="youtube2-eYaWxljC4sA" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;eYaWxljC4sA&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/eYaWxljC4sA?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><p>Michael Maximilien spent a year building RAG systems for customer after customer. Every new project required navigating dozens of moving parts. He had to pick a vector database, select an embedding model, chunk the data, ingest it, search it, and iterate.</p><blockquote><p><em>&#8220;I was doing this a lot and I wasn&#8217;t getting the results I wanted.&#8221;</em> &#8212; Max</p></blockquote><p>The failures were concrete. Halfway through an ingestion run, Milvus would run out of memory. Two collections made it in. The third was broken. Without a checkpoint or resume function, he had to recompute everything from scratch.</p><blockquote><p><em>&#8220;The experiment doesn&#8217;t just run, it fails. You have to be able to pick up from the failure.&#8221;</em> &#8212; Max</p></blockquote><p>Another failure mode involved manually comparing Weaviate against Milvus. One configuration typo could lead to drawing the wrong conclusion.</p><blockquote><p><em>&#8220;You might end up thinking Weaviate is better than Milvus when actually your comparison was wrong.&#8221;</em> &#8212; Max</p></blockquote><p>This manual flywheel stole time from actually helping his customers ship their products. He burned days on reset and re-ingest cycles that failed halfway. Worse, he produced results he could not trust.</p><p>Most teams treat RAG as a simple setup task. They picked a vector database because it trended online. They pick an embedding model because OpenAI is the safe default.</p><p>They guess a chunking strategy, guess the top-K retrieval parameters, and ship it. Then they spend the next six months vibe-checking the system.</p><p>Users complain. The team swaps a configuration knob. Nobody knows if it actually helped because nothing was measured.</p><blockquote><p><em>&#8220;There&#8217;s a lot of steps.&#8221;</em> &#8212; Max</p></blockquote><p>You lose the working system you thought you had. You burn weeks debugging silent ingestion failures because no trace exists.</p><p>Customer trust evaporates when the same question gets three different answers across releases.</p><p><em><strong>Max took the opposite bet. He built <a href="https://github.com/maximilien/weave-cli">Weave CLI</a>: a unified command-line tool for RAG over eleven vector databases.</strong></em></p><p>It features first-class observability implemented with <a href="https://github.com/comet-ml/opik">Opik</a>, an open-source evaluation and optimization tool, baked in from the first commit. You can try out their managed platform for free <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">here</a> for 25k spans/month.</p><p>By the end of this case study, you will understand how to unify your RAG stack so that switching a database, an embedding model, or an agent is merely a config change. You will learn how to measure everything, so every switch is tracked, evaluated and compared. Ultimately, you will learn how to benchmark your solution against multiple parameters to find the best configuration for your problem.</p><blockquote><p><em>&#8220;There&#8217;s no one solution. You iterate and evaluate.&#8221;</em> &#8212; Max</p></blockquote><p>But first, let&#8217;s understand what Weave CLI is and how it works.</p><h2>Understanding the System Architecture of Weave CLI</h2><p>Weave CLI wraps 11 vector databases behind a single interface. From the outside, it looks and feels like any other RAG system. On the ingestion side, it populates the chosen vector database with chunks, metadata, and embeddings. On the query side, it takes natural-language questions and returns top-k ranked chunks that an agent can use to create an answer with citations.</p><p>What makes Weave CLI special is that everything is swappable via a configuration file: the vector database, the embedding model, the chunking strategy, the query agent, the RAG agent that interprets the chunks and so on. With the goal of making it very easy for you to benchmark, iterate on and improve your RAG solution.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!EBUu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!EBUu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 424w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 848w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 1272w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!EBUu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png" width="1400" height="549" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:549,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 1. Weave CLI in one breath.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 1. Weave CLI in one breath." title="Image 1. Weave CLI in one breath." srcset="https://substackcdn.com/image/fetch/$s_!EBUu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 424w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 848w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 1272w, https://substackcdn.com/image/fetch/$s_!EBUu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F657a97ea-990e-4bc0-879e-9d1c1695c547_1400x549.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 1: Weave CLI in one breath.</em></figcaption></figure></div><p>Weave CLI is composed of seven core components, each swappable by configuration.</p><p>The user-facing component is the <a href="https://github.com/spf13/cobra">Cobra-based CLI</a> and the interactive REPL. Weave stack sits underneath as the deployment layer. It brings the whole system, the databases, up or down with a local Docker/Podman Compose fallback.</p><p>Behind that surface sits the intelligence layer. Ten built-in agents share an <code>AgentChain</code> sequencer. Agents are used both within the CLI and during ingestion. Weave CLI supports RAG, QA and summarization agents, but what&#8217;s more interesting is during ingestion. For example, you describe your data, the <code>SchemaAgent</code> proposes a collection schema and a vector-database fit, the <code>ChunkingAgent</code> recommends a chunking strategy and an embedding provider is picked to match. The <code>Executor</code> drives a seven-step orchestration covering query analysis, planning, user confirmation, execution, reporting, display, and evaluation metrics.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5j2b!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5j2b!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5j2b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 2. System architecture.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 2. System architecture." title="Image 2. System architecture." srcset="https://substackcdn.com/image/fetch/$s_!5j2b!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!5j2b!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b5ddfba-3610-4349-b378-e31cdb6538d4_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 2: High-level system architecture.</em></figcaption></figure></div><p>The data layer is built around the <code>VectorDBClient</code> interface in <a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/vectordb/interfaces.go">src/pkg/vectordb/interfaces.go</a>. It is cleanly split into four sub-interfaces: <code>CollectionOperations</code>, <code>DocumentOperations</code>, <code>QueryOperations</code>, and <code>SchemaOperations</code>. A package-level factory registry in <a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/vectordb/factory.go">factory.go</a> registers all 11 adapter sub-packages using the ports-and-adapters pattern.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fQna!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fQna!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!fQna!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!fQna!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!fQna!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fQna!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png" width="1456" height="562" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!fQna!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 424w, https://substackcdn.com/image/fetch/$s_!fQna!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 848w, https://substackcdn.com/image/fetch/$s_!fQna!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 1272w, https://substackcdn.com/image/fetch/$s_!fQna!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1019df63-46ff-4c02-a7ed-e9cb14dfe5fe_2120x819.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Still... There is a trade-off to this design. A unified interface is a lowest-common-denominator by construction, so if you need PGVector&#8217;s transactional semantics or Neo4j&#8217;s native graph traversal as first-class features, a unified adapter costs you that expressiveness.</p><p>On top of the vector-database layer sit five embedding providers: OpenAI, sentence-transformers, Ollama, Cohere, and Voyage. The ingestion pipeline runs alongside these, handling file scanning, processing, and batching.</p><p>As of April 2026, Max has strong views on which vector database to choose. Weaviate is his default for cloud deployments. Pinecone is the pick for hosted solutions. OpenSearch covers self-hosted cloud. Milvus handles both local and cloud. Qdrant is his go-to for local use because its Rust implementation is low-memory and fast.</p><p>On top of the agent layer, we have the observability layer implemented using Opik and OpenTelemetry, along with an evaluation harness with four LLM judges. The evaluation harness is itself pluggable between a local evaluator and <a href="https://github.com/comet-ml/opik">Opik</a>.</p><p>The configuration is the source of truth for the whole stack. A <code>config.yaml</code> file holds the non-secret details of the vector database, agent, embedding model, and LLM, while secrets are loaded from a <code>.env</code> file. Check all the configs <a href="https://github.com/maximilien/weave-cli/tree/main/configs">here</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!l2Ox!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!l2Ox!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 424w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 848w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 1272w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!l2Ox!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png" width="1456" height="781" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:781,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!l2Ox!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 424w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 848w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 1272w, https://substackcdn.com/image/fetch/$s_!l2Ox!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F60b40610-b299-4b36-9eec-a721dc5a399e_2244x1203.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let us trace a query through the system end-to-end using a concrete example: a user asks about Leica Noctilux lens auctions. The flow unfolds across nine hops, each an Opik span. First, the user submits the natural-language query to the REPL, which immediately starts monitoring the trace with Opik.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N6p7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N6p7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 424w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 848w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 1272w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N6p7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png" width="1400" height="1356" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1356,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 3. Every hop in a RAG query is an Opik span.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 3. Every hop in a RAG query is an Opik span." title="Image 3. Every hop in a RAG query is an Opik span." srcset="https://substackcdn.com/image/fetch/$s_!N6p7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 424w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 848w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 1272w, https://substackcdn.com/image/fetch/$s_!N6p7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5f2a275f-baff-4366-ba01-bebe3442410a_1400x1356.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 3: The data flow of the RAG query execution.</em></figcaption></figure></div><p>The QueryAgent then validates and classifies the intent, passing control to the PlanningAgent to generate an execution plan. Next, the VectorDB adapter performs a semantic search to retrieve relevant documents. The ContextBuilder filters, deduplicates, and sorts these results before handing them to the RAGAgent, which generates the final answer with citations. Finally, the REPL ends the Opik trace, in which every step emits a span containing details such as costs, latency and input/output.</p><h3>Why Building in Go and Not TypeScript or Python</h3><p>Most popular agentic CLIs / REPLs, such as Claude Code or OpenCode, are built in TypeScript. But Max, as a former Node.js board chairperson, strongly suggests just going with Go or Rust if memory constraints are a concern.</p><p>Why? Because Go apps ship as single binaries. Simple. Beautiful. It runs everywhere.</p><p>On-premise customers cannot rely on npm, uv, or JVM registries being reachable inside their own networks, and dependency pinning does not fix network isolation. A single compiled binary sidesteps the entire problem. Go&#8217;s track record as the language of Kubernetes is the existing proof that this trade-off works for infrastructure tooling, which is exactly the category Weave CLI sits in. Max himself spent 10 years writing Go on those systems.</p><p>Max&#8217;s second argument is that language choice matters less than it used to, because AI coding assistants lower the learning-curve barrier across the board.</p><blockquote><p><em>&#8220;Most people don&#8217;t write code anymore.&#8221;</em> &#8212; Max</p></blockquote><p>Still... Max&#8217;s newer project (ClawMax.ai) is mostly in TypeScript because it is the best tool for the job, not because he switched allegiances.</p><blockquote><p><em>&#8220;The stack decision has to be what your system wants, not what the herd is doing.&#8221;</em> &#8212; Max</p></blockquote><p>Next, we zoom into the layers doing the heavy lifting, the ingestion pipeline and the unified VDB interface.</p><h2>Supporting 11 Vector Databases</h2><p>The vector database layer is where the ingestion pipeline meets the unified VDB interface. To see how they work together, we&#8217;ll trace Max&#8217;s Leica Noctilux auction catalog through the system one step at a time.</p><p>Each document in the catalog is a single lens listing. It contains a photo of the Noctilux, a short caption with the model number and condition, a price, and a few lines of provenance. The text is sparse. Most of the signal sits in the image itself, and the caption is just enough to disambiguate one Noctilux from another. That sparseness drives a multi-modal ingestion decision up front. The image and the surrounding caption are embedded into two separate collections, one keyed on image vectors and one on caption text vectors. At query time, the auction agent fans out to both collections and merges the results through the <code>ContextBuilder</code>.</p><p>Before the actual ingestion, we run a <code>FileScanner</code> that walks the 426 listing files on disk, applying glob matching, exclusion filters, and SHA256 deduplication (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/pipeline/scanner.go">src/pkg/pipeline/scanner.go</a>). Re-running ingestion on the same directory skips unchanged documents, making this step fully idempotent and computationally cheap.</p><p>The <code>DocumentProcessor</code> extracts text and images from each listing (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/pipeline/processor.go">src/pkg/pipeline/processor.go</a>). For the Leica dataset, the PDF extractor pulls the caption text, and OCR runs on the lens photo to catch any model number printed on the barrel. This step is idempotent but computationally expensive due to PDF parsing and OCR, and it fails if the document format is unsupported. Next, the <code>ChunkingAgent</code> dynamically selects the best chunking strategy for each document.</p><div class="callout-block" data-callout="true"><p>&#128161; Chunking is a tier 1 knob. Public benchmarking shows that swapping between recursive, sentence-level, and token-level strategies can move retrieval accuracy by double-digit percentages on the same corpus <a href="https://research.trychroma.com/evaluating-chunking">[1]</a>.</p></div><p>Next, we move to embedding (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/embeddings/model_registry.go">src/pkg/embeddings/model_registry.go</a>). In the Leica flow, caption text flows through the text embedder, and image descriptors flow through a separate image embedding model. Raw images larger than per-backend limits (Milvus caps fields at 65KB) get offloaded to S3/MinIO, leaving only a URL in the VDB payload. The default option is to use OpenAI&#8217;s embedding model, which is highly expensive in compute and API costs and can fail if you hit rate limits. When scaling, you can use open-source embeddings via Ollama. They run locally with no API key.</p><p>The <code>BatchWriter</code> processes documents with durability, such as checkpoint and resume functionality. For example, when ingesting data at scale, you often have network I/O failures or database connection drops. Through checkpointing, we ensure the state is idempotent. Batch checkpointing is the difference between a short retry and a multi-hour rebuild.</p><blockquote><p><em>&#8220;You have to recompute everything from scratch, which is crazy.&#8221;</em> &#8212; Max</p></blockquote><p>The <code>VectorDBClient</code> Interface sits at the core of the adapter pattern (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/vectordb/interfaces.go">src/pkg/vectordb/interfaces.go</a>) used to support the 11 databases. The project started with Weaviate. Milvus was surprisingly similar. Qdrant was also very similar. MongoDB was a different beast, but the interface still fit.</p><blockquote><p><em>&#8220;The biggest surprise was PGVector.&#8221;</em> &#8212; Max</p></blockquote><p>PGVector is the most incompatible on paper. Postgres is a relational database with its own migrations. Yet the unified interface fits.</p><p>The pipeline ends at any of the eleven vector databases (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/vectordb/factory.go">src/pkg/vectordb/factory.go</a>), emitting a final <code>vectordb.adapter</code> span. The 426 Leica listings are split into roughly 426 caption vectors in one collection and 426 image vectors in a parallel collection, both sharing listing IDs as the cross-reference key.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0znX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0znX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 424w, https://substackcdn.com/image/fetch/$s_!0znX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 848w, https://substackcdn.com/image/fetch/$s_!0znX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 1272w, https://substackcdn.com/image/fetch/$s_!0znX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0znX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png" width="1400" height="590" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:590,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 4. A document's seven-hop journey from source to vector store.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 4. A document's seven-hop journey from source to vector store." title="Image 4. A document's seven-hop journey from source to vector store." srcset="https://substackcdn.com/image/fetch/$s_!0znX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 424w, https://substackcdn.com/image/fetch/$s_!0znX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 848w, https://substackcdn.com/image/fetch/$s_!0znX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 1272w, https://substackcdn.com/image/fetch/$s_!0znX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd956a09a-c56f-43ae-80ee-1a7c28ca7bd0_1400x590.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: The data flow of the document ingestion pipeline.</em></figcaption></figure></div><p>These steps cover every component any production ingestion pipeline needs, and Weave CLI ensures each one is swappable by configuration (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/stack/ingest.go">src/pkg/stack/ingest.go</a>): the FileScanner, the DocumentProcessor, the ChunkingAgent, the embedding provider, the BatchWriter, the VectorDBClient interface, and the concrete VDB adapter.</p><p>During retrieval, when a user asks <code>weave query "summarise the 2024 auction catalogue"</code>, the <code>QueryAgent</code> classifies the intent, the <code>PlanningAgent</code> decides to hit both Leica collections, and the <code>VectorDB</code> adapter runs a semantic search on each. The <code>ContextBuilder</code> then merges the image-collection hits with the caption-collection hits, deduplicates by listing ID, sorts by relevance score, and extracts content in priority order (caption text first, image metadata second, URL fallback last) into a single prompt for the <code>RAGAgent</code>.</p><p>The ingestion pipeline and VDB interface are the skeleton of Weave CLI. The agent layer is what makes it feel like Claude Code for vector databases.</p><h2>Zooming into the REPL</h2><p>Weave CLI provides a Claude-Code-like experience for vector databases, which, at its core, is a Read-Eval-Print Loop (REPL) environment hooked up to multiple agents.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pAbT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pAbT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 424w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 848w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 1272w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pAbT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png" width="1400" height="1344" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1344,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 5. The Agent Layer up close.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 5. The Agent Layer up close." title="Image 5. The Agent Layer up close." srcset="https://substackcdn.com/image/fetch/$s_!pAbT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 424w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 848w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 1272w, https://substackcdn.com/image/fetch/$s_!pAbT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4424806c-ee3c-456b-bb7f-ae4514b9688b_1400x1344.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 5: The Agent Layer up close.</em></figcaption></figure></div><p>Weave CLI ships with 12 built-in agents that you configure via YAML. Three of them are user-facing:</p><ol><li><p><strong>Precise QA</strong> &#8212; asks a question and answers it, and says it cannot answer when it lacks information. Zero hallucination tolerance.</p></li><li><p><strong>RAG</strong> &#8212; finds the closest chunks and generates an answer over them. This is the default.</p></li><li><p><strong>Summarize</strong> &#8212; produces a short summary of retrieved chunks.</p></li></ol><p>&#128161; The beauty is that you can add or modify them as you please.</p><p>The next eight agents power the Claude-Code-like orchestration loop: the <code>QueryAgent</code> for intent classification, the <code>PlanningAgent</code> for the execution plan, the <code>WeaveAgent</code> for tool execution with retries, the <code>BashAgent</code> for safe execution, the <code>RAGAgent</code> that the RAG persona dispatches to, the <code>OutputAgent</code> to format progress, the <code>ReportAgent</code> to generate operation reports, and the <code>EvalAgent</code> to track metrics.</p><p>The final two are domain helpers used during ingestion: the <code>ChunkingAgent</code> and the <code>SchemaAgent</code>.</p><p>Similar to the vector database layer, all the agents implement the same interface:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7L_X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7L_X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 424w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 848w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 1272w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7L_X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png" width="1456" height="378" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a78c406d-7dd3-4366-9375-25385f1357be_2418x627.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:378,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!7L_X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 424w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 848w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 1272w, https://substackcdn.com/image/fetch/$s_!7L_X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa78c406d-7dd3-4366-9375-25385f1357be_2418x627.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let&#8217;s tie everything together. When you ask a query, the <code>QueryAgent</code> classifies intent and acts as a router. The <code>PlanningAgent</code> generates a plan of CLI commands. The <code>BashAgent</code> executes them and pipes the output through a command-line JSON processor for filtering. The <code>OutputAgent</code> formats the result. This is the Claude-Code-like loop in action.</p><p>The cherry on top is that the Weave CLI capabilities are also exposed as a Model Context Protocol (MCP) server. Thus, instead of using the Weave CLI directly, you can leverage its full functionality through your harness of choice (Claude Code, Codex, etc.).</p><p>Twelve agents, eleven databases, five embedding providers, and multiple chunking strategies create a lot of surface area. Opik is what makes the whole thing observable when something breaks.</p><h2>Monitoring the System</h2><p>With so many moving parts, you need to know the system is working. <a href="https://github.com/comet-ml/opik">Opik</a> is how Weave CLI answers that question: it traces every LLM call, every agent step, and every database write as an OpenTelemetry span.</p><blockquote><p><em>&#8220;Using Opik to tell me how many LLM calls, tokens, and cost per query.&#8221;</em> &#8212; Max</p></blockquote><p>During development, Max tracked a bug in which documents appeared to be ingested but were never persisted to Milvus. The Opik trace waterfall showed the database flush operations were silently timing out.</p><p><em>&#128161; If you want to try it out, you can create an account for free on Opik&#8217;s managed platform <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">here</a> for 25k spans/month.</em></p><p>The fix was adding dedicated timeout contexts per collection. Without the trace, this would have been a multi-day hunt through logs.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!JSuf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!JSuf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 424w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 848w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 1272w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!JSuf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png" width="1400" height="1243" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1243,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1628767,&quot;alt&quot;:&quot;Image 6. Opik turns the RAG pipeline into a measurable waterfall.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 6. Opik turns the RAG pipeline into a measurable waterfall." title="Image 6. Opik turns the RAG pipeline into a measurable waterfall." srcset="https://substackcdn.com/image/fetch/$s_!JSuf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 424w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 848w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 1272w, https://substackcdn.com/image/fetch/$s_!JSuf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff46859e3-3d44-4ec2-bc07-cb30c6250d7d_1400x1243.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 6: Opik turns the RAG pipeline into a measurable waterfall.</em></figcaption></figure></div><p>The integration provides cost and latency visibility per trace. You see tokens and dollars per query without writing custom logging. It provides a latency breakdown.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!57X_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!57X_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 424w, https://substackcdn.com/image/fetch/$s_!57X_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 848w, https://substackcdn.com/image/fetch/$s_!57X_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 1272w, https://substackcdn.com/image/fetch/$s_!57X_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!57X_!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png" width="1200" height="780.4945054945055" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:947,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;opik_monitoring_dashboard.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="opik_monitoring_dashboard.png" title="opik_monitoring_dashboard.png" srcset="https://substackcdn.com/image/fetch/$s_!57X_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 424w, https://substackcdn.com/image/fetch/$s_!57X_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 848w, https://substackcdn.com/image/fetch/$s_!57X_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 1272w, https://substackcdn.com/image/fetch/$s_!57X_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4aed6d3d-347f-4923-8c80-2df1d69fd2e2_2834x1844.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 7: <a href="https://github.com/comet-ml/opik">Opik&#8217;s</a> monitoring dashboard.</em></figcaption></figure></div><p>Finally, it provides error visibility to make silent failures loud.</p><p><strong>How hard was it to integrate Opik into Weave CLI?</strong></p><blockquote><p><em>&#8220;It&#8217;s a very straightforward integration &#8212; I pass all queries to the LLMs through Opik via OpenTelemetry, and then I query Opik to aggregate cost from the start of the command to the end.&#8221;</em> &#8212; Max</p></blockquote><p>Every step in the ingestion and retrieval data flows emits a span (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/llm/opik.go">src/pkg/llm/opik.go</a>), which are aggregated under traces containing all the steps between a user request/response.</p><p>It includes the query, the LLM reasoning, the tool calls, and the final response. The executor initializes Opik tracing here (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/executor/executor.go">src/pkg/executor/executor.go</a>).</p><p>Monitoring helps you debug your system. Evaluation moves everything forward, allowing you to quantify your application&#8217;s performance.</p><h2>Evaluating the Default Setup</h2><p>How do you know your agent is actually better after you swap an embedding model, a vector database or your chunking strategy? You need a good evaluation practice.</p><blockquote><p><em>&#8220;My customers always have five or six questions they ask every release to sanity-check the system. They know what to expect. So I took their QA questions and made them the baseline eval dataset.&#8221;</em> &#8212; Max</p></blockquote><p>Evaluation datasets come from real user behavior anchored in your business use case, not from standardized, generic benchmarks. If you do not have users yet, you should compile a small set of sanity questions a domain expert would actually ask.</p><p><strong>How does this work in Weave CLI?</strong></p><p>You start by defining an evaluation dataset in YAML format. This includes the query, expected answer, expected citations, and a minimum relevance score.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!aJ_u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!aJ_u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 424w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 848w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 1272w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!aJ_u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png" width="1456" height="923" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:923,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;code&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="code" title="code" srcset="https://substackcdn.com/image/fetch/$s_!aJ_u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 424w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 848w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 1272w, https://substackcdn.com/image/fetch/$s_!aJ_u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb02ca7f-37d7-462d-b6d4-7c00d649b34e_2302x1459.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Here is the full <a href="https://github.com/maximilien/weave-cli/blob/main/evals/datasets/baseline.yaml">baseline.yaml</a> file. Or this is how it looks in Opik:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lT6I!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lT6I!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 424w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 848w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 1272w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lT6I!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png" width="1200" height="581.0439560439561" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:705,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;opik_dashboard_dataset.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="opik_dashboard_dataset.png" title="opik_dashboard_dataset.png" srcset="https://substackcdn.com/image/fetch/$s_!lT6I!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 424w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 848w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 1272w, https://substackcdn.com/image/fetch/$s_!lT6I!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6e2b4d24-959a-40ec-bece-a2eb48c9d76b_2840x1376.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 8: <a href="https://github.com/comet-ml/opik">Opik&#8217;s</a> dataset dashboard.</em></figcaption></figure></div><p>Then you pick an evaluator harness that includes a set of metrics to evaluate against. This harness is itself pluggable: you pick between a local evaluator and Opik (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/evaluation/provider.go">src/pkg/evaluation/provider.go</a>).</p><p>We use two families of evaluators. Rule-based evaluators use regular expressions, exact matches, and citation presence (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/evaluation/custom_evaluator.go">src/pkg/evaluation/custom_evaluator.go</a>) to compute metrics such as <code>CitationMatching</code> for the RAG agent.</p><p>They are fast, deterministic, and free. You use them for structural checks.</p><p>The second family uses an LLM as a judge. Weave CLI ships four of these judges (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/evaluation/provider_opik.go">src/pkg/evaluation/provider_opik.go</a>). They evaluate Accuracy, Faithfulness, Hallucination, and Context Relevance.</p><p>They are slower and cost tokens. You use them for semantic quality.</p><blockquote><p><em>&#8220;The hallucination, citation, and accuracy metrics are all from Opik&#8217;s library &#8212; I ported them to Golang.&#8221;</em> &#8212; Max</p></blockquote><div class="callout-block" data-callout="true"><p>&#128161; One key step most people forget is to align the LLM judge with the human expert. In our use case, the correlation between an LLM judge&#8217;s faithfulness score and human judgment hovers around 0.55. Judges are a signal, not a ground truth. For example, on average, I spent three weeks labeling a few-shot examples and computing agreeability scores before I trusted my own judgment.</p></div><p>Then, you run the evaluation command against a chosen agent. Finally, you compare the result of the experiment with the previous run. Each pair of agent and dataset is one experiment (<a href="https://github.com/maximilien/weave-cli/tree/main/src/cmd/eval/run.go">src/cmd/eval/run.go</a>).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HxOa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HxOa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 424w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 848w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 1272w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HxOa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png" width="1400" height="639" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:639,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:301887,&quot;alt&quot;:&quot;Image 7. The evaluation spine.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 7. The evaluation spine." title="Image 7. The evaluation spine." srcset="https://substackcdn.com/image/fetch/$s_!HxOa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 424w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 848w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 1272w, https://substackcdn.com/image/fetch/$s_!HxOa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fee8df39c-8c74-42f1-ab0c-f4bb96f2f044_1400x639.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 9: The evaluation spine.</em></figcaption></figure></div><p>The <code>--use-opik</code> flag ships every trace and evaluation result to Opik (<a href="https://github.com/maximilien/weave-cli/tree/main/src/pkg/evaluation/runner.go">src/pkg/evaluation/runner.go</a>). Once in <a href="https://github.com/comet-ml/opik">Opik</a>, you get dataset management and experiment comparison.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mdXv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mdXv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 424w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 848w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 1272w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mdXv!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png" width="1200" height="763.1868131868132" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/aed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:926,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;opik_dashboard_experiments&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="opik_dashboard_experiments" title="opik_dashboard_experiments" srcset="https://substackcdn.com/image/fetch/$s_!mdXv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 424w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 848w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 1272w, https://substackcdn.com/image/fetch/$s_!mdXv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Faed8789c-7b27-4092-b23c-f800edad149f_2838x1804.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 10: Opik&#8217;s experiments dashboard.</em></figcaption></figure></div><p>Scoring every run forces a decision on which agent to ship. Benchmarking on top of your custom datasets provides a structured way to choose a parameter, such as your chunking strategy or top k results, without guessing.</p><h2>Benchmarking and Optimizing the System</h2><p>An experiment is a single parameterized run over an agent, dataset, embedding, chunking strategy, database, and judge. A benchmark is a structured set of experiments.</p><p>You hold most variables constant to isolate the effect of one. Benchmarking is how you turn random runs into a parameter- and prompt-search problem. This is often known as the optimization flywheel.</p><blockquote><p><em>&#8220;That&#8217;s the reason I created Weave CLI. Because this is tedious, but also error-prone.&#8221;</em> &#8212; Max</p></blockquote><p>Every benchmark is one configuration typo away from drawing the wrong conclusion. Disciplined benchmarking catches that error.</p><p>Experiment metadata guarantees reproducibility. Every experiment records the database, embedding model, chunking strategy, dataset, and everything else required to reproduce it. That&#8217;s usually the whole config.</p><p>Opik tracks this out of the box. Without it, a benchmark from four weeks ago is useless.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MCDv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MCDv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 424w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 848w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 1272w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MCDv!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png" width="1200" height="766.4835164835165" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:930,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;opik_dashboard_experiment.png&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="opik_dashboard_experiment.png" title="opik_dashboard_experiment.png" srcset="https://substackcdn.com/image/fetch/$s_!MCDv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 424w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 848w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 1272w, https://substackcdn.com/image/fetch/$s_!MCDv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15b350ec-7b0d-4014-a58e-7db286550336_2830x1808.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 11: <a href="https://github.com/comet-ml/opik">Opik&#8217;s</a> experiment dashboard.</em></figcaption></figure></div><p>When working on RAG systems, the optimization flywheel involves resetting the database, re-ingesting data with new parameters, re-evaluating, and comparing on your metrics of choice.</p><blockquote><p><em>&#8220;Benchmark is comparing multiple agents side by side. Same dataset, different agents &#8212; and each (agent, dataset) combination is its own experiment, you can compare later with its metadata.&#8221;</em> &#8212; Max</p></blockquote><p>You fix a baseline dataset and hold it constant. You vary one axis, typically the agent. You score against multiple metrics.</p><p>Each pair of agent and dataset is one <a href="https://github.com/comet-ml/opik">Opik</a> experiment. You compare them side-by-side to spot regressions and unexpected wins.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DwWF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DwWF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 424w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 848w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 1272w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DwWF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png" width="1400" height="1324" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1324,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Image 8. The optimization flywheel.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Image 8. The optimization flywheel." title="Image 8. The optimization flywheel." srcset="https://substackcdn.com/image/fetch/$s_!DwWF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 424w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 848w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 1272w, https://substackcdn.com/image/fetch/$s_!DwWF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F95d52fb2-ed34-4ad8-a77c-56e4c202260b_1400x1324.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 12: The optimization flywheel.</em></figcaption></figure></div><p>You trigger this loop via the command line with <code>weave eval run --dataset baseline --agents precise-qa,rag,summarize --use-opik</code>. Every subsequent benchmark streams into the same Opik project.</p><p>Max ran this loop for his Leica auction customer. He held the dataset and agent constant.</p><p>He varied only the embedding provider. He tested OpenAI against sentence-transformers. The open-source model won on quality by 11 percent.</p><p>It was 240 times faster for re-embedding. The vectors were 50 percent smaller, and the cost was zero.</p><p>This is a counterintuitive outcome. Without a structured benchmark, Max would have defaulted to OpenAI and been wrong.</p><h3>How to Keep the Flywheel Under Control?</h3><p>This optimization process involves running your ingestion and retrieval hundreds of times. Which can get costly fast. Super fast. The ingestion checkpointing makes it affordable.</p><p>Still, you should optimize your system in order of cheapest-to-change, biggest-win-first <a href="https://jxnl.co/writing/2024/02/28/levels-of-complexity-rag-applications/">[8]</a>. First, tune retrieval parameters like top-K. They are free to change and often provide the biggest wins.</p><p>Second, tune the embedding model. It is the cheapest component to swap and has a huge impact. Third, tune the chunking strategy. It requires re-ingestion but offers moderate quality gains.</p><p>Finally, tune the vector database. It has the highest switching cost and usually the smallest difference in quality.</p><p>The optimization flywheel effectively isolates variables, but it remains a manual process today.</p><p>The good news is that Weave CLI is heading toward full automated hyperparameter optimization across databases, embeddings, and chunking strategies. Just imagine. You will launch it before the weekend, and it will return on Monday with the best configuration for your dataset.</p><div class="callout-block" data-callout="true"><p>&#128173; P.S. If you want to use Weave CLI but think it&#8217;s missing a feature, Max is more than pleased to add it. Just open a PR/issue on the repository.</p></div><p><em>You can reproduce this benchmark step by step on your own stack by following <a href="https://github.com/maximilien/weave-cli/blob/main/demos/opik/DEMO.md">this doc</a>.</em></p><p><em>Watch our full interview on YouTube for all the 3am stories &#8595;</em></p><div id="youtube2-eYaWxljC4sA" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;eYaWxljC4sA&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/eYaWxljC4sA?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h2>Final Thoughts</h2><blockquote><p><em>Looking back, what was the hardest thing to implement, and what surprised you the most while building weave-cli?</em> &#8212; Paul</p></blockquote><p>The hardest part was designing a unified <code>VectorDBClient</code> that felt natural across 11 providers with wildly different APIs. The adapter pattern was the insight that made it work.</p><p>The biggest surprise was benchmarking OSS embeddings against OpenAI on the client&#8217;s data and finding them 11% higher quality, 240x faster, and free. A call we&#8217;d never have made without evals in place.</p><blockquote><p><em>If you had to rebuild Weave CLI from scratch, at what point would you introduce monitoring and evaluation? Would you do it earlier, later, or at the same time?</em> &#8212; Paul</p></blockquote><p>I&#8217;d introduce monitoring from day one. Having <a href="https://github.com/comet-ml/opik">Opik</a> traces during the early vector DB work would have immediately surfaced issues such as the silent Milvus persistence failures, which we debugged manually. As for evals, I&#8217;d keep at the same stage (after the core RAG pipeline was functional), but I&#8217;d design the harness interface up front for citation tracking and confidence scoring.</p><p><a href="https://github.com/comet-ml/opik">Opik</a> was easy to integrate and was key to getting the client dashboard working, since I could just run experiments and use evaluations and tracing to decide on the best options for the client.</p><p>Now, your <strong>next practical step</strong> is to experiment with <a href="https://github.com/maximilien/weave-cli">Weave CLI</a> on a real problem. Point it at 100 documents you want to do RAG on, ingest everything into two collections with two different embedding providers, and run the benchmark against the baseline evaluation dataset.</p><p>You can follow the step-by-step tutorial from <a href="https://github.com/maximilien/weave-cli/blob/main/demos/opik/DEMO.md">here</a></p><p><em>But here is what I&#8217;m wondering:</em></p><p><strong>While building your latest RAG system, what was your strategy to find the right parameters, such as the embedding model, chunking or retrieval strategies?</strong></p><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ship-rag-with-weave-cli/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/ship-rag-with-weave-cli/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ship-rag-with-weave-cli?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://www.decodingai.com/p/ship-rag-with-weave-cli?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><p><em>Thanks again to <a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Opik</a> for sponsoring this case study and keeping it free!</em></p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oSDm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oSDm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 424w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 848w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1272w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png" width="1456" height="364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:364,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Opik Banner&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Opik Banner" title="Opik Banner" srcset="https://substackcdn.com/image/fetch/$s_!oSDm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 424w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 848w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1272w, https://substackcdn.com/image/fetch/$s_!oSDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F26c21863-4ee6-4026-91c7-74650eb16dac_3168x792.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><a href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul">Try Opik for free here</a> (25k spans/month free)</figcaption></figure></div><p><strong>If you want to monitor, evaluate and optimize your AI workflows and agents:</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul&quot;,&quot;text&quot;:&quot;Try Opik for free&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.comet.com/site/?utm_source=newsletter&amp;utm_medium=partner&amp;utm_campaign=paul"><span>Try Opik for free</span></a></p><div><hr></div><h2>References</h2><ol><li><p>Chroma. (n.d.). Evaluating Chunking Strategies for Retrieval. Chroma. <a href="https://research.trychroma.com/evaluating-chunking">https://research.trychroma.com/evaluating-chunking</a></p></li><li><p>OpenTelemetry. (n.d.). Traces &amp; Spans specification. OpenTelemetry. <a href="https://opentelemetry.io/docs/concepts/signals/traces/">https://opentelemetry.io/docs/concepts/signals/traces/</a></p></li><li><p>Husain, H. (n.d.). Creating a LLM-as-a-Judge That Drives Business Results. <a href="http://Hamel Husain. https://hamel.dev/blog/posts/llm-judge/">Hamel Husain. https://hamel.dev/blog/posts/llm-judge/</a></p></li><li><p>Husain, H. (n.d.). Escaping POC Purgatory: Evaluation-Driven Development for AI. Hamel Husain. <a href="https://hamel.dev/blog/posts/evals/">https://hamel.dev/blog/posts/evals/</a></p></li><li><p>Liu, J. (2025, May 19). There Are Only 6 RAG Evals. Jason Liu. <a href="https://jxnl.co/writing/2025/05/19/there-are-only-6-rag-evals/">https://jxnl.co/writing/2025/05/19/there-are-only-6-rag-evals/</a></p></li><li><p>Comet. (n.d.). Opik &#8212; LLM observability &amp; evaluation platform. GitHub. <a href="https://github.com/comet-ml/opik">https://github.com/comet-ml/opik</a></p></li><li><p>Yan, E. (2024, August 18). Evaluating the Effectiveness of LLM Evaluators (LLM-as-Judge). Eugene Yan. <a href="https://eugeneyan.com/writing/llm-evaluators/">https://eugeneyan.com/writing/llm-evaluators/</a></p></li><li><p>Liu, J. (2024, February 28). Levels of Complexity: RAG Applications. Jason Liu. <a href="https://jxnl.co/writing/2024/02/28/levels-of-complexity-rag-applications/">https://jxnl.co/writing/2024/02/28/levels-of-complexity-rag-applications/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Stop Orchestrating AI Agents. Use Ralph Loops Instead.]]></title><description><![CDATA[How one simple loop beats multi-agent orchestration and context rot in production.]]></description><link>https://www.decodingai.com/p/ralph-loops</link><guid isPermaLink="false">https://www.decodingai.com/p/ralph-loops</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Thu, 23 Apr 2026 11:02:54 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!65x_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!65x_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!65x_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!65x_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!65x_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!65x_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!65x_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1356719,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/194537664?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!65x_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!65x_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!65x_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!65x_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5105d46d-79c6-417e-bf82-08a1b9b36f28_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>When building Brown, my writing assistant, I designed five specialized LLM nodes. One handled the introduction, another wrote sections, and others managed the conclusion, title, and editing. It became complicated, slow, and expensive.</p><p>I eventually collapsed the system into two agents: a writer and a reviewer operating in a loop. The simpler version performed better. The model retained the full context, and verification became a simple review step rather than a massive orchestration problem.</p><p>Most AI teams hit this exact wall. Developers spend more time babysitting AI than engineering, copying error logs and re-prompting models. The real bottleneck is the human.</p><p>Three failure modes explain why.</p><p>First, <strong>context rot.</strong> In long AI conversations, the context window becomes a junk drawer. Every failed attempt piles up until the sliding window drops the original specification. The model slides into a &#8220;dumb zone&#8221; where it hallucinates and forgets its goals. Traditional fixes like summarizing break down over dozens of reasoning rounds.</p><p>Second, <strong>premature exit.</strong> AI agents declare victory too early. Anthropic&#8217;s research notes that agents usually look around, see that progress has been made, and declare the job done <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">[1]</a>. Standard ReAct loops inherit the flaw.</p><p>Third, <strong>single-pass fragility.</strong> One prompt, one context, one shot. When it fails, the failure is chaotic. Jumping to multi-agent orchestration introduces distributed systems nightmares.</p><p>Ralph loops break the cycle by making &#8220;try again with fresh eyes&#8221; the default. Named after Ralph Wiggum from The Simpsons, the pattern wipes the conversation, reloads the full specification fresh each iteration, and uses the filesystem and git as the memory layer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!p_kr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!p_kr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 424w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 848w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 1272w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!p_kr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png" width="1400" height="1275" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1275,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1214355,&quot;alt&quot;:&quot;Top shows context accumulating until the model forgets. Bottom shows state living on disk where each turn starts clean.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Top shows context accumulating until the model forgets. Bottom shows state living on disk where each turn starts clean." title="Top shows context accumulating until the model forgets. Bottom shows state living on disk where each turn starts clean." srcset="https://substackcdn.com/image/fetch/$s_!p_kr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 424w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 848w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 1272w, https://substackcdn.com/image/fetch/$s_!p_kr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a12d8a1-8961-409a-958c-2b398c62ed60_1400x1275.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 1: The top shows context accumulating until the model forgets. Bottom shows the state living on disk, where each turn starts clean.</em></figcaption></figure></div><p>They remove the AI&#8217;s ability to grade its own work, using objective signals such as passing tests or linters to call the job done. Boris Cherny, creator of Claude Code, states that giving Claude a way to verify its work increases quality two to three times <a href="https://x.com/bcherny/status/2007179832300581177">[2]</a>.</p><p>One model. One loop. One verification signal. Failure becomes predictable, the loop catches errors and re-prompts automatically, creating a relatively deterministic feedback loop that will 10x the quality of the agent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dR8u!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dR8u!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 424w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 848w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 1272w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dR8u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png" width="1400" height="724" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:766461,&quot;alt&quot;:&quot;The Ralph loop. One model, one task per iteration, filesystem and git as memory, objective verification as the only exit.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Ralph loop. One model, one task per iteration, filesystem and git as memory, objective verification as the only exit." title="The Ralph loop. One model, one task per iteration, filesystem and git as memory, objective verification as the only exit." srcset="https://substackcdn.com/image/fetch/$s_!dR8u!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 424w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 848w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 1272w, https://substackcdn.com/image/fetch/$s_!dR8u!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F922e43de-ab6a-486e-8b41-2e5dd3bf3851_1400x724.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 2: The Ralph loop. One model, one task per iteration, filesystem and git as memory, objective verification as the only exit.</em></figcaption></figure></div><p>Now, let&#8217;s look at what Ralph loops are and when you can actually use them in practice.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Go Deeper Into Production AI Engineering (Product)</a></h2><p>Ralph loops prove that most of the leverage lies in the harness, not the model. If you want to master how to design, verify, and ship those AI harnesses in production, check out my <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a></strong>, built with Towards AI.</p><p>34 lessons. Three end-to-end portfolio projects. A certificate. And a Discord community with direct access to industry experts and me.</p><p><em>Rated 5/5 by 300+ students. The first 6 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p></div><h2>What Ralph Loops Are and How They Work</h2><p>Geoffrey Huntley named the pattern after Ralph Wiggum from The Simpsons, noting the character tries the same thing over and over until it works. Huntley&#8217;s motto captures the philosophy: the technique is deterministically bad in an undeterministic world. The simplest implementation is a bash while-true loop that pipes a prompt file into the agent forever, acting as a continuous harness pattern <a href="https://ghuntley.com/ralph/">[3]</a>, <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">[4]</a>.</p><p>As Einstein reportedly said: &#8220;Insanity is doing the same thing over and over again and expecting different results.&#8221; Well... I am sure he didn&#8217;t predict the rise of Claude Code, because that&#8217;s exactly what Ralph loops are all about.</p><p>Models are stochastic, strong at reading large contexts but imperfect on first pass. Re-running the same instruction forces self-review. The first iteration produces good but flawed output.</p><p>During the second pass, the model spots what it missed and refactors. The third iteration handles cleanup. Huntley delivered a minimum viable product quoted at 50,000 <em>for</em> <em>just </em>297 in tokens using a single Ralph loop: a 170x cost reduction over the human estimate <a href="https://ghuntley.com/ralph/">[3]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7XzG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7XzG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7XzG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Single-pass fails chaotically. Multi-agent deadlocks on shared state. Ralph loops isolate one task per iteration and use verification as the exit gate.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Single-pass fails chaotically. Multi-agent deadlocks on shared state. Ralph loops isolate one task per iteration and use verification as the exit gate." title="Single-pass fails chaotically. Multi-agent deadlocks on shared state. Ralph loops isolate one task per iteration and use verification as the exit gate." srcset="https://substackcdn.com/image/fetch/$s_!7XzG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!7XzG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc5267ce9-c548-40a1-959b-8416f9387c06_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 3: Single-pass fails chaotically. Multi-agent deadlocks on shared state. Ralph loops isolate one task per iteration and uses verification as the exit gate.</em></figcaption></figure></div><p>You can run these loops in two modes. Shared context keeps the session alive for explicit self-review. Fresh context starts a new session each iteration, removing confirmation bias.</p><p>The model sees only the repository and the skill file.</p><p>Nowadays, it&#8217;s common to replace brittle n8n workflows with a single Claude Code skill. This becomes even more powerful when running in a Ralph loop, especially because at the end of each run, you can take the signal and tell the model to update the skill with anything it should have done differently.</p><p>The skill evolves and quality improves automatically <a href="https://read.readwise.io/read/01kp5bgy8b07y256ythvkz2tt7">[5]</a>.</p><p>This self-improving mechanism reduces manual prompt tuning when applied to specific, repetitive engineering tasks.</p><h2>Three Real-World Use Cases</h2><p>In practice, Ralph loops don&#8217;t have a clear implementation pattern. They are more of an intuitive strategy you can get creative with. Thus, you have multiple ways of implementing them.</p><p>From my experience with Claude, you have three options for running Ralph loops, from highest abstraction to lowest:</p><ul><li><p><code>/ralph-loop</code><strong> plugin</strong> &#8212; the fastest path. Install it, run <code>/ralph-loop</code> in your session, and it manages the cycle for you.</p></li><li><p><code>/loop</code><strong> command</strong> &#8212; Claude Code&#8217;s built-in scheduler. <code>/loop every 1 minute /your-skill</code> fires the skill on a schedule <a href="https://www.anthropic.com/engineering/claude-code-best-practices">[6]</a>.</p></li><li><p><code>while true</code><strong> bash loop</strong> &#8212; the most primitive form. A one-liner that pipes a prompt file into the agent and restarts it forever.</p></li></ul><p>Because Claude Code keeps state through the files it&#8217;s working on, it retains context from the failed attempt and reads its own git diffs. Each iteration learns from the last.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mJx5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mJx5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 424w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 848w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 1272w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mJx5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png" width="1400" height="742" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e828a6ca-601e-42ce-8973-5e7817283061_1400x742.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:742,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The Stop Hook turns objective signals into the loop's only exit condition.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The Stop Hook turns objective signals into the loop's only exit condition." title="The Stop Hook turns objective signals into the loop's only exit condition." srcset="https://substackcdn.com/image/fetch/$s_!mJx5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 424w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 848w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 1272w, https://substackcdn.com/image/fetch/$s_!mJx5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe828a6ca-601e-42ce-8973-5e7817283061_1400x742.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: The Stop Hook turns objective signals into the loop&#8217;s only exit condition.</em></figcaption></figure></div><h3>Implementing a ticket backlog with test-driven development</h3><p>You can set up a ticket folder with numbered text files. Run a while-true loop that tells Claude to implement the next most important ticket using Test-Driven Development (TDD). The model writes tests first, writes the code, commits the changes, and moves on.</p><p>Claude reads all tickets, skips completed ones, picks the next priority, implements it, marks it done, and commits. No dependency graph is needed because the model decides the ordering on the fly. One dumb loop acts like a relentless single-threaded engineer working through the backlog.</p><p>For example, set up a <code>doc/tickets</code> folder with numbered tickets (001, 002, 003...). Each describes a feature or fix. Then run:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;shell&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-shell">while true; do
  claude "implement the next most important ticket using TDD principles from doc/tickets. commit when done"
done</code></pre></div><p>Or use Claude Code&#8217;s built-in loop:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;shell&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-shell">/loop every 1 minute
build the next ticket from doc/tickets using TDD, run tests, commit when done</code></pre></div><h3>Adding test coverage</h3><p>You can set a concrete goal to raise coverage from 16 percent to 95 percent. The loop reads coverage metrics, writes tests for uncovered functions, runs the suite, identifies gaps, and iterates.</p><p>The coverage report provides the objective backpressure. The loop does not stop until the numbers validate success. Each iteration chips away at untested code paths until the threshold is met.</p><p>The implementation is as easy as:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;shell&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-shell">while true; do
  claude "analyze coverage gaps, write tests for uncovered functions, run the test suite, fix failures. stop when coverage exceeds 95%"
done</code></pre></div><h3>Framework and dependency migrations</h3><p>Migrations require crisp completion criteria. Upgrading React v16 to v19, Next.js 14 to 15, or migrating Jest to Vitest demands a clean build and passing tests. The agent swaps syntax, updates dependencies, and runs build commands.</p><p>It uses compiler errors and failing tests as feedback. Each cycle fixes a batch of errors until the toolchain confirms the code is clean. Deterministic verification signals make framework migrations the perfect Ralph loop candidate.</p><p>These are three concrete starting points. Before you wire the first one up, there is one honest limit you should know.</p><h2>What&#8217;s Next</h2><p>Ralph loops are the starting point. Once comfortable, add self-improving skills that update their instructions after each run, wire stop hooks for objective quality gates to avoid infinite loops, and connect to external systems like Linear or GitHub Issues so the loop reacts to new work automatically.</p><p>The pattern scales further than it looks. OpenAI&#8217;s Codex team shipped one million lines of code across 1,500 pull requests with zero human-written code using what they call a &#8220;Ralph Wiggum Loop&#8221; <a href="https://openai.com/index/harness-engineering-codex/">[7]</a>.</p><p>These loops are safe when repo-contained and the toolchain acts as the judge. They get dangerous with irreversible side effects outside the repo. Alexey Grigorev learned this when a Claude Code agent ran <code>terraform destroy</code> on DataTalks.Club&#8217;s production infrastructure, wiping the database, VPC, and all automated snapshots &#8212; two and a half years of data gone in one iteration. If your loop can destroy shared state, review every plan manually <a href="https://alexeygrigorev.com/posts/dropped-production-database/">[8]</a>.</p><p><em><strong>What is the first piece of work in your repo you would trust a Ralph loop with? You could choose a TDD backlog, a coverage ramp, a framework migration or what else?</strong></em></p><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ralph-loops/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/ralph-loops/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/ralph-loops?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/ralph-loops?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Anthropic. (n.d.). Effective Harnesses for Long-Running Agents. Anthropic. <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents</a></p></li><li><p>Cherny, B. (n.d.). I&#8217;m Boris and I Created Claude Code. X. <a href="https://x.com/bcherny/status/2007179832300581177">https://x.com/bcherny/status/2007179832300581177</a></p></li></ol><ol><li><p>Huntley, G. (n.d.). Ralph Wiggum as a &#8220;software engineer&#8221;. Geoffrey Huntley. <a href="https://ghuntley.com/ralph/">https://ghuntley.com/ralph/</a></p></li><li><p>LangChain. (n.d.). The Anatomy of an Agent Harness. LangChain Blog. <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">https://blog.langchain.com/the-anatomy-of-an-agent-harness/</a></p></li><li><p>Parsons, C. (n.d.). Ralph Loops: Build Dumb AI Loops That Ship. AI Engineer. <a href="https://read.readwise.io/read/01kp5bgy8b07y256ythvkz2tt7">https://read.readwise.io/read/01kp5bgy8b07y256ythvkz2tt7</a></p></li><li><p>Anthropic. (n.d.). Claude Code: Best Practices for Agentic Coding. Anthropic. <a href="https://www.anthropic.com/engineering/claude-code-best-practices">https://www.anthropic.com/engineering/claude-code-best-practices</a></p></li><li><p>Lopopolo, R. (n.d.). Harness engineering: leveraging Codex in an agent-first world. OpenAI. <a href="https://openai.com/index/harness-engineering-codex/">https://openai.com/index/harness-engineering-codex/</a></p></li><li><p>Grigorev, A. (n.d.). How I Dropped Our Production Database and Now Pay 10% More for AWS. Alexey Grigorev. <a href="https://alexeygrigorev.com/posts/dropped-production-database/">https://alexeygrigorev.com/posts/dropped-production-database/</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Karpathy Named It. I Built One on My Notes.]]></title><description><![CDATA[A deep research agent over my notes, highlights, and transcripts, grounded in years of curated thinking, not the public web.]]></description><link>https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm</link><guid isPermaLink="false">https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 21 Apr 2026 08:00:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!OKCv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OKCv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OKCv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OKCv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1413999,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/194537609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!OKCv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!OKCv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fef7e9dd7-3fa1-446d-83da-2dee056f71a5_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I&#8217;ve been building what Andrej Karpathy calls <strong>an LLM Knowledge Base</strong> on top of my private data for the past few months &#8212; without realizing that was the name for it. Now, seeing it&#8217;s such a hot topic, I want to share my own twist on it. Similar to Andrej&#8217;s design, but still very different in how I approach the problem.</p><p>I keep my notes in Obsidian, my reading in Readwise, and my topical research in NotebookLM. Each tool is excellent in isolation, but no AI can reach across all three.</p><p>Whenever I reach for a general-purpose deep-research tool like Perplexity or Gemini Deep Research, it just searches the public web. Every user gets the exact same sources, and the resulting article reads like everyone else&#8217;s. What I actually want to research is my own curated thinking.</p><p>I want to leverage the books I highlighted, the notes I wrote, and the transcripts I dumped into NotebookLM. That is the edge. That is the signal nobody else has.</p><p>To solve this, I built a deep research agent as three Claude Code skills. The <code>/research_create</code>, <code>/research_search</code>, and <code>/research_distill</code> skills run on top of my private data via the <code>obsidian</code>, <code>readwise</code>, and <code>nlm</code> command-line interfaces (CLIs).</p><p>The system uses multi-round query expansion with gap analysis between rounds. It outputs a <code>memory/</code> folder with an <code>index.yaml</code> file that acts as a progressive-disclosure wiki over the source files. We also apply post-processing, including deduplication and re-ranking, to keep the result focused.</p><p>There is no vector database and no Retrieval-Augmented Generation (RAG) pipeline. We use the filesystem as state and Markdown, YAML, and JSON as the wire format. If you already keep notes in Obsidian, articles in Readwise, or research in NotebookLM, this is for you.</p><p>By the end of this article, you will know exactly how it works, see it run on this very article, and have a blueprint to build your own.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WeAK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WeAK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 424w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 848w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WeAK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png" width="1400" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;From three scattered tools to a queryable research memory to a grounded article&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="From three scattered tools to a queryable research memory to a grounded article" title="From three scattered tools to a queryable research memory to a grounded article" srcset="https://substackcdn.com/image/fetch/$s_!WeAK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 424w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 848w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!WeAK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd980dfbc-f43d-41a9-85a7-fe27e6e20b61_1400x1000.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 1: From three scattered tools to a queryable research memory to a grounded article. This is the end-to-end loop in one frame.</em></figcaption></figure></div><p>Here is the system at a glance. We will look at the three skills, three CLI adapters, and one memory folder, before we open the heaviest skill in the next section.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Your Path to Agentic AI Engineering for Production (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Uql0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Uql0!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!Uql0!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!Uql0!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe507da12-ec85-47cf-bd9e-afadffc7e99d_1200x1200.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The three-skill + memory-folder pattern in this article is one slice of harness engineering. If you want to master the rest, such as orchestration, context engineering, evals, and production deployment, check out my <a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a>, built with Towards AI.</p><p>34 lessons. Three end-to-end portfolio projects. A certificate. And a Discord community with direct access to industry experts and me.</p><p><em>Rated 5/5 by 300+ students. The first 6 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p></div><h2>Three Skills, Three CLIs, One Memory Folder</h2><p>The system relies on three distinct skills. First, <code>/research_create</code> builds a <code>memory/</code> folder from scratch for a given topic or brain dump. Second, <code>/research_search</code> handles the read side, letting any future agent query an existing <code>memory/</code> folder via <code>index.yaml</code> with progressive disclosure.</p><p>Third, <code>/research_distill</code> takes a finished piece of content and extracts only the sources that were actually used into a single portable <code>research.md</code> appendix.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L-BX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L-BX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 424w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 848w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 1272w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L-BX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png" width="1400" height="1154" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1154,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1232783,&quot;alt&quot;:&quot;The system at a glance&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The system at a glance" title="The system at a glance" srcset="https://substackcdn.com/image/fetch/$s_!L-BX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 424w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 848w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 1272w, https://substackcdn.com/image/fetch/$s_!L-BX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9e2d9468-d2e9-4b2a-8e18-dd56482d4a83_1400x1154.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 2: The system at a glance. Claude Code orchestrates three skills that wire CLI adapters into a single memory folder.</em></figcaption></figure></div><p>The <code>memory/</code> folder is built around <code>index.yaml</code>. It holds metadata per source, including <code>uri_highlights</code>, <code>uri_full</code>, <code>original_path</code>, and <code>origin</code>. The LLM reads the index first, then picks three to five relevant files based on summaries and reads those directly.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!62sR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!62sR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 424w, https://substackcdn.com/image/fetch/$s_!62sR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 848w, https://substackcdn.com/image/fetch/$s_!62sR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 1272w, https://substackcdn.com/image/fetch/$s_!62sR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!62sR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png" width="1328" height="944" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:944,&quot;width&quot;:1328,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Memory Dir Screenshot&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Memory Dir Screenshot" title="Memory Dir Screenshot" srcset="https://substackcdn.com/image/fetch/$s_!62sR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 424w, https://substackcdn.com/image/fetch/$s_!62sR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 848w, https://substackcdn.com/image/fetch/$s_!62sR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 1272w, https://substackcdn.com/image/fetch/$s_!62sR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb67fbab3-a24a-4b9d-95e1-98643cf616e6_1328x944.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 3: The </em><code>memory/</code><em> folder on disk &#8212; </em><code>index.yaml</code><em> alongside each source&#8217;s key-highlights and full-document files.</em></figcaption></figure></div><p>There are no embeddings, no chunking, and no vector store to maintain, ensuring references stay perfectly traceable. Like OpenClaw, we treat memory as plain Markdown in the agent workspace, where files are the source of truth and the model only remembers what gets written to disk <a href="https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory">[1]</a>.</p><p>The Obsidian, Readwise, and NotebookLM files act as the raw, immutable data. We touch them manually as humans, never through this pipeline. On top of that, <code>/research_create</code> produces a local actionable knowledge base for a specific scope, resulting in an ephemeral <code>memory/</code> folder per topic.</p><p>This separation allows the same raw data to feed many different research projects without contamination. The key invariant of this architecture is that the orchestrator never loads source files. Researcher subagents touch the raw files, while the orchestrator only ever sees structured JSON summaries flowing between steps.</p><p>We chose CLIs over Model Context Protocol (MCP) servers for three reasons. First, token economics. A skill enters Claude Code&#8217;s context at boot at ~100 tokens of metadata, and the body loads only when invoked.</p><p>By comparison, Notion&#8217;s MCP server dumps roughly 20,000 tokens of self-documenting tools at startup whether you use them or not. That is roughly 200&#215; less context before you have done anything <a href="https://youtube.com/watch?v=vEvytl7wrGM">[2]</a>.</p><p>Second, CLIs compose with bash. The orchestrator can pipe results through tools like <code>jq</code> or redirect output straight to a file, whereas MCP tool calls must round-trip through the LLM.</p><p>Third, Markdown is the native language of LLMs. As Simon Willison argues, Markdown with YAML frontmatter is more in the spirit of LLMs than MCP, because you put text in the context and let the LLM pick <a href="https://read.readwise.io/read/01kh8p44e70a1273g7ykgx7h5y">[3]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QNsK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QNsK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 424w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 848w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QNsK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png" width="1400" height="1040" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1040,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1174644,&quot;alt&quot;:&quot;Token economics &#8212; MCP vs skill&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Token economics &#8212; MCP vs skill" title="Token economics &#8212; MCP vs skill" srcset="https://substackcdn.com/image/fetch/$s_!QNsK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 424w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 848w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 1272w, https://substackcdn.com/image/fetch/$s_!QNsK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F920270dc-457a-4cbd-97c4-7612d667565e_1400x1040.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: A skill enters context at ~100 tokens of metadata. An MCP server dumps ~20,000 tokens of self-documenting tools, whether you use them or not.</em></figcaption></figure></div><p>That is the whole architecture. Now let&#8217;s open up the heaviest of the three skills, <code>/research_create</code>, and watch the multi-round research loop in detail, where the orchestrator-never-loads invariant earns its keep.</p><h2>How <code>/research_create</code> Works</h2><p>The process starts with a brain dump from the user, which can include text, URLs, or local file paths. During the deep research, you confirm three configuration knobs in one prompt: the number of rounds, queries per round, and a topic slug. Seed URIs from the brain dump always land in the output with a relevance score of 1.0, bypassing reranking because they are your explicit picks.</p><p>The orchestrator generates queries and dispatches one researcher subagent per query in parallel. Each researcher runs platform-specific searches. For Readwise, this means querying the library, feed, highlights, and document notes. For Obsidian, it means querying the local vault files. For NotebookLM, it means querying the projects and their associated sources and notes.</p><p>For Obsidian, we found that using its CLI &#8212; which leverages its index &#8212; is 10&#215; more efficient than letting the LLM roam around your vault.</p><p>The subagent does its own within-agent deduplication by original path. It captures metadata while files are open. It also caps output at a top-15 limit of unique findings.</p><p>Between rounds, a <code>gap_analyzer</code> subagent reads the deduplicated findings via <code>jq</code> without full reads. It flags thin or missing themes against the initial key themes and emits the next round&#8217;s queries. After all rounds, a <code>reranker</code> subagent scores every candidate between 0.0 and 1.0 using the cheapest sufficient signal. It checks metadata first, then reads the head and tail of the doc, and uses full reads only as a last resort.</p><p>Finally, a <code>builder</code> subagent invokes a Python script to emit the YAML deterministically, placing seeds first, then descending by score.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8chM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8chM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!8chM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!8chM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!8chM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8chM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The full /research_create pipeline&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The full /research_create pipeline" title="The full /research_create pipeline" srcset="https://substackcdn.com/image/fetch/$s_!8chM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!8chM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!8chM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!8chM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb24424a5-ab62-44e5-9458-dc2fdb92079a_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 5: The full </em><code>/research_create</code><em> pipeline. The orchestrator schedules. Subagents do the heavy reads.</em></figcaption></figure></div><p>We use this shape because context isolation is our central design choice. Every step that touches real source content runs in an isolated subagent with its own context window. The orchestrator only sees the compacted metadata of each file, while moving the actual file using <code>mv</code> bash commands into the memory folder.</p><p>The <code>index.yaml</code> file holds pointers and metadata for every file in the wiki. The orchestrator holds pointers, while subagents hold content. Geoffrey Huntley, creator of Ralph Loops, states that your primary context window should operate as a scheduler, scheduling other subagents to perform expensive allocation-type work <a href="https://ghuntley.com/ralph/">[4]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kmhw!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kmhw!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 424w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 848w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 1272w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kmhw!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png" width="1200" height="801.0695187165776" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/df9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:749,&quot;width&quot;:1122,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:174291,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/194537609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kmhw!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 424w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 848w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 1272w, https://substackcdn.com/image/fetch/$s_!kmhw!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdf9a9df2-03c9-4289-b05b-5b8778885174_1122x749.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 6: The top of an index.yaml file &#8212; topic, input summary, and the first few source entries with their summaries and relevance scores.</figcaption></figure></div><p>Subagents compress tens of thousands of input tokens into 1,000&#8211;2,000 output tokens before handing back to the orchestrator. That compression ratio is the whole point. The researcher subagents read deeply, and the orchestrator stays light.</p><p>Once the <code>memory/</code> folder exists, anyone can read it without loading source files. We use the <code>/research_search</code> skill to query this index.</p><h2>How <code>/research_search</code> Works</h2><p>The <code>/research_search</code> skill handles the read side of the system. Any agent can be handed a <code>memory/</code> folder and query it without loading source files into context. The skill encodes the protocol once so future agents do not have to re-derive it.</p><p>The system uses three layers of detail. Layer 1 is the <code>summary</code> field in <code>index.yaml</code>. It contains two to three sentences per source and is always loaded as part of the index. It is enough to answer what you have on a topic or build a table of contents.</p><p>Layer 2 is the key-highlights file, which holds the condensed topics of a file. This is extremely powerful when using reader tools such as Readwise, as these highlights are made manually by you, the reader, consisting of huge signal. Thus, not every source has this layer. It&#8217;s better not to have it at all than to have an LLM extract it.</p><p>Layer 3 is the <code>uri_full</code> file, representing the complete original document. You read it only when key highlights are insufficient or inexistent.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!iqIL!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!iqIL!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 424w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 848w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 1272w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!iqIL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png" width="1400" height="1255" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1255,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1230683,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/194537609?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!iqIL!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 424w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 848w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 1272w, https://substackcdn.com/image/fetch/$s_!iqIL!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe08b1e99-8f5f-4a88-a373-fbae8cef9811_1400x1255.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Image 7: Three layers of detail per source. The agent stays at Layer 1 unless it has a reason to descend.</figcaption></figure></div><p>Anthropic notes that models are great at navigating filesystems, and presenting tools as code on a filesystem allows models to read tool definitions on-demand, rather than reading them all up-front <a href="https://www.anthropic.com/engineering/building-more-efficient-ai-agents">[5]</a>. That maps exactly onto <code>index.yaml</code> plus lazy key-highlights loading.</p><p>Intuitively, the <code>index.yaml</code> file gives us progressive disclosure &#8212; the same pattern used inside skills &#8212; so the agent can choose from many options without drowning in information <a href="https://newsletter.swirlai.com/p/agent-skills-progressive-disclosure">[6]</a>.</p><p>The agent slices <code>index.yaml</code> by origin, location, relevance-score threshold, tags, author, publication, date range, or NotebookLM notebook.</p><p>The most beautiful part? Because <code>index.yaml</code> is structured data, the agent writes code on top of it. It uses <code>jq</code> filters, Python sorts, and <code>awk</code> projections.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KCNN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KCNN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 424w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 848w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 1272w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KCNN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png" width="1015" height="412" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:412,&quot;width&quot;:1015,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Index Single Sample Screenshot&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Index Single Sample Screenshot" title="Index Single Sample Screenshot" srcset="https://substackcdn.com/image/fetch/$s_!KCNN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 424w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 848w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 1272w, https://substackcdn.com/image/fetch/$s_!KCNN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3e53bda1-434e-4d87-a916-8ba090446067_1015x412.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 8: A single source entry in </em><code>index.yaml</code><em> &#8212; origin, authors, relevance score, and the URIs that power progressive disclosure.</em></figcaption></figure></div><p>LlamaIndex&#8217;s head-to-head benchmark proves this scales. A filesystem-explorer agent beat a hybrid vector RAG pipeline on correctness (8.4 vs 6.4) and relevance (9.6 vs 8.0) at a sub-60 document scale, precisely because the LLM saw whole files instead of chunks <a href="https://www.llamaindex.ai/blog/did-filesystem-tools-kill-vector-search">[7]</a>.</p><p>Portability comes for free. Hand the self-contained <code>memory/</code> folder to any agent, and they get up to speed instantly. Search lets agents find what is there. But once you have drafted an article, you also need to know what part of the wiki you actually used within your piece. That is <code>/research_distill</code>.</p><h2>How <code>/research_distill</code> Works</h2><p>Given any piece of content and the <code>memory/</code> folder used during writing, the skill walks every source in <code>index.yaml</code>. It decides whether the content actually used it by checking for explicit references or traceable ideas. The process is conservative by default. It is better to miss a borderline source than include one that was not actually used.</p><p>The output is a single <code>research.md</code> file. It is fully self-contained, meaning you never need to go back to the <code>memory/</code> folder again. For this very article, <code>/research_distill</code> should match around 15 to 20 of the 62 sources in the memory folder.</p><p>This matters because downstream generation loops re-load the research on each iteration. For example, within the evaluator-optimizer pattern, the system generates, critiques, and revises <a href="https://www.anthropic.com/engineering/building-effective-agents">[8]</a>. Keeping the anchor research small is the difference between an article that stays grounded and one that starts hallucinating.</p><p>As I explained in my article on <a href="https://www.decodingai.com/p/your-rag-pipeline-is-overkill-rlms">Recursive Language Models (RLMs)</a>, when the corpus fits in context with progressive disclosure, fancy retrieval is overkill <a href="https://www.decodingai.com/p/your-rag-pipeline-is-overkill-rlms">[9]</a>.</p><h2>What&#8217;s Next</h2><p>For personal-scale research involving hundreds of sources, a well-structured <code>memory/</code> folder with an <code>index.yaml</code> beats a RAG pipeline on every axis. It gives you full lineage back to source URLs, portability to pass the folder to any agent, and lower costs with no embedding model or vector store.</p><p>To further optimize the system, making it more context-efficient, I am considering moving the deduplication and re-ranking fully into Python scripts, adding a local cross-encoder reranker to avoid LLM calls for scoring, and extending the researcher with tag-aware filtering.</p><p><em>But here is what I&#8217;m wondering:</em></p><p><strong>What data source in your work makes you most want a private deep research agent? Is it your Obsidian vault, your Readwise library, a code repository, or your team&#8217;s shared documents?</strong></p><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/llm-knowledge-base-obsidian-readwise-notebooklm?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>Govindarajan, V. (2026). OpenClaw Architecture Part 3 - Memory and State Ownership. The Agent Stack. <a href="https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory">https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory</a></p></li><li><p>Talebi, S. (2026). Claude Skills Explained in 23 Minutes. YouTube. <a href="https://youtube.com/watch?v=vEvytl7wrGM">https://youtube.com/watch?v=vEvytl7wrGM</a></p></li><li><p>Bowne-Anderson, H. (n.d.). Episode 70: 1,400 Production AI Deployments. Vanishing Gradients Podcast. <a href="https://read.readwise.io/read/01kh8p44e70a1273g7ykgx7h5y">https://read.readwise.io/read/01kh8p44e70a1273g7ykgx7h5y</a></p></li><li><p>Huntley, G. (n.d.). Ralph Wiggum as a &#8220;software engineer&#8221;. ghuntley.com. <a href="https://ghuntley.com/ralph/">https://ghuntley.com/ralph/</a></p></li><li><p>Anthropic. (n.d.). Building More Efficient AI Agents. Anthropic Blog. <a href="https://www.anthropic.com/engineering/building-more-efficient-ai-agents">https://www.anthropic.com/engineering/building-more-efficient-ai-agents</a></p></li><li><p>Grici&#363;nas, A. (n.d.). Agent Skills: Progressive Disclosure as a System Design Pattern. SwirlAI Newsletter. <a href="http://Govindarajan, V. (2026). OpenClaw Architecture Part 3 - Memory and State Ownership. The Agent Stack. https://theagentstack.substack.com/p/openclaw-architecture-part-3-memory Talebi, S. (2026). Claude Skills Explained in 23 Minutes. YouTube. https://youtube.com/watch?v=vEvytl7wrGM Bowne-Anderson, H. (n.d.). Episode 70: 1,400 Production AI Deployments. Vanishing Gradients Podcast. https://read.readwise.io/read/01kh8p44e70a1273g7ykgx7h5y Huntley, G. (n.d.). Ralph Wiggum as a &quot;software engineer&quot;. ghuntley.com. https://ghuntley.com/ralph/ Anthropic. (n.d.). Building More Efficient AI Agents. Anthropic Blog. https://www.anthropic.com/engineering/building-more-efficient-ai-agents Grici&#363;nas, A. (n.d.). Agent Skills: Progressive Disclosure as a System Design Pattern. SwirlAI Newsletter. https://newsletter.swirlai.com/p/agent-skills-progressive-disclosure LlamaIndex. (n.d.). Did Filesystem Tools Kill Vector Search?. LlamaIndex Blog. https://www.llamaindex.ai/blog/did-filesystem-tools-kill-vector-search Anthropic. (2025). Building Effective AI Agents. Anthropic Blog. https://www.anthropic.com/engineering/building-effective-agents Iusztin, P. (n.d.). Your RAG Pipeline Is Overkill (RLMs). Decoding AI Magazine. https://www.decodingai.com/p/your-rag-pipeline-is-overkill-rlms">https://newsletter.swirlai.com/p/agent-skills-progressive-disclosure</a></p></li><li><p>LlamaIndex. (n.d.). Did Filesystem Tools Kill Vector Search?. LlamaIndex Blog. <a href="https://www.llamaindex.ai/blog/did-filesystem-tools-kill-vector-search">https://www.llamaindex.ai/blog/did-filesystem-tools-kill-vector-search</a></p></li><li><p>Anthropic. (2025). Building Effective AI Agents. Anthropic Blog. <a href="https://www.anthropic.com/engineering/building-effective-agents">https://www.anthropic.com/engineering/building-effective-agents</a></p></li><li><p>Iusztin, P. (n.d.). Your RAG Pipeline Is Overkill (RLMs). Decoding AI Magazine. <a href="https://www.decodingai.com/p/your-rag-pipeline-is-overkill-rlms">https://www.decodingai.com/p/your-rag-pipeline-is-overkill-rlms</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[How to Ship a Weekly Article in One Day]]></title><description><![CDATA[Inside the agentic AI workflow behind my weekly newsletter, course, and content]]></description><link>https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business</link><guid isPermaLink="false">https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Wed, 15 Apr 2026 14:10:24 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/aae0f997-35e5-4220-8eaf-1a906167a606_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LUpQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LUpQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LUpQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1410501,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/194297155?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LUpQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!LUpQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F15e30b47-9be5-46d0-8c1f-dc8836b5adb9_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I publish one in-depth technical article every week on Decoding AI. That cadence sounds simple until you live it. The article itself eats up the time I should be digging into the Claude Code leak to understand how it works under the hood.</p><p>I am a builder first, not a writer. Most weeks, the writing strangles the building. This is the exact trap most weekly writers fall into.</p><p>When the writing eats the week, the next article has nothing real underneath it. So writers fill the gap with generics, surface-level takes, or invented examples that add noise to an already noisy internet.</p><p>The default fix most people reach for is to let AI write it. That fails for the opposite reason. When you put zero thought into the process, AI just industrializes the noise.</p><p>The whole point of writing is to share something you actually thought through, built, and learned. If AI writes for you, you publish nothing of value. If you write everything by hand, you don&#8217;t have enough time to build something worth publishing.</p><p>Both ends starve the loop that actually feeds the business: research, build, and teach.</p><p>What I built instead is an agentic AI workflow that automates ~90% of the manual writing pipeline while keeping me as the irreplaceable seed at the top. I provide the research direction and the brain dump that reflects my personal experience.</p><p>AI handles distribution speed. I handle thought, taste, and direction. By the end of this article, you will see exactly how the system works.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_tFE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_tFE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 424w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 848w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 1272w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_tFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png" width="1400" height="353" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:353,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:331639,&quot;alt&quot;:&quot;The full pipeline at a glance. Human seed on the left, automated components in the middle, published article on the right.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The full pipeline at a glance. Human seed on the left, automated components in the middle, published article on the right." title="The full pipeline at a glance. Human seed on the left, automated components in the middle, published article on the right." srcset="https://substackcdn.com/image/fetch/$s_!_tFE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 424w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 848w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 1272w, https://substackcdn.com/image/fetch/$s_!_tFE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcd5e5540-20a1-4d9d-9c5e-edb32202cd5d_1400x353.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 1: The full pipeline at a glance. Human seed on the left, automated components in the middle, published article on the right.</em></figcaption></figure></div><p>We will cover my deep research agent, writing workflow with its evaluator-optimizer loop, image style-transfer step, and title &amp; SEO generator. And for the most important part, you will learn where the human-in-the-loop is irreplaceable.</p><h2>My Workflow: What Stays Human, What Gets Automated</h2><p>Before showing any architecture, I want to walk you through the manual workflow exactly as I used to run it. This is the boring, honest version. This is what every weekly technical writer secretly does, even if they pretend otherwise.</p><p>I used to research the topic for hours or days while taking notes. Then, I would write a high-level outline of the piece. Next, I sketched the first high-level diagram that helped me better visualize the narrative of the piece.</p><p>I expanded each outline section into bullet points, creating what I call the article guideline. After that, I wrote the article, edited it, and created the rest of the visuals. Finally, I wrote the title and SEO and copy-pasted everything into Substack.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zPY6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zPY6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 424w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 848w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 1272w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zPY6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png" width="1400" height="274" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:274,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:407709,&quot;alt&quot;:&quot;The nine-step workflow. Research and outline stay human; the rest gets automated with validation gates on the load-bearing steps.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The nine-step workflow. Research and outline stay human; the rest gets automated with validation gates on the load-bearing steps." title="The nine-step workflow. Research and outline stay human; the rest gets automated with validation gates on the load-bearing steps." srcset="https://substackcdn.com/image/fetch/$s_!zPY6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 424w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 848w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 1272w, https://substackcdn.com/image/fetch/$s_!zPY6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6d8c2a-8192-440a-93c2-41c8b8c0d52f_1400x274.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption"><em>Image 2: The nine-step workflow. Research and outline stay human; the rest gets automated with validation gates on the load-bearing steps.</em></figcaption></figure></div><p>Now, everything gets automated except two things. I still do an in-depth round of research to understand the topic and collect a few high-quality golden source seeds. This is the fun part. These are mostly pulled from my Readwise reading list, which acts as a curated library I built over time while browsing Substack, YouTube, LinkedIn, X, and more. Then, I use this as a high-quality seed for my deep research agent to expand it and fill any potential gaps.</p><p>Second, while researching I do a brain dump of everything I consider relevant on the topic. After wrapping up the research, I refactor the brain dump into an outline that follows an engaging narrative. Then, I do a combination of manual and Claude Code work to expand it with bullet points, creating the article guideline.</p><p>Together, those two steps are the seed that makes everything downstream mine. Without them, the pipeline produces generic AI mush.</p><p>Before the automated pipeline existed, a 3,000-word article like one of my latest pieces, <a href="https://www.decodingai.com/p/agentic-harness-engineering">Agentic Harness Engineering</a>, would eat two to three days of my week running this exact nine-step grind by hand. Now, the same piece takes about a day.</p><h3>Why this works</h3><p>Writing prose is a translation step. It turns thoughts into words on a page or boxes in a diagram. Translation is exactly the kind of work LLMs excel at, if you already did the thinking.</p><p>If you haven&#8217;t, no amount of agent orchestration saves you. AI as a writing tool fails when you put zero thought into your process. It becomes a force multiplier when you use it to distribute your thoughts.</p><p>Now, let&#8217;s look at how the actual system works.</p><h2>Understanding The System Architecture</h2><p>The architecture has five big components plus a memory layer. The contract between them is the artifact each one writes to disk, such as the research markdown, the article guideline, the final article, branded image PNGs, and the final HTML bundle.</p><p>Here are the five components at a glance:</p><ol><li><p><strong>Deep Research agent (we call it Nova)</strong>: Takes a topic and golden sources, returning a ranked, structured research file.</p></li><li><p><strong>Writing Workflow (Brown)</strong>: Takes the article guideline and research, returning the full styled article via an evaluator-optimizer loop.</p></li><li><p><strong>Media style transfer</strong>: Because the article contains raw Mermaid diagrams, we apply the Decoding AI brand style.</p></li><li><p><strong>Title and SEO generator</strong>: Runs an expand-and-narrow loop to produce the title, subtitle, SEO title, and SEO description.</p></li><li><p><strong>HTML exporter</strong>: Converts the final markdown into platform-ready HTML for Substack, Medium, X, or LinkedIn to easily copy-paste the piece.</p></li></ol><p>The handoff contract between components is the filesystem. Each stage reads and writes plain files in a working directory. Internal per-component state lives in databases: PostgreSQL for Nova, and an SQLite checkpointer for Brown.</p><p>The artifacts make the pipeline debuggable, resumable, and human-in-the-loop friendly across stages. The databases make each stage individually resumable mid-run. For example, if the writing workflow fails after generating the first draft, we can easily resume without having to spend tokens on rerunning from scratch.</p><p>Also, because everything is managed through files, I can open any artifact at any key step, inspect it, edit it, and re-run downstream.</p><p>We will show you how we used this system to write one of our latest popular pieces: <a href="https://www.decodingai.com/p/agentic-harness-engineering">Agentic Harness Engineering</a>.</p><p>I&#8217;ve also used the same process to research and write professional lessons for other educational projects, such as our latest Agentic AI Engineering course, as the pipeline adapts to any type of educational business.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9Mog!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9Mog!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 424w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 848w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 1272w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9Mog!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png" width="1200" height="814" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:814,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The full data flow. Human-seeded research at the left, evaluator-optimizer writing in the middle, branded media and SEO on the right, finished HTML at the terminus.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The full data flow. Human-seeded research at the left, evaluator-optimizer writing in the middle, branded media and SEO on the right, finished HTML at the terminus." title="The full data flow. Human-seeded research at the left, evaluator-optimizer writing in the middle, branded media and SEO on the right, finished HTML at the terminus." srcset="https://substackcdn.com/image/fetch/$s_!9Mog!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 424w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 848w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 1272w, https://substackcdn.com/image/fetch/$s_!9Mog!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2c5e383a-655e-45e9-b56d-1535601cbc20_1200x814.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 3: End-to-end system architecture: Human-seeded research on the left, evaluator-optimizer writing in the middle, branded media and SEO on the right, finished HTML at the terminus.</em></figcaption></figure></div><p>Each component is explained in depth in the sections below. Two are MCP servers (Nova and Brown) and three are skills (media style transfer, title &amp; SEO, HTML export).</p><p>In terms of concrete economics, the whole process runs at roughly ~$0.30 <em>to $</em>1 per image, mostly in Gemini credits, with the rest of the pipeline costing cents. This article, with 9 images, landed closer to $6, while a leaner piece with a single diagram sits around $1.</p><div class="callout-block" data-callout="true"><h2><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Build This Exact Stack Yourself (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NL_4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NL_4!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NL_4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:&quot;placeholder&quot;,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!NL_4!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!NL_4!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6823b5d3-72be-461a-9dfe-78be888cd22b_1200x1200.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Reading about a pipeline is one thing. Building one is another. In my <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering Course</a></strong>, built with Towards AI, I walk you through this exact stack from scratch.</p><p>Nova&#8217;s deep research loop, Brown&#8217;s evaluator-optimizer built on LangGraph, both served via FastMCP, plus the style-transfer skill, evaluation with Opik, and deployment on Docker, GCP, and GitHub Actions.</p><p>34 lessons. Three end-to-end portfolio projects. A certificate. And a Discord community with direct access to industry experts and me.</p><p>Rated 5/5 by 300+ students. The first 6 lessons are free:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p></div><h2>Walkthrough: The Artifacts of One Article</h2><p>Before diving into each component, let&#8217;s take a look at the input and output artifacts the pipeline produced while generating the <a href="https://www.decodingai.com/p/agentic-harness-engineering">Agentic Harness Engineering</a> article. Here are some trimmed versions of each, as they get pretty large.</p><h4>outline.md: the hand-written seed, Nova&#8217;s input (88 lines)</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">## Outline
1. Introduction - Why Do We Need a Harness?
&#9;1. Personal story: To be researched
&#9;2. Problem + Agitation: ...
&#9;3. Transformation + Solution: ...
&#9;4. Intuitively, Mitchell Hashimoto has the best definition of a harness: "the idea that anytime you find an agent makes a mistake, you take the time to engineer a solution such that the agent never makes that mistake again."
&#9;5. 200 words
2. What the Hell Is A Harness?
    ...
3. How does a Harness Look?
&#9;1. Key components: LLM, tools, planning loop, context engineering, sandbox, memory, orchestration layer, serving layer, interfaces
&#9;2. The agent loop: Powered by planning techniques like ReAct
    ...
4. Planning &amp; Orchestration
    ...
&#9;4. 200 words
5. Key Tools
    ...
6. Sandbox Environment
    ...
7. Memory
    ...
8. Conclusion - The Future of Harness
    ...

# Resources

1. [My AI Adoption Journey](https://mitchellh.com/writing/my-ai-adoption-journey)
2. ...</code></pre></div><p>The seed is deliberately rough. It contains placeholders like &#8220;To be researched&#8221;, section blocks that will later be restructured, and hand-picked golden sources that anchor Nova&#8217;s first round of research. The idea is to dump ideas without thinking too much about structure while you are in your creative mindset.</p><h4>research.md: Nova&#8217;s output (1377 lines)</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SbxN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SbxN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 424w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 848w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SbxN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png" width="1416" height="1364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1364,&quot;width&quot;:1416,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A trimmed view of Nova's collapsible-HTML research.md output.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A trimmed view of Nova's collapsible-HTML research.md output." title="A trimmed view of Nova's collapsible-HTML research.md output." srcset="https://substackcdn.com/image/fetch/$s_!SbxN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 424w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 848w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 1272w, https://substackcdn.com/image/fetch/$s_!SbxN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff49e76f9-5e97-45d1-9551-bf8757309256_1416x1364.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: A trimmed view of Nova&#8217;s collapsible-HTML research.md output.</em></figcaption></figure></div><h4>article_guideline.md: Expanded outline, Brown&#8217;s input (201 lines, 8 sections).</h4><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">## What We Are Planning to Share

...

## Why We Think It's Valuable

...

## Point of View

I write the article, Paul Iusztin. I am part of a bigger team known as Decoding AI....

----

## Article Outline

1. Why Do We Need a Harness?
2. What the Hell Is a Harness?
3. The Anatomy of a Harness
4. How the Agent Decides What to Do Next
5. The Tools That Let Agents Act
6. Where Agents Run
7. Memory Is Just the Filesystem
8. What's Next

## Section 1 - Why Do We Need a Harness?

...

## Section 2 - What the Hell Is a Harness?

...

- **Hook:** Start with the horse analogy. A horse is powerful on its own, but useless for farming without a harness &#8212; the straps, reins, and attachments that let you direct its strength toward useful work (inspiration from Jonathan Gimick from Manning). Same with LLMs: the model has the intelligence, but without tools, memory, state, guardrails, and orchestration, you can't put it to work reliably.
- **The clean definition:** LangChain's formulation is the clearest &#8212; **Agent = Model + Harness**. The harness is "every piece of code, configuration, and execution logic that isn't the model itself." The model provides intelligence. The harness makes that intelligence useful.
...

[GENERATE_DIAGRAM] Three levels of engineering: prompt, context, and harness engineering.
...

- **Transition:** Now that you know what a harness is, let's look at all its components and how they fit together at a high level &#8212; before diving deeper into each one.

- **Section length:** 300 words

## Section 3 - The Anatomy of a Harness

...

## Section 8 - What's Next

...</code></pre></div><p>The article guideline is deliberately as structured and detailed as possible. The idea is to have enough or even more detail about each section to fill in the requested word budget to ensure the LLM doesn&#8217;t fill in any gaps with generalities or, worse, with hallucinations.</p><h4>article.md: Brown&#8217;s final prose (~3,000 published words, 8 sections)</h4><p>See the <a href="https://www.decodingai.com/p/agentic-harness-engineering">Agentic Harness Engineering</a> article we posted a few weeks ago on Substack.</p><p>Now let&#8217;s see how Nova, the deep research agent, turns the outline and its golden sources into a structured research file.</p><h2>Deep Research: How Nova Builds the Knowledge Base</h2><p>Nova is an MCP server exposing ten specialized tools, orchestrated by the client, which is often a harness such as Claude Code or Cursor.</p><p>Here is how the overall deep research architecture works:</p><ol><li><p><strong>Query generation loop:</strong> Nova takes the topic and golden sources, runs gap analysis between the outline and the provided sources with Gemini Pro, and generates the next round of research queries based on what is missing. Three rounds hits the cost-versus-coverage sweet spot.</p></li><li><p><strong>Concurrent retrieval:</strong> Each round fans out concurrent Perplexity calls that return only metadata and a summary of each new source.</p></li><li><p><strong>Two-stage filtering:</strong> We full-scrape only the top five by a four-dimensional rubric evaluating trustworthiness, authority, relevance, and quality. For the rest of the sources we keep only the summary, which is enough for providing examples such as <code>Anthropic is implementing compaction in Claude Code</code>.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ckWR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ckWR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 424w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 848w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 1272w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ckWR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png" width="1400" height="698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:698,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:841138,&quot;alt&quot;:&quot;Nova's deep research loop. Three rounds of gap-driven Perplexity queries, a two-stage filter, and source-specific ingestion produce the structured research file.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Nova's deep research loop. Three rounds of gap-driven Perplexity queries, a two-stage filter, and source-specific ingestion produce the structured research file." title="Nova's deep research loop. Three rounds of gap-driven Perplexity queries, a two-stage filter, and source-specific ingestion produce the structured research file." srcset="https://substackcdn.com/image/fetch/$s_!ckWR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 424w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 848w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 1272w, https://substackcdn.com/image/fetch/$s_!ckWR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feeb5adf8-5280-4597-a537-70fb43ac542d_1400x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 5: Nova&#8217;s deep research loop. Three rounds of gap-driven Perplexity queries, a two-stage filter, and source-specific ingestion produce the structured research file.</em></figcaption></figure></div><p>Nova ships one purpose-built tool per source family. We scrape web URLs using Firecrawl, while we ingest GitHub repos through gitingest. We ingest YouTube videos using Gemini Pro directly on the URL without a local download.</p><p>For example, this is how I used Nova when writing my harness article. I started with a vague topic about what an agent harness is and why it matters. I handed Nova a seed set of golden-source URLs inside the guideline, including the <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">LangChain harness post</a>, the <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">Anthropic long-running agents piece</a>, and <a href="https://mitchellh.com/writing/my-ai-adoption-journey">Mitchell Hashimoto&#8217;s AI adoption journey</a>. Nova extracted these, scraped each one, and wrote the cleaned content into its working memory.</p><p>Nova then ran the three-round gap-analysis loop, fanning out concurrent Perplexity queries aimed at topics the seed sources had not covered. Every raw result was appended to the log. Ultimately, each source is filtered using a set of heuristics and LLMs to ensure we keep only high-quality results.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!GkHV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!GkHV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 424w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 848w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 1272w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!GkHV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png" width="1408" height="752" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:752,&quot;width&quot;:1408,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Full Nova system architecture &#8212; MCP tools, Postgres state, two-stage filter, source-specific ingestion.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Full Nova system architecture &#8212; MCP tools, Postgres state, two-stage filter, source-specific ingestion." title="Full Nova system architecture &#8212; MCP tools, Postgres state, two-stage filter, source-specific ingestion." srcset="https://substackcdn.com/image/fetch/$s_!GkHV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 424w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 848w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 1272w, https://substackcdn.com/image/fetch/$s_!GkHV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffa5550d9-3163-47db-8fa2-2376f0c74f82_1408x752.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 6: Full Nova system architecture &#8212; MCP tools, Postgres state, two-stage filter, and source-specific ingestion.</em></figcaption></figure></div><p>Finally, Nova compiles everything into the collapsible HTML research file.</p><p>The client knows how to leverage all of Nova&#8217;s MCP tools through a skill that glues together the ingestion, search, and all the other utility tools into the unified deep research algorithm that takes as input the outline.md file and outputs research.md.</p><h2>Writing Workflow: How Brown Turns an Idea Into an Article</h2><p>Brown picks up where Nova left off. Brown is a workflow, not an agent, implemented with LangGraph. We chose a workflow over an agent deliberately: prose generation rewards predictability over exploration.</p><p>First, we generate all the required Mermaid diagrams for the article using the orchestrator-worker pattern that looks around the article and spins up a specialized Mermaid-diagram agent based on all the user requests found within the article. These are usually flagged within the article guideline explicitly by stating &#8220;generate diagram&#8221;, &#8220;create a diagram&#8221;, or [GENERATE_DIAGRAM]. Next, these diagrams are passed downwards through the generation process. We&#8217;ll come back to how they get styled in the Branded Images section. The orchestrator-worker pattern can easily be extended to generate other types of media such as images, videos, or audio.</p><p>Next, we control Brown&#8217;s voice via the system prompt through three large tricks.</p><p>The <strong>first one</strong> is based on defining a set of six profile classes, each targeting a different family of rules. There are four generic profiles, which are static and agnostic to who is using the tool and what they are doing:</p><ol><li><p><strong>Structure Profile:</strong> How the prose is physically laid out on the page such as sentence, paragraph, list, and subheading shape.</p></li><li><p><strong>Mechanics Profile:</strong> The grammatical scaffolding the writing must respect such as active voice, point of view, and punctuation rules.</p></li><li><p><strong>Terminology Profile:</strong> What vocabulary is allowed and what filler is banned such as word choice, sentence phrasing, and descriptive language.</p></li><li><p><strong>Tonality Profile:</strong> How the article should feel to the reader such as formality level, voice characteristics, and emotional register.</p></li></ol><p>And two customizable:</p><ol><li><p><strong>Character Profile:</strong> Who is writing. For example, I added here my biography. This should be adapted per user.</p></li><li><p><strong>Article Profile:</strong> Special article characteristics such as the structure, referencing, and citations. This can be swapped to a LinkedIn, Reddit, or X profile to adapt the system to different formats.</p></li></ol><p>The <strong>second trick</strong> is to force the LLM to respect the article guideline and research over anything else, to ensure the user gets what they expect and that Brown adheres only to the research to avoid hallucinations.</p><p>The <strong>third trick</strong> is to add a set of few-shot examples, which beats anything else because showing works better than telling. For the best quality this should be changed when switching article formats and especially when switching content formats.</p><p>After we compile our system prompt, we call Gemini at a 0.7 temperature to produce a first draft with more randomness.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yFlH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yFlH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 424w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 848w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 1272w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yFlH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png" width="1200" height="946" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:946,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Brown's writing loop. Six profiles compose the system prompt; a Generator-Reviewer-Editor loop iterates until the draft passes review.&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Brown's writing loop. Six profiles compose the system prompt; a Generator-Reviewer-Editor loop iterates until the draft passes review." title="Brown's writing loop. Six profiles compose the system prompt; a Generator-Reviewer-Editor loop iterates until the draft passes review." srcset="https://substackcdn.com/image/fetch/$s_!yFlH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 424w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 848w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 1272w, https://substackcdn.com/image/fetch/$s_!yFlH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0c1496a1-738f-4f84-b063-fd8d445d5a70_1200x946.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 7: Brown&#8217;s writing loop. Six profiles compose the system prompt; a Generator-Reviewer-Editor loop iterates until the draft passes review.</em></figcaption></figure></div><p>After the first generation pass, we start an evaluator-optimizer loop running a Reviewer node with 0.0 temperature against the guideline, research, and profiles to ensure the draft respects all the expected requirements. The Reviewer node returns a list of structured review objects via Pydantic. If issues are found, we run an Editor node at a 0.1 temperature that applies all these fixes.</p><p>The evaluator-optimizer loop runs for a fixed iteration count, not until a quality score is good enough. Because writing, like any creative work, is highly subjective, a single quality score becomes noisy and unpredictable. Empirically, running the loop for a fixed number of iterations yields better results and gives us more control over cost and latency.</p><p>Because the article might not be polished enough, we expose editing tools through the MCP server so the user can kick off another review-edit iteration on demand.</p><p>Now let&#8217;s see how we transform raw Mermaid output into branded diagrams.</p><h2>Generating Branded Images</h2><p>Brown produces Mermaid source for every diagram in the article. Mermaid is fast and predictable to generate with LLMs but visually generic. In theory you can customize them. But let&#8217;s be honest. They are ugly. Thus, the job of this stage is to keep the structure of the Mermaid diagrams Brown produced while applying a styling layer on top of them.</p><p>We use a skill that leverages Gemini&#8217;s Nano Banana for the style transfer. The skill takes a file as input and detects all the Mermaid diagrams in it. Then, for each diagram, it runs parallel subagents. Each invokes the Gemini script on the raw Mermaid text and outputs a styled PNG.</p><p>Here is the prompt engineering behind the styling:</p><ul><li><p>The branding is referenced both through a written file with color codes, fonts, and general guidelines, plus a representative image.</p></li><li><p>2 positive examples containing both the Mermaid inputs and positive styled outputs.</p></li></ul><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/83770f76-610c-4f37-9a7b-eeef0e7d9028_406x643.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dc8ff545-b867-4f12-ab8f-a11e83a7ed2b_1456x720.png&quot;}],&quot;caption&quot;:&quot; Image 8: Positive few-shot example&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c8d6ee6-897f-41c2-ba75-42a7100660b8_1456x720.png&quot;}},&quot;isEditorNode&quot;:true}"></div><ul><li><p>2 negative examples also containing the Mermaid inputs and faulty styled outputs.<br></p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3ab302a2-6dd3-4948-9f8a-0d9509900edd_1262x1614.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40004311-517b-45dc-8b95-7461e8785d4d_912x1168.png&quot;}],&quot;caption&quot;:&quot;Image 9: Negative few-shot example&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a82133df-94b6-4842-88d6-b4428a5ff50a_1456x720.png&quot;}},&quot;isEditorNode&quot;:true}"></div></li></ul><p>When using images as few-shot examples, you should be really careful not to go overboard with them, as they add up in tokens quickly. Also, adding the positive and negative examples on top of just random style images and files was the special sauce for us that made everything work, as it clearly shows Nano Banana how to make the mapping between the two.</p><p>Now, let&#8217;s see how we generate punchy titles and relevant SEO.</p><h2>Generating Title &amp; SEO</h2><p>Title and SEO are the most important components. They decide whether the article gets read at all. Doing it by gut on a Friday night is the worst possible workflow.</p><p>The pipeline replaces gut with an expand-and-narrow loop. We generate nine versions from many angles, score ruthlessly, and keep only the top four. Then we repeat this process three times.</p><p>The generator creates nine candidate title, subtitle, SEO title, and SEO description packages per round, each from a different angle like personal transformation, curiosity, making bold claims, showing proof of work, and more. The idea is to have a lot of diversity during the expansion round.</p><p>The validator scores every candidate on six rubric-anchored dimensions: title, subtitle, SEO title, and SEO description quality, article alignment, and cohesion across the four pieces. It uses hybrid scoring, combining an LLM-judge for the qualitative rubrics and heuristic penalties for the hard constraints such as character count. For example, shorter titles score higher.</p><p>Then, based on the scores generated by the validator, we pick the top four winners and use them as seeds for the next round of generation.</p><p>The key here is to make the validator a subagent that doesn&#8217;t share the same context window as the generator to avoid any type of bias. Fresh eyes prevent self-confirmation bias. This is the same principle Brown uses for its evaluator-optimizer split and Nova uses for its filter step.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Ixet!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Ixet!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 424w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 848w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 1272w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Ixet!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png" width="1400" height="1078" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1078,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1496877,&quot;alt&quot;:&quot;The expand-and-narrow loop. 9 angles &#215; 3 rounds, scored by an isolated validator on 6 dimensions, narrowing to a top-4 for A/B testing.&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The expand-and-narrow loop. 9 angles &#215; 3 rounds, scored by an isolated validator on 6 dimensions, narrowing to a top-4 for A/B testing." title="The expand-and-narrow loop. 9 angles &#215; 3 rounds, scored by an isolated validator on 6 dimensions, narrowing to a top-4 for A/B testing." srcset="https://substackcdn.com/image/fetch/$s_!Ixet!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 424w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 848w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 1272w, https://substackcdn.com/image/fetch/$s_!Ixet!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5c04250a-50e3-4908-9312-8e42b2071a2a_1400x1078.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 10: The expand-and-narrow loop. 9 angles &#215; 3 rounds, scored by an isolated validator on 6 dimensions, narrowing to a top-4 for A/B testing.</em></figcaption></figure></div><p><strong>So why pick the top four, and not three?</strong> When scheduling on Substack, we pick the top four for A/B testing rather than committing to the single highest-scored one. The validator is good but not omniscient, so we let real readers settle close calls.</p><h2>Exporting to HTML</h2><p>The last step is to compile the Markdown article into HTML so we can easily copy-paste everything into Substack. Boring, but necessary.</p><p>For this step, we created a skill that wraps <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Tivadar Danka&quot;,&quot;id&quot;:10322584,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!09ow!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F3b26cd48-153a-4207-b1e3-e14e1ec8d5e8_400x400.jpeg&quot;,&quot;uuid&quot;:&quot;90c20a7b-6f1f-4610-b387-9577d43f7932&quot;}" data-component-name="MentionToDOM"></span>&#8217;s <a href="https://github.com/the-palindrome/nb2wb">nb2wb</a> CLI tool that does all the heavy lifting. The tool supports most popular formats such as Substack, Medium, X, and LinkedIn.</p><p>Initially, it was built to map Jupyter Notebooks to these formats, but it works amazingly for Markdown files too.</p><h2>What Stays Irreplaceable</h2><p>It is not 100% automated. I still follow the original research direction. I still write the outline brain dump. I still validate every artifact. I still write the code that runs the pipeline.</p><p>The 90% automation is real, but the 10% is the part that matters most. It&#8217;s the part that makes this article stand out as human: the seed, the taste, and the validation are irreplaceable.</p><h2>What&#8217;s Next</h2><p>You might wonder how well this works. Well... You <strong>just read an article</strong> created by this exact workflow. In other words, this is an article that talks about itself. It&#8217;s not yet perfect, but it will get there.</p><p>End-to-end, it took about a day of my time. Without the pipeline, this same article would have taken three days of mostly translation work.</p><div class="callout-block" data-callout="true"><p><strong>&#128161; Want to build this exact stack yourself?</strong> Nova and Brown built with FastMCP &amp; LangGraph, the style-transfer skill, human-in-the-loop orchestration, evaluation with Opik, and deployment on Docker, GCP, and GitHub Actions. Every line walked through with me and the Towards AI team. That&#8217;s exactly what we teach in our <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering Course</a></strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KX3c!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KX3c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;placeholder&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="placeholder" title="placeholder" srcset="https://substackcdn.com/image/fetch/$s_!KX3c!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!KX3c!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fba704c84-6c91-43fa-9ade-fd25ee51f175_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></div><p>Otherwise, here is what I&#8217;m wondering:</p><p><em>Which step of your own writing workflow do you think is the most dangerous to automate, and which one have you been avoiding automating because you weren&#8217;t sure how? </em></p><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/how-i-automated-91-percent-of-my-business?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><h2>Further Reading</h2><ol><li><p>LangChain. <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">The Anatomy of an Agent Harness</a></p></li><li><p>Anthropic. <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">Effective Harnesses for Long-Running Agents</a></p></li><li><p>Mitchell Hashimoto. <a href="https://mitchellh.com/writing/my-ai-adoption-journey">My AI Adoption Journey</a></p></li><li><p>The Agent Stack. <a href="https://theagentstack.substack.com/p/openclaw-architecture-part-1-control">OpenClaw Architecture Part 1</a></p></li><li><p>cefboud. <a href="https://cefboud.com/posts/coding-agents-internals-opencode-deepdive/">How Coding Agents Actually Work: Inside OpenCode</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item><item><title><![CDATA[Your RAG Pipeline Is Overkill]]></title><description><![CDATA[The pattern that lets your model write code to explore its context instead of retrieving it.]]></description><link>https://www.decodingai.com/p/recursive-language-models</link><guid isPermaLink="false">https://www.decodingai.com/p/recursive-language-models</guid><dc:creator><![CDATA[Paul Iusztin]]></dc:creator><pubDate>Tue, 07 Apr 2026 11:03:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/59a9c371-4dba-4e06-a6d5-2eae4959bd57_1376x768.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8GRO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8GRO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8GRO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png" width="1376" height="768" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1376,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1294434,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://www.decodingai.com/i/193050808?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8GRO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 424w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 848w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 1272w, https://substackcdn.com/image/fetch/$s_!8GRO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0802fd65-5846-45c3-af31-760acd29f8c2_1376x768.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>We constantly fight a battle against the context window limit. You either compress your data until it loses meaning, or you build a massive infrastructure project just to read a few documents. Today, we look at a third option. We explore a pattern that allows models to read millions of tokens by treating data as an environment rather than an input.</p><p>In most AI projects, such as the financial assistant I am working on, there is a constant battle between Retrieval-Augmented Generation (RAG) and Context-Augmented Generation (CAG). Should you implement a heavy RAG architecture up front that might not even work, or does CAG get the job done? For example, in our financial assistant system, we ultimately decided to use RAG only when we really HAVE to, because it introduces zigzag retrieval patterns that require dozens of queries per operation, increasing latency.</p><p>Also, while building Brown, my writing agent, I hit another wall. Brown needs to ingest massive amounts of research to anchor its writing process. At 180,000 input tokens, the Gemini API became entirely unreliable.</p><p>I faced constant timeouts, disconnections, and infrastructure breakdowns. Huge context windows suffer from API reliability and infrastructure stability issues, as well as performance degradation. But the thing is, I didn&#8217;t want to overcomplicate my solution with a RAG layer, so I started looking around for other solutions.</p><p>Most engineers face this painful tradeoff when working with large documents. You can stuff everything into the context window, but performance degrades quickly. This causes context rot, which happens when attention degrades over long contexts and earlier information loses its influence <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">[1]</a>, <a href="https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/">[2]</a>.</p><p>Alternatively, you can build a RAG pipeline. But that requires maintaining vector databases, chunking strategies, and retrieval evaluation infrastructure.</p><p>Even the tools we use daily, like Claude Code or Cursor, rely on summarization-based context compression that loses critical information. I just wanted to dump my research into one file and get good answers without the infrastructure breaking. Recursive Language Models (RLMs) solve this exact problem <a href="https://arxiv.org/abs/2512.24601">[3]</a>.</p><p>RLMs use an inference-time pattern that treats your input as an external environment the model interacts with programmatically. You do not need chunking infrastructure or embedding pipelines. The model writes code to explore, filter, and recursively process your data on demand.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jJY1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jJY1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 424w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 848w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jJY1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png" width="1400" height="1000" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1000,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The three approaches to processing large documents&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The three approaches to processing large documents" title="The three approaches to processing large documents" srcset="https://substackcdn.com/image/fetch/$s_!jJY1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 424w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 848w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 1272w, https://substackcdn.com/image/fetch/$s_!jJY1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08afe0b8-6aa1-41ce-8bb3-cae88284181f_1400x1000.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 1: The three approaches to processing large documents. RAG adds infrastructure complexity. Context stuffing causes degradation. RLMs treat the input as an external environment the model programs against.</em></figcaption></figure></div><p>This approach scales the effective input and output lengths of LLMs. Researchers tested RLMs up to 10 million tokens across GPT-5 and Qwen3-Coder, showing they easily outperform base models <a href="https://arxiv.org/abs/2512.24601">[3]</a>. Base model performance degrades as a function of input length and task complexity, while RLM performance scales with less degradation.</p><p>RLMs are also a model-agnostic inference strategy, meaning they work with any model you choose.</p><p>However, this architecture has honest downsides you must consider. The inference cost has high variance due to differences in trajectory lengths. The system suffers from code fragility, meaning that if the model writes buggy code, the entire reasoning chain fails.</p><p>Errors in sub-calls can compound through the recursive tree, propagating hallucinations. Sequential sub-calls also create latency bottlenecks. This makes RLMs best suited for deep thinking applications rather than real-time chat.</p><p>To understand how we bypass these infrastructure limits, we need to examine the specific programming trick that keeps the model&#8217;s memory clean.</p><p>Here is what you will learn about this pattern:</p><ul><li><p>The mechanism that keeps massive documents outside the context window.</p></li><li><p>The orchestration loop that drives programmatic data exploration.</p></li><li><p>The specific use cases where this pattern outperforms retrieval systems.</p></li><li><p>A practical method to approximate this behavior using Claude Code.</p></li></ul><div><hr></div><h2><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">If You Want To Go Deeper Into Production AI (Product)</a></h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!59a6!,w_424,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!59a6!,w_848,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!59a6!,w_1272,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!59a6!,w_1456,c_limit,f_webp,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!59a6!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!59a6!,w_424,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 424w, https://substackcdn.com/image/fetch/$s_!59a6!,w_848,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 848w, https://substackcdn.com/image/fetch/$s_!59a6!,w_1272,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 1272w, https://substackcdn.com/image/fetch/$s_!59a6!,w_1456,c_limit,f_auto,q_auto:good,fl_lossy/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62a5bb56-1fed-426d-8284-cb8bf74b8599_1200x1200.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Patterns like RLMs show that the real challenge isn&#8217;t the model, but the infrastructure and systems around it, called the harness. If you want to master that harness, check out my <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agentic AI Engineering course</a></strong>, built with Towards AI.</p><p>34 lessons. Three end-to-end portfolio projects. A certificate. And a Discord community with direct access to industry experts and me.</p><p>Rated 5/5 by 300+ students. The first 6 lessons are free:</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><div><hr></div><h2>The REPL Trick That Keeps Your Context Window Clean</h2><p>RLMs introduce a simple core idea. Do not feed the document into the model&#8217;s context window. Instead, load it as a variable in a persistent programming environment and let the model write code to interact with it <a href="https://www.primeintellect.ai/blog/rlm">[4]</a>.</p><p>The model never sees your 10-million-token document directly. In a traditional agent, the prompt goes into the model, completely blowing up your context window. In an RLM, the context stays outside as an external variable, and the model receives only a symbolic handle to it.</p><p>The system initializes a Read-Eval-Print Loop (REPL), which is a persistent interactive programming environment where variables and state persist across iterations <a href="https://arxiv.org/abs/2512.24601">[3]</a>.</p><p>The root model receives only metadata, such as the total character count and data structure. It also receives instructions on how to access the REPL. The model then writes code to peek into, filter with regex, chunk, or summarize the data.</p><p>When the model identifies a sub-task, it uses a specific primitive such as <code>llm_query(prompt, chunk)</code> to spawn a fresh, isolated worker sub-model <a href="https://arxiv.org/abs/2512.24601">[3]</a>. The system pauses, executes this sub-call, and returns the result to the root model&#8217;s REPL.</p><p>Variables persist across these REPL turns. The model aggregates findings into a buffer, building the response progressively across iterations. Once confident, it calls <code>FINAL(answer)</code> to stop the recursive loop and return the response <a href="https://dextralabs.com/blog/recursive-language-models-rlm/">[5]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i4L_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i4L_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i4L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The RLM REPL mechanism&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The RLM REPL mechanism" title="The RLM REPL mechanism" srcset="https://substackcdn.com/image/fetch/$s_!i4L_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!i4L_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc48c578c-3a1e-4fbf-9c88-a08a748ee2bb_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 2: The RLM mechanism. The document stays outside the context window as a REPL variable. The model writes code to explore, decompose, and recursively process it.</em></figcaption></figure></div><p>RLMs essentially perform context engineering on autopilot. Traditional context engineering requires you to carefully curate what goes into the context window through retrieval and compression <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">[1]</a>. RLMs automate this by letting the model itself decide what to extract, filter, and process.</p><p>Costs and performance stay intact because the model filters the input context without explicitly seeing it. By writing Python scripts, the model processes only the relevant portions through sub-calls. Only constant-size metadata about execution results is appended to the root model&#8217;s history, keeping its context window small and clean.</p><p>Understanding this mechanical loop allows us to map the pattern directly to production harness engineering.</p><h2>Turn Any Agent Into a Plan-Execute-Validate Machine</h2><p>RLMs are an inference-time orchestration pattern that maps directly to production harness engineering. If you have built agent systems, you already know the components: a planning loop, tool execution and validation <a href="https://blog.langchain.com/the-anatomy-of-an-agent-harness/">[7]</a>. RLMs formalize this into a programmable, recursive architecture.</p><p>A robust RLM harness uses a multi-tiered architecture. The root controller is a frontier model that acts as the project manager. It plans the reasoning process, writes code, and coordinates execution, but never directly interacts with tools or the full document <a href="https://www.anthropic.com/engineering/building-effective-agents">[8]</a>.</p><p>Worker sub-models are cheaper, faster models spawned via an operation such as <code>llm_query()</code> to handle specific, localized sub-tasks. This reduces overall costs while maintaining high quality. The aggregation layer is the REPL environment that combines recursive step results into a final structured response via persistent variables.</p><p>This setup naturally follows the plan-execute-validate mapping. In the plan phase, the root controller reviews the query, creates a reasoning plan, and decides how to decompose the problem. It might plan to regex-filter a codebase, chunk a document, or batch sub-calls for parallel analysis.</p><p>In the execute phase, the model translates the plan into code. It writes Python scripts, issues <code>llm_query()</code> calls, and spawns worker sub-models for parallel execution in isolated REPL environments. External tools, like web search, are provided ONLY to worker sub-models, keeping the root model&#8217;s context perfectly clean.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!OWkF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!OWkF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!OWkF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;The plan-validate-execute orchestration loop&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="The plan-validate-execute orchestration loop" title="The plan-validate-execute orchestration loop" srcset="https://substackcdn.com/image/fetch/$s_!OWkF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!OWkF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fec670a03-124b-4954-93e7-745b5cf1a5d3_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 3: The plan-execute-validate loop. The root controller plans, worker sub-models execute, the system validates, and the cycle repeats until FINAL().</em></figcaption></figure></div><p>After execution, the system enters the validation phase, where results feed back as observations. The root model assesses accuracy, launches verification sub-calls, and handles errors by dynamically adjusting its plan. If the Python code fails, the error traceback is yielded back to the model as an event.</p><p>This allows the model to adapt and fix its code on the next turn. The cycle repeats until the model calls <code>FINAL(answer)</code>.</p><p>Deploying this in the real world requires strict production guardrails. You must configure <code>maxIterations</code> to cap the number of REPL turns, typically between 10 and 50. You need <code>maxDepth</code> to limit the recursive stack depth, where a depth of 1 is usually sufficient.</p><p>You also need <code>maxStdoutLength</code> to truncate REPL output returned to the model to prevent context overflow. Finally, permission gating is required to provide sandboxed execution with explicit approval for sensitive operations.</p><p>Neither Claude Code nor OpenAI Codex uses true RLM patterns. They rely on summarization-based context compression, file-system state tracking and progressive disclosure techniques <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">[9]</a>. This creates a succession of agents connected by prompts and file state, rather than maintaining a persistent REPL environment with programmatic sub-calls.</p><p>With this architecture in place, we can identify the specific real-world scenarios where this pattern outperforms traditional data processing.</p><h2>Four Scenarios Where RLMs Beat Traditional Approaches</h2><p>RLMs are best suited for deep thinking applications that require accuracy, multi-step reasoning, and reliability over massive contexts. They are not suited for real-time, low-latency chat applications.</p><p>The <strong>first scenario</strong> is parsing large files without building retrieval infrastructure. Instead of building a hybrid index with vector and graph search, you keep everything in one file or directory and use an RLM agent to extract information on demand.</p><p>We can view the relationship between RAG and RLMs as a spectrum. For simple cases, RLMs replace RAG entirely, removing the need for chunking and embeddings. For advanced scenarios, RLMs complement retrieval beautifully.</p><p>You use semantic search to find your first pool of candidates, write the results to disk as cached short-term memory, and use an RLM to query that refined dataset on demand.</p><p>The retrieval narrows the haystack, and the RLM reasons deeply over what is left. I use this exact workflow for my research, dumping everything into a massive text file and using an RLM to extract relevant information.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K9A3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K9A3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 424w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 848w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 1272w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K9A3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png" width="1400" height="1208" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1208,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1040009,&quot;alt&quot;:&quot;RLM replacing RAG for large file parsing&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="RLM replacing RAG for large file parsing" title="RLM replacing RAG for large file parsing" srcset="https://substackcdn.com/image/fetch/$s_!K9A3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 424w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 848w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 1272w, https://substackcdn.com/image/fetch/$s_!K9A3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41df1265-00a8-4373-8862-dd260870cd6c_1400x1208.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 4: RLM replaces the entire RAG pipeline for large file parsing. One file, one agent, no retrieval infrastructure.</em></figcaption></figure></div><p>The <strong>second scenario</strong> is complex software engineering and codebase comprehension. RLMs ingest massive codebases containing millions of tokens to answer questions about architecture, map dependencies, and perform reviews.</p><p>The RLM paper tested this on LongBench-v2 CodeQA using Qwen3-Coder with a Python REPL. The model writes code to break down the codebase, launches sub-queries to smaller language models, and aggregates findings <a href="https://arxiv.org/abs/2512.24601">[3]</a>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HwsN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HwsN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HwsN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png" width="1400" height="1400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1400,&quot;width&quot;:1400,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;RLM decomposing a codebase through recursive sub-queries&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="RLM decomposing a codebase through recursive sub-queries" title="RLM decomposing a codebase through recursive sub-queries" srcset="https://substackcdn.com/image/fetch/$s_!HwsN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 424w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 848w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 1272w, https://substackcdn.com/image/fetch/$s_!HwsN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe733bf97-fdcf-4e10-9d2c-4d242b1baf1d_1400x1400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption"><em>Image 5: An RLM decomposes a codebase question into parallel sub-queries, each handled by a worker sub-model, then aggregates the results.</em></figcaption></figure></div><p>The <strong>third scenario</strong> is enterprise legal and financial analysis. RLMs provide consistent interpretation across thousands of contracts, case files, and policies that would overwhelm a standard context window. They also excel at financial audits and due diligence by tracing, validating, and reasoning through massive financial datasets.</p><p>The <strong>fourth scenario</strong> is deep research and information synthesis. RLMs synthesize research across thousands of files by programmatically filtering, chunking, and summarizing. They enable knowledge graph exploration and multi-hop reasoning over large document dumps.</p><p>At scale, RLMs become both more accurate and cheaper than standard long-context approaches. They avoid paying for n-squared attention over massive contexts by having the model process only relevant slices via sub-calls. In all these scenarios, the RLM pattern succeeds because it treats the LLM as a project manager that decides what to look at and delegates sub-tasks to workers.</p><p>Knowing these optimal use cases helps us approximate the pattern using tools you likely already have installed.</p><h2>Build a Naive RLM SKILL in Claude Code</h2><p>Claude Code does not natively use the RLM pattern. It relies on summarization-based context compression, file-system state tracking, and progressive disclosure. However, you can approximate RLM behavior using Claude Code&#8217;s existing harness features to build a naive RLM SKILL.</p><p>First, you set up the environment by having the SKILL load the target file or directory as a reference. Instead of feeding it into the context window, it writes the file path and metadata to a prompt for the root agent.</p><p>Second, the root Claude Code agent receives only this metadata and a set of instructions for how to interact with it. It uses its Explore subagent type <br>to examine the data structure, identify relevant sections, and plan its approach.</p><p>Third, the SKILL uses Claude Code&#8217;s Agent tool to spawn subagents. Each subagent receives a focused prompt to read specific lines and extract mentions, returning a condensed summary of a few thousand tokens. This mirrors the RLM pattern of spawning isolated sub-calls that process slices of the input.</p><p>Finally, the root agent collects these subagent results. It aggregates them into a coherent answer and decides whether more exploration is needed or whether to finalize the output.</p><p>Here is what this naive RLM SKILL looks like as a <em>SKILL.md</em> file:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;markdown&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-markdown">---
name: rlm-research-analyzer
description: "Analyze large research files by treating
  them as an external environment. Instead of stuffing
  content into context, the model explores, decomposes,
  and recursively processes the data through subagents."
---

# Analyze Large Research Files Using the RLM Pattern

## Step 1 &#8212; Initialize the environment

Accept the target file path as an argument. Do NOT read
the file into context. Instead, run a Bash command to
collect metadata:

wc -l &lt;file_path&gt;   # total lines
wc -c &lt;file_path&gt;   # total bytes
head -5 &lt;file_path&gt;  # short prefix

Write the metadata and file path to a temporary prompt
file at &lt;working_dir&gt;/rlm_prompt.md. The root agent
receives ONLY this metadata, never the full content.

## Step 2 &#8212; Plan the exploration

Read rlm_prompt.md. Based on the metadata and prefix,
decide how to decompose the file. Use an Explore
subagent to scan the file structure:

- Identify section boundaries, headings, or delimiters
- Estimate which regions are relevant to the query
- Produce a ranked list of target ranges to process

## Step 3 &#8212; Delegate to worker subagents

For each target range, spawn an Agent subagent with a
focused prompt:

"Read lines {start}-{end} of {file_path}. Extract all
findings related to {query}. Return a summary under
2000 tokens."

Launch multiple subagents in parallel when ranges are
independent. Write each subagent's output to
&lt;working_dir&gt;/slice_{n}.md.

## Step 4 &#8212; Aggregate and finalize

Read all slice files. Synthesize the findings into a
single coherent answer. If gaps remain, return to
Step 3 with new target ranges. Otherwise, write the
final output to &lt;working_dir&gt;/answer.md and present
it to the user.</code></pre></div><p>Notice how the four steps map directly to RLM primitives. Step 1 mirrors REPL initialization, where the data becomes an external variable rather than context input. Step 3 replaces the theoretical <code>llm_query()</code> operation with Claude Code&#8217;s Agent tool. Step 4 mirrors the <code>FINAL()</code> call that terminates the recursive loop.</p><p>This naive approximation lacks several critical features. It has no true REPL persistence, as Claude Code subagents do not share a persistent variable space. The filesystem serves as a proxy for REPL state, but it is slower and less elegant.</p><p>It also lacks sandboxing, as Claude Code runs directly in your environment. Then you miss out on configurable guardrails like <code>max_iterations</code> and <code>max_output_chars</code>, requiring manual limits instead. You get the idea.</p><p>Still, I&#8217;ve been using a similar technique in all my current projects: instead of stuffing the research into a file, I dump everything into a dir and link everything together in an <code>index.yaml</code> file that contains URIs to all the files, plus metadata such as the title and a 1-2 sentence summary of each source. Like this, through the <code>index.yaml</code> file, Claude Code can efficiently navigate the whole research dump token through progressive disclosure.</p><p>My structure looks something like this:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">research/
&#9500;&#9472;&#9472; index.yaml
&#9500;&#9472;&#9472; file_1.md
&#9500;&#9472;&#9472; file_2.md
&#9500;&#9472;&#9472; ...
&#9492;&#9472;&#9472; file_N.md</code></pre></div><p>Also, the only out-of-the-box implementation I found is within the <a href="https://dspy.ai/api/modules/RLM/">DSPy framework</a>.</p><p>The naive SKILL is a useful thought exercise and a practical first step. For production use, you should reference the DSPy framework&#8217;s <code>dspy.RLM</code> module.</p><h2>What&#8217;s Next</h2><p>RLMs represent a fundamental shift in how we process large inputs. We are moving from asking how to fit data in the context window to asking how we let the model interact with it programmatically. This is a great thought exercise on integrating specialized inference-time functionality into your harness.</p><p>As models get better at writing code and REPL environments become more sophisticated, the boundary between the model and its infrastructure will blur. The model does not just use tools, it writes the tools on the fly to solve the specific problem in front of it.</p><p>Your next practical step is to experiment with our SKILL or with the DSPy framework&#8217;s <code>dspy.RLM</code> module on a real problem. Point it at a large codebase you need to understand or a research corpus you need to synthesize. Start with something you have been using RAG or context stuffing on, and see whether the RLM approach is more effective.</p><p><em>But here is what I&#8217;m wondering: </em></p><p><em><strong>How have you been passing large files, such as deep research results or books, to your agents so far? RAG, CAG or other creative techniques?</strong></em></p><p><em>Click the button below and tell me. I read every response.</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/recursive-language-models/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/recursive-language-models/comments"><span>Leave a comment</span></a></p><div><hr></div><p><em>Enjoyed the article? The most sincere compliment is to restack this for your readers. </em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://www.decodingai.com/p/recursive-language-models?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://www.decodingai.com/p/recursive-language-models?utm_source=substack&utm_medium=email&utm_content=share&action=share"><span>Share</span></a></p><div><hr></div><div class="callout-block" data-callout="true"><h4>Whenever you&#8217;re ready, here is how I can help you</h4><p><em>Go from agent user to agent builder.</em> Master the foundations of AI agents and turn fragile demo code into reliable, production-ready systems with my course, <strong><a href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">Agent Engineering: Building Multi-Agent Systems</a></strong> (made with Towards AI).</p><p>35 lessons. Pure foundations from scratch. 4 mini-projects. 2 production systems. A certificate and direct access to me &amp; industry experts in our Discord.</p><p>Built for software and data professionals transitioning into AI engineering. <em>Rated 5/5 with 300+ students. The first 7 lessons are free:</em></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering&quot;,&quot;text&quot;:&quot;Start here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://academy.towardsai.net/courses/agent-engineering?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering"><span>Start here</span></a></p><p><em>Not ready to commit?</em> Start with our <strong><a href="https://email-course.towardsai.net/?ref=b3ab31&amp;utm_source=decodingai&amp;utm_medium=partner&amp;utm_campaign=agent_engineering">free Agent AI Engineering Guide</a></strong>, a 6-day email course on the mistakes that silently break AI agents in production.</p></div><div><hr></div><h2>References</h2><ol><li><p>(n.d.). Effective Context Engineering for AI Agents. Anthropic. <a href="https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents">https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents</a></p></li><li><p>(n.d.). MIT&#8217;s new &#8216;recursive&#8217; framework lets LLMs process 10 million tokens without context rot. VentureBeat. <a href="https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/">https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/</a></p></li><li><p>Zhang, A. L., Kraska, T., &amp; Khattab, O. (2025). Recursive Language Models. arXiv. <a href="https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/">https://arxiv.org/abs/2512.24601</a></p></li><li><p>(n.d.). Recursive Language Models: the paradigm of 2026. Prime Intellect. <a href="https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/">https://www.primeintellect.ai/blog/rlm</a></p></li><li><p>(n.d.). Why Recursive Language Models (RLMs) Beat Long-Context LLMs. Dextra Labs. <a href="https://venturebeat.com/orchestration/mits-new-recursive-framework-lets-llms-process-10-million-tokens-without-context-rot/">https://dextralabs.com/blog/recursive-language-models-rlm/</a></p></li><li><p>Mansurova, M. (2026, March 30). Going Beyond the Context Window: Recursive Language Models in Action. Towards Data Science. <a href="https://towardsdatascience.com/going-beyond-the-context-window-recursive-language-models-in-action/">https://towardsdatascience.com/going-beyond-the-context-window-recursive-language-models-in-action/</a></p></li><li><p>(2026, March 21). The Anatomy of an Agent Harness. LangChain Blog. <a href="https://towardsdatascience.com/going-beyond-the-context-window-recursive-language-models-in-action/">https://blog.langchain.com/the-anatomy-of-an-agent-harness/</a></p></li><li><p>(2025, December 24). Building Effective AI Agents. Anthropic. <a href="https://towardsdatascience.com/going-beyond-the-context-window-recursive-language-models-in-action/">https://www.anthropic.com/engineering/building-effective-agents</a></p></li><li><p>(2026, March 25). Effective Harnesses for Long-Running Agents. Anthropic. <a href="https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents">https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents</a></p></li></ol><div><hr></div><h2>Images</h2><p>If not otherwise stated, all images are created by the author.</p>]]></content:encoded></item></channel></rss>