Skip to content

Memory Pipeline

Every meaningful exchange gets summarized, embedded, indexed, and made searchable across 44 per-agent SQLite databases. Search runs at 70% vector + 30% BM25 keyword hybrid.

Hybrid Retrieval

Storage · 44 SQLite DBs

Embedding

Inputs

Conversation chunks

Files / docs

Tool results

Voyage-4 via Portkey

(pc-opencl-22d508)

Embedding cache

(dedup by hash)

chunks_fts

FTS5 keyword index

chunks_vec

vec0 vector index

chunks

raw text + metadata

pending_saves

queue

dead_letters

failures

Vector search

weight 0.7

Keyword search

weight 0.3

Score fusion + rerank

memory_search

'find X'

Ranked results

  • Inputs: anything that flows through Claude — conversation text, file contents, tool results — gets queued for embedding.
  • Embedding: Voyage-4 via Portkey (config slug pc-opencl-22d508). Embeddings are cached by content hash so duplicate text doesn’t re-embed.
  • Storage: 44 SQLite databases at ~/.openclaw/memory/<agent>.sqlite. Each DB has 5 tables:
    • chunks — raw text + metadata
    • chunks_fts — SQLite FTS5 keyword index
    • chunks_vec — vec0 vector index
    • pending_saves — queue for async writes
    • dead_letters — failed embeddings for retry
  • Hybrid retrieval: when you call memory_search, both indexes run in parallel. Vector search weights 0.7 (semantic similarity); BM25 keyword weights 0.3 (exact match). Scores fuse and rerank.

Each agent has its own DB. The aurora agent’s memory is separate from acq’s. To search across all 44, the memory CLI accepts --agent <name> to scope or scan multiple.

Terminal window
python3 ~/.openclaw/tools/claude-memory.py search "your query"
python3 ~/.openclaw/tools/claude-memory.py search "your query" --agent acq
python3 ~/.openclaw/tools/claude-memory.py stats

Or via MCP from inside Claude: memory_search (openclaw-tools server) returns top-K hits.

~5,568 chunks fleet-wide as of last fleet check. Largest DBs are agent-specific working sets (aurora, acq, dispo); smallest are fresh agents (single-digit chunks).