Agent inner-loop memory
Give an agent a memory it can query hundreds of times per task without blowing the latency budget — ~4 ms per read, with a confidence signal to branch on.
At ~4 ms per query on a CPU, Rekall is fast enough to sit inside an agent's inner loop.
Write observations to a store as the agent works; search that memory every step; branch on
confidence. Two ways to wire it up: the built-in MCP server, or the SDK directly.
One store per agent or session
Stores are cheap and fully isolated. Use one per agent, task, or session — e.g.
agent-<sessionId> — so an agent's memory never leaks across tasks. Delete the store when
the task ends.
Variant A — MCP (zero glue code)
Point your agent host at rekall mcp (see the MCP guide). The agent
gets rekall_search and rekall_ingest tools with millisecond latency. The model calls
them like any other tool; confidence and trace come back in the tool result, so the
agent can decide whether to trust a memory or keep reasoning.
{
"mcpServers": {
"rekall": {
"command": "rekall",
"args": ["mcp"],
"env": { "REKALL_API_KEY": "rk_…" }
}
}
}A turn then looks like: the agent calls rekall_ingest to remember an observation, and
rekall_search to recall relevant memories before acting — no retrieval code in your app.
Variant B — SDK inner loop
import { Rekall } from "rekall-search";
const rekall = new Rekall();
const memory = await rekall.store(`agent-${sessionId}`);
// Remember an observation.
async function remember(step: number, text: string) {
await memory.ingest([
{ id: `obs-${step}`, text, metadata: { step, ts: Date.now() } },
]);
}
// Recall before acting.
async function recall(query: string) {
const r = await memory.search(query, { maxResults: 3 });
if (r.confidence < 0.5) return null; // nothing solid remembered yet
return r.passages.map((p) => p.text);
}
// Inner loop
for (let step = 0; step < maxSteps; step++) {
const context = await recall(currentGoal); // ~4 ms
const observation = await act(currentGoal, context);
await remember(step, observation); // ~4 ms
}import time
from rekall import Rekall
rekall = Rekall()
memory = rekall.store(f"agent-{session_id}")
def remember(step: int, text: str):
memory.ingest([
{"id": f"obs-{step}", "text": text, "metadata": {"step": step, "ts": time.time()}},
])
def recall(query: str):
r = memory.search(query, max_results=3)
if r.confidence < 0.5: # nothing solid remembered yet
return None
return [p.text for p in r.passages]
# Inner loop
for step in range(max_steps):
context = recall(current_goal) # ~4 ms
observation = act(current_goal, context)
remember(step, observation) # ~4 msBecause writes are incremental (no reindex) and reads are single-digit milliseconds, the agent can consult and update its memory as often as it likes — the memory reasons over what it has seen, following chains across earlier observations rather than matching the last thing it wrote.
Python SDK
rekall-search — the same shape as the TypeScript SDK, Pythonic surface. Sync-first with AsyncRekall, search_many for eval loops, and LangChain / LlamaIndex adapters in-package.
LLM fallback on low confidence
Take the 4 ms path for most queries; escalate to an LLM only when Rekall's confidence says the question is hard. The core composability pattern.