Short answer: When search brings a memory into play beside new evidence, write a correction so transform rewrites that object instead of appending a sibling.
Prediction error is the gate: match means leave it alone; contradict or extend means update. Engram’s search-then-add path makes the retrieved neighbor labile. Bounded topics update in place; unbounded ones need care to rewrite the right id. Avoid thrashing by not rewriting on every glance. Measure stale-fact and duplicate rates after corrections.
Reconsolidation is the update that happens because you remembered something, not only because new text arrived in isolation. Consolidation lifts episodes into stable semantic rules. Reconsolidation opens those rules again when retrieval puts them back in play beside new evidence. The biological metaphor is a labile window after recall. The engineering version is simpler. Search returns a live memory. The current turn contradicts or extends it. You write a correction through Weaviate Engram so transform can rewrite the retrieved object instead of appending a sibling. Prediction error is the gate. If reality matches the memory, leave it alone.
This chapter covers when retrieval should trigger an update, how Engram’s search-then-add loop implements reconsolidation, how to classify extend versus contradict, and how to avoid rewriting on every glance. Preference drift is the long-horizon cousin of this pattern, but reconsolidation is the per-turn mechanism that keeps a recalled fact honest.
Why does retrieving a memory create a chance to change it?
After consolidation, semantic memories feel finished. They are not. The next time the agent loads “use filter X for genre queries,” the user may say the collection uses a different property name now. The recalled rule is active in the prompt. New evidence sits beside it. That joint context is exactly when belief revision is cheapest and most accurate. Systems that only update on write, without checking what was just retrieved, miss that moment.
Research on hierarchical agent memory treats retrieval failure and conflict as learning signals. When note-like semantic memory is weak but episodes supply evidence, reconsolidation supplements or revises the note. Typed operations matter. Independent facts get added. Extendable facts get updated. Contradictions get rewritten or deleted. Indiscriminate overwrite is not reconsolidation. It is amnesia with extra steps.
Engram already retrieves related memories inside TransformWithContext on the write path. Application reconsolidation adds an explicit read-path habit. Search before answer. After the turn, if the user corrected a retrieved claim, call memories.add with a clear correction in the same scope so the pipeline can rewrite.
When should you reconsolidate, and when should you leave the memory sealed?
Once you accept that recall can open a memory, you need a gate. Always rewriting after every search creates churn and can damage useful detail. Prefer prediction-error triggers. The agent used memory M. The user or tool result showed M was incomplete or wrong. Then reconsolidate. If the turn merely restated M, keep it.
Good triggers include explicit user corrections, tool outputs that disagree with a cited memory, and self-checks where the model flags low confidence in a retrieved line. Weak triggers include vague vibes, speculative assistant guesses, and contradictions that live in a different user_id or property scope. Scope mistakes look like conflicts but are tenancy bugs.
Also separate extend from contradict. “Also avoid near-text for year filters” extends a genre-filter rule. “Do not use the genres property; use category_id” contradicts it. Extensions rewrite with an added clause. Contradictions supersede with history, as covered earlier. Reconsolidation chooses the operation. It does not invent a new storage API.
How does Engram make reconsolidation concrete?
Knowing the gate, the loop is search, act, write. Before the model answers, memories.search loads candidates with hybrid retrieval in the right group and properties. Those contents enter the prompt. After the turn, if a correction occurred, send the exchange or a focused correction string through memories.add. Engram extracts, transforms against existing neighbors, and may rewrite the old memory while deleting a redundant extract.
That is reconsolidation through infrastructure. The retrieved neighbor is the labile object. The new input is the evidence. Transform instructions and topic descriptions decide how much prior wording to keep. Poll runs.wait when the next search must see the update immediately. Otherwise fire-and-forget is fine, because the latest messages still sit in the context window.
Bounded topics sharpen the pattern. A single profile or experience memory per scope updates in place. Unbounded topics need more care so reconsolidation rewrites the right id rather than minting a near-duplicate. When in doubt, search again after the run completes and prune leftover absolute old values.
What does a retrieval-triggered update look like in code?
Imagine a darkroom agent on darkroom-enlarger-bench-5. It recalls a contrast filter habit, then the printer corrects it mid-session. The app reconsolidates only because the retrieved memory was actually used and then contradicted.
import os
from engram import EngramClient, HybridRetrieval
client = EngramClient(api_key=os.environ["ENGRAM_API_KEY"])
printer = "printer-lea-vos"
bench = {"bench_id": "darkroom-enlarger-bench-5"}
def seed_rule():
run = client.memories.add(
"On darkroom-enlarger-bench-5, for muddy midtones on multigrade paper "
"start with a grade 2 filter and soft light.",
user_id=printer,
group="personalization",
properties=bench,
)
client.runs.wait(run.run_id)
def retrieve_for_turn(user_text: str):
hits = client.memories.search(
user_text,
user_id=printer,
group="personalization",
properties=bench,
retrieval_config=HybridRetrieval(limit=5),
)
return hits
def should_reconsolidate(retrieved, user_text: str) -> bool:
if not retrieved:
return False
correction_markers = ("actually", "not grade 2", "use grade 4", "correction")
return any(m in user_text.lower() for m in correction_markers)
def reconsolidate(user_text: str, assistant_text: str, retrieved):
if not should_reconsolidate(retrieved, user_text):
return None
cited = retrieved[0].content
run = client.memories.add(
[
{"role": "assistant", "content": f"I recalled: {cited}"},
{"role": "user", "content": user_text},
{"role": "assistant", "content": assistant_text},
],
user_id=printer,
group="personalization",
properties=bench,
)
status = client.runs.wait(run.run_id)
refreshed = retrieve_for_turn("multigrade filter grade muddy midtones")
return status, refreshed
seed_rule()
user_q = "Print looks muddy again on darkroom-enlarger-bench-5."
retrieved = retrieve_for_turn(user_q)
# Agent answers using retrieved[0], then user corrects:
user_fix = (
"Actually not grade 2. For muddy midtones on that bench use grade 4 "
"with less diffusion, not soft light."
)
assistant_ack = (
"Understood. I will treat grade 4 with less diffusion as the starting point "
"for muddy midtones on darkroom-enlarger-bench-5."
)
result = reconsolidate(user_fix, assistant_ack, retrieved)
if result:
status, refreshed = result
print("run", status.status)
for m in refreshed:
print(m.updated_at, m.content)
The important detail is the gate. Without should_reconsolidate, every polite acknowledgment would rewrite memory. With the gate, only turns that challenge a retrieved claim open the write path. Transform then performs the actual merge.
How do you keep reconsolidation from thrashing the store?
Log which memory ids were injected into the prompt. Only those ids are eligible for rewrite in that turn. Require an evidence snippet from the user or tool output in the correction payload. Cap reconsolidations per scope per hour for non-safety topics. For safety-critical rules, require dual confirmation before delete or rewrite.
Measure stale-fact errors on questions that previously failed after a correction. Measure duplicate rate for the same subject-relation key. Both should fall. If useful nuance disappears, your transform instructions keep too little history, or you are reconsolidating on weak signals.
Reconsolidation keeps individual recalled facts current. Over months, preferences can shift gradually without a single sharp correction. That slower movement needs its own drift policy on top of per-turn updates.
Our next chapter, How do you handle preference drift over time?, focuses on noticing and absorbing gradual changes in what users want without waiting for an explicit “actually” moment.