<?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"><channel><title><![CDATA[Macrokit]]></title><description><![CDATA[Macrokit]]></description><link>https://macrokit.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Mon, 09 Nov 2026 11:11:36 GMT</lastBuildDate><atom:link href="https://macrokit.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[We ported how brains manage the cost of thinking to LLM systems]]></title><description><![CDATA[Maker disclosure: I build Macrokit (Apache-2.0, fully open). This is the idea, not a pitch — there's nothing to buy. Links at the end; the demo is keyless…]]></description><link>https://macrokit.hashnode.dev/we-ported-how-brains-manage-the-cost-of-thinking-to-llm-systems</link><guid isPermaLink="true">https://macrokit.hashnode.dev/we-ported-how-brains-manage-the-cost-of-thinking-to-llm-systems</guid><category><![CDATA[Open Source]]></category><category><![CDATA[AI]]></category><category><![CDATA[llm]]></category><category><![CDATA[Machine Learning]]></category><dc:creator><![CDATA[Cheng Qian]]></dc:creator><pubDate>Wed, 10 Jun 2026 04:26:27 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p><strong>Maker disclosure:</strong> I build Macrokit (Apache-2.0, fully open). This is the idea, not a pitch — there's nothing to buy. Links at the end; the demo is keyless and runs entirely in your browser, so you can verify every claim in your own network tab.</p>
</blockquote>
<p>Open one link and a ~0.5–7B model running <strong>in your browser</strong> — no signup, no API key, no server, nothing installed — does GitHub-maintainer work you'd assume needs a frontier model: triaging the newest PR on a public repo, proposing labels, summarizing open issues. Open your network tab while it runs and the only outbound traffic is the model weights downloading once and public GitHub reads. No inference server. No key, mine or yours.</p>
<p>That demo isn't a trick, and it isn't "weak models are secretly as smart as GPT-4." It's a structural choice about <em>where the thinking happens</em> — and the cleanest way to explain it is that <strong>we ported how brains manage the cost of thinking to LLM systems.</strong></p>
<h2>Intelligence is expensive, so brains don't think twice</h2>
<p>Thinking burns energy. The brain is ~2% of body mass and ~20% of resting metabolic cost, and deliberate reasoning is the most expensive thing it does. Evolution's answer wasn't "think faster." It was to <strong>think a thing through once, and then stop thinking about it.</strong></p>
<p>This is the dual-process picture Kahneman popularized as System 1 and System 2:</p>
<ul>
<li><strong>System 2 — deliberation:</strong> slow, effortful, expensive, flexible. It's what you use for genuinely novel problems.</li>
<li><strong>System 1 — automaticity:</strong> fast, effortless, cheap, reflexive. It's what carries the overwhelming majority of your day.</li>
</ul>
<p>The whole trick of an efficient mind is <strong>having both</strong>, and routing almost everything to the cheap one. You deliberated hard the first ten times you drove a car; now you do it while holding a conversation. The cheap reflex carries ~95% of the load; the expensive mind is held in reserve for when the world surprises you.</p>
<p>Macrokit is that architecture, ported to LLM systems:</p>
<ul>
<li><strong>The strong model is System 2</strong> — slow, expensive, for the novel.</li>
<li><strong>A <em>macro</em> is System 1</strong> — fast, cheap, deterministic, for the routine.</li>
</ul>
<blockquote>
<p>A fast cheap reflex and a slow expensive mind, with the reflex carrying the load.</p>
</blockquote>
<h2>The sharpened version: macros are <em>compiled deliberation</em>, not instinct</h2>
<p>It's tempting to call a macro an "instinct," but that's wrong, and the correct version is more interesting. Pure instinct is <strong>innate</strong> — genetic, like a spider's web or a suckling reflex. No macro is born; every macro is <em>learned</em>. The right analog is <strong>habit and acquired expertise</strong>, and the key is <em>how it forms</em>.</p>
<p>A behavior starts as effortful System-2 deliberation. Repeated enough, the brain <strong>chunks</strong> it and physically migrates it from the prefrontal cortex (slow, costly) to the <strong>basal ganglia</strong> (fast, cheap). The skill stops being something you reason through and becomes something you <em>run</em>. <strong>Deliberation compiles itself into reflex.</strong></p>
<p>That's the deepest framing of what Macrokit does: <strong>intelligence compiling itself into instinct through repetition.</strong> A strong model reasons a workflow out step by step exactly once, and that reasoning is compiled down into a deterministic artifact a weak model can just <em>run</em> — no reasoning required.</p>
<h2>The pattern maps end-to-end</h2>
<table>
<thead>
<tr>
<th>Macrokit</th>
<th>Cognition</th>
</tr>
</thead>
<tbody><tr>
<td>Macro / weak-model routing</td>
<td>System 1 — fast, automatic, cheap</td>
</tr>
<tr>
<td>Strong model</td>
<td>System 2 — slow, deliberate, expensive</td>
</tr>
<tr>
<td>Distillation gate (encode on recurrence)</td>
<td>Neural chunking (cortex → basal ganglia)</td>
</tr>
<tr>
<td>Graduation %</td>
<td>The novice → expert curve</td>
</tr>
<tr>
<td>Bail-out detector</td>
<td>"Wait — this isn't working, think harder"</td>
</tr>
<tr>
<td>Encode once, run cheap forever</td>
<td>The brain's energy budget — the <em>same</em> argument</td>
</tr>
</tbody></table>
<p>The distillation gate is the piece I think is genuinely novel, and it's the artificial version of <strong>neural chunking</strong> — same trigger (repetition), same reason (the cost of thinking). More on it below.</p>
<h2>The failure mode is predicted, not hidden</h2>
<p>Here's where the analogy earns its keep instead of just sounding nice: it <strong>predicts the failure mode</strong> rather than papering over it.</p>
<p>Habits are fast <em>but brittle</em>. They misfire when the environment shifts — the moth that navigated by moonlight for a million years flies into the flame; the experienced driver's reflexes betray them on the opposite side of the road. The reflex is only safe in the world it was compiled for.</p>
<p><strong>Macros rot exactly the same way.</strong> A macro over a third-party surface breaks when that surface changes underneath it. The cognitive frame doesn't excuse this — it <em>anticipates</em> it, and prescribes the same fix biology uses: when the automatic path fails, <strong>re-deliberate</strong>. That's the <strong>bail-out detector</strong> — "this isn't working, think harder" — kicking the system from autopilot back into System 2. Loud, typed failures, caught in CI, not a "self-healing" hand-wave.</p>
<h2>Where the analogy honestly breaks</h2>
<p>Never over-romanticize this. Three places it doesn't hold, and you should know them:</p>
<ul>
<li><strong>Innate vs. learned.</strong> No macro is genetic. (If you squint: the SDK's <em>primitives</em> are the innate reflexes the system is born with; macros are the habits learned from them.)</li>
<li><strong>Metacognition.</strong> A human can introspect and <em>choose</em> to override a habit. Macrokit's "which system fires" is a confidence-gated router — far cruder than real metacognitive control.</li>
<li><strong>Generality.</strong> Some instincts transfer broadly; a macro is narrow and parameterized — a <em>specific</em> skill, not a broad drive.</li>
</ul>
<p>It's a real structural correspondence under a shared cost constraint, not a claim of biological fidelity. That's the honest version.</p>
<hr />
<p>The rest of this is the engineering and the evidence. The cognition frame is the spine; everything below is the proof that the spine is load-bearing.</p>
<h2>The two-phase split, concretely</h2>
<p>Most production LLM workflows aren't novel reasoning problems. They're the <strong>same shape of work, with different arguments, run thousands of times</strong> — fetch this, extract that, score it, label it. The hard part isn't deciding what to do once you understand the request; it's <em>reasoning your way there step by step</em>, which is exactly what weak models can't do reliably.</p>
<p>So don't make weak models reason better. <strong>Remove the runtime reasoning requirement.</strong></p>
<blockquote>
<p>Any workflow a strong model can solve by reasoning step-by-step on a known surface can be encoded once as a deterministic, parameterized sequence of tool calls. After that, <em>executing</em> it only requires intent classification — a one-shot routing problem small models handle fine.</p>
</blockquote>
<p>That encoded sequence is a <strong>macro</strong>, and it splits the work in two — design-time deliberation, runtime reflex:</p>
<ul>
<li><strong>Design time (offline, rare — System 2):</strong> a strong model, supervised by a developer using the coding agent you already use, solves the workflow once and writes the macro. Versioned, reviewable, deterministic. Costs ~$0.50 of inference and happens once.</li>
<li><strong>Runtime (online, constant — System 1):</strong> a weak/local model gets a request, classifies which macro it maps to, and calls it with extracted arguments. The macro runs as ordinary tested code. The model never plans the workflow.</li>
</ul>
<p>The cost asymmetry is the whole point — the same argument the brain's energy budget makes. Encode once with a frontier model; execute thousands of times with a model that costs ~1/100th–1/1000th as much and runs on a laptop. The capability gap between models stops mattering <em>for that workflow</em>.</p>
<h2>What a macro actually is</h2>
<p>Not a prompt template, not a cache. A parameterized program with five parts: an intent spec the router matches against, a typed argument schema, a deterministic handler (the real tool-call sequence, in code), a structured failure contract, and test fixtures.</p>
<pre><code class="language-ts">defineMacro({
  name: "triage_arxiv_paper",
  intent: "summarize and classify an arXiv paper by its ID or URL",
  schema: z.object({
    paperId: z.string(),
    classifier: z.enum(["relevance", "novelty", "method"]).default("relevance"),
  }),
  handler: async ({ paperId, classifier }, ctx) =&gt; {
    const meta = await ctx.tools.arxiv.fetchMetadata(paperId);
    const pdf  = await ctx.tools.arxiv.fetchPdf(paperId);
    const text = await ctx.tools.pdf.extract(pdf, { pages: "1-3" });
    const score = await ctx.tools.classify(text, { dimension: classifier });
    return { paperId, title: meta.title, score, oneLine: meta.summary };
  },
  tests: [/* recorded request → expected-output fixtures */],
});
</code></pre>
<p>At runtime the model sees <em>"triage 2401.12345, I care whether the method is new"</em> and emits exactly one call:</p>
<pre><code class="language-json">{ "tool": "triage_arxiv_paper", "args": { "paperId": "2401.12345", "classifier": "method" } }
</code></pre>
<p>It doesn't decide to fetch, then extract, then score. That sequence was compiled offline — the reflex already exists. The model only routes. (Composition is also a macro — if a workflow is "run A, then B, then C," that's <em>one</em> macro <code>run_full_pipeline</code>, not three router turns. Three router turns is reasoning-at-runtime by the back door.)</p>
<h2>The distillation gate = neural chunking, as a CLI</h2>
<p>A macro library is only useful if it's complete enough for the workflows people actually run. Most tool collections grow organically and rot — every session adds a one-off helper, no session consolidates. The brain has the opposite reflex: repeat something enough and it <em>gets chunked</em> into automaticity, on purpose, because re-deliberating it every time is too expensive.</p>
<p>Macrokit makes that reflex a discipline, enforced by tooling:</p>
<blockquote>
<p><strong>Every session that touches a workflow with no existing macro must encode one before it ends.</strong></p>
</blockquote>
<p>A CLI reads the session log and fails the build when it sees raw tool calls for an un-encoded workflow — repetition that should have been chunked but wasn't:</p>
<pre><code>$ macrokit gate
Session 2026-05-24T14:02Z used 4 raw tool calls for an unmacro'd workflow:
  → fetch_user_profile(id=…)
  → list_user_open_issues(id=…)
  → label_issues(ids=…, label="needs-triage")
  → notify_assignees(issue_ids=…)
