memnode
Sign InSign Up
Back to Articles

Spreading Activation: Why Graph-Aware Recall Beats Top-K Similarity

Top-k vector similarity is the wrong default for agent recall: similarity is not relevance and it cannot follow the chain of facts a task needs. Spreading activation over a typed memory graph fixes under-recall without over-recall.

memnode8 min read
agent memorymemnoderecallspreading activationgraphdesign notes

Most agent memory systems retrieve the same way a search box does. You hand them a query, they embed it, and they return the k stored memories whose vectors sit closest to that query. This is the top-k similarity pattern, and it is the default in nearly every vector store and memory layer shipping today. It is also the reason agents recall the wrong thing so often. Similarity is not relevance, and an agent rarely needs the memory that looks most like its question. It needs the chain of facts that the task actually depends on, and many of those facts do not resemble the query at all.

This article is about a different retrieval model: spreading activation, where recall starts from the cued memories and flows outward across typed edges in a memory graph. We will look at why pure top-k fails for agent state, how activation spreading fixes the failure without dragging in noise, and howsalience and recency shape what gets pulled back. The mechanism stays conceptual on purpose. The point is the principle, not the constants.

Why top-k similarity is the wrong default for an agent

Top-k similarity has one job: find the stored items whose embeddings are nearest the query embedding. For document search that is often enough, because the thing you want usually shares vocabulary and topic with what you typed. Agent recall is not like that. An agent operating across sessions is reconstructing state, and the state it needs is structured, not a bag of similar sentences.

Three failures recur, and they all come from the same root.

  • Semantic similarity is not relevance. A memory can be the closest match in vector space and still be the wrong thing to act on. A superseded fact looks just as similar as the correction that replaced it. A guess looks as similar as a confirmed observation. The embedding has no idea which one the agent should trust, because cosine distance carries no notion of truth, status, or recency.
  • It cannot follow a chain. The fact an agent needs is frequently one or two hops away from anything that matches the query. Ask a coding agent "can I change the user route" and the decisive memory may be a deployment incident that touched that route last month, recorded in language that shares almost no words with the question. Top-k will never surface it, because nearest-neighbor search has no concept of "connected to." It only knows "looks like."
  • It treats memory as a flat pile. A flat index has no structure to follow even when the structure exists. The relationship that says this observation was corrected by that one, orthis fact was observed from that source, is exactly the relationship recall should respect, and a similarity scan throws all of it away.

We have written about the broader version of this problem inwhy vector embeddings are the wrong default for agent memory and inwhy AI memory layers recall the wrong thing. The short version: a vector database gives you similarity but no structure, and structure is what agent state is made of.

What a graph gives you that a flat index cannot

memnode stores memory as a graph, not as a flat list of vectors with a search index bolted on. Nodes are observations and consolidated facts. Edges are typed, and the types carry meaning recall can use. A handful of the relevant ones:

  • anchored-to: a memory is attached to a concrete artifact, such as a file path or a service.
  • observed-from: a memory points back to the source it came from.
  • supports: one memory provides evidence for another.
  • corrects: one memory supersedes an earlier one that is now wrong.
  • related: a looser associative link between memories that tend to matter together.

Those edge types are the difference between a pile and a structure. A pile can only answer "what looks like this." A structure can answer "starting from what looks like this, what else does the task need." That second question is the one an agent actually has, and it is the question spreading activation is built to answer.

Spreading activation, conceptually

Spreading activation is an old idea from cognitive science, and it maps unusually well onto a typed memory graph. The mechanism, stripped to its essence:

  • Seed the activation. The query produces an initial set of cued memories. These seeds can come from embedding similarity, keyword overlap, or an explicit anchor entity the agent names. Similarity is not thrown away. It is demoted from being the whole answer to being only the starting point.
  • Spread across edges. Each seed passes activation to its neighbors along the typed edges. How much flows depends on the edge type. A supports or anchored-to link carries activation strongly, because it usually leads somewhere the task cares about. A loose related link carries less.
  • Decay with distance. Activation weakens as it travels, so a memory three hops away contributes less than a direct neighbor. The decay is a tunable falloff, not a fixed cutoff. This is what keeps the spread from flooding the whole graph: activation runs out before it reaches everything.
  • Suppress the superseded. Correction edges work in the opposite direction. When a memory has been corrected, activation flowing through it is dampened, so recall is pulled toward the current truth rather than the stale fact it replaced. The graph does not just connect memories; it knows which ones no longer hold.

The memories that accumulate the most activation across all of this are the ones recall returns. Note what this produces: a memory can rank highly even though it shares no words and little vector similarity with the query, simply because it sits on a strongly weighted, short, un-superseded path from something the query did match. That is associative recall, and it is precisely what top-k cannot do.

