Retain
Retain takes raw content, breaks it into atomic facts, and integrates each fact into the knowledge graph.
Pipeline
Section titled “Pipeline”Raw Content │ ▼[1. Find Relevant Memories] │ ▼[2. Extract Atomic Memories] │ ▼[3. Match Against Existing] ← per candidate │ ▼[4. Decide Operation] │ ▼[5. Execute]Phase 1: Find Relevant Memories
Section titled “Phase 1: Find Relevant Memories”Gather context from the existing knowledge graph before processing new content.
- Generate embedding of the incoming content
- Semantic search for top-k similar memories
- Graph traversal from anchor points: parents, siblings, children, relationship edges
Phase 2: Extract Atomic Memories
Section titled “Phase 2: Extract Atomic Memories”The LLM breaks raw content into individual facts.
- LLM receives raw content + relevant memories from Phase 1
- Extracts atomic statements — one fact per memory
- Classifies each statement’s layer and importance
Phase 3: Match Against Existing
Section titled “Phase 3: Match Against Existing”For each candidate, check if this fact already exists in the graph.
- Generate embedding for the candidate
- Scoped similarity search within the relevant neighborhood
- Fetch full memory + history for high-similarity matches
- Rank by similarity
Phase 4: Decide Operation
Section titled “Phase 4: Decide Operation”An LLM decides how to integrate each fact:
| Operation | Description |
|---|---|
| CREATE | New fact, no existing equivalent |
| UPDATE | Same entity, newer info supersedes |
| NOOP | Duplicate or irrelevant, skip |
Phase 5: Execute
Section titled “Phase 5: Execute”Atomically update the memory store and vector store:
- Execute the decided operation
- Link to parent concept (create if needed)
- Create relationship edges to related memories
Decision Model
Section titled “Decision Model”The decision in Phase 4 is non-deterministic. The same input can reasonably produce different outcomes:
- “Alice works at Beta” vs. existing “Alice works at Acme”
- Same Alice, job changed → UPDATE
- Different Alice → CREATE
- User correcting themselves → UPDATE
MemLayer guarantees invariants regardless of path:
| Operation | Invariants |
|---|---|
| CREATE | New memory ID, both old and new exist |
| UPDATE | Same entity, history preserved, old accessible via temporal query |
| NOOP | No changes |
curl -X POST http://localhost:8080/api/v1/retain \ -H "Content-Type: application/json" \ -d '{ "content": "Alice started working at Beta Corp in January 2025.", "source": "conversation" }'| Field | Type | Required | Description |
|---|---|---|---|
content | string | Yes | Raw content to ingest |
source | string | No | Origin identifier |