Note to the editor: this article deliberately stays at the engineering level. I have a thesis about what self-improving agents say about machine intelligence as a category, but it doesn't belong in a production-engineering piece. That's a separate essay for a different venue.
The fourth time my coding agent failed the same way in one week, I finally learned something about the limits of context windows.
I'd been running a small local model in place of a frontier coding assistant on lower-stakes work. Qwen3-coder, 30 billion parameters, sitting on a single accelerator at the edge of my home office. The agent was good at the obvious things and bad at the non-obvious ones. The bad ones weren't random. They were a small, fixed set of failure modes. It would confuse a grep line count for a line number. It would try to "review" a stub file that held no logic. It would cite line numbers that didn't exist in the source. Any one of those failures was trivially recoverable on its own. The pattern wasn't.
Your first instinct here is to fine-tune. Pull the failed transcripts, hand-label them, ship them to a training run, swap in the new weights. That's the playbook the field reaches for by default.
In production it's the wrong playbook, for three reasons. Fine-tuning is expensive and it's slow. The deeper problem is that it's opaque. After a training run you can't point at a specific weight delta and say "this is why the agent stopped citing line 17 as the line number when 17 was a count." The behavior change is real. The audit trail isn't.
So I built something different, and I now think it's the right pattern for a real class of self-correcting agent systems. I call the thing a failure-driven memory loop. Structured evidence of a failure becomes a structured rule that constrains future behavior, with no parameter updates and full audit at every step.
The pattern is general enough to be worth describing.
The four pieces
The loop has four components. Each one has a precise job.
1. A critic, run after every session.
After the agent finishes a task, a separate model (not the one that did the work) scores the output against the evidence the working model actually saw. The critic gets the task, the agent's self-summary, and a verbatim transcript of every successful tool call: the bash output, the file contents, the grep results. It returns a score on a 0-10 scale and a one-sentence verdict.
The design choice that matters is that the critic doesn't just look at the output. It looks at the output against the evidence. A review that says "Line 26 is wrong, move imports to top" is checkable. Did the source actually have something at line 26 that justified that claim? When the answer is no, the score drops, even if the review reads plausibly.
Critic failure rates give you an empirical measure of agent quality that needs no human labeling. That alone pays for the implementation cost.
2. A post-mortem generator, fired by low scores.
When the critic flags a session as a failure, a second model writes a concrete mitigation rule. "Be more careful" is useless, so that's banned. The post-mortem has to produce a JSON object with four fields. A one-sentence rule. A one-sentence "why" grounded in specific evidence from the failing session. A one-sentence "how to apply" that says when future sessions should check the rule. And a one-sentence trigger intent describing the task class where the rule should fire.
The trigger intent is the operational hinge. It's what lets the system match a future task to a past lesson without making the agent re-read every prior failure on every new task.
3. A verifier, run before any rule lands.
Generative models hallucinate, and post-mortem generators are no exception. The third component is a separate model that gates whether the proposed rule is actually grounded in the evidence the failing session produced. The verifier asks two questions, in order. First, does every specific factual claim in the rule (a line number, a file size, a function name) actually appear in the source evidence? Second, does the proposed rule contradict any rule already in the policy library?
If either check fails, the rule is rejected. It never enters the policy. The original failing session is kept as a finding, a human can step in if they want, but the system won't silently ingest a hallucinated lesson. This is the part that surprises engineers most the first time they build a loop like this. In our production traffic the verifier rejects somewhere between 5% and 20% of proposed rules. Without it, those rejections would be noise drifting straight into the policy library.
4. A trigger evaluator, run on every new task.
When a new task arrives, the agent walks every rule in the active policy library and asks two questions per rule. The lexical question (does the task contain a specific substring or match a specific regex) runs in microseconds. The semantic question (does the task match the natural-language trigger intent the post-mortem produced) is one small-model call, capped at a sub-second timeout, with the result cached per session.
Rules that match get injected into the agent's prompt as system-level reminders. Severe rules, like "escalate this task class to a larger model," can refuse the session outright. Now the agent has on its prompt exactly the lessons relevant to the task in front of it. Not its entire history. A curated, evidence-grounded subset.
Why this pattern, and not any of the obvious alternatives
There are four obvious alternatives. The pattern earns its keep against each one.
Alternative one: just fine-tune. Fine-tuning is the right answer when the failure mode is so dense in the training distribution that a few rules can't address it. In practice that's uncommon. Most agent failures are a small number of recurring patterns, maybe five to thirty in a mature application, and those respond extremely well to explicit rules. Fine-tuning takes a week and costs real money. A failure-driven memory loop adds a rule in 30 seconds and costs a few cents.
Alternative two: just write a longer system prompt. This works for the first dozen rules. By rule fifty the system prompt is unreadable and rules contradict each other in ways no human can audit. The failure-driven memory pattern keeps each rule as a separate addressable artifact and injects only the relevant ones, which is a meaningfully different scaling property.
Alternative three: vector-search over past sessions. Embedding-based memory is fashionable and it works for some kinds of recall. It works poorly for governance. "Find the three most similar past sessions and inject them" produces lossy guidance that the agent might or might not follow. "If this task matches the trigger intent of rule X, prepend rule X to the prompt" is deterministic, auditable, and cheaper.
Alternative four: human-curated rule libraries. This works in shops with a dedicated MLOps team. It doesn't scale to teams without one. The whole point of a failure-driven memory loop is that the agent itself generates candidate rules and the verifier keeps those candidates from contaminating the library. Humans review at the rule-library level instead of the per-session level.
The unsentimental observations
Three things have surprised me across roughly six months of running this in production.
The verifier earns its cost almost immediately. The naive intuition is that a generative model proposes a rule and you write the rule to the library. That produces a memory store that drifts within a few weeks, because hallucinated rules pile up. With the verifier in place, the policy library stays small and tight. Rejected proposals are still useful, since they cluster around weaknesses in the post-mortem prompt itself, but they don't pollute the library.
The trigger intent is the part new builders consistently underestimate. That natural-language description of the task class does most of the work. Lexical predicates only get you so far. The real value of the loop is that a rule learned from a failure on a Vue review fires correctly on a React review, because the trigger intent describes the task class semantically.
And the whole pattern is recoverable in a way fine-tuning is not. If a rule turns out to be wrong, you delete one markdown file and the agent's behavior reverts on the next task. Try that with a fine-tune run.
What this is not
I want to be careful here, because there are people who'll read an architecture like this and start writing prophecies. A failure-driven memory loop is a production engineering pattern, and that's all it is. It takes a specific problem, small-model agents plateauing on recurring failure modes, and hands it a specific solution: structured rules, verified before they land, applied with semantic match. It doesn't generalize without bound. It doesn't "learn" in the sense the field reserves the word for foundation model training. What it does is accumulate discrete operational lessons in a structured format that humans and other systems can audit.
That accumulation is useful. It's nothing close to transcendent.
Where this goes next
The natural next step is to point the same loop at AI systems besides coding agents. Customer-support agents. Code-review tools embedded in CI pipelines. Cybersecurity agents. Any system where failures recur with structure, and where a small library of explicit rules can plausibly cover the recurring cases.
What the broader ecosystem is missing is shared infrastructure. A stable rule format that multiple agent vendors can write to and read from. A verifier service that any agent platform can call. An audit log standard that compliance teams can rely on. Building those primitives is the next 12 months of work for anyone serious about operational self-correction. The patterns are clear. The standards aren't.
There's plenty of room to do that work badly. There's just as much room to do it well.