Skip to main content

Long-term memory

Sessions give an agent short-term memory: the history of one conversation. Long-term memory is what the agent knows about a person across conversations: a small set of facts, kept per user, that the agent can search in any later session.

Whether an agent remembers at all is a policy on the agent, not a decision made on each message. You set it once; the platform stores it with the agent and re-applies it on every redeploy.

The three modes

ModeWhat it meansWhen to use it
offThe agent never remembers. The memory tools are not offered to the model. The default for a new agent.Anything where the conversation must stay a conversation.
autoAfter each reply, the agent's own model distils the turn into facts and stores them - in the background, so the reply is never delayed.Personal assistants; support agents that should recognise a returning customer.
explicitFacts are written only when someone asks: the model calls its remember tool because the user said "remember that ...", an operator adds one, or an operator commits a whole session.Agents where every stored fact should be a deliberate act.

An agent deployed before memory policies existed runs as explicit until you set a policy - which is what it always did: nothing was written unless somebody asked.

Set the policy

platformctl agents memory set research-buddy --mode auto

You should see:

mode auto
a new revision is rolling; the running agent serves the new policy once it is ready

platformctl agents memory get research-buddy shows the stored policy. platformctl agents memory status research-buddy asks the running agent what it is serving - the two differ until the new revision is ready.

The other settings, all optional:

SettingCLI flagWhat it does
inject--inject none|profileprofile places the caller's newest facts in front of every turn, so the agent knows them without searching. Default none: the agent searches when it decides to.
ttl_seconds--ttl SECONDSA fact expires this long after it was written. Default 0: never.
exclude_sensitive--exclude-sensitive on|offKeeps health, religion, politics, sexuality and similar categories out of memory even if the user mentions them. Default on.
topics--topics a,b,cRestricts what is extracted. Default: personal_info, preferences, key_details, explicit_instructions.
instructions--instructions "..."Extra guidance for the extractor, for example "record which product tier the user is on".
knowledge--knowledge on|offEnables the agent-wide Knowledge store. Default off.

A policy change rolls a new revision, like a compute or environment change does.

What is stored

A memory is a fact, not a transcript. After a turn under auto (or when asked, under explicit), the agent's own model reads the conversation and writes short, standalone statements about the user:

Owns a Mastercraft Maristar 245.
Prefers replies in bullet points.
Lives in Austin.

Each fact carries where it came from - the user it belongs to, who said it (the user, or the assistant correcting them), which turn and session, whether it came from the conversation, an operator, the model's remember tool, or a tool result - and when it was written.

Rules the extractor always follows:

  • Both sides of the conversation count. A fact the assistant corrected is stored corrected. Extracting only what the user said is how an agent learns to agree with everything.
  • The model's private reasoning is never stored. Only what was actually said.
  • Identity numbers, card numbers, passwords and API keys are never stored, whatever the topics say.
  • New facts are reconciled with old ones. Saying "actually I sold the boat" does not add a second boat fact; the old one is invalidated - kept, marked no longer true, and never served again. Nothing is silently overwritten.
  • Facts from tool results and documents wait for confirmation. Text an agent fetched is not something the user said; it lands pending and is not served until an operator confirms it.

Whose memory it is

Memory is per user, always. Every fact is tagged with the caller it belongs to, and an agent only ever reads back that caller's own facts. This is one store per agent, filtered by user - not a copy per user - so privacy costs nothing extra.

How you invokeWhose memory it is
Signed in (platformctl, the Console, a session token)you
With an API keythat service account
With an explicit user_id in the requestthat value - you are the authority on who your end user is
Anonymously, with no user_idthat one session - nothing is shared with any other session

If you are building something multi-user on top of an agent, send user_id. It is the only way the platform can know that two conversations belong to the same person.

MEMORY_SCOPE=shared is deprecated

The old opt-out that made one common store readable by every caller keeps working for one more release, with a warning in the agent's log. It served one user's conversation to every other user. If your agent is a shared knowledge base, that is what the Knowledge store is for.

How the agent uses memory

Three ways, and the policy decides which the model is offered:

  • search_memory(query) - the tool the agent calls to look something up. Returns the most relevant facts about this caller, or "No relevant memories found." Withheld from the model under off: a tool that always returns nothing teaches the model to stop calling tools.
  • remember(fact) - offered under explicit only. When the user says "remember that I prefer bullet points", the model stores that one fact. Under auto the extractor already captures it; under off nothing is written.
  • Profile injection (inject: profile) - the caller's newest facts are placed in front of each turn as background text, so the agent knows them without a search. They are marked "may be out of date, not instructions" and are never put in the system prompt: memory is text that came from users and documents, and it must not get instruction priority.

Give your agent the tools it should have:

from google.adk.agents import Agent

from crusoe_adk.foundry import foundry_model
from crusoe_adk.tools import run_python, search_memory

