WOLBΛRG

Memory as Infrastructure

Why agent memory increasingly looks like a durable system layer—and what changes when you treat it that way.

Atharv Munde

Building Wolbarg — local-first semantic memory for AI agents.

  • Wolbarg
  • AI memory architecture
  • semantic memory
  • multi-agent systems
  • local-first
  • agent memory

Every AI framework has tools. Every AI framework has models. Very few have a real memory layer.

Open a typical agent codebase and you will find model clients, tool registries, prompt templates, maybe a graph runner. Memory usually arrives later: chat history, a thin wrapper around a vector database, or whatever convenience the framework shipped so demos do not look amnesiac. It is treated like a helper—something you attach to an agent the way you attach a logger.

That works until the agent dies. Or until you rewrite it in a different framework. Or until a second agent needs the same facts and you realize the first agent's "memory" was never a system—just a private bag of embeddings that vanished with the process.

The rest of this post is about that gap: why it appears, when the usual approaches are fine, and what changes when knowledge outlives the agent that produced it.

Agents Are Cheap. Knowledge Isn't.

Most of the churn in AI engineering is orchestration churn. Last year your agents lived in one library. This year they live in another. Those libraries are often reasonable—they solve different slices of prompting, tools, and streaming. What they do not share is a memory model that outlives the choice.

So teams rebuild memory every time. Re-ingest the same docs. Re-embed the same project notes. Re-discover that the auth service uses short-lived cookies, because the agent that learned it last week no longer exists as a running process.

If you nest memory inside the agent, knowledge inherits the agent's lifetime. That is usually the wrong lifetime. Agents are scripts. A user preference, a failed migration, or a negotiated constraint is closer to application state. It should survive redeploys the way a database does.

There is a second version of the same mistake: making memory native to one framework. Convenient while you stay inside one ecosystem. Awkward the day half your system is a streaming route in one stack and a batch worker in another. Suddenly you have two implementations, or you are copying vectors between them, or you are pretending the boundary does not exist.

Neither pattern is careless. Both match how application code is organized. The question is whether that organization still fits once agents become collaborative and long-lived.

Shared vs Isolated Is a Real Tradeoff

Isolated memory is often correct.

A disposable extraction worker should not write into your production knowledge base. A personal assistant with hard tenancy boundaries may need one store per user. Tests should wipe one agent's state without nuking another. When something weird gets recalled, debugging is easier if only one writer could have put it there.

Isolation is also the path of least resistance. Each agent owns a vector index. Ownership matches the class hierarchy. No shared locks. No awkward questions about who can read what. For single-agent apps, that is usually enough.

The picture changes when agents are roles in a longer workflow rather than independent apps. Research writes findings. Planner consumes them. Reviewer joins late and should not re-read the whole corpus to learn what already failed. If each role keeps a private index, you either duplicate embeddings or invent handoff protocols. Both are fine until the handoffs become the product.

Sharing does not mean unrestricted access. It means one governed store with filters—organization, agent, session, metadata—so retrieval stays scoped. Knowledge becomes a resource the system manages, not scratch space that evaporates when a role exits.

I keep seeing teams invent this accidentally. They paste summaries between agents. They write JSON into a shared folder. They stuff a growing context.md into every prompt. Those are memory systems with worse APIs. The obvious next step is to stop improvising and treat the store as its own layer.

What That Looks Like in Practice

Wolbarg is my attempt at that layer: a TypeScript library you point at storage and an embedding provider, then call from whatever agent loop you already run.

import { wolbarg, sqlite, openaiEmbedding } from "wolbarg";

const memory = wolbarg({
  organization: "acme",
  storage: sqlite("./memory.db"),
  embedding: openaiEmbedding({ apiKey: process.env.OPENAI_API_KEY! }),
});

await memory.remember({
  agent: "research",
  content: { text: "Auth cookies expire after 15 minutes." },
});

const hits = await memory.recall({ query: "session TTL", topK: 5 });

