Public beta — not for production use. Data may be wiped at any time. Questions? Contact us.
Documentation menu

Agent memory

How flows remember things across executions: sessions, episodic conversation history, consolidated semantic memories, and the axiom memory CLI.

View as Markdown

What agent memory is

Agent memory is Axiom's built-in durable store that lets a flow remember things across executions. Each execution of a flow is otherwise stateless: a node receives its input message, returns its output message, and the execution context is gone. Memory fills that gap — a customer-support flow can recall what a user said yesterday, and accumulate facts about its task over many executions.

Node code reaches memory through one entry point: ax.agent.memory on AxiomContext. There is nothing to provision and no connection string to manage. Memory is scoped to the flow: every execution of the same flow shares one memory store, and different flows have isolated stores. Tenant isolation is enforced by the platform, not by your code — the sidecar stamps your tenant and flow identity onto every memory call, and whatever a node puts in those fields is ignored (see Sandboxing and tenancy).

Outside node code, the axiom memory CLI lists, inspects, searches, and deletes memory, and the flow debugger shows memory reads and writes live as a flow runs.

The three memory tiers

Axiom separates "memory" into three tiers with different lifetimes:

Working memory: the typed payload

The message flowing through the flow is the working memory. If a node needs conversation context within a single execution, that context belongs in its input and output message types. This tier is explicit, typed by Protocol Buffers, and needs no memory API at all. See Type system.

Episodic memory: conversation history per session

Episodic memory is the time-ordered record of conversation turns within a session. Each turn has a role (user, assistant, tool, or system), a content string, and a timestamp. Node code appends turns and reads back the last N turns through the session API (below). Episodic memory is scoped to (tenant, flow, session) and is retained for a platform-configured period (90 days by default).

Semantic memory: long-term facts per flow

Semantic memory is the flow's long-term knowledge: concise factual statements distilled from episodic history by a background consolidation process (below). Each entry carries an importance score between 0 and 1 and a confidence score. Semantic memory is scoped to (tenant, flow) — it persists across sessions and executions — and is retrieved by semantic search. Node code can also write facts directly with ax.agent.memory.write(...).

Sessions

A session groups related conversation turns — typically one user's conversation thread. Your node code chooses the session ID (a string, usually taken from the input message) and addresses it with ax.agent.memory.session(session_id). The session object gives you:

  • history.append(role=..., content=...) — record a turn.
  • history.last(n) — read the most recent n turns.
  • search(query, limit=5) / write(content, importance=0.5) — session-scoped memory entries.
  • end() — formally close the session and trigger consolidation.

Sessions are not opened or declared anywhere; appending the first turn to a new session ID creates it. A session can also be closed from outside node code with axiom memory end <session-id>.

How consolidation works

Consolidation turns a session's episodic history into permanent semantic memory. It runs when a session is ended — either node code calls session.end() or you run axiom memory end <session-id>. When a session ends, the platform reads its conversation history, extracts distinct facts and preferences as concise statements, and stores them as flow-scoped semantic memories. Near-duplicate facts are merged rather than duplicated, so the same piece of information does not accumulate as redundant entries over time.

Consolidation is non-destructive — the conversation history remains readable after it runs. Extracted facts typically appear within a minute of ending a session. Until a session has been ended and consolidated, axiom memory show reports no semantic memories for it (facts written directly with write(...) are the exception — they appear immediately).

How memory search ranks results

ax.agent.memory.search(query) (and axiom memory search) searches the flow's memories and returns ranked results. The search combines keyword matching with semantic similarity, so relevant entries surface whether the query uses the exact same words or a different phrasing. Every returned entry includes its relevance score. The CLI also reports the retrieval method and the query latency in milliseconds.

Read and write memory from node code

Memory is available in every SDK language through AxiomContext. The example below is Python (see the per-language guides for the others); it assumes a package whose messages define ChatRequest with session_id and text fields and ChatReply with a text field. Declare the handler async def to await the memory APIs.

# nodes/chat_agent.py — node file in a Python package (axiom create node ChatAgent)
from gen.messages_pb2 import ChatRequest, ChatReply
from gen.axiom_context import AxiomContext


async def chat_agent(ax: AxiomContext, input: ChatRequest) -> ChatReply:
    """Replies using recent conversation turns and long-term facts."""
    session = ax.agent.memory.session(input.session_id)

    # Episodic: record this turn, then load recent history.
    await session.history.append(role="user", content=input.text)
    recent = await session.history.last(20)

    # Semantic: retrieve facts consolidated from earlier sessions of this flow.
    facts = await ax.agent.memory.search(input.text, limit=5)

    reply = f"I see {len(recent)} recent turn(s) and {len(facts)} relevant memorie(s)."
    await session.history.append(role="assistant", content=reply)
    return ChatReply(text=reply)

ax.agent.memory.write(content, importance=0.5) stores a flow-scoped fact directly and returns the new memory's ID; session.write(...) does the same at session scope. You never pass tenant or flow identifiers — the platform injects them.

Inspect memory with the CLI

The axiom memory command group inspects and manages agent memory from your terminal. All commands require an active login (axiom login); memory data lives in the Axiom platform, with no local state.

# Requires: axiom CLI installed and logged in (axiom login)
axiom memory ls                                    # flows that have memory
axiom memory ls --flow <flow-id>                   # sessions for one flow
axiom memory show <session-id>                     # conversation + semantic memories
axiom memory search --flow <flow-id> "the query"   # semantic search over a flow's memories
axiom memory end <session-id>                      # close a session, trigger consolidation
axiom memory rm <session-id>                       # delete one session
axiom memory rm --flow <flow-id> --all             # delete all memory for a flow

rm deletes permanently and end closes a session; both ask for confirmation unless you pass --yes. For a worked walkthrough, see Inspect agent memory; for every flag, see the axiom memory CLI reference. While debugging a run, the flow debugger also displays each memory read and write as it happens — see Debug a flow.