REM: What to Store, When to Recall, What to Forget in Experience Memory for Coding Agents
Organizations: Yale University · Amazon
Abstract
Large language model (LLM) agents now autonomously complete long-horizon tasks, such as repository-level coding, through hundreds of think-act steps, yet the experience each run produces is rarely reused on the next. Prior memory systems concentrate on retrieval, finding the most relevant past trajectory. Retrieval cannot observe the running agent, so it cannot decide whether the agent needs an experience, at which point, or for how long. We introduce REM (Reusable Experience Memory), a framework that manages the memory lifecycle from inside the agent's think-act loop through three explicit decisions. What to store: each completed trajectory is consolidated into a phase-structured document, two orders of magnitude smaller than the trajectory. When to recall: the document is injected at the start of the task; the costlier implementation record is withheld until an in-loop gate detects the agent struggling. What to forget: the record is evicted after a single exposure. On repository-level bug fixing (SWE-ContextBench Lite), REM retrieves the related trajectory more accurately than every state-of-the-art memory system (68.7% vs. 55.6% match@1) and improves, in every replicate, end-task resolution (27.6% vs. 24.9%) at 17% lower cost. Injecting the same experience as a summary or raw trajectory, even when oracle-retrieved, does not. Ablating any of the three decisions reduces resolution. Altogether, these results demonstrate that the bottleneck in experience reuse is not retrieval fidelity but how experience is stored and governed across its lifecycle, opening a control-theoretic perspective on agent memory.
Figures & tables
| Method | Stored unit | Candidates | Match@1 |
| Free trajectory † | raw trajectory ( 105K tok) | self-selected | 22.2% |
| Supermemory | managed chunks ( 30 tok) | 15 | 23.2% |
| Mem0 | extracted facts ( 12 tok) | 3 | 25.3% |
| Free summary † | trajectory summary ( 373 tok) | self-selected | 35.4% |
| OpenViking | indexed file chunks ( 246 tok) | 3 | 38.4% |
| LangMem | extracted memory items ( 48 tok) | 10 | 55.6% |
| Injected form | Tokens | Injected | Referenced | Coverage |
|---|---|---|---|---|
| Wrong summary | 380 | 8.9 | 0.3 | 3.4% |
| Free trajectory | 105K | 67.7 | 17.9 | 26.7% |
| Oracle trajectory | 111K | 67.7 | 18.1 | 27.2% |
| Oracle summary | 390 | 9.3 | 4.3 | 45.7% |
| Free summary | 373 | 9.3 | 4.8 | 52.5% |
| Oracle phased document | 540 | 12.4 | 7.8 | 64.7% |
| Recall policy for the record | Injected in | Resolution (sd) | ( ) | Cost tok/task |
|---|---|---|---|---|
| Never, document only | 0% | 26.9% (1.5) | (0.82) | 374K |
| Eager, at first source edit | 100% | 25.3% (1.7) | (0.17) | 423K |
| On struggle, then pinned | 56% | 24.9% (1.5) | (0.08) | 353K |
| On struggle, then evicted (REM) | 58% | 27.6% (1.5) | — | 374K |
Appendix figures & tables11 assets
Supplementary material from the paper’s appendix.
Appendix
| Condition | Resolved / 99 | ITT | Cost tok/task | Turns | Min | PatchNA |
|---|---|---|---|---|---|---|
| No memory | 23, 26, 25 | 24.9% | 452K | 70.4 | 11.9 | 7.0 |
| Wrong summary † | 23 | 23.2% | 431K | 72.0 | 14.4 | 7 |
| Free trajectory † | 22 | 22.2% | 637K | 66.3 | 13.1 | 11 |
| Free summary † | 24 | 24.2% | 484K | 68.6 | 13.8 | 10 |
| Oracle summary † | 23 | 23.2% | 378K | 67.4 | 13.7 | 6 |
| Oracle trajectory † | 24 | 24.2% | 768K | 49.9 | 9.5 | 11 |
| Extraction schema | Cosine top-1 | Gold in top-5 | Match@1 | Conversion | Parse fail. |
|---|---|---|---|---|---|
| Hand-written | 65.7% | 83.8% | 66.7% | 79.6% | 5 |
| Discovered | 62.6% | 78.8% | 68.7% | 87.2% | 0 |
| condition | res/patch/N | ITT | prec. | min | turns | tok/inst | failures |
|---|---|---|---|---|---|---|---|
| No memory | 20/88/99 | 20.2% | 22.7% | 9.5 | 71.1 | 444,070 | error 8, max_turns 3 |
| Oracle phased document | 23/91/99 | 23.2% | 25.3% | 10.6 | 72.1 | 442,141 | error 6 |
| REM, document only | 24/93/99 | 24.2% | 25.8% | 10.2 | 68.3 | 381,828 | error 4, max_turns 2 |
| REM, gate without eviction | 24/96/99 | 24.2% | 25.0% | 10.0 | 66.6 | 385,833 | error 2, max_turns 1 |
| REM | 21/92/99 | 21.2% | 22.8% | 9.7 | 68.7 | 419,678 | error 3, max_turns 4 |
| condition | res/patch/N | ITT | prec. | min | turns | tok/inst | failures |
|---|---|---|---|---|---|---|---|
| No memory | 23/97/99 | 23.2% | 23.7% | 14.5 | 71.5 | 452,536 | max_turns 1, no_patch 1 |
| Wrong summary | 23/95/99 | 23.2% | 24.2% | 14.4 | 72.0 | 430,526 | max_turns 2, no_patch 2 |
| Free trajectory | 22/94/99 | 22.2% | 23.4% | 13.1 | 66.3 | 636,529 | context_overflow 3, max_turns 2 |
| Free summary | 24/98/99 | 24.2% | 24.5% | 13.8 | 68.6 | 484,142 | max_turns 1 |
| Oracle summary | 23/97/99 | 23.2% | 23.7% | 13.7 | 67.4 | 378,265 | none |
| Oracle trajectory | 24/90/99 | 24.2% | 26.7% | 9.5 | 49.9 | 767,810 | context_overflow 3, error 1, max_turns 3 |
| condition | res/patch/N | ITT | prec. | min | turns | tok/inst | failures |
|---|---|---|---|---|---|---|---|
| No memory | 31/99/99 | 31.3% | 31.3% | 14.6 | 56.7 | 279,947 | none |
| Oracle phased document | 32/94/99 | 32.3% | 34.0% | 15.2 | 56.6 | 296,278 | error 1, max_turns 2 |
| REM, document only | 32/97/99 | 32.3% | 33.0% | 13.2 | 50.5 | 230,611 | max_turns 2 |
| REM, gate without eviction | 29/98/99 | 29.3% | 29.6% | 14.5 | 51.9 | 248,034 | max_turns 1 |
| REM | 31/98/99 | 31.3% | 31.6% | 13.8 | 49.9 | 242,595 | max_turns 1 |
| condition | res/patch/N | ITT | prec. | min | turns | tok/inst | failures |
|---|---|---|---|---|---|---|---|
| No memory | 47/95/99 | 47.5% | 49.5% | 17.0 | 24.5 | 129,623 | error 4 |
| Oracle phased document | 42/93/99 | 42.4% | 45.2% | 16.9 | 32.5 | 191,712 | error 1, timeout 3 |
| REM, document only | 39/98/99 | 39.4% | 39.8% | 17.0 | 25.6 | 140,603 | error 1 |
| REM, gate without eviction | 40/98/99 | 40.4% | 40.8% | 17.0 | 25.9 | 137,940 | max_turns 1 |
| REM | 40/97/99 | 40.4% | 41.2% | 16.7 | 24.4 | 136,395 | error 2 |
| condition | res/patch/N | ITT | prec. | min | turns | tok/inst | failures |
|---|---|---|---|---|---|---|---|
| No memory | 52/98/99 | 52.5% | 53.1% | 25.3 | 49.0 | 330,975 | no_patch 1 |
| Oracle phased document | 50/94/99 | 50.5% | 53.2% | 28.0 | 54.1 | 364,212 | error 1, max_turns 1, timeout 1 |
| REM, document only | 50/98/99 | 50.5% | 51.0% | 26.3 | 50.6 | 326,477 | max_turns 1 |
| REM, gate without eviction | 43/98/99 | 43.4% | 43.9% | 24.2 | 46.7 | 301,082 | error 1 |
| REM | 47/98/99 | 47.5% | 48.0% | 25.3 | 47.3 | 303,257 | no_patch 1 |
| condition | res/patch/N | ITT | PatchNA | min | turns | tok/inst |
|---|---|---|---|---|---|---|
| No memory, replicate 1 | 23/97/99 | 23.2% | 8 | 14.5 | 71.5 | 452,536 |
| replicate 2 | 26/95/99 | 26.3% | 6 | 10.5 | 69.0 | 442,914 |
| replicate 3 | 25/98/99 | 25.3% | 7 | 10.8 | 70.7 | 459,158 |
| mean | 24.7/96.7/99 | 24.9% | 7.0 | 11.9 | 70.4 | 451,536 |
| REM, document only, replicate 1 | 27/99/99 | 27.3% | 7 | 9.1 | 65.7 | 375,712 |
| replicate 2 | 28/98/99 | 28.3% | 3 | 10.0 | 65.6 | 373,133 |
| Condition | Coverage | Window | Dead weight | First infl. | |
|---|---|---|---|---|---|
| REM, phased document only | 99 | 69.1% | 38.8 | 35.3% | 4.1 |
| REM, gate and evict | 99 | 50.3% | 42.9 | 27.2% | 4.8 |
| REM, gate without eviction | 99 | 50.5% | 42.1 | 28.1% | 4.3 |
| REM, eager record | 99 | 38.8% | 44.9 | 19.1% | 3.8 |
| Oracle phased document | 97 | 64.7% | 45.6 | 35.7% | 2.1 |
| Free summary | 97 | 52.5% | 28.2 | 52.8% | 3.6 |
| Grouping | Quantity | Resolved | Unresolved | MW | |
|---|---|---|---|---|---|
| Start-of-run forms | coverage | 0.423 | 0.378 | 0.03 | |
| identifiers referenced | 12.9 | 11.0 | 0.10 | ||
| identifiers injected | 39.7 | 36.2 | 0.84 | ||
| REM recall policies | coverage | 0.511 | 0.527 | 0.34 | |
| identifiers referenced | 12.4 | 12.7 | 0.42 | ||
| identifiers injected | 28.8 | 28.3 | 0.76 |
| Hand-written | Discovered |
|---|---|
| files_modified | files_modified |
| root_cause | root_cause |
| fix_approach | fix_approach |
| functions_changed , classes_involved | related_functions |
| test_names , test_commands | test_cases |
| files_read , key_identifiers | — |