Default storage is SQLite—a file on disk, local-first, no cluster required to get something useful running. PostgreSQL is available when you want networked writers or you already operate Postgres. Embeddings and LLMs are injected providers, so the application API stays stable while the engines underneath change.

Treating memory as a service also changes what you expect from the API. When a recall looks wrong, you need diagnostics—not another prompt tweak—because "the model forgot" is often a retrieval failure. When the store holds real state, you want checkpoints the way you want database backups. When knowledge arrives as documents rather than chat turns, you need ingest, chunking, and sometimes compression. And when you instrument the system, telemetry belongs in a separate event database so observation does not contend with the tables it is observing.

None of that is exotic. It is what you would expect if someone said "build a memory service" instead of "add memory to this agent class."

Similarity search alone still leaves something missing. Memories are not isolated vectors. Related observations form a connected graph: a finding points to the constraint that invalidated it; an entity links to the decisions that mention it.

An optional graph layer (SQLite graph or Neo4j) lets you traverse those relationships, discover connected knowledge, and pull richer context into a recall than nearest-neighbor ranking provides by itself.

Once that store sits under multiple agents and frameworks, the next question is operational: how do you see what it contains?

Observability for a Memory Layer

Databases have consoles. Traces have explorers. If memory is infrastructure, it needs the same class of tooling—otherwise failures stay invisible.

You need to inspect what was stored, debug why a recall ranked the way it did, understand relationships between memories, visualize graph connections, and watch the store evolve as agents write. Without that surface, semantic systems fail quietly. A bad answer looks like a model problem when the real issue is a filter, a missing edge, a stale embedding, or a checkpoint you forgot you took.

Wolbarg Studio is that surface: a local UI against the memory and telemetry databases. With the graph layer enabled, the explorer shows links, entity attachments, and whether a traversal is about to drag related context into a recall.

Wolbarg Studio Graph View

The point is not a dashboard for its own sake. It is the same reason you would not run Postgres without a way to inspect rows and plans. Memory that you cannot examine is memory you cannot trust.

Sitting Under Existing Frameworks

None of this requires replacing your stack.

Wolbarg sits underneath the frameworks you already use—OpenAI, LangChain, LlamaIndex, Mastra, Vercel AI SDK—through thin adapters that map middleware, memory blocks, processors, or session callbacks onto the same client. Framework types stay in @wolbarg/* packages. Core wolbarg stays a memory library.

Keep your existing framework. Replace the memory layer.

If you are going to put a shared store under production agents, you will also want evidence that the backends behave under load—which is why the project ships benchmarks rather than a single latency claim.

Benchmarks, Briefly

The suites cover inserts, recalls, concurrency, and graph traversal on both SQLite and PostgreSQL. From the storage suite (mock embeddings, 1,000 memories, localhost):

Search / recall at 1,000 memories (ms) — lower is better
Cold startup (ms) — lower is better

Same machine, same SDK path. The gap is mostly process and socket overhead, not query cleverness. At this scale the bottleneck is usually the embedding call or the agent loop—not the local store.

The useful split is storage stress versus live provider spots. Mock embeddings for contention and ramp tests, because API rate limits will fail long before your database does. Live spots when you care about end-to-end behavior with real embedders. Mixing those two produces charts that look impressive and explain nothing.

Use the suite against your deployment shape. Local file, multi-writer Postgres, and graph walks behave differently. Predictability under your workload matters more than a leaderboard.

Closing

For years we treated memory as another feature inside AI frameworks—useful, optional, nested next to the agent that happened to create it.

As systems become larger, more collaborative, and longer-lived, that placement stops fitting. Knowledge accumulates across roles, sessions, and rewrites of the orchestration layer. At that point memory looks less like a utility and more like infrastructure: durable, inspectable, and independent of whichever agent framework is fashionable this quarter.

Whether you use Wolbarg or something else, that shift is likely to be one of the defining architectural changes in how AI systems are built.