Self-Crystallizing Systems

2026-05-17

Self-Crystallizing Systems: LLMs as Pattern Extractors, Not Runtime Dependencies

Build with the LLM. Don’t put the LLM in the thing. Related: Deterministic Layer Cakes, Path-Dependent Memory.

The Core Distinction

There are two ways to use an LLM in a product:

  1. Use an LLM to build the thing — one-time cost, deterministic output, runs for free at scale
  2. Put an LLM in the thing — ongoing cost per interaction, non-deterministic, subsidised today, repriced tomorrow

Most of what ships as “AI-powered” is option 2 applied to problems that need option 1. Input classification that should be a lookup table. Template selection that should be a rule engine. Data extraction that should be a parser. FAQ responses that should be a search index.

This isn’t innovation. It’s outsourcing thinking to an API because building a rule engine requires understanding the domain. The demo ships in an afternoon, works 85% of the time, and locks you into per-token pricing forever for something that should have been a config file.

The sane architecture: a system that starts with the LLM in the hot path and progressively removes it — crystallising patterns into deterministic code until the LLM only handles what’s genuinely novel.

Architecture: Failure Is the Router

You don’t need a “confidence-scoring router layer.” The code’s own failure paths are the router.

try the deterministic thing
  ↓ worked? → done, cheap, fast
  ↓ didn't work? → fallback to LLM, log WHY it fell through

The catch, the else, the regex non-match, the lookup miss — these aren’t errors. They’re discovery signals. The system telling you “here’s a shape I don’t have a rule for yet.”

Every deterministic handler naturally has escape hatches:

  • Regex didn’t match → unknown pattern
  • Try/catch fired → unexpected structure
  • Final else in a case statement → unrecognised category
  • Lookup returned empty → new entity

These escapes route to the LLM. The LLM handles it, the result gets logged. No special routing logic needed — the code structure is the router.

The Feedback Loop

The controller watches the fallback log:

"fell through at: input_classifier, reason: no match" — seen 3 times
"fell through at: input_classifier, reason: no match" — seen 47 times
"fell through at: input_classifier, reason: no match" — seen 200 times

threshold hit

ask LLM: "here are 200 inputs that fell through at this point,
          and here's what you answered each time.
          write me the code that handles them."

validate against historical pairs → promote → deterministic path extended

The system grows at its failure points. Each promoted handler has its own try/catch/else, which accumulates its own fallbacks, which eventually crystallise into the next extension. The tree grows at its leaves.

Signal Processing, Not AI

Strip away the language and what you have is:

noise → filter → signal → pattern detect → codify → filter gets better

The fallback bucket is unprocessed signal — stuff that hasn’t found a home yet. The pattern detection threshold is: “enough similar shapes in the fallback bucket that it’s worth building a filter for them.”

This is what DSP has done forever. Matched filters, adaptive thresholds, training sequences. The LLM’s role is: the thing that can look at a cluster of unstructured signals and write the matched filter for them. It’s the engineer, not the system.

The actual runtime:

ComponentRoleCost
Filter bankDeterministic handlers, fast pathNegligible
Unmatched bufferAccumulating fallbacks, monitoredStorage only
Threshold trigger”Enough similar failures” detectorStatistical, simple
Filter generatorLLM, invoked rarely, offline/batchPer-token, but infrequent

The LLM is barely in the runtime picture. It’s a batch job that fires when the unmatched buffer says “I’ve got something for you.” This is not an AI product. It’s a signal processing system with an automated engineer on retainer.

Bootstrapping: Fast-Track from Historical Data

You don’t have to start cold. If you have historical flows, decisions, outcomes — the crystallisation can be pre-seeded before the system goes live.

1. Dump historical data

Past decisions, inputs, outputs, corrections, things that were ignored.

2. LLM-assisted triage (one-time batch cost)

  • “Classify these into groups by shape”
  • “Which of these led to the same outcome regardless of input variation?”
  • “Which of these are noise — no signal, no action needed?”

3. Signal vs noise separation

If 60% of historical inputs were noise that led to “discard/no action” — that’s your first rule. Don’t even route to the LLM. Pattern: looks like X → discard. Massive cost savings from day one.

