Recall without a vector search: how Memoir finds what it knows
Most agent memory recalls by embedding the query and scanning vectors. Memoir recalls the way you'd browse folders: the agent sees the map of named paths, picks the relevant ones, and reads them — no embeddings, no similarity scan, no extra model.
"Recall" doesn't have to mean "embed the query and cosine-search a vector DB." That's the reflex, but it's a choice — and Memoir makes a different one. Because Memoir already organized every memory into a meaningful taxonomy at write time, recall becomes navigation. And the thing doing the navigating — your agent — is already an LLM, so it can do the choosing itself.
Memoir recalls the way you'd browse folders, not the way a search engine guesses: the agent sees the map of named paths, picks the relevant ones, then reads them. No embeddings, no similarity scan, no extra model.
Let's follow a returning chat. The user says: "set things up
the way I like them." Stored from earlier sessions are
preferences.ui.theme = "dark mode",
preferences.editor.keymap = "vim",
profile.personal.health = "allergic to penicillin", and
dozens more. Here's how the assistant finds the right ones.
Step 1 — get the map with memoir_summarize
The agent first asks for a histogram of stored paths, grouped by taxonomy depth. It's a pure structural scan — instant, no API key, no model:
memoir_summarize({ depth: 3 })
// →
{ "namespaces": { "default": {
"preferences.ui.theme": 1,
"preferences.editor.keymap": 1,
"profile.personal.health": 1,
"context.people.family": 2
}}}
The agent now sees what exists — readable paths, not opaque
vector ids. metrics.* and the internal
taxonomy namespace are excluded; this is user facts only.
Step 2 — the agent picks
The host model reads the map and selects the paths relevant to "the
way I like things" → preferences.ui.theme and
preferences.editor.keymap.
Memoir doesn't choose — the calling agent does, using
the full conversation it already has in context.
Step 3 — read exactly those with memoir_get
A batched exact-path fetch. No model, milliseconds:
memoir_get({ keys: ["preferences.ui.theme", "preferences.editor.keymap"] })
// →
[ { "key": "preferences.ui.theme", "content": "dark mode" },
{ "key": "preferences.editor.keymap", "content": "vim" } ] Drilling a large store
For a big store, the depth-3 map is huge — so the agent drills by depth instead. Ask for the top level, pick a branch, narrow, repeat. This is the O(log n)-shaped move: a constant-size prompt at every step.
Vector recall fans out — compare the query to everything. Memoir narrows in — walk the tree. O(n) scan vs O(log n) drill.
The recall modes
The caller-driven drill above (summarize → get) is the recommended
default, because the agent with full context picks the keys. There's
also a one-shot memoir_recall shortcut with a
mode for when the host can't drill:
single/tiered need a key and fall back to
lexical without one.
Why this works
Two ideas carry the whole design:
- Structure beats similarity. Because writes are classified into a meaningful taxonomy, reads are navigation. You don't guess relevance with vectors — you see the labels.
- The agent is already an LLM. Don't pay for a second model inside the memory layer to pick keys. Hand the map to the agent that already understands the conversation — keyless, low-latency recall by default.
Remember classifies a fact into a path; recall walks back to it. The intelligence lives in the structure — so finding a memory is browsing, not searching. The same flow powers the Claude Code, Hermes, and OpenClaw plugins.