Skip to main content

Memory

A Memory is a named, versioned collection of small text files that persists across agent runs. Attach a memory to an agent and it appears as a directory inside the container — agents read and write it with their normal file tools, and every change is captured as a version you can audit and roll back.

Memories let agents carry context between sessions: user preferences, project conventions, prior decisions, and lessons learned.

CLI usage

# Create a memory
pai create memory user-prefs --description "Per-user preferences and project context."
pai create memory user-prefs --size 2Gi --retention-days 60

# List memories
pai get memories

# Describe a memory (entries, versions, retention, status)
pai get memory user-prefs

# Delete a memory (cascades all entries and versions)
pai delete memory user-prefs

# Archive a memory — makes it read-only and unattachable to new agents.
# One-way; to fully remove it, use `pai delete memory`.
pai memory archive user-prefs

Attaching a memory to an agent

Add spec.memories to your Agent. Each entry mounts a memory at the declared path; the agent reads and writes it like any other directory.

apiVersion: pai.io/v1
kind: Agent
metadata:
name: jane-bot
spec:
models:
- anthropic/claude-sonnet-4-6
system: |
You help Jane stay on top of her week.
memories:
- name: user-prefs
mountPath: /pai/memory/prefs
access: readWrite
instructions: "Check before starting any task. Update when Jane corrects you."
- name: company-standards
mountPath: /pai/memory/standards
access: readOnly

Per-attachment fields:

FieldTypeRequiredDescription
namestringYesMemory resource name in the same namespace
mountPathstringYesAbsolute path inside the container where the directory will appear
accessstringNoreadWrite (default) or readOnly
instructionsstringNoPer-attachment guidance shown to the agent alongside the memory's description (≤4096 chars)

A maximum of 8 memories may be attached to one agent. Mount paths must be unique per agent.

Read-only memories

Use access: readOnly for shared reference material the agent should not change — company conventions, formatting standards, frozen domain knowledge. Writes are blocked at the kernel level (Landlock LSM); the agent can still read freely.

Mixing read-only and read-write

A common pattern is to attach one read-write memory for the agent's own notes and one read-only memory for shared reference material:

memories:
- name: jane-prefs # personal — agent updates as it learns
mountPath: /pai/memory/prefs
- name: company-handbook # shared — read-only reference
mountPath: /pai/memory/handbook
access: readOnly

Templates and task agents

When a memory is declared on a template Agent, every task Agent that references the template inherits the attachment. Task Agents and Session resources may add or override entries by name (later wins on conflict), the same as spec.files and spec.skills.

How agents see a memory

Harness agents (task / template mode)

A note describing each attached memory is automatically prepended to the system prompt:

You have persistent memory across sessions. Read and write these directories with your normal file tools (read/write/edit/glob/grep):

  • /pai/memory/prefs (read-write) — Per-user preferences and project context.
    Check before starting any task. Update when Jane corrects you.
  • /pai/memory/standards (read-only) — Company formatting standards.

The agent then reads and writes the directory using its normal read, write, edit, glob, and grep tools — no special syntax. Writes are flushed back to the memory in the background and become available to future sessions.

Service agents (your own image)

The directory is mounted at the same path. Your agent code receives a PAI_MEMORIES_JSON environment variable describing every attached memory:

[
{"name": "user-prefs", "mountPath": "/pai/memory/prefs",
"access": "readWrite", "description": "...", "instructions": "..."}
]

Use it however you like — read the JSON to discover which paths are persistent memory, or just read/write the mounted directory directly. Writes are flushed back to the memory by the platform; your code does not need to do anything special.

Seeding initial content

For self-contained YAML examples, declare the initial entries inline on the Memory itself with spec.seed[]. The first time the memory's server starts, each seed entry is created if no file at that path already exists. Re-applies that change spec.seed are intentionally NOT propagated — agent writes always win, and seed only bootstraps an empty memory.

apiVersion: pai.io/v1
kind: Memory
metadata:
name: pairun-context
spec:
description: PaiRun platform architecture and conventions
seed:
- path: /architecture.md
content: |
# Architecture
...
- path: /conventions.md
content: |
- Use Python + FastAPI
- ...

Loading content from a file

For larger seeds, replace content with contentFile and point at a path relative to the YAML file's directory. The CLI inlines the file body before posting to the API server — the cluster only ever sees the resolved content.

spec:
seed:
- path: /pairun.md
contentFile: ./pairun-context.md # resolved client-side by `pai apply`
- path: /handbook.md
contentFile: ~/docs/handbook.md # absolute paths and ~ are honored

contentFile is a CLI convenience and only works through pai apply -f or pai create -f. It cannot be used when piping YAML from stdin and is not recognized by kubectl.

Use pai memory put to update entries after seeding.

Working with memory entries from the CLI

# List entries
pai memory ls user-prefs
pai memory ls user-prefs --prefix /preferences --depth 2

# Read an entry
pai memory cat user-prefs /preferences/formatting.md

# Create or update an entry
pai memory put user-prefs /preferences/formatting.md --content "Use 2-space indent."
pai memory put user-prefs /preferences/formatting.md --from-file ./formatting.md
echo "Use 2-space indent." | pai memory put user-prefs /preferences/formatting.md

# Rename
pai memory mv user-prefs /old/path.md /archive/path.md

# Delete
pai memory rm user-prefs /old/path.md

# Bulk import / export
pai memory import user-prefs --from-dir ./seed/
pai memory export user-prefs --to-dir ./backup/

pai memory put creates the entry on first write and updates it on subsequent writes — no separate create/update commands.

Versioning

Every write to a memory creates a new immutable version. Versions are kept for 30 days by default (configurable per memory). Use them to audit changes or roll back.

# List all versions for a memory
pai memory versions user-prefs

# Filter to one entry
pai memory versions user-prefs --path /preferences/formatting.md

# Show one version's content
pai memory show-version user-prefs user-prefs-0000007

# Restore a version — writes its content back as a new version (preserves history)
pai memory restore user-prefs user-prefs-0000007

The default retention keeps at least 5 versions per entry path even when older than the retention window, so memories that change rarely don't lose their history.

Redacting sensitive content

If an agent accidentally writes a secret into a memory, scrub it from history while preserving the audit trail (who did what, when):

# 1) Overwrite or delete the current entry so the leaked content is no
# longer the live value
pai memory put user-prefs /notes.md --content "redacted by ops 2026-04-23"

# 2) Redact the historical version that holds the leaked content
pai memory redact user-prefs user-prefs-0000012

Redact refuses to scrub the current head — write a new version (or delete the entry) first, then redact the older one.

spec.memories field reference

FieldTypeRequiredDescription
namestringYesMemory resource name in the same namespace
mountPathstringYesAbsolute path inside the container where the directory will appear
accessstringNoreadWrite (default) or readOnly. Read-only mounts are enforced at the kernel level.
instructionsstringNoPer-attachment guidance shown to the agent alongside the memory's description (≤4096 chars)

Limits

LimitValue
Size per entry100 KiB
Entries per memory2,000
Total size per memory100 MiB
Memories attached per agent8
Inline version body32 KiB (larger versions stream from the memory's storage)
Version history retention30 days (configurable; minimum 5 versions per entry always kept)
instructions per attachment4,096 characters

Cluster admins can raise the per-entry, entry-count, and total-size caps via Helm values.