Rekalldocs
Recipes

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.

claude_desktop_config.json
{
  "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

agent-memory.ts
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
}
agent_memory.py
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 ms

Because 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.

On this page