Here is the shape of the flow as a sketch. It is deliberately schematic. The real weighting profile and decay behavior are tuned internally and are not a public spec.

seed memories  (from similarity + keyword + anchor)
   |
   |  pass activation along typed edges
   v
neighbors       (anchored-to, supports, observed-from, related)
   |
   |  weight by edge type, modulate by salience and recency,
   |  decay with each hop, dampen through corrected nodes
   v
ranked recall   (highest accumulated activation wins)

Salience and recency modulate the flow

Edge type and distance are not the only things that shape the spread. Two stored, first-class properties on each memory adjust how strongly it participates: salience and recency.

Salience is a memory's standing weight. It rises with use. A memory that gets recalled often, that gets reinforced, that survives correction after correction, carries more salience than one written once and never touched again. When activation spreads, salient memories both receive and pass along more of it. This is the graph's way of saying that proven, frequently relevant knowledge should be easier to reach than a one-off observation buried at the same distance.

Recency tilts the same way toward what is current. A fact observed in this session, or reinforced recently, gets a recency boost so that fresh state surfaces ahead of stale state when both are otherwise comparable. An agent reconstructing where it left off needs the recent thread, and recency modulation is how the spread favors it without ignoring the durable facts that recency alone would bury.

Together these two signals turn the graph from a static network into a live one. The same query against the same nodes can return a different, better answer next week, because the salience and recency that shaped the spread have moved. Recall is not a read-only operation here; recalling a memory feeds back into its salience, so the paths that keep proving useful keep getting easier to travel.

Avoiding both under-recall and over-recall

The two ways retrieval fails are mirror images, and spreading activation is designed to dodge both.

Under-recall: missing the linked but dissimilar fact

This is the top-k failure. The decisive memory is connected to the query's subject but does not resemble the query, so a similarity scan never returns it. The agent acts without the one fact that would have changed its decision. Activation spreading cures under-recall by following the edges: if the fact is reachable along a strong, short, un-superseded path, the spread carries activation to it even though no embedding ever flagged it.

Over-recall: dragging in everything connected

The naive fix to under-recall is to widen the net, walk the graph broadly, and return everything within a few hops. That trades one failure for another. Now the agent's context fills with loosely related noise, the signal drowns, and the model spends its window on memories that do not matter. A plain breadth-first walk has exactly this problem.

Spreading activation avoids over-recall through the same mechanics that enable the recall in the first place. Decay with distance means activation runs out before it reaches the whole graph. Edge-type weighting means weak related links pass little activation, so tangential branches never light up strongly. Salience and recency mean a distant, low-salience node stays dim even if it is technically connected. The result is a bounded, weighted neighborhood rather than an unbounded flood. Recall pulls in the connected facts that matter and leaves the merely-adjacent ones behind.

A concrete agent example

Consider a coding agent that returns to a project after a week. Its task: add a field to the user profile endpoint. It recalls against memnode with the question "how do I change the user profile route."

A top-k system embeds that question and returns the memories most similar to it, which are mostly notes about the route's request shape. Useful, but incomplete. What it misses is the memory that should stop the agent cold.

Spreading activation runs differently:

  • The seed set includes the memory anchored to app/api/users/route.ts, found by similarity and by the anchor on that file path.
  • Activation spreads along an anchored-to edge from the file to a deployment incident memory: a schema migration on that route broke a downstream consumer last month. This incident shares almost no words with "change the user profile route," so top-k would never surface it. The edge does.
  • From the incident, a supports edge reaches a consolidated convention: "changes to the user route require a coordinated migration on the analytics consumer." That convention is highly salient because the agent has recalled and reinforced it before, so it lights up strongly even though it sits two hops out.
  • An older note that contradicted the convention is dampened, because a corrects edge marks it as superseded. Activation does not propagate through the stale claim.
  • A tangential memory about a different endpoint is two hops away through a weak related edge. It receives a trickle of activation, decays below the threshold that matters, and stays out of the result. That is over-recall avoided.

Recall returns the route notes and the migration convention together, with the stale claim suppressed and the unrelated endpoint absent. The agent now knows the thing that actually governs the task, and it learned it by following structure, not similarity.

Why this is a recall-quality story, not a retrieval trick

Spreading activation is not a clever re-ranking bolted onto vector search. It is a different answer to the question "what does this task need," grounded in the structure the memory graph already carries. Similarity seeds the search; the graph decides what the seeds connect to; salience and recency decide which connections are live; correction edges decide which are dead. The output is a bounded, ranked, evidence-bearing set rather than the nearest k sentences.

This is also why an MCP tool that merely exposes a memory store is not enough on its own. Tool access is not recall quality, a point we make inan MCP memory server is not enough. The intelligence is in how recall traverses the graph, and that is the layer worth building. For the full arc of how memnode grew from a graph store into a system that reasons over memory, seehow memnode evolved.

The memnode design series