An agent learns that your team deploys with make ship, not npm deploy. There are two ways to make that stick. You can write it to a memory file, where it will be retrieved and pasted into the context window every time it might be relevant — instantly effective, perfectly faithful, and billed on every future use. Or you can put it in a training set, where after some number of gradient steps the model simply behaves that way — free at inference, generalizing to situations you never wrote down, and impossible to remove cleanly when it becomes wrong.
These are usually discussed as different disciplines by different people. They are better understood as the same operation at two ends of a continuum, and almost every interesting design question in agent engineering right now is really a question about where on that continuum a particular piece of knowledge belongs.
01One operation, two learning rates
Line them up against each other and the symmetry is hard to unsee:
| Write it to memory | Train it into weights | |
|---|---|---|
| Learning rate | 1.0 — one write, fully learned | ~1e-6, many steps, partially learned |
| Fidelity | Exact. The string comes back verbatim. | Approximate. It comes back as a tendency. |
| Generalization | None. It applies where you retrieve it and nowhere else. | That is the entire point — it transfers to cases you never wrote. |
| Cost shape | Marginal. Tokens on every single use, forever. | Fixed. Pay once, then free at inference. |
| Latency to take effect | Instant. | Your training cadence — days to weeks. |
| Reversibility | Delete the line. | Hard. You retrain, and hope. |
| Blast radius | One agent, one task. | Every user, every task, at once. |
| Auditability | You can read it. | You cannot. |
The last three rows are the ones that should make you conservative. A memory write is a local, inspectable, reversible change. A weight update is a global, opaque, sticky one. When in doubt, the reversible option is worth a substantial premium — which is an argument for context that has nothing to do with the economics, and usually wins before the economics are even consulted.
02Where should this fact live?
Now the economics, because they are unusually clean. Two properties of a fact decide almost everything:
- How often it is used (
u, times per week). Every use in context costs a retrieval; in weights it costs nothing. - How long it stays true (
h, weeks until stale). Weights must be refreshed when a fact changes, and you can only refresh on your training cadence.
Measure the cost of training in retrieval-equivalents — call it B, the number of retrievals a training cycle is worth — and the rule falls out immediately. Over a fact’s lifetime you would perform u × h retrievals, so:
In log-log space that boundary is a straight diagonal, which makes the whole decision one picture. Hover any fact to see the arithmetic behind its verdict:
Three things in that chart are worth more than the rule itself.
Stability alone is not enough. The rollback procedure is one of the most durable facts on the board — true for years — and it still belongs in context, because it is consulted twice a quarter. Rarity beats stability. Teams reliably get this backwards, because “this is a permanent fact about our system” feels like it should be baked in.
There is a region where weights are simply not available. Anything that goes stale faster than you retrain — the on-call rota, the sprint deadline, the incident status — can never be current in the weights, no matter how often it is used. Raise the training cadence slider and watch that orange band swallow more of the board. For most teams shipping a model every few weeks, a startling share of what an agent needs to know lives permanently in that band.
And one axis is missing from the chart on purpose. The ringed dots are per-user facts. Their economics say weights; their scope forbids it, because a shared model cannot hold a fact that is true for one person. Generality is a hard gate that runs before the cost comparison — which is why personalization is overwhelmingly a memory problem and not a fine-tuning one, whatever the retrieval bill looks like.
The rule of thumb this collapses to
Facts go in context. Behaviors go in weights. A fact is specific, checkable, and perishable — everything weights are bad at. A behavior is a way of acting that should generalize to situations nobody enumerated — everything context is bad at, because you would have to re-specify it in every window, forever.
Most of the disappointment I have seen with fine-tuning for agents comes from using it to install facts. The model dutifully learns them, they go stale, and now you have a wrong fact you cannot delete.
03Forgetting and compaction are the same bug
Two posts ago the argument was that compaction is a lossy step applied repeatedly, so what survives decays as fk — and since the number of compactions grows with task length, the oldest context is the most compressed.
Catastrophic forgetting is that exact structure, one level down and one timescale slower. Each fine-tune is a lossy transformation of everything the model previously knew. Capability from earlier training rounds must survive every subsequent round, so retention decays in the number of rounds, and the oldest capabilities are the most degraded. Same shape, same exponent, different substrate.
| Context compaction | Catastrophic forgetting | |
|---|---|---|
| What degrades | Facts in the window | Capabilities in the weights |
| Per-event loss | Summarizer fidelity | Interference from the new objective |
| Cadence | Every time the window fills | Every training round |
| Who suffers most | The oldest context — the plan | The oldest capabilities — the general ones |
| The standard fix | Write it down before compressing | Rehearsal — mix old data into new training |
Read that last row twice. Write it down before you compress and mix the old data back in are the same move: keep an external, uncompressed copy of what you are about to squeeze, and re-inject it. Two fields arrived at one answer independently, which is usually a sign the answer is about the structure of the problem rather than the details of either domain.
04The flywheel, and the point where it reverses
Here is what makes this intersection urgent rather than merely tidy. A long-running agent generates, as a by-product, exactly the artifact post-training is starved of: trajectories with outcomes. Thousands of decisions, tool calls, corrections, and a signal at the end about whether it worked. That is a preference dataset assembling itself, for free, in your logs.
So the obvious loop: harvest the successful runs, train on them, deploy a better agent, harvest better runs. Every serious agent company is either doing this or planning to. And it works — right up until it doesn’t, for a reason the previous post makes concrete.
You cannot tell which runs actually succeeded. A run that finished and a run that finished wrong emit the same signal. So “harvest the successful runs” really means “harvest the runs that looked successful,” and some fraction of those are confident, fluent, complete, and wrong. Which makes them the most dangerous possible training examples: they are not noise, they are coherent demonstrations of the failure mode, labelled as things to do more of.
Drag the contamination slider. The loop does not oscillate or explode — it converges, and what contamination controls is where it converges to. Clean labels take you toward 100%. At 20% contamination the ceiling is 69%: the model still improves, just to a worse place than it could have reached, and nothing in the process tells you what you gave up.
Keep dragging and the ceiling crosses the dashed line marking the model you started with. Past that point every training cycle moves the model down toward its new, lower ceiling — while producing exactly the artifacts that make it look like progress: fresh data, completed runs, a new checkpoint.
The trap gets worse as you get better
The contamination you can tolerate depends on how good the model already is, and it moves in the cruel direction. A weak model has room to improve, so noisy data still nets out positive. A strong one does not — there is less to gain and more to lose, so a smaller share of bad labels is enough to drag it below where it started.
With the constants in this lab: starting from a 40% model you can tolerate about 45% contamination before training hurts. Starting from 70%, the limit is 19%. Starting from 80%, it is 12%. The self-training loop is most dangerous exactly when it is most tempting — when your agent is finally good enough that its own trajectories look like a training set.
Where the last post’s fleet actually sat
With verification turned off, that fleet reported 25 successful runs of which 9 were wrong — 36% contamination in exactly the pile you would harvest for training. For a 70%-capable agent, the level at which self-training starts subtracting is 19%.
Do not read those constants as laws of nature; the threshold moves with how much a good example helps against how much a bad one hurts, and I chose illustrative values. Read the relationship instead: the contamination that ordinary production systems generate is comfortably larger than the contamination a good model can absorb. That is not a distant failure mode. It is the default outcome of doing the obvious thing without measuring first.
› Go deeper: why a bad example hurts more than a good one helps
The asymmetry in that model — a contaminated example doing more damage than a clean one does good — is not a modelling convenience. A correct trajectory mostly confirms behaviour the model already has some mass on; the gradient is small because the prediction was already decent. An incorrect trajectory labelled as correct pushes against a behaviour the model may currently get right, and the gradient is large precisely because the example is surprising. Learning is driven by surprise, and wrong labels are surprising.
Preference methods do not rescue you here either. DPO and its relatives learn from pairs, which means a mislabelled winner does double duty: it raises the wrong response and lowers a right one in the same step. The pairwise framing that makes these methods sample-efficient also makes them efficient at learning your labelling errors.
Which points at the practical answer: the scarce resource in an agent data flywheel is not trajectories. You have millions. It is trustworthy labels on trajectories, and the only known sources are execution-grounded signals that cannot be faked — tests that pass, builds that compile, transactions that reconcile — plus human review of a sample. Everything else is the model grading its own homework.
05What I would actually do
Start everything in context. It is reversible, inspectable, and instant. Promote to weights only when a fact or behaviour has proven both that it is used constantly and that it is stable — which you will only know after it has lived in context for a while. Context is the staging environment for the weights.
Promote behaviors, not facts. If you cannot state what you are teaching as “when in situation X, act like Y,” it is a fact, and it belongs in a file. The test is whether the thing should generalize to cases you have not written down.
Instrument retrieval to find training candidates. Your retrieval logs already contain the answer to “what should we train on next.” The memories retrieved most often, across the most distinct tasks, with the longest time since last edit, are exactly the upper-right corner of that first chart. That query is a roadmap, and almost nobody runs it.
Gate the flywheel on execution-grounded labels. Only harvest runs whose success was verified by something that cannot be talked into agreeing — tests passing, a build succeeding, a reconciliation matching. “The model said it was done” is not a label; it is the thing you are trying to measure.
Measure your contamination rate before you train, not after. Sample completed runs, grade them properly, and put that number next to the training decision. If you do not know it, you do not know whether the ceiling you are converging toward is above or below the model you already have — and the model will not tell you, because from the inside both look like progress.
Keep the uncompressed copy, in both worlds. Write facts down before compaction; keep old data in the mix during fine-tuning. Same rule, two timescales.
Takeaways
- Memory and post-training are one decision. Same operation — teaching the system something — at opposite ends of a learning-rate, cost, and reversibility continuum.
- The boundary is
u × h > B. Frequency times durability against the cost of a training cycle, measured in retrievals. Everything else is a rationalization of that inequality. - Facts in context, behaviors in weights. Fine-tuning facts is how you get wrong answers you cannot delete.
- Forgetting is compaction. Lossy compression applied repeatedly, and the fix in both worlds is to keep the uncompressed copy and re-inject it.
- Know your contamination rate before you self-train. It sets the ceiling the loop converges to, and that ceiling drops below your current model sooner the better your model is — while every cycle still looks like progress from the inside.
Related reading
Where the contamination number comes from · Compaction compounds · What to store and where · Four kinds of memory · The verification gap · The arithmetic of long tasks
Both labs are models with stated, illustrative parameters rather than measurements of any system. Their arithmetic — the break-even boundary and the flywheel’s ceiling — was verified independently before publication and is reproducible in a few dozen lines of JavaScript. The reversal threshold in particular depends on constants I chose; the structural claim — that contamination sets a ceiling, and that the tolerable level falls as the model improves — is the part worth carrying.