Apply to my task
arXiv:2610.17763 ★ 85 Oct 13, 2026

Memory Echo and FPA: how writing recaps back into an agent's memory turns one old note into a “choir” — and how to stop it

Key result

Finding: an agent that retrieves a note and writes a recap back into memory multiplies old information all by itself. One record turns into three to five, while your correction stays single. The FPA method (family, provenance, authority) lets the agent answer from the fresh verified fact instead of a choir of old recaps. It puts a filter between retrieval and answering: it lets one record per source into the context, and after a verified correction it shuts out the entire old family. The model stops counting repeats as confirmations and answers from confirmed data. Note: in the paper this is code, not a prompt. The text adaptation below is ours, and the authors did not measure it.

01

TL;DR

Memory Echo is a finding about long-term agent memory: when an agent retrieves a note and writes a recap of it back, a single old record multiplies into several. The fix, FPA (Family–Provenance–Authority), adds three steps between retrieval and answering. It keeps one representative per source in the context, switches off stale records once a verified correction arrives, and forces the answer to rest on confirmed facts.

You know the pain. You told your agent: “I'm looking for low-carb vegetables.” It still recommends the keto bars you talked about a month ago. The reason: the old recommendation got recapped and saved over and over. Now it holds three to five slots in search results, while your correction holds one. To the model that looks like “five independent confirmations versus one,” even though all five come from the same source. Crucially, plain reading without writing doesn't cause this. The echo grows specifically from the “retrieve → recap → write” loop. Even after the correction, the old record's descendants stay in the results and keep leaning on the answer.

The method fixes this in three steps. Step 1: records are grouped by origin (by “parent,” not by wording), and at most one per family gets into the context. Step 2: if a verified correction has arrived, the whole old family stays in the archive but is not allowed to take part in the current answer. Step 3: the answer is built from confirmed data, and the draft is checked against it.

Want this for your own case? Apply this study to your task: AI adapts its method to what you are working on and writes the prompt.

02

Method Blueprint

STEP 1 (Family): group retrieved records by source/parent
                → at most 1 record per family goes into the context

STEP 2 (Provenance): check records against the verified correction
                → the old family stays in the archive but is barred from the answer

STEP 3 (Authority): answer from verified, current facts
                → the draft is checked against the admitted data

The store is never deleted: history is kept for auditing.
Only what enters the answer's context changes.

In the paper, FPA runs as code between memory retrieval and answer generation. The steps are not executed by a single prompt.

03

Example in Practice

Task: You run a small coffee shop in Austin. A purchasing agent keeps notes on suppliers. In those notes, the bean price from “Southfield Farms” ($16.50/kg) is recorded three times: the supplier's email, a recap in the meeting notes, and a line in the weekly summary. All three descend from one email. Then an invoice arrives with the price now at $20/kg. You ask the agent to calculate the month's purchase.

Prompt:

You are the coffee shop's purchasing agent. Before answering, go through three stages.

<Records>
M1 | source: supplier email (March 12) | parent: — | status: active
   “Arabica Blend beans, $16.50/kg”
M2 | source: meeting notes (March 14) | parent: M1 | status: active
   “Southfield Farms is holding the price at $16.50/kg”
M3 | source: weekly summary (March 21) | parent: M2 | status: active
   “Main bean supplier: Southfield Farms, ~$16.50/kg”
M4 | source: supplier invoice #188 (April 2) | parent: — | status: verified
   “Arabica Blend, $20/kg, effective April 1”
M5 | source: coffee shop operating schedule | parent: — | status: active
   “Bean usage: 60 kg per month”
</Records>

<Stage_1_Family>
Group the records into families by parent and source, not by wording.
Keep no more than one representative record from each family.
Output the list of families and the chosen representatives.
</Stage_1_Family>

<Stage_2_Provenance>
Check the families against the verified records.
If a verified record replaces a fact, the whole old family is marked
“archived, not for answering.”
Output which records are admitted to the answer, which are switched off, and why.
</Stage_2_Provenance>

<Stage_3_Authority>
Answer the question using only the admitted records.
If there is no verified source, say so plainly.
Check the draft against the admitted records and fix any mismatches.
</Stage_3_Authority>

Question: how much will we spend on beans in April?

Result: The model will show three blocks. In the first, records M1–M3 are merged into one family with a single representative, while M4 and M5 stand on their own. In the second, the old family is marked as switched off because of invoice M4. In the third, the calculation uses the invoice price and the usage from the schedule, and the old price stays out of the math. The model does the actual arithmetic itself.

04

Why It Works

