Skip to main content

Memories

Named containers for storing and retrieving knowledge entries within a project.

Overview

Memories provide a logical namespace for text content that agents can read and write during generation. Each memory holds many memory entries — individual pieces of text that are automatically embedded for semantic search via the Knowledge module.

Agents can retrieve relevant entries automatically via knowledge_config and write new facts using the built-in write_memory tool. See Agent Integration for details.

See the Permissions Reference for the IAM action strings for this module.

Data Model

Memory

FieldTypeDescription
idstringPublic ID (mem_ prefix)
project_idstringID of the owning project
namestringHuman-readable name
descriptionstring | nullOptional description
tagsstring[] | nullOptional labels for filtering by category
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last-updated timestamp

Memory Entry

Memory entries are the individual knowledge items stored inside a memory. When an entry is created or updated, its content is automatically embedded for semantic similarity search.

FieldTypeDescription
idstringPublic ID (mem_entry_ prefix)
memory_idstringID of the parent memory
contentstringText content of the entry
source_typestringHow the entry was created: manual (default), agent, or extraction
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last-updated timestamp

Key Concepts

Write Algorithm

Every write to a memory — via REST, agent tool, or extraction — goes through the same deduplication algorithm.

When you call POST /api/v1/memory-entries (with memory_id in the body), the server:

  1. Embeds the incoming content.
  2. Finds the most similar existing entry in that memory (cosine similarity via pgvector).
  3. Decides based on two configurable thresholds:
Similarity rangeDecisionWhat happens
duplicate_thresholdSkipThe fact is already known. Returns the existing entry unchanged.
update_thresholdMergeThe fact overlaps. The two facts are consolidated into the existing entry (see below).
< update_thresholdCreateThe fact is new. A new entry is created.

On Merge, writes made during a generation (the write_memory tool and automatic extraction) consolidate the existing and incoming facts into a single atomic fact using the agent's LLM — contradictions resolve in favour of the new fact. Writes without an agent context (the manual POST /api/v1/memory-entries endpoint) append the incoming content instead. Consolidation is best-effort: if the completion fails, the write falls back to appending, so a merge never loses content.

See all three outcomes in action in Agent with Persistent Memory - Step 5 (Write memory entries).

Request Fields

FieldTypeDefaultDescription
contentstringThe fact or observation to write
source_typestringmanualHow the entry was created: manual, agent, extraction
duplicate_thresholdnumber0.95Similarity above which the write is skipped
update_thresholdnumber0.75Similarity above which entries are merged

Response action Field

The response always includes an action field alongside the entry:

actionHTTP statusMeaning
created201New entry written
updated200Existing entry merged with new content
skipped200Duplicate detected — existing entry returned

Tag Filtering

Tags are free-form strings attached to a memory at creation or update time.

POST /api/v1/memories
{
"project_id": "proj_abc",
"name": "Customer Preferences",
"tags": ["customer", "crm", "user-prefs"]
}

Use the tags query parameter on GET /api/v1/memories to filter. The parameter supports glob patterns:

PatternMatches
crmOnly crm (exact)
customer*customer, customer-support, customer-prefs
user-?refsuser-prefs, user-xrefs, etc.

Multiple patterns are ORed — a memory is included if any of its tags match any pattern. The same glob syntax applies to memory_tags in Knowledge search.

Agent Integration

Agents can read from and write to memories automatically during generation.

Automatic Knowledge Retrieval

Set knowledge_config on an agent to have the server search relevant memory entries before every generation and inject them as a delimited reference-context message (never as system content, since memory entries can be user-derived). See Knowledge Config in the Agents module.

write_memory Tool

Set write_memory_id in the agent's knowledge_config to automatically inject a write_memory tool into every generation. The tool accepts a single content input — the atomic fact to write. The target memory is fixed by write_memory_id; the agent cannot choose a different memory. Entries written by the tool are tagged with source_type: "agent".

{
"knowledge_config": {
"memory_ids": ["mem_alice"],
"write_memory_id": "mem_alice"
}
}

You can set write_memory_id to the same memory used for retrieval (so the agent reads from and writes to the same pool) or to a separate memory.

Automatic Extraction

Set extraction alongside write_memory_id to have the server extract facts from completed generation turns automatically — no explicit write_memory call by the agent is needed. Pass true for the defaults, or an object to customize the provider, model, and prompt used for extraction:

{
"knowledge_config": {
"write_memory_id": "mem_alice",
"extraction": true
}
}
{
"knowledge_config": {
"write_memory_id": "mem_alice",
"extraction": {
"ai_provider_id": "aip_cheap",
"model": "gpt-4o-mini",
"prompt": "Extract only customer food preferences and dietary restrictions."
}
}
}

How it works:

  • After a conversation, session, or direct agent generation completes, the server runs a fire-and-forget extraction step. It never blocks or fails the generation response.
  • The extraction step sends the turn's transcript as a plain completion (no tools, no knowledge injection) and asks for a JSON array of atomic facts. Transient content such as greetings is skipped.
  • Each candidate fact (at most 20 per turn) goes through the standard write algorithm — duplicates are skipped, related facts are merged. Entries are tagged with source_type: "extraction".
  • A summary ({ candidates, created, updated, skipped }) is recorded on the originating generation's metadata.extraction field for observability via the Generations API.

Object form fields (all optional):

FieldDefaultDescription
enabledtrueSet false to keep the configuration but disable extraction
ai_provider_idagent's providerProvider override for extraction calls — must belong to the agent's project
modelsee belowModel override for extraction calls
promptbuilt-in instructionsReplaces the default task instructions; the JSON response contract and the transcript are always appended

Model resolution order: extraction.model → the override provider's default_model (when ai_provider_id is set) → the agent's model → the agent provider's default_model. A provider override switches the fallback to that provider's default because the agent's model name is usually meaningless on a different provider.

The custom prompt controls what to extract, not the response format — the server always appends the JSON-array contract line and the conversation transcript, since the extraction parser accepts nothing else.

Extraction is opt-in and requires both fields: extraction without write_memory_id does nothing. Streaming generations and requires_action (client-tool) turns do not trigger extraction; the turn must complete in the same request.

See it end to end in Agent with Persistent Memory - Step 11 (Enable automatic extraction).

Examples

Create a memory

soat create-memory \
--project-id proj_ABC \
--name "Customer Preferences" \
--tags '["customer", "crm"]'

Write a memory entry

soat create-memory-entry \
--memory-id mem_01 \
--content "Customer prefers email over phone calls"