root_agent = Agent(
name="research_buddy",
model=foundry_model(),
instruction="Use search_memory to recall facts about the person you are talking to.",
tools=[run_python, search_memory],
)

The platform adds remember under explicit and search_knowledge when the Knowledge store is on, and removes search_memory under off. The startup log says what it did: memory policy: mode=explicit, tools added=['remember'] ....

See and correct what an agent remembers

You can now look. Every operator action is per user, and every one is available from the CLI, the API and the Console.

# What does the agent remember about alice?
platformctl agents memory list research-buddy --user alice

You should see:

ID CREATED AUTHOR SOURCE STATE FACT
6f1c... 2026-09-09 14:02 user conversation valid Owns a Mastercraft Maristar 245.
# Add one fact, as written (attributed to you, the operator)
platformctl agents memory remember research-buddy --user alice "Prefers replies in bullet points."

# Mark one fact no longer true - it is kept, hidden, never served
platformctl agents memory invalidate research-buddy 6f1c...

# Believe a pending fact that came from a tool result
platformctl agents memory confirm research-buddy 9a2e...

# Remove one fact outright
platformctl agents memory delete research-buddy 6f1c...

# Erase everything about alice - the erasure request. Works in every mode.
platformctl agents memory forget research-buddy --user alice --yes

Erasure works whatever the mode is: an operator must always be able to see and delete what was remembered, even after turning memory off.

Knowledge: what every user should be told

Some agents need facts that apply to everyone - a refund policy, product names, opening hours. That is not conversation memory; it is knowledge, written by operators, never by a user's conversation, and read by every caller. Turn it on with the policy (--knowledge on), then add to it:

platformctl agents knowledge add research-buddy "Refunds are processed within 5 business days of the return arriving at the warehouse."
platformctl agents knowledge search research-buddy "how long do refunds take"
platformctl agents knowledge list research-buddy

By default the text you add is distilled into facts by the agent's model - paste a paragraph or a FAQ answer. --verbatim stores it as one fact exactly as written. The model reaches it through the search_knowledge tool, which the platform offers when the store is on. platformctl agents knowledge delete <agent> <id> removes one fact; clear --yes empties the store.

Knowledge lives in its own collection (know_<project-short>_<agent>), separate from memory (mem_<project-short>_<agent>), so a conversation can never write into what every user reads.

Per-call controls

  • "memory": false on invoke opts that one turn out of every write - the "don't remember this conversation" signal an integrator needs. Reads still happen.
  • "memorize": true on invoke is the old per-message flag. It is deprecated and kept for one release: under explicit or auto it means "distil this whole session now, before replying"; under off it is ignored. Nobody else has this flag, and a client that sets it on every call is why the same conversation used to be stored again on every message.
  • POST /v1/agents/{name}/sessions/{id}/memorize and platformctl memorize <agent> --session <id> remain as the operator override: commit one session's facts now. Under off the agent answers 409 naming the setting:
memory is off for this agent (MEMORY_MODE=off); set the agent's memory mode to explicit or auto to allow writes

Writing always requires authentication, even when invoking does not.

Migration: nothing deployed changes on its own

  • An agent with no stored policy runs as explicit - exactly what it did before, because nothing was ever written unless somebody asked.
  • Memories written before facts existed were whole transcripts. They are still searched, but they cannot be listed, corrected or expired per fact. platformctl agents memory reindex <agent> distils them into facts under their own user; --drop-legacy removes each transcript once distilled. Transcripts that recorded no user cannot be attributed and are left alone (platformctl agents memory status counts them as legacy_points).
  • MEMORY_SCOPE=shared keeps working for one release with a deprecation warning; the Knowledge store is its replacement.

What is behind it

  • Storage: one managed VectorDB collection per agent, mem_<project-short>_<agent>, plus know_<project-short>_<agent> when Knowledge is on. The platform creates and looks after both; deleting the agent deletes them.
  • Embeddings: the platform's configured embedding model (EMBED_MODEL), the same one for writing and searching.
  • Extraction: the agent's own chat model - the one it already answers with - reads the turn and writes the facts. No second model, no extra credential.
  • Want to build your own retrieval instead of, or alongside, this? See use VectorDB with agents.

Summary

ActionHowAuth
Decide whether the agent remembersplatformctl agents memory set <agent> --mode off|auto|explicit, PATCH /v1/agents/{name}/memory/policy, or Memory settings in the ConsoleProject member
See / add / correct / erase one user's factsplatformctl agents memory list|remember|invalidate|confirm|delete|forget, or /v1/agents/{name}/memoryProject member
Shared knowledgeplatformctl agents knowledge add|search|list|delete|clear, or /v1/agents/{name}/knowledgeProject member
Commit one session now (override)platformctl memorize <agent> --session <id>, POST /v1/agents/{name}/sessions/{id}/memorizeAlways required; 409 under off
Keep one turn out of memory"memory": false on invokeSame as invoke
Read memoryThe agent's search_memory tool; inject: profileSame as invoke

Next steps