4. Decision tree extraction

For signal clusters: “Given these 200 examples that all resulted in outcome Y, what’s the minimum decision logic?” The LLM drafts a tree. You validate against the historical pairs.

5. Stability scoring

Historical data reveals:

  • Stable patterns (same input shape → same output for months) → crystallise immediately
  • Volatile patterns (same input shape → different outputs over time) → keep on LLM path
  • Rare patterns (seen 3 times ever) → insufficient data, LLM path

6. Edge case catalog

Historical corrections, escalations, exceptions → don’t crystallise. Tag as “LLM territory” with few-shot examples ready.

Boot sequence result:

Historical data

LLM batch analysis (one-time cost)

├── Noise filters       → discard rules, live immediately
├── Stable patterns     → deterministic handlers, live with monitoring
├── Volatile patterns   → LLM path, observe for stabilisation
└── Known edges         → LLM path, few-shot primed

System goes live with 60-70% already crystallised

Organic discovery handles the rest

Model Independence

Crystallised code doesn’t care who wrote it. It’s just code. So you can:

  • Run a newer model against the same fallback data → see if it generates better rules
  • A/B test rule generation across models
  • Periodically re-challenge existing rules: “here’s what this does — is there a better way?”

No model lock-in. The rules are the artifact, not the model. This aligns with Path-Dependent Memory’s position: persist deliverables, not opinions. A crystallised rule is testable against concrete input/output pairs — it either handles the case correctly or it doesn’t, regardless of which model generated it.

The one caveat: if you swap models and the new model draws the fallback boundary differently (what counts as “matched” vs “fell through”), you get novel inputs matching stale rules. Mitigation: continuous validation of promoted rules against live traffic. Drift detection demotes rules that stop working.

Economics

The subsidy problem: most “AI features” are priced below cost to capture market share. When real pricing hits, every product with an LLM in the hot path either eats the margin or passes it on. The cost cascades down to the consumer — an invisible tax embedded in the infrastructure layer.

A self-crystallising system inverts this:

  • Day 1: Expensive (LLM handling most traffic)
  • Week 2: Cheaper (common patterns crystallised)
  • Month 3: Mostly free (LLM handles <10% of traffic — the genuinely novel stuff)

Cost trends down over time instead of scaling linearly with usage. The LLM earns its keep only on the frontier. Everything behind the frontier is solved and runs for negligible cost.

The labs won’t sell you this. Their business model is the meter running. A system designed to need itself less over time is antithetical to per-token pricing. You’d have to build it yourself.

Relationship to Product Development

The pattern mirrors how you should build any product:

  1. Manual first — do everything by hand, learn what the real patterns are
  2. Automate the main bits — the 80% that repeats, codified
  3. Manual for edges — handle exceptions, think about pivoting
  4. Repeat — new edges become common, crystallise, new edges emerge

The self-crystallising system is this loop automated. The LLM plays the role of “the founder doing things manually at first” — handling everything, observing what repeats, then writing the automation that replaces itself.

What This Is Not

  • Not “AI that learns” — no weights change, no fine-tuning, no online learning
  • Not “self-improving AI” — it’s self-replacing with deterministic code
  • Not magic — it’s error handling with a feedback loop and a code generator
  • Not expensive to run — the expensive part is the occasional batch generation; runtime is filter-bank cheap

The Honest Description

A signal processing system where:

  • Known patterns are handled by deterministic filters (free, fast, testable)
  • Unknown patterns fall through to an LLM (expensive, slow, but handles anything)
  • The boundary between known and unknown shifts over time as patterns are discovered
  • Discovery is driven by the system’s own failure signals
  • A code generator (LLM, offline) writes new filters when enough signal accumulates

The LLM’s role: automated engineer on retainer, not runtime dependency. Called rarely, for batch work, to extend the system. Not sitting in the hot path burning tokens on things that should be an if statement.


For why accumulated LLM-authored memory doesn’t transfer across model versions (but crystallised code does), see Path-Dependent Memory.

For the argument that nodes are unreliable and trust belongs in the plumbing, see Deterministic Layer Cakes.