| name | slm-recall |
| description | Search and retrieve facts, decisions, and past context from SuperLocalMemory. Use when the user asks to recall, find, search, or "what did we decide/say about X". Triggers multi-channel semantic retrieval with reranking; always call before storing anything new. |
| when_to_use | - "What did we decide about X?"
- "Recall anything about Y"
- "Do we have context on the Z feature?"
- "Find stored information about authentication / the database / error handling"
- "Search for what I said about Y"
- Automatically before any non-trivial task, to surface prior context
|
| allowed-tools | recall, search, fetch, list_recent, Bash |
slm-recall — Search & Retrieve Memory
Retrieve stored facts, decisions, and past context from SuperLocalMemory using
multi-channel retrieval. The golden rule: recall before you remember.
When to use recall vs search vs fetch vs list_recent
| Situation | Tool |
|---|
| Conceptual or paraphrase query ("what did we agree on for auth?") | recall — full multi-channel retrieval + rerank |
| Exact keyword match needed ("find facts containing BM25") | search — FTS5 BM25 only, lower latency |
You have a specific fact_id from a prior result | fetch — exact lookup, full detail |
| Browse newest entries without a query | list_recent |
Use recall as the default. search is a fallback for zero-result recall on a
known exact term. fetch is for when you already know the ID.
Recall-before-remember discipline
Before storing anything new, always call recall first. If a near-duplicate
fact already exists, call update_memory(fact_id, content) to refine it
rather than creating a duplicate. Duplicates degrade retrieval quality for
every future session.
MCP-first workflow
1. Standard recall
recall(
query="authentication strategy decision",
limit=20, # default 20; reduce to 5 for quick pre-task checks
session_id="<sid>", # pass the session_id returned by session_init
fast=False, # default False; True skips SpreadingActivation channel
)
Real response shape (--json equivalent):
{
"success": true,
"results": [
{
"fact_id": "f8a2bc91",
"content": "Decided to use JWT with 1h expiry for API auth (2026-06-10)",
"score": 0.87,
"confidence": 0.91,
"trust_score": 0.84,
"fact_type": "decision",
"channel_scores": {
"semantic": 0.88,
"lexical": 0.61,
"temporal": 0.72,
"structural": 0.55
}
}
],
"count": 1,
"query_type": "semantic",
"channel_weights": {
"semantic": 0.4,
"lexical": 0.2,
"temporal": 0.2,
"structural": 0.2
},
"retrieval_time_ms": 134,
"no_confident_match": false
}
Always check no_confident_match. When true, no result cleared the
evidence floor. Do not invent a memory — tell the user nothing was found and
offer to search more broadly or store a new fact.
2. Passing session_id
Pass the session_id returned by session_init. It threads engagement signals
through to the ranker so each recall contributes to improving retrieval for
your project over time. Omitting it degrades the learning loop — recall works
correctly, but feedback is not attributed to the session.
3. Fast mode
Use fast=True for pre-tool-call checks where sub-second response matters.
This skips the SpreadingActivation channel. The remaining channels — semantic,
lexical, temporal, and structural — still run.
recall(query="rate limiting approach", limit=5, session_id="<sid>", fast=True)
4. Keyword fallback via search
When recall returns zero results on a specific term, try search:
search(query="BM25 indexing", limit=10, profile_id="")
profile_id="" uses the active profile. Response has success, results,
and count but no channel_scores or query_type.
5. Pull full detail for a known fact
fetch(fact_ids="f8a2bc91,d4c1e203")
Returns the full record for each ID: entities, lifecycle, access_count,
importance, observation_date, referenced_date. Use this when the recall
summary (120-char truncation in list_recent) is not enough.
6. Browse recent memories
list_recent(limit=20, profile_id="")
Returns facts newest-first. Content is truncated to 120 chars. Use fetch
once you have the fact_id for full content.
How multi-channel retrieval works
recall runs four channels in parallel — semantic vector similarity, lexical
BM25, temporal recency, and structural/graph — then fuses them with Reciprocal
Rank Fusion (RRF) and applies a reranker. The channel_weights field in the
response shows how each channel contributed for that query. Weights adapt over
time based on engagement signals attributed via session_id.
To inspect per-channel scores for a real query against your own data:
slm trace "<query>" [--limit N] [--json]
No benchmark numbers are cited here; performance is workload-dependent.
CLI fallback (when MCP is unavailable)
slm recall "<query>" [--limit N] [--fast] [--json]
slm recall "<query>" --include-global --include-shared
slm search "<query>" [--limit N] [--json]
slm trace "<query>" [--limit N] [--json]
slm list [--limit N] [--json]
Flags verified in source (main.py):
slm recall: --limit, --fast, --json, --include-global / --no-global, --include-shared / --no-shared
slm search: --limit, --json
slm trace: --limit, --json
slm list: --limit / -n, --json
Multi-scope (v3.6.15, opt-in): recall is shared-OFF by default — it returns only
this profile's facts. Pass --include-global / --include-shared (or the MCP
include_global / include_shared args) to opt in for a query, or set the defaults in
your mode_a/b/c.json config. See docs/shared-memory.md.
Flags that do NOT exist (fabricated in old skills — never write these):
--min-score, --format, --project, --tags on recall or search.
Never fabricate a memory
If results is empty or no_confident_match is true, report it plainly.
Never construct a response as if a memory was found when it was not. The user
trusts that what you surface came from the store.
SuperLocalMemory v3.6.18 · Qualixar · AGPL-3.0-or-later