Skip to main content
Memory is what an agent learned from prior events that lets it behave like a teammate who’s been here before, instead of one that showed up this morning. An agent writes facts via memory_store and reads them back via memory_recall on the next event. Memory is always on — no setup, no flag.

The four categories

CategoryScopeLifetimeUse for
coreagentdurable; evicted last at the entry capLearned facts about durable entities — customers, accounts, preferences.
dailyagent72h auto-pruneTime-bounded follow-ups, open tickets, scheduled reminders.
conversationeventdies with the runWithin-run scratch — checkpoint findings during a long incident.
workspaceworkspacedurableFacts shared across every agent in the workspace.
Pick core for “would I want a future event to know this?” Pick daily for “this should expire on its own.” Pick conversation only for staging during a long run. Pick workspace only when multiple agents need the same fact.

The four tools

The agent calls these from inside a run; the runtime wires them to the memory backend.
ToolShapePurpose
memory_store(key, category, content, tags?)upsertWrite a distilled fact.
memory_recall(key)one entry or emptyExact lookup by key.
memory_list(filter)matching entriesFilter by category / tags / recency.
memory_forget(key)deleteRemove or correct a fact.
There is no vector search. Pre-filter with tags + categories + recency, then let the model reason over the candidate set.

Where memory fits in a run

The two memory touchpoints are at the start of a run (memory_recall before deciding) and at the end (memory_store after deciding what was learned). Anything writing to memory in the middle is probably scratch — that belongs in conversation.

What survives — selection and eviction

Hydration (what an agent sees at run start) and eviction (what the platform deletes at the per-agent entry cap) are both category-pinned: core wins.
  • Hydration fills a fixed byte budget: every core entry that fits loads first (newest first), then the newest non-core entries fill the remainder. A core fact written once — an owner, a deploy target, a customer’s plan — is still in context at entry 1001, even after a noisy month of daily writes.
  • Eviction at the entry cap deletes the coldest non-core entries first. A core entry is deleted only when nothing else remains.
  • Custom categories (and anything the platform doesn’t recognise) are windowed by recency — never silently pinned.
Selection is deterministic — same entries, same budget, same result — so “why does my agent remember X but not Y?” always has a checkable answer: X was core; Y was windowed, or too big for the budget. Four habits make selection work for you instead of against you:
  1. Store load-bearing facts as core. If a future event must know it, it’s core. Everything windowed ages out of hydration.
  2. Reuse stable keys. Re-storing a key refreshes the entry instead of duplicating it — deploy_target, not deploy_target_jun12.
  3. Forget what’s stale. memory_forget beats letting eviction pick the victim. Hoarding everything as core defeats the pinning: an all-core set over the cap evicts your coldest core facts.
  4. Keep entries small. The hydration budget is bytes, not entries — snapshot conclusions, not transcripts.

Entry format

Memory is stored in Postgres but exports as markdown for human review.
---
key: customer_bob_chen_acme
category: core
tags: [customer, plan_pro]
---

Bob Chen, Acme. Pro since Jan 15. API user (not dashboard), webhooks → Slack.
Prefers technical responses. Prior: Feb 3 signature issue (NTP).
Frontmatter is structured metadata; the body is the distilled prose the agent wrote.

Correcting what the agent learned

To remove or fix a fact, the agent itself calls memory_forget(key) followed by memory_store(...) with the corrected entry — typically driven from a steer message:
zombiectl steer zmb_2041 "forget customer_bob_chen_acme; Bob is now on the Enterprise plan"
The next event uses the corrected memory.

Isolation

Every memory operation is scoped by zombie_id. Agent A cannot read Agent B’s memory. The memory store is a separate Postgres database, not a shared filesystem — even an agent with shell or file tools can’t reach it through the wrong protocol.

Common questions

My agent keeps re-asking the user for the same info. Either memory_store isn’t being called at the end of the previous event, or memory_recall isn’t being called at the start of the next one. Audit your SKILL.md — recall must happen before the reasoning step. My agent remembers something stale. The underlying system changed but memory didn’t. Steer the agent to call memory_forget(key) and re-store the corrected entry. For systems-of-record that change frequently, build a sync job into the agent’s prose. Should I use core or conversation for this? conversation only for run-scoped scratch (e.g. checkpointing tool-call findings during a long incident — see How long does a run take?). Everything else is core or daily.

Troubleshooting

SymptomCauseFix
Recall returns nothing on a known entityInconsistent key conventionUse a stable, deterministic key derivation in SKILL.md (e.g. customer_<email-slug>).
Memory grows forevercore has no time-based pruning; at the entry cap, coldest core entries are evicted when no non-core entries remainSteer the agent to call memory_forget on stale keys, or move time-bounded entries to daily.
UZ-MEM-003 on storeMemory backend unavailableRe-run the trigger; if persistent, file an issue.
UZ-MEM-001 on storeMemory scope denied (cross-agent access attempt)Memory is per-agent. Use workspace-category writes if you need to share facts across agents.