PAMbaseDocs
Concept

Vector + graph.

This page explains how PAMbase finds the right memories when your app asks for them. It stores each memory (a durable, typed statement about the user — see the memory model) two ways at once: as a point in “meaning space” (the vector layer) and as a node in a web of typed links (the graph layer). You don't need any machine-learning background to follow along.

Why it matters

Good retrieval is what makes an app feel like it truly remembers. When a Margin user asks “what should I read next?”, you want the highlight they saved months ago about a related idea — even if they used completely different words, and even if the most relevant memory is one hop away from the obvious match. The vector and graph layers together make that possible.

The vector layer, from first principles

Two ideas, one plain sentence each:

  • An embedding is a list of numbers that captures a memory's meaning, arranged so that similar ideas end up with similar lists (i.e. they sit near each other).
  • Cosine similarity is a measure of how aligned two of those lists are — in other words, how related two memories are. Higher means more related.

Put together: PAMbase converts your query into an embedding too, then finds the memories whose embeddings are most aligned with it. This is why a search for “rate limiting” can surface a highlight about “backpressure” — the two phrases share almost no words, but their meanings sit close together, so their embeddings do too.

margin/search.ts
const { memories } = await pambase.recall({
query: "rate limiting",
scope: "note",
});
// Matches the saved highlight about backpressure — semantic, not literal.
// memories[0].content → "Backpressure is how a system says 'slow down'…"

The graph layer

Vectors capture meaning, but they don't capture connections you've declared. The graph layer fills that gap: memories can be joined by typed links, where the type says what kind of relationship it is. PAMbase uses these link types:

  • relates_to — a general association between two memories.
  • caused_by — one memory is a cause of another.
  • about_entity — a memory is about a specific named thing (a topic, person, or concept).
  • contradicts — two memories disagree.

Example with Margin: the user saves two separate highlights — one about how queues absorb load, another about flow control in TCP — and both are linked about_entity to the concept “backpressure.” Even though the two highlights might not be each other's nearest neighbors by meaning, the graph knows they share an entity, so asking about backpressure surfaces both together.

Hybrid retrieval

When your app requests context, PAMbase doesn't rely on the vector layer alone. It scores each candidate memory by blending several signals, then graph-expands the top results to pull in their linked neighbors. In words:

  • Semantic similarity — how aligned the memory's embedding is with your query (the cosine measure above).
  • Keyword match — literal word overlap, which catches exact terms a model might otherwise miss.
  • Recency — newer memories rank higher, on a 14-day half-life (weight roughly halves every two weeks).
  • Importance — memories marked more important rank higher.
Pinned memories are always kept
Ranking decides what surfaces by relevance, but a pinned memory bypasses the score entirely — it is always retrievable. Users pin the things that should never drop off, no matter how old or how loosely they match the query.

After scoring, PAMbase takes the top hits, follows their graph links one hop to gather closely related memories, filters everything down to scopes your permissions allow, and returns the result.

Why both, not just one

  • Vectors alone miss declared relationships — “these two highlights are both about backpressure” isn't something raw similarity reliably knows.
  • Graph alone misses the semantic neighborhood — it can't connect “rate limiting” to “backpressure” unless someone drew that edge by hand.
  • Together they cover both axes — meaning and explicit structure — so retrieval is both broad and precise.

Next