Encode this before ending the session.
Suggested: triage_open_issues_for_user(user_id, label="needs-triage")
</code></pre>
<p>The runtime is just engineering. The gate is the cultural piece — it's chunking, triggered by repetition, for the same reason brains chunk: the cost of thinking. Wire it into CI and your library compounds at the rate you use the system, instead of becoming a graveyard of helpers. That's why this pattern compounds where agent frameworks and RPA libraries haven't — and <strong>graduation %</strong>, the share of traffic the cheap reflex now carries, is just the novice→expert curve made into a metric.</p>
<h2>The honesty beat: four local models clear the bar — and the one that doesn't</h2>
<p>I pre-registered a 100-task intent-routing benchmark, temperature 0, no cloud and no key. Four off-the-shelf local models straight from <code>ollama pull</code> — Qwen 2.5 1.5B / 3B / 7B and Llama 3.1 8B — score <strong>74–82.5%</strong>. The same 7B tuned as the production reference (llama.cpp, Q4_K_M) reaches <strong>94.5%</strong> with zero structural failures; most of that gap is serving, quantization, and sampling config, not raw model capability. No frontier rows — deliberately.</p>
<p>The benchmark also ships the model that flunks: <strong>Mistral 7B v0.3 scored 14%</strong>. It narrated tool calls in prose ("the <code>triage_pull_request</code> macro will be called with…") instead of emitting structured ones, and the bail-out detector caught that on 24 tasks rather than scoring a hallucinated success. Publishing the row that fails is the point — a bar you can't fail isn't a bar.</p>
<p>And the methodology earned its keep before any of that. The production 7B's <em>first</em> pre-registered run scored <strong>53.5%</strong> — not a model problem, a bug in my own SDK: zod schemas don't carry JSON Schema by default, so the router fell back to a permissive <code>{type: object}</code> and the model never saw the real argument names. A ~12-line fix (zod → JSON Schema at <code>defineMacro()</code> time) took the same model on the same corpus to 94.5%. The failed run is shipped right next to the fixed one. Pre-registration is <em>for</em> catching exactly that kind of silent config miss — re-run the harness yourself.</p>
<h2>Where it does <em>not</em> help (so you don't misapply it)</h2>
<p>This falls right out of the System-1/System-2 split: automaticity is for the routine, deliberation is for the novel. So —</p>
<ul>
<li><strong>Genuinely novel reasoning</strong> — "write a reply to this angry customer," "price a brand-new category." That's System-2 work; route it to a frontier model. Hybrid routing (local handles the routine 80–90%, frontier handles the novel remainder) is opt-in.</li>
<li><strong>Workflows that change every time</strong> — exploratory research, open-ended debugging. Nothing to chunk; the pattern is pure overhead. The value comes from the ratio of executions to encodings.</li>
<li><strong>Surfaces that change underneath you</strong> — the brittle-habit failure mode above. Mitigation is loud, typed failures caught in CI plus a DOM/action-menu abstraction, not a "self-healing" claim.</li>
<li><strong>Models that can't reliably emit tool calls</strong> — it's less about size than structured-output discipline. Qwen 2.5 scales cleanly from 1.5B (74%) up, but a <em>7B</em> that narrates calls in prose instead of emitting them (Mistral 7B v0.3, 14% here) won't clear the bar until its tool-calling is fixed. The bail-out detector catches those rather than scoring hallucinated successes.</li>
</ul>
<h2>What it is not</h2>
<p>Not an agent framework (those compete on <em>better</em> runtime reasoning — more System 2; this <em>eliminates</em> it — "an agent that routes," not "an agent that thinks"). Not a model (BYO — OpenAI-compatible + Ollama out of the box). Not RPA (macros are semantic tool calls, not recorded pixels). Not a fine-tuning pipeline. Not no-code (authoring needs a developer + strong model).</p>
<p>This isn't a fad or a hack. It's the <strong>universal architecture of efficient intelligence under a cost budget</strong> — the same answer brains, animals, and now LLM systems all converge on, because the cost asymmetry between deliberating and executing isn't going away. I've run the pattern in production for about a year inside an unrelated operations tool serving users with no practical frontier-API access, and pulled the vertical-agnostic core out into Macrokit. The interesting question to me isn't whether weak models can match frontier — it's how much of your real workload is repetitive enough that you never need to find out.</p>
<h2>Try it / read it</h2>
<ul>
<li><strong>Demo</strong> (keyless, in-browser, public repos — open the network tab): <a href="https://studio.macrokit.dev">https://studio.macrokit.dev</a></li>
<li><strong>The pattern + the benchmark, including the failed first run:</strong> <a href="https://macrokit.dev">https://macrokit.dev</a></li>
<li><strong>SDK (Apache-2.0, TypeScript):</strong> <a href="https://github.com/macrokit/core">https://github.com/macrokit/core</a></li>
</ul>
<p>I'd genuinely like to hear where this breaks on real work — that's the useful feedback. Pushback welcome.</p>
<p>— Cheng Qian</p>
]]></content:encoded></item></channel></rss>