The weakness. The model doesn't know that three records are the same email. To it, three similar notes look like three independent confirmations. The more repeats, the heavier the old version weighs, and a single fresh correction loses to the choir. Stopping the writes doesn't kill this inertia: the descendants are already sitting in the store.

The strength. If each record carries metadata (where it came from, whose descendant it is, whether it's verified), deduplicating by origin and checking against verified facts is an easy job. The researchers showed you need to group by lineage, not by word similarity. Two independent sources can say the same thing, while two recaps of the same retrieval remain one family.

How the method exploits this. It steps in between retrieval and answering. The store stays untouched, so nothing is lost and everything can be audited. What changes is what gets admitted into the context.

Levers: - Per-family limit (one record in the paper) → you can raise it to two for complex tasks, but the echo will come back. - Order of checks → families first, then corrections, then the answer: in this order each step cleans the input for the next. - Record status (active / verified / archived) → the key to the whole method. Without it, step 2 doesn't work. - Rule for when there's no verified source → swap in your own: “ask the user,” “flag as unverified.”

05

Prompt Template

The paper has no ready-made prompts; FPA is implemented there as code. Below is a translation of the three-step logic into text instructions you can run in a chat or an agent. This is not the authors' prompt.

You are an agent with long-term memory. Before every answer, go through three stages.

<Records>
{id} | source: {source} | parent: {parent id or —} | status: {active / verified / archived}
{record text}
...
</Records>

<Stage_1_Family>
Group the records into families by parent and source, not by wording.
Two records with different words but a shared parent are one family.
Admit no more than {per_family_limit} record(s) from each family.
Output: the families and the chosen representatives.
</Stage_1_Family>

<Stage_2_Provenance>
Check the families against the verified records.
If a verified record replaces or refutes a fact, the whole old family
gets the status “archived” and is not admitted to the answer.
Do not delete or modify archived records.
Output: admitted records, switched-off records, the reason.
</Stage_2_Provenance>

<Stage_3_Authority>
Answer the question using only the admitted records.
If there is no verified source, say so and {action_without_source}.
Check the draft against the admitted records and fix any mismatches.
</Stage_3_Authority>

<Rule>
Do not write your recap of a retrieved note as a new fact.
If you need to save a recap, name its parent and mark it as derived.
</Rule>

Question: {question}

What to fill in: - {id}, {source}, {parent}, {status} — data from your notes. You can reconstruct the parent like this: “this record is a recap of that one.” - {per_family_limit} — 1 by default. - {action_without_source} — “ask me a clarifying question” or “flag the answer as unverified.” - {question} — the current task.

🚀 Quick start — paste into the chat:

Here is a template with three stages for cleaning up memory (families → admission based on verified corrections → answer from confirmed facts). Adapt it to my task: [your task].
Ask me questions to fill in the fields.

[paste the template above]

The LLM will ask where your records come from, what counts as a verified source for you, and what to do without verification. That's because the method rests on three things: record origin, the “verified” status, and a rule for the unconfirmed case. The model will take the structure from the template and fit it to your note-keeping system.

06

Limitations

⚠️ Metadata required: the method works when records have a source, a parent, and a status. If your notes are flat text with no origin, step 1 can't tell “five recaps of one thing” from “five independent sources.”

⚠️ A verified source is required: steps 2 and 3 rely on a confirmed “ground truth” (an invoice, a document, your direct correction). What to do when there isn't one, the authors did not test. The recovery branch in the diagram is labeled illustrative.

⚠️ In the paper it's code, not a prompt: FPA is built into memory retrieval for four existing systems. Moving it into a chat prompt is our translation of the logic. The authors did not measure the effect of that translation.

⚠️ Reading without writing doesn't feed the echo: the problem comes from the “retrieve → recap → write” loop. If your agent writes nothing back to memory, the main part of the risk doesn't apply to you.

⚠️ The effect is uneven: in two of the four systems the accuracy gain is more modest. There the final retrieval results often stay “clogged” with old records, yet the answer still improves. A single snapshot of the results doesn't show what happens to the answer.

⚠️ The test is artificial: the “old claim” was taken from another real answer in the same dataset. Real-world scenarios (shopping, medicine, travel) were checked on an early pilot protocol and aren't part of the headline numbers. Some appendices aren't visible in the text.

07

How They Studied It

The researchers built a benchmark called MEchoBench. They took 50 questions each from four well-known memory evaluation sets (LoCoMo, LongMemEval, HotpotQA, BEAM). That left 190 questions, with ten set aside for development. Into each question they mixed an “old” claim taken from another real answer, while the correct answer served as the verified correction. For each question they created three memory histories. In the first, the old claim appears once; in the second, it's read six times without writing; in the third, a recap is written after every read. Then the same correction was introduced in all histories, followed by 30 more memory reads with no writes.

The picture came out clear. Reading without writing barely changes anything, while writing recaps sharply increases the old family's share in all four memory systems (A-MEM, Mem0, CoM, LangMem). The takeaway: the culprit is the “retrieve → write” loop itself, not any particular ranking algorithm. After the correction, the old descendants kept occupying slots: the old family's presence score in the results held at around 0.65–0.70 across all 30 no-write queries. The echo lives on without new writes, as an inherited advantage.

To compare methods fairly, the candidates and the history were frozen. Four retrieval approaches were run on the same set of records with two models (DeepSeek V4 Flash and Kimi K2.6). Answers were graded by GPT-5.6. Baseline accuracy was 0.825 (DeepSeek) and 0.782 (Kimi); with FPA it rose to 0.920 and 0.916. “Decision contamination” (how much closer the answer is to the old claim than to the correct one) dropped from 0.106 to 0.030 and from 0.109 to 0.038. Three standard alternatives (a repetition penalty, record quality scoring, learned ranking) also raised accuracy but barely removed the persistent presence of the old family. FPA cut persistent presence the most: the index fell from 0.427 to 0.057. The practical lessons: a useful write can help the answer while old descendants still creep into the results, and cleanup has to go by lineage and by correction status.

08

Adaptations and Extrapolations

💡 Adaptation for an agent instructions file (CLAUDE.md, AGENTS.md, assistant memory): the principle carries over into note-keeping rules. This is our extrapolation: the authors did not test such rules in prompts.

## Memory rules
- Every note record: what, where from (source), whose recap (parent),
  status (active / verified / replaced).
- Do not write a recap of a retrieved note as a new fact. Write: “derived from {id}”.
- When I correct a fact or a confirming document arrives: mark the old record
  and all its derivatives as “replaced”, do not delete them.
- When answering, rely on records with the status “verified”; from each chain
  of recaps take no more than one record.
- No verified source — say so, don't silently fall back on the old version.

🔧 Technique: add a memory audit → catch the echo before it sways the answer

Here are my notes on {topic}. Find records that are recaps of each other
(shared source, different words). Group them into families and show how many
“votes” each version of a fact really has. Flag versions that contradict
more recent verified records.

This way you can see that “five confirmations” are really one source.

09

Resources

  • Paper title: Memory Echo in Single-Agent Long-Term Memory: Lifecycle Evaluation and Provenance-Guided Mitigation
  • Code and benchmark: https://github.com/OrcasSam/memory-echo-benchmark
  • Authors: Yufeng Li, Sheng Yao, Peng Zeng, Dezhang Kong, Shi Lin, Changting Lin, Xun Wang, Meng Han
  • Affiliations: East China Normal University, University of Southern California, Zhejiang University, Zhejiang Gongshang University
  • Memory systems in the paper: A-MEM, Mem0, CoM, LangMem
  • Datasets: LoCoMo, LongMemEval, HotpotQA, BEAM

Research digest

Key result

Finding: an agent that retrieves a note and writes a recap back into memory multiplies old information all by itself. One record turns into three to five, while your correction stays single. The FPA method (family, provenance, authority) lets the agent answer from the fresh verified fact instead of a choir of old recaps. It puts a filter between retrieval and answering: it lets one record per source into the context, and after a verified correction it shuts out the entire old family. The model stops counting repeats as confirmations and answers from confirmed data. Note: in the paper this is code, not a prompt. The text adaptation below is ours, and the authors did not measure it.

Principle

A three-step process where each step cleans the input for the next. 1. Family. Records are grouped by lineage: who recapped whom. Wording doesn't matter. At most one record per family goes into the context. 2. Provenance. Records are checked against the verified correction. The old family goes to the archive as a whole and takes no part in the answer. 3. Authority. The answer is built only from admitted records. The draft is checked against them once more. The store stays untouched: only what the model sees before answering changes. Nothing is lost, and everything can be audited after the fact. Think of a judge who doesn't burn old transcripts — just doesn't let them into the courtroom once there's a fresh ruling.

Why it works

The model doesn't know that three similar notes are the same email. To it, they're three independent confirmations. The more repeats, the heavier the old version gets, and one fresh correction loses to the choir. Stopping the writes isn't enough: the descendants are already in the store, leaning on the answer. You need one simple thing: tags on records (where from, whose descendant, verified or not). With those tags, filtering out recaps of a single source and checking against the verified fact is easy — and you group by lineage, not by word similarity. Two independent sources can say the same thing, and that's fine. Two recaps of one retrieval remain one family. The twist: in two of the four systems, the results are still clogged with old records after cleanup, yet the answer still gets better. You can't judge what happens to the answer from a single snapshot of the results. The echo grows specifically from the “retrieve → recap → write” loop. Plain reading without writing doesn't create it.

When to apply

Agents with long-term memory that write back → purchasing, personal assistants, client and project notes, especially when a fact has changed (a price, a preference, terms) and the agent stubbornly keeps returning to the old one. Not a fit if your agent writes nothing to memory: you don't have the main risk. Also not a fit for flat notes with no source or parent: step 1 can't tell five recaps from five independent sources. If there's no verified source, the authors didn't test that case.

Mini recipe

1. Tag your records: each needs a source, a parent (whose recap it is), and a status: `active / verified / archived`. You can reconstruct the parent by asking “which record is this a recap of?”. 2. Define what “verified” means for you: an invoice, a document, your direct correction. Without this, steps 2 and 3 don't work. 3. Set a per-family limit: one record by default. Raise it to two for complex tasks, but the echo will come back. 4. Decide what to do without verification: “ask a clarifying question” or “flag the answer as unverified.” 5. Ban writing recaps: the model doesn't save its recap as a new fact. If it needs to save one, it names the parent and marks the record as derived. 6. Run the three stages in sequence: families, then checking against corrections, then the answer. Order matters. 7. Don't delete the archive: old records stay for auditing; they're just not admitted to the answer.

Examples

[BAD]: `Here are my notes on suppliers. Calculate how much we'll spend on beans in April.` (the notes record the $16.50/kg price three times and the $20/kg invoice once: the model calculates at $16.50) [GOOD]: `Before answering, go through three stages. Stage 1: group the records into families by parent, not by wording, and keep one record per family. Stage 2: if there's a record with the status “verified” that replaces a fact, the whole old family goes “to the archive, not for answering.” Output what's admitted and what's switched off. Stage 3: answer only from the admitted records and check the draft against them. Records: M1 (email, $16.50/kg, parent —), M2 (meeting notes, $16.50/kg, parent M1), M3 (summary, ~$16.50/kg, parent M2), M4 (invoice, $20/kg, verified), M5 (usage 60 kg per month). Question: how much will we spend on beans in April?` The model will show three blocks. M1–M3 become one family and go to the archive because of invoice M4. The calculation runs at $20/kg and 60 kg. The model does the math itself.

In plain words

When an AI agent keeps long-term memory, it runs into a systemic glitch called Memory Echo. The agent reads its own old note, recaps it, and saves the copy back into the database. Before long, one fact starts multiplying out of control. And to an LLM, three similar records aren't duplicates — they're three independent receipts. When a fresh correction arrives, the one current fact simply drowns in a choir of old clones.

It's like office gossip that's gone full circle. Dave starts a rumor, Mike repeats it to Sarah, Sarah puts it in a report — and now the boss hears the same story from three corners and takes it as gospel truth. When someone shows up with the official paperwork, the boss doesn't buy it, because “come on, three sources confirmed it.” A textbook case of a system convincingly fooling itself.

To cure this madness, researchers came up with FPA (Family–Provenance–Authority). It's ruthless: it traces the lineage of every record and keeps just one ancestor, cuts off stale clones the moment the first correction lands, and makes the model lean only on a verified, authoritative source. A fresh invoice for $20 instantly zeroes out three relatives still quoting the old $16.50.

The mechanics were tested on coffee shop purchasing, but the principle is universal. Any autonomous agent, support bot, or corporate RAG assistant that's allowed to write into its own database will sooner or later fall into this trap. Wherever there's a memory feedback loop, the agent will inevitably start quoting itself and piling up noise.

Bottom line: never let an agent blindly trust its own recaps. If a model takes notes on its own thoughts unchecked, you don't get accumulated experience — you get garbage echo. Build in fact provenance control, or your smart assistant will blow the budget simply because it repeated its own old mistake three times.

AI lab assistant

Apply this study to your task

Describe what you're working on. AI takes the method and the measured results from this paper and adapts them to your case, or writes a ready prompt built on them.

Based on Memory Echo and FPA: how writing recaps back into an agent's memory turns one old note into a “choir” — and how to stop it arXiv:2610.17763

Sign in to apply this study New accounts get 50 free credits.