Compiled Cognition: When Agents Should Stop Thinking
TL;DR Today’s LLM agents solve every task as if for the first time — re-deriving, at full cost in tokens, latency, and error, conclusions that they (or someone else) already reached a thousand times. Nothing is kept between runs.
The idea: treat this as a compilers problem. An agent that reasons through every instance is an interpreter; the fifty-year-old theory of partial evaluation says how to do better — split each recurring task into the part that can be decided once and frozen into fast, tested, reusable tools, and the part that genuinely needs fresh judgment, which stays with the model.
The payoff: reasoning gets paid for once and reused forever — microseconds and zero tokens instead of seconds and a fresh chance of error. The maturity metric for an agent system is the fraction of routine work that no longer needs the model at all. Spend inference only on what is genuinely new.
In 1911, Alfred North Whitehead wrote that “civilization advances by extending the number of important operations which we can perform without thinking about them” (Whitehead, 1911). Modern LLM agents invert the principle: they think about everything, every time. Ask a coding agent to port an attention kernel to H100 GPUs and it will happily re-derive shared-memory swizzle patterns for Tensor Cores1 that have been settled knowledge for most of a decade and are already encoded in CUTLASS. Ask it to shard a PyTorch model and it will reason step by step through a parallelism insertion that existing machinery performs mechanically.2 The same derivations run again tomorrow, in the next session, and in thousands of other organizations, every day. I will call this cost interpretive overhead: tokens, latency, and error spent re-deriving what is already known.
This post argues that the situation is not a prompt-quality problem, and not exactly a capability gap either. It is an architectural stage. A prompted agent is an interpreter for natural-language programs, and the field has not yet built its compilers. The claim I want to defend:
The central engineering problem of agent systems is partial evaluation: deciding, per step and per parameter, what binds ahead of time into deterministic, verifiable artifacts, and what remains in the runtime residual where judgment is genuinely required.
I will call the overall program compiled cognition. Stated in the vocabulary agent builders already use, it is the question of when a system should rely on the model’s internal knowledge — the weights, plus whatever gets re-derived at runtime as reasoning — and when it should reach for external tools; and, more importantly, how the second store gets built out of the first. The rest of the vocabulary is borrowed deliberately: “binding time,” “specialization,” “residual,” “guard,” and “deoptimization” all have precise meanings in the programming-languages and compiler literature, and I think they transfer to agents almost without modification. Related ideas appear under many names across fields — proceduralization and production compilation in cognitive science, chunking in classical AI, speedup learning in the 1980s machine-learning literature, library learning in modern program synthesis, consolidation in memory science. I take the convergence as weak evidence that the phenomenon is real and load-bearing.
One positioning note. Weng (2026) surveys harness engineering: the runtime layer around the model that orchestrates tools, context, memory, workflows, and evaluation, and increasingly optimizes itself. This post is about a complementary question: not how the harness invokes the model, but what the harness should accumulate so that the model is invoked less. Evolving context playbooks and workflow code is the soft end of that accumulation; I will argue the hard end — verified, deterministic artifacts that permanently retire whole classes of reasoning — is where the compounding lives. If the harness is the agent’s operating system, this post is about its compiler toolchain.
Table of Contents
Background
The Cost Structure of a Forward Pass
Interpretive execution pays the full marginal cost of cognition on every instance: tokens, wall-clock latency, energy, and a per-step error probability. The error term compounds over long horizons. If each step of an interpretive chain succeeds with probability $1-\epsilon$, a $k$-step chain succeeds with probability
\[p_{\text{success}} = (1-\epsilon)^k,\]so a 50-step chain at a modest 1% per-step error rate completes correctly about 60% of the time. The same pipeline as a deterministic artifact fails only where its specification fails, and fails the same way twice — which is what makes failure debuggable. Interpretation is also non-reproducible in a deeper sense: sampling temperature, context sensitivity, and model updates all perturb the mapping from task to behavior, which is corrosive for any process that must be audited, replayed, or trusted downstream.
Compiled execution inverts every term: near-zero marginal cost, microsecond latency, bit-identical replay, and inspectability. In economic terms, tokens are labor and artifacts are capital — a framing I will return to, because it turns out to predict which objections people raise and why they fail.
A Short History of Binding Time
Every abstraction jump in computing — binary to assembly, assembly to high-level languages, static binaries to managed runtimes — has consisted of two things: a notation for humans and a deterministic translator downward. The organizing concept is binding time: the moment at which a decision gets fixed. Compilers bind early (fast, rigid); interpreters bind late (flexible, slow, paying per execution). JIT compilers move bindings adaptively: profile the hot paths, speculate, compile with guards, and deoptimize back to the interpreter when a guard fails. Modern VMs like V8 are tiered systems that spend expensive optimization only where execution frequency justifies it.
Partial evaluation made this precise (Futamura, 1971; Jones, Gomard & Sestoft, 1993). Given a program $p$ with static inputs $s$ and dynamic inputs $d$, a specializer $\textit{mix}$ produces a residual program $p_s = \textit{mix}(p, s)$ such that $p_s(d) = p(s, d)$, with all $s$-dependent work paid once at specialization time. The Futamura projections follow:
- $\textit{mix}(\textit{interpreter}, \textit{source})$ = a compiled program.
- $\textit{mix}(\textit{mix}, \textit{interpreter})$ = a compiler.
- $\textit{mix}(\textit{mix}, \textit{mix})$ = a compiler generator.
Deciding which parts of a program are static versus dynamic is called binding-time analysis (BTA), and two-level languages (Nielson & Nielson, 1992) annotate every construct with its stage.
Natural language is the newest source language in this sequence — but it arrived without its translator. Today the model plays the role of a human at every level of the stack simultaneously: requirements analyst, compiler, and CPU. That is what “interpretation” means here, and it is why the waste has the particular shape it does.
Cognitive Precedents
The pattern “expensive deliberate reasoning consolidates into cheap automatic procedure” is among the best-studied phenomena in the science of skill. In ACT-R, production compilation converts slow declarative retrieval into fast procedural rules (Anderson, 1983). SOAR’s chunking caches successful problem-solving traces as production rules that fire directly the next time (Laird, Rosenbloom & Newell, 1986). The 1980s explanation-based learning program (Mitchell, Keller & Kedar-Cabelli, 1986) named the general category speedup learning: learning that changes how fast something is computed, not what is computable. Memory science calls the offline version systems consolidation — episodic traces are replayed during sleep and re-encoded as semantic and procedural knowledge — and it is no accident that DreamCoder (Ellis et al., 2021) named its library-abstraction phase “sleep.” Psychometrics distinguishes fluid intelligence (novel reasoning) from crystallized intelligence (accumulated skill) (Cattell, 1963); a tool library is crystallized intelligence with an API.
One inversion is worth pausing on. Humans compile explicit rules into intuition: novice-to-expert development is System 2 sinking into System 1. LLM agents should compile in the opposite direction — intuition into explicit rules — because their cost structure is inverted. For a human, neural execution is cheap and automatic while symbol manipulation is slow and effortful. For an agent system, symbolic execution is essentially free CPU time, and the neural forward pass is the expensive, slow, unreliable deliberate act. The agent’s System 1 should be symbolic.
The philosophy literature supplies the external half of the story: cognition compounds through artifacts — the “extended mind” (Clark & Chalmers, 1998). Whitehead’s line is the design goal, restated for machines.
The Problem: Perpetual Interpretation
Interpretive Waste
Three concrete instances, in increasing generality.
GPU kernels. Ask an agent to write a new attention variant in pure CUDA and watch where the tokens go: online-softmax tiling, mma fragment layouts (which thread holds which element of the tile), bank-conflict-free shared-memory swizzles, cp.async double-buffering, warp specialization. Every one of these transformations already exists in CUTLASS/CuTe — and frequently cannot be reached, because the abstractions do not compose toward the new kernel: the template machinery is deep, the extension points are rigid, and bending them costs more than dropping to raw CUDA. So the agent drops down and re-derives the transformations inline. The sharp description of what is happening: the agent is rebuilding a kernel compiler’s lowering rules by hand, per prompt. On KernelBench-style tasks, that rebuild is where most tokens go — not to the genuinely open scheduling decisions. There is a systems lesson buried here: a library whose abstractions do not fit is interpretively equivalent to no library. Where the interpretive frontier sits is set by abstraction quality, not by whether the knowledge exists somewhere — which is exactly why schedule languages matter: Halide-style decoupling made the transformations composable at the level where the choices are actually made.
Model parallelization. The right structure is known from the XLA world: GSPMD decouples plan declaration from implementation — annotate a handful of tensors with placements, and propagation plus SPMD partitioning implements the parallelism mechanically everywhere else. PyTorch eager has no settled equivalent; DTensor is a real step toward one, but not yet an abstraction an agent can reliably target. The consequence is that an agent asked to parallelize a model today does both jobs, every time: it invents the plan and hand-implements it — inserting collectives, rewriting modules, threading device meshes through the code. It re-derives the search and the compiler in the same session. With the missing layer in place, the plan becomes a small declaration — a hole, fillable by search in the style of Alpa, or stated as a schedule decoupled from the model definition in the style of Slapo — and the implementation becomes an engine invocation. Without it, the entire stack is residual.
Codebase migration. Ask an agent to move a repository from one API to another — a renamed tensor-library namespace, a deprecated logging interface, a new async runtime — and it will happily perform the same rewrite hundreds of times, call site by call site, paying tokens and a fresh chance of error at each one. Instance 3 and instance 400 get subtly different treatments, because each was a separate act of judgment. The mechanical alternative has existed for decades: syntax-aware rewrite engines — OpenRewrite, jscodeshift, ast-grep, clang-tidy — apply one transform uniformly across a million lines in seconds. The right division of labor is a sketch: the model supplies the mapping (what replaces what, and where the edges need judgment); the rewrite engine supplies the application. This is interpretive waste at its purest — the instance count is enormous, the per-site variance is near zero, and the oracle (the typechecker, the test suite) already exists. The precedent is fifteen years old: FlashFill (Gulwani, 2011) watched two example edits, synthesized the string-transformation program, and ran it down the whole column inside Excel — per-cell interpretation retired by a per-column artifact, at consumer scale.
The three examples share one moral. In each case the agent is rebuilding a compiler inline — its lowering rules, its search, or its rewrite rules — because the compiler is missing, unusable, or abandoned at an abstraction boundary. Interpretive waste concentrates exactly there. Every repeated chain-of-thought is a feature request for a compiler.
Context Windows Are Scratchpads, Not Capital
Whatever an agent derives in a session evaporates with the session. Memory systems help, but the state of the art stores text: episodic traces, semantic summaries, evolving playbooks of bullet-point lessons as in Agentic Context Engineering (Zhang et al., 2025). This is real progress, and it is also structurally limited: a playbook is advice for the next interpretation, not a replacement for it. The model still executes; the artifact only steers.
There is a second, subtler failure: with no canonical form of intent, there is no cache. “Optimize this GEMM for mma” and “make this matmul use tensor cores” do not hit the same stored anything. Prompt libraries deduplicate human effort; nothing yet deduplicates machine reasoning, because nothing canonicalizes what was asked.
A Missing Decision Procedure
Practice today distinguishes prompts, skills (natural-language procedures bundled with scripts), tools, and one-off generated scripts — and chooses among them by taste. The question should the model think about this step, or should a tool do it? is the load-bearing decision of agent engineering, and the field treats it as a matter of intuition. It has a formal name and a forty-year literature elsewhere: binding-time analysis. The rest of this post takes that seriously.
A Framework: Consolidation as Partial Evaluation
Definitions
- Interpretive execution: the model performs the task at each instance, paying tokens, latency, and error per instance.
- Compiled execution: a deterministic artifact performs it, at near-zero marginal cost.
- Elaboration: translating natural-language intent into a checkable specification. This is the model’s irreducible job.
- Consolidation: converting a recurring process into an artifact — the specialization step.
- Residual: what remains for runtime after specialization. The residual is where judgment genuinely lives; everything else was interpretive overhead.
This vocabulary also settles the question usually posed informally as internal knowledge versus external tools. Internal knowledge itself splits in two — parametric knowledge frozen in the weights, and knowledge re-derived at runtime as reasoning tokens (the expensive kind). External tools are the compiled column. The interpret/compile boundary is the internal/external boundary, binding-time analysis is its decision procedure, and — as the continual-learning discussion later argues — the boundary is not fixed: the two stores feed each other, and where it sits gets renegotiated every time either one improves.
Specialization Is Per Parameter, Not Per Task
Applying the first Futamura projection: consolidating a task family means partially evaluating the agent with respect to that family. The crucial detail is that partial evaluation operates per variable, not per program. Within one workflow, some arguments are static across instances and some are dynamic — so the right output of consolidation is rarely “a script” or “keep prompting.” It is a sketch (Solar-Lezama, 2008): a deterministic skeleton with typed holes, where the model — or a cheaper search procedure — fills only the holes. A schema-migration tool where the model supplies only the column mapping. A kernel template where an autotuner supplies only tile sizes. A refactoring engine where the model supplies only the target API.
This dissolves the binary question “does the agent need to reason about this process?” into a set of per-parameter annotations: this binds now, that stays open. Getting the annotations right is the whole game, which motivates the next subsection.
Binding-Time Analysis: When to Consolidate
Four factors govern whether a step should bind:
- Variance. If the conditional entropy of the correct action given the task family is near zero — the step is done the same way every time — it should bind. High-variance steps stay in the residual.
- Frequency. Expected instance count $N$ must amortize the fixed costs of synthesis, verification, and maintenance.
- Verifiability. An oracle — tests, properties, a reference implementation — must exist for trust to transfer to the artifact. No oracle, no full compilation (though partial hardening still helps; see the ladder below).
- Stakes. Determinism, reproducibility, or audit requirements can force compilation even at low $N$. A financial calculation run twice a year still should not depend on a sampler.
As a cost inequality, consolidate when
\[N \cdot \big[(c_{\text{int}} - c_{\text{exec}}) + \lambda\,(\epsilon_{\text{int}} - \epsilon_{\text{exec}})\big] \;>\; C_{\text{synth}} + C_{\text{verify}} + C_{\text{maint}}(N),\]where $c$ terms are per-instance costs, $\epsilon$ terms are error rates, and $\lambda$ prices the cost of an error. The folk version of this criterion is refactoring’s “rule of three.” The principled version is minimum description length: an abstraction is worth reifying when extracting it compresses the corpus of solution traces — precisely the criterion DreamCoder uses to decide which program fragments deserve promotion into its library (Ellis et al., 2021). And the mechanism for computing candidate abstractions from concrete traces has a name too: anti-unification, Plotkin’s least general generalization (Plotkin, 1970) — keep what is shared across instances, parameterize what varies. Candidate guards (preconditions) can be mined the same way, via dynamic invariant detection à la Daikon (Ernst et al., 2007).
The Hardness Ladder
Binding is not binary; artifacts occupy a spectrum of hardness, and consolidation is movement down a ladder:
Two readings of this ladder matter. First, skills — in the sense now shipping in agent products (Anthropic, 2025) — are level 2: a mid-level IR of cognition, a compilation in progress, not a destination. A skill that has stabilized should be shedding steps downward: each sub-step that proves invariant across uses becomes a call into level-4 code, until the skill is a thin residual of genuine judgment wrapped around deterministic machinery. Second, domains without oracles — taste, strategy, open-ended research judgment — legitimately stop mid-ladder. Evolving playbooks (the ACE regime) are the right endpoint there. The framework is the ladder, not the bottom level.
The hardware analogs are more than decoration. The industry already accepts this spectrum in silicon — general-purpose cores for the unpredictable, FPGAs for the reconfigurable-but-stable, ASICs for the frozen — and accepts that moving a workload along that spectrum is how cost per operation collapses. Compiled cognition is the same argument one level up: synthesize the software the way we already synthesize the circuit, exactly when nothing varies anymore.
Speculative Consolidation: Guards and Deoptimization
The flexibility-versus-consolidation tradeoff, as usually posed, is a false choice, and the JIT literature shows why. Every compiled artifact ships with a guard: a cheap, checkable precondition describing the region it was specialized for — input shapes, schema versions, architecture flags, distributional assumptions. Guard passes: take the fast path, spend zero forward passes. Guard fails: deoptimize — fall back to the interpreter (the model), handle the instance interpretively, and log the miss as evidence for the next recompilation.
This one mechanism absorbs most of the standard objections. Distribution drift? Guard misses rise, triggering re-mining. Premature abstraction? A wrong abstraction has a shrinking guard region and gets evicted like a cold cache line. Model improvements? Artifacts are caches keyed by (spec, model version): a model upgrade invalidates the implementation, but the spec and its tests persist, so regeneration is cheap — sample a new implementation, re-verify, re-register. I expect “recompilation storms” after major model releases to become a routine CI event, and artifact regeneration to become a standard pipeline stage.
The Toolmaker: The Second Projection
Hand-building individual tools misses the point. The second Futamura projection says the leverage is in building the specializer — the system that turns recurring agent behavior into artifacts. Concretely, a toolmaker loop:
- Trace mining. Continuously cluster trajectories across sessions; detect recurring subprograms via anti-unification and frequent-substructure mining.
- Abstraction selection. Score candidates by corpus compression (MDL), penalized by interface complexity — a short abstraction with an ugly signature is not a good abstraction.
- Synthesis. Sample implementations from the model against the mined specification, sketch-first: deterministic skeleton, typed holes.
- Verification. Property tests, differential testing against the interpretive behavior the artifact replaces, proofs where the domain permits. Trust attaches here, not at generation.
- Registration. Package artifact + spec + guards + tests + effect declarations + provenance; publish to the library.
- Sleep. Run 1–5 offline, in batch, over accumulated trajectories — the direct analog of consolidation during sleep replay. DreamCoder’s wake–sleep cycle is the existing template; Voyager’s ever-growing library of verified skills (Wang et al., 2023) is the existing agent-world demonstration; LATM (Cai et al., 2023), TroVE (Wang et al., 2024), and ReGAL (Stengel-Eskin et al., 2024) are LLM-era variants of steps 2–4.
Why is it safe to compile with a stochastic generator in the loop? Because of verification asymmetry: checking is vastly cheaper than generating. We do not need to determinize the model; we need to determinize the artifact. The compiler-correctness literature offers exactly the right split. Proving the generator correct once and for all — the CompCert route (Leroy, 2009) — is unattainable for an LLM. But translation validation (Pnueli, Siegel & Singerman, 1998) — checking each individual output against its specification — is practical and composes with sampling: sample until the checker passes, and the artifact’s trustworthiness derives from the checker, not from the sampler. The blacksmith’s hands may tremble; the jig does not.
It is worth situating this against the harness self-improvement line — ADAS, AFlow, Meta-Harness, Self-Harness (see Weng, 2026 for the survey). Those systems evolve the orchestration code: how the model is prompted, sequenced, and evaluated. The toolmaker consolidates task competence: what no longer needs the model at all. The axes are complementary — one optimizes each invocation, the other reduces the count — and I suspect the second compounds harder, because its wins are permanent and additive. One lesson does transfer directly from that literature: the observability discipline of AHE-style systems (every edit evidence-backed, falsifiable, attributable) is exactly the discipline consolidation needs. Every promoted artifact should be an evidence-backed, falsifiable claim that a piece of reasoning is now closed.
The Missing Layer: A Spec-IR
Everything above quietly assumes something that mostly does not exist: a representation that natural-language intent can be elaborated into and that deterministic toolchains can compile from. I think this is the bottleneck of the whole program — more than synthesis quality, more than verification technique — and it deserves the most careful treatment. It is also the part I am least certain about; read this section as a design brief, not a survey.
Why Natural Language Cannot Be the Source Code
Dijkstra argued in EWD667 that natural-language programming is foolish because precision is the entire point of programming notation. He was right about execution and wrong about interfaces. Ambiguity is a feature for intent capture — it is how humans state goals cheaply, deferring detail — and it is fatal for execution. The resolution is a division of labor, not a winner. The model’s enduring, irreducible job is elaboration: resolving ambiguity, importing context the user did not state, asking the clarifying question, and emitting a spec. Below the spec, everything should be deterministic or verifier-gated. Natural language is the new requirements document, not the new source code.
Why Now: LLMs Collapse the Cost of Specification
Formal specification did not fail on soundness; it failed on adoption economics. CYC, the semantic web, executable UML — each assumed humans would author formal content, and authoring the spec cost more than writing the implementation, so nobody did. The bottleneck was always the author. Elaboration is precisely what LLMs are good at: the human states intent in a sentence and audits a generated spec instead of writing one, and schema-constrained decoding makes the generated spec syntactically valid by construction. This reopens a design space that has been effectively dead since the 1990s, which is exactly why I expect the next structural progress here rather than in synthesis or verification, where the machinery already broadly works.
Requirements
What must a spec-IR be? Eight properties, each earning its place:
- Meet-in-the-middle. Simultaneously a reliable generation target for the model (schemas, grammars, constrained decoding) and a genuine compiler front-end with defined semantics. Most formats today satisfy one side only.
- Checkable. Types, contracts, and well-formedness verifiers at minimum. The spec is the trust boundary of the whole system: stochastic above, deterministic below. Everything that crosses it gets checked.
- Gradual, with first-class holes. Real intent is partial. Each hole carries a type, a binding-time annotation, and a resolution policy — ask-the-user, model-fill, search/autotune, or fail-loud. This is a two-level language generalized to many stages; the binding-time analysis of the framework section becomes annotations in the IR itself.
- Canonicalizing. Many phrasings, one spec. The spec is the cache key of cognition: canonicalization is what turns a library from a pile of scripts into a hit rate. Spec-level equivalence checking (e-graph techniques; Willsey et al., 2021) enables deduplication across teams that never talked to each other.
- Compositional. Spec fragments must compose, and composed specs must mean what their parts mean. This is the ABI of intent — the property that lets independently consolidated artifacts interoperate, the way calling conventions once let independently compiled objects link.
- Effect- and capability-aware. The spec declares what the artifact may touch: filesystem globs, network endpoints, budget. Sandboxes enforce the declaration; the entire supply-chain story hangs on this field existing.
- Legible and diffable. Humans audit the contract, not the implementation. Text-based, versionable, with provenance links from every spec node back to the natural-language intent and the trace evidence that motivated it. Auditing specs is the new code review.
- Bidirectional. Lowering (spec → artifact) and lifting (traces, existing code → spec). Lifting is what makes the toolmaker’s mining well-defined: anti-unification should operate at the spec level, not the token level, or the abstractions it finds will be syntactic accidents.
Fragments That Already Exist
The layer is emerging piecemeal, which is itself informative:
| System | What it demonstrates |
|---|---|
| SQL (Codd, 1970) | The granddaddy: declarative intent + deterministic planner. Text-to-SQL is the most mature NL → spec → engine pipeline in production anywhere. |
| Tool schemas + MCP | Typed calls as micro-specs; MCP standardizes the calling convention (though not the trust layer). |
| Halide / TVM / Exo / Allo schedules | Algorithm–schedule decoupling: a working spec-IR for performance engineering, and the model case for this entire post. |
| Terraform / Kubernetes manifests | Desired-state specs consumed by deterministic reconciliation engines; agents already emit these. |
| DSPy signatures | Declarative I/O specs with the “how” compiled by an optimizer — spec-IR thinking applied to prompting itself. |
| Sketch (Solar-Lezama, 2008) | Partial programs with holes: the hole-filling contract, verified. |
| Property-based tests, refinement types, Dafny, Lean | The evidence spectrum, from cheap-and-partial to total-and-expensive. |
| Daikon | Lifting: mining likely invariants — candidate guards — from concrete executions. |
Notice what is absent: nothing on this list spans domains, and nothing carries holes, effects, evidence, and provenance in one envelope. Each fragment solved its own vertical.
The MLIR Lesson: Dialects, Not a Universal Language
The tempting mistake is to design The Universal Specification Language. Universal spec languages fail — UML and the semantic web are the cautionary tales — because expressiveness for everyone means semantics for no one. MLIR (Lattner et al., 2020) succeeded in compiler infrastructure with the opposite bet: shared machinery (types, verification hooks, progressive lowering, provenance) hosting many small dialects, each with crisp local semantics, lowered step by step with a verifier at every boundary.
The spec-IR layer should be a meta-layer of exactly this shape: common infrastructure for holes, effects, evidence, and provenance; domain dialects for kernel schedules, sharding plans, data pipelines, infrastructure state, schema migrations, UI flows. “Layer-by-layer lowering with a check at each layer” is the MLIR discipline applied above source code rather than below it. And dialect-by-dialect emergence matches how the fragments table already looks — the design should ratify the pattern, not fight it.
The Ratchet
Once a dialect has a compiler, the model permanently stops reasoning below that line in that domain. Its tokens migrate up-stack: to elaboration, and to genuinely novel composition no existing artifact covers. This is measurable — track the distribution of tokens over stack levels; in a maturing system it should climb — and it is a one-way ratchet, because a verified artifact does not un-exist when attention moves on. The interpretive frontier shrinks toward true novelty, which is exactly where forward passes belong.
Evolving the Stack
The framework so far describes a steady state. Three questions remain about dynamics, and they were among the questions that motivated this post: how does a new optimization enter the stack in a form later users inherit; what exactly happens at a deoptimization; and how does any of this relate to continual learning.
The Life of an Optimization
Trace one contribution end to end. Suppose an engineer — or an agent — working on a new accelerator discovers a pipelining pattern that beats the library: some overlap of memory movement and compute that no existing dialect primitive expresses.
Stage 0 — novelty. The first instances are solved interpretively: model reasoning, human steering, raw CUDA. This is where new knowledge is born, and it is the one place interpretation is irreplaceable — the interpreter is the R&D lab. Trajectories are logged.
Stage 1 — recurrence. The pattern recurs: the same engineer next week, a teammate next month. The toolmaker’s mining detects the shared subderivation — anti-unification over spec-level traces — and the MDL criterion confirms that extracting it compresses the corpus.
Stage 2 — lifting. The pattern is lifted into the schedule dialect as a contribution: a new primitive, a new rewrite rule, or a new hole-resolution strategy, with its parameters exposed as typed holes. This step is what makes the knowledge reusable by construction: the contribution lands in a dialect, so everything downstream of the dialect — every agent, every autotuner, every artifact that later recompiles — can now reach it. A contribution is a triple: spec delta, implementation, evidence.
Stage 3 — verification and registration. Differential tests against the interpretive behavior it replaces; properties discharged; effects declared; the capsule signed and published with provenance back to the traces that motivated it.
Stage 4 — distribution. Other organizations pull it from the registry the way they pull a package today, and their agents’ interpretive frontier retreats over territory their own engineers never explored. This is the direct answer to “reusable for later people”: the unit of sharing is a verified, spec-level contribution — not a prompt, not a blog post, not a fine-tune. Notice that the field currently has exactly one diffusion channel for this kind of knowledge, and it is slow and cultural: papers and blog posts, into training corpora, into the next model’s weights — lossy, unverified, with latency measured in months. A registry of evidence-carrying dialect contributions is a second channel: exact, verified, latency measured in minutes. Both should exist; today only the slow one does.
Stage 5 — evolution. Guard-miss telemetry and regressions drive updates; semantic versioning governs compatibility; model and hardware changes trigger recompilation. Retirement is honest: a primitive superseded on new architectures keeps its guard region shrinking until eviction.
Nothing in this lifecycle requires the contributor to be human. But notice where humans naturally sit — stages 0 and 2, supplying novelty and judging which abstractions deserve to exist. That is “humans move up the stack” made concrete.
What Deoptimization Looks Like
Deoptimization has been invoked as a slogan; here is the mechanism. A guard is a cheap predicate over the instance — shapes, dtypes, target architecture, schema version, a distributional check — evaluated before the fast path takes any side effect (which is why fast paths want to be pure, or to keep their effects transactional). On a miss, four things happen in order:
- Abort cleanly. The fast path never ran, or its effects roll back. A guard miss must be boring.
- Fall back with context. Control passes to the interpreter — but not with the original natural-language request. The model receives the artifact’s spec, the identity of the failed guard, and the instance. That package is a far better prompt than starting over: the spec states everything already known to be true about the task, and the failed guard states exactly what is new. Deoptimization is not amnesia; it is the system saying here is the boundary of what we knew — proceed from there. (The analog of on-stack replacement exists too: where a dialect defines typed intermediate states, an artifact can hand over mid-task at a checkpoint instead of aborting.)
- Log the counterexample. The interpretive resolution is recorded as a labeled miss: spec, miss reason, resolution trace.
- Feed the miner. Accumulated misses with shared structure trigger Stage 1 of the lifecycle above, and the toolmaker chooses among three responses: widen the guard (the artifact generalizes; re-verify on the enlarged region), fork a sibling artifact specialized for the new region, or promote a new dialect primitive when the misses reveal a concept the dialect cannot yet express.
The design consequence deserves plain statement: guard misses are the gradient. They are the system’s only unforgeable signal about where its consolidated knowledge ends, and routing them into mining is precisely how newly learned knowledge gets consolidated. The miss stream is the curriculum.
The Relationship to Continual Learning
Continual learning, as usually construed, means the weights improve with experience. Compiled cognition is the externalized branch of the same ambition, and together they form a dual-store memory system with an old precedent: complementary learning systems (McClelland, McNaughton & O’Reilly, 1995) — a fast, exact, instance-specific store cooperating with a slow, statistical, generalizing one. Here the library is the fast store — writable in minutes, exact, auditable, monotonic — and the weights are the slow store — updated on training timescales, tacit, generalizing. (Note the substrate inversion once more: in the brain the fast store is neural; here the fast store is symbolic.)
The two stores feed each other in both directions:
- Artifacts → weights. The library is training data. Specs, implementations, and evidence flow into the next pretraining or distillation run, and patterns the field consolidated externally become internal knowledge — which improves elaboration, the one job that never leaves the model. External consolidation is how the internal store should be curated: cache first, distill later.
- Weights → artifacts. A better model recompiles the library: tighter implementations, wider guards, whole dialects newly within reach. Model releases become recompilation events, and the library converts each model improvement into permanent, inspectable capital rather than transient capability.
- The residual co-evolves. As weights improve, holes migrate from
resolve: autotunetoward cheapresolve: model-fill; as the library grows, the weights are relieved of procedural memorization and capacity flows toward judgment. The internal/external division of labor is not fixed — it is renegotiated at every consolidation and every training run, and binding-time analysis is the negotiator.
Against weight-space continual learning alone — the test-time-training and self-improvement lines — the external store has three properties that matter operationally: updates are attributable (every change carries provenance and evidence), revertible (roll back a package, not a checkpoint), and monotonic (a new artifact cannot degrade an old one that still guards true). Weight updates have none of these; they buy generalization at the price of auditability. The sensible architecture uses both — and uses the auditable one first.
Economics and Metrics
Tokens are labor; artifacts are capital; consolidation is capital formation — what Böhm-Bawerk called roundabout production, spending effort on tools that make all future production cheaper. The textile analogy people reach for is apt twice over: the Jacquard loom did not merely mechanize weaving, its punch cards made the process programmable — the historical bridge from craft to software, and the direct inspiration for Babbage. Against that standard, today’s agent practice is pre-industrial piecework: every shop re-derives the spinning jenny nightly and calls it reasoning.
The standard objection — inference is getting cheaper, so why bother — fails three separate ways. First, Jevons: cheaper interpretation raises volume, so aggregate waste scales with adoption rather than shrinking. Second, latency, energy, and reproducibility do not fall with the price of tokens; a compiled path is microseconds and bit-identical at any token price. Third, determinism and auditability are qualitative properties that no price decline supplies — a cheaper sampler is still a sampler.
What to measure:
- Amortization ratio: the fraction of task steps served by compiled artifacts rather than forward passes. I would nominate this as the north-star systems metric for agent maturity.
- Marginal cost at instance N: tokens and failures on the N-th instance of a task family. Prediction, in the spirit of Wright’s law (Wright, 1936): for mature systems this falls as a power law in cumulative instances — driven by consolidation, not by model improvement — so within-family learning curves should appear even under a frozen model.
- A benchmark gap: current benchmarks measure first-contact capability — instance-1 cost. KernelBench’s
fast_pmeasures artifact quality; nothing yet measures whether the system stopped paying for that quality. Score systems at instance 100 of a family: same distribution, does it still think?
One aside on the bitter lesson (Sutton, 2019), since it is the reflexive objection to anything resembling engineered structure. Compiled cognition is not a return to hand-engineered knowledge: the structure is machine-built, disposable, and regenerated whenever the model improves. Artifacts are how compute gets deployed, not a substitute for learning — AlphaZero kept MCTS, and AlphaEvolve is compute searching over code precisely because code is the medium in which discoveries persist.
Future Challenges
1. Automatic binding-time analysis over natural-language processes. Learning per-parameter static/dynamic annotations from traces is essentially unstudied; today a human eyeballs it. This is the field’s version of BTA, and it is wide open.
2. Dialect design and governance. Who defines the sharding-plan dialect, and who evolves it? Specs are the ABI of intent, and ABIs need stewards. My expectation is piecemeal per-domain emergence (kernel schedules are already real; infrastructure and data engineering next), with standardization pressure arriving late and painfully, as it did for calling conventions.
3. Guard synthesis and deoptimization safety. A false-passing guard is a silently wrong answer — the worst failure mode this architecture can produce, strictly worse than interpretive error because it carries the authority of a verified artifact. Invariant mining yields candidate guards; certified guard inference, and principled coverage accounting for the guarded region, are open problems.
4. Abstraction quality beyond compression. MDL favors short. Libraries also need composable, maintainable, and evolvable, and those properties are not compression. DreamCoder-style objectives are necessary, not sufficient; nobody has a loss function for “good API.”
5. Trust and the supply chain. A poisoned artifact is worse than a poisoned prompt: it is trusted, deterministic, and silent. Cross-organization sharing — where the real economies live — requires evidence-carrying packages (spec + tests + effects + provenance, signed) and registry policy. MCP standardizes the socket; nothing yet standardizes the evidence.
6. The weights-versus-artifacts boundary. Consolidation has two destinations: parametric (distillation, fine-tuning) and external (artifacts). A working split: tacit, perceptual, and stylistic knowledge wants weights; checkable input–output processes want artifacts, which are inspectable, composable, shareable, and survive model swaps as re-verifiable caches. The continual-learning section above argues for cache-first, distill-later as the default policy; where exactly the boundary sits, and how it moves as both stores improve, remains open.
7. Recompilation policy. When to invalidate: model upgrades, drift signals, rising guard-miss rates. The economics of regeneration — artifact CI, staged rollouts of recompiled libraries, provenance-aware bisection when a recompile regresses — is unexplored territory that will feel very familiar to anyone who has operated a build system.
8. The unconsolidatable. Taste, strategy, and research judgment lack oracles, and consolidation legitimately stops mid-ladder there — playbooks and evolving context, the ACE regime, are the honest endpoint. Mapping where the ladder ends, per domain, is an empirical program in itself. The human role moves with the model’s: up the stack. Auditing specs is the new code review, and deciding what deserves to become permanent is the judgment that remains after everything mechanical has been compiled away.
A mature agent system, on this view, is a compiler under construction, and its maturity is measured by the fraction of recurring work that no longer requires a forward pass. Whitehead’s dictum was about civilizations, but it compiles cleanly to this setting: extend the number of important operations performed without thinking about them. Spend inference only on novelty.
Citation
Please cite this work as:
Hongzheng Chen. “Compiled Cognition: When Agents Should Stop Thinking”. chhzh123.github.io (Jul 2026). https://chhzh123.github.io/blogs/2026-07-26-compiled-cognition/
Or use the BibTeX citation:
@article{chen2026compiledcognition,
title = {Compiled Cognition: When Agents Should Stop Thinking},
author = {Chen, Hongzheng},
journal = {chhzh123.github.io},
year = {2026},
month = {July},
url = {https://chhzh123.github.io/blogs/2026-07-26-compiled-cognition/}
}
References
[1] Whitehead, A. N. An Introduction to Mathematics. Williams & Norgate, 1911.
[2] Futamura, Y. “Partial Evaluation of Computation Process — An Approach to a Compiler-Compiler.” Systems, Computers, Controls 2(5), 1971.
[3] Jones, N. D., Gomard, C. K., and Sestoft, P. Partial Evaluation and Automatic Program Generation. Prentice Hall, 1993.
[4] Nielson, F. and Nielson, H. R. Two-Level Functional Languages. Cambridge University Press, 1992.
[5] Anderson, J. R. The Architecture of Cognition. Harvard University Press, 1983.
[6] Laird, J. E., Rosenbloom, P. S., and Newell, A. “Chunking in Soar: The Anatomy of a General Learning Mechanism.” Machine Learning 1(1), 1986.
[7] Mitchell, T. M., Keller, R. M., and Kedar-Cabelli, S. T. “Explanation-Based Generalization: A Unifying View.” Machine Learning 1(1), 1986.
[8] Cattell, R. B. “Theory of Fluid and Crystallized Intelligence: A Critical Experiment.” Journal of Educational Psychology 54(1), 1963.
[9] Clark, A. and Chalmers, D. “The Extended Mind.” Analysis 58(1), 1998.
[10] Plotkin, G. D. “A Note on Inductive Generalization.” Machine Intelligence 5, 1970.
[11] Ellis, K., et al. “DreamCoder: Bootstrapping Inductive Program Synthesis with Wake-Sleep Library Learning.” PLDI 2021.
[12] Wang, G., et al. “Voyager: An Open-Ended Embodied Agent with Large Language Models.” arXiv:2305.16291, 2023.
[13] Cai, T., et al. “Large Language Models as Tool Makers.” arXiv:2305.17126, 2023.
[14] Wang, Z., et al. “TroVE: Inducing Verifiable and Efficient Toolboxes for Solving Programmatic Tasks.” ICML 2024.
[15] Stengel-Eskin, E., et al. “ReGAL: Refactoring Programs to Discover Generalizable Abstractions.” ICML 2024.
[16] Schick, T., et al. “Toolformer: Language Models Can Teach Themselves to Use Tools.” NeurIPS 2023.
[17] Solar-Lezama, A. Program Synthesis by Sketching. PhD thesis, UC Berkeley, 2008.
[18] Gulwani, S. “Automating String Processing in Spreadsheets Using Input-Output Examples.” POPL 2011.
[19] Ernst, M. D., et al. “The Daikon System for Dynamic Detection of Likely Invariants.” Science of Computer Programming 69(1–3), 2007.
[20] Pnueli, A., Siegel, M., and Singerman, E. “Translation Validation.” TACAS 1998.
[21] Leroy, X. “Formal Verification of a Realistic Compiler.” Communications of the ACM 52(7), 2009.
[22] Ragan-Kelley, J., et al. “Halide: A Language and Compiler for Optimizing Parallelism, Locality, and Recomputation in Image Processing Pipelines.” PLDI 2013.
[23] Chen, T., et al. “TVM: An Automated End-to-End Optimizing Compiler for Deep Learning.” OSDI 2018.
[24] Ikarashi, Y., et al. “Exocompilation for Productive Programming of Hardware Accelerators.” PLDI 2022.
[25] Chen, H., Zhang, N., Xiang, S., Zeng, Z., Dai, M., and Zhang, Z. “Allo: A Programming Model for Composable Accelerator Design.” Proc. ACM Program. Lang. 8(PLDI), Article 171, June 2024.
[26] Lattner, C., et al. “MLIR: Scaling Compiler Infrastructure for Domain Specific Computation.” CGO 2021.
[27] Willsey, M., et al. “egg: Fast and Extensible Equality Saturation.” POPL 2021.
[28] Codd, E. F. “A Relational Model of Data for Large Shared Data Banks.” Communications of the ACM 13(6), 1970.
[29] Khattab, O., et al. “DSPy: Compiling Declarative Language Model Calls into Self-Improving Pipelines.” arXiv:2310.03714, 2023.
[30] Zhang, Q., et al. “Agentic Context Engineering: Evolving Contexts for Self-Improving Language Models.” ICLR 2026.
[31] Ouyang, A., et al. “KernelBench: Can LLMs Write Efficient GPU Kernels?” arXiv:2502.10517, 2025.
[32] Novikov, A., et al. “AlphaEvolve: A Coding Agent for Scientific and Algorithmic Discovery.” arXiv:2506.13131, 2025.
[33] Weng, L. “Harness Engineering for Self-Improvement.” Lil’Log, July 2026.
[34] Dijkstra, E. W. “On the Foolishness of ‘Natural Language Programming’.” EWD667, 1978.
[35] Sutton, R. “The Bitter Lesson.” 2019.
[36] Wright, T. P. “Factors Affecting the Cost of Airplanes.” Journal of the Aeronautical Sciences 3(4), 1936.
[37] Anthropic. “Introducing Agent Skills.” 2025.
[38] Xu, Y., et al. “GSPMD: General and Scalable Parallelization for ML Computation Graphs.” arXiv:2105.04663, 2021.
[39] Zheng, L., et al. “Alpa: Automating Inter- and Intra-Operator Parallelism for Distributed Deep Learning.” OSDI 2022.
[40] Chen, H., Yu, C. H., Zheng, S., Zhang, Z., Zhang, Z., and Wang, Y. “Slapo: A Schedule Language for Progressive Optimization of Large Deep Learning Model Training.” ASPLOS 2024.
[41] McClelland, J. L., McNaughton, B. L., and O’Reilly, R. C. “Why There Are Complementary Learning Systems in the Hippocampus and Neocortex: Insights from the Successes and Failures of Connectionist Models of Learning and Memory.” Psychological Review 102(3), 1995.
[42] Würthinger, T., et al. “Practical Partial Evaluation for High-Performance Dynamic Language Runtimes.” PLDI 2017.
[43] Bolz, C. F., Cuni, A., Fijalkowski, M., and Rigo, A. “Tracing the Meta-Level: PyPy’s Tracing JIT Compiler.” ICOOOLPS 2009.
-

A fragment of the reasoning summary from prompting Fable 5 to write a Kimi Delta Attention kernel in pure CUDA. The derivation runs through many steps — numerical stabilization, memory layout, tiling, shared-memory orchestration, validation — and each step corresponds, almost one for one, to a known compiler pass or optimization. ↩
-
Megatron-LM (Shoeybi et al., 2019) is the canonical example: tensor- and pipeline-parallel sharding of transformer training implemented once as library machinery — the collectives, the module rewrites, the device meshes — so that applying it to a new model is a configuration choice, not a per-session derivation. ↩