Attention-Weighted Memory Graphs

I just had a new idea for how an LLM’s memory system could be structured. Roughly speaking, you can visualize it as a Graph-RAG setup where an entry point is located via an embedding, followed by step-by-step traversal along the edges.

Late chunking

The system builds onlate chunking(a technique introduced by Jina AI): rather than embedding each sentence independently, the whole document is tokenized and embedded first, and chunk-level vectors are derived afterward. This preserves document-level context inside each chunk’s embedding.In the Jina-embedding model the attention in the Transformer is calculated between sentences and not just tokens what I used inthememory.

Attention defines the graph’s edges

Instead of asking an LLM toextract nodes and edges for the graph,Jinaembeds an entire document at once and runs a forward pass withoutput_attentions=True. The resulting attention matrix is then averaged across layers and heads, and used directly as the edge weight between chunks: how much did chunk A attend to chunk B while the model was processing the document as a whole?

Swarming retrieval with a decaying budget

The retrieval is starting from the node with the most similar embedding, the system does a breadth-first traversal where each hop consumes part of a starting “budget” - a combination of a fixed step cost and a penalty proportional to how weak the edge is. Traversal stops naturally once the budget runs out, rather than at an arbitrary hop limit or a fixed result count. The found nodes are put into the new document with the new entry and are the context for the new entry.

Embedding updates

When new information touches an existing node reached through swarming, the old embedding isn’t discarded or replaced. It’s nudged:updated = old_embedding + alpha * remaining_budget * new_embedding, renormalized back to unit length. Nodes reached with more remaining budget (i.e., more central to the current context) get updated more; distant, weakly-connected nodes barely move .

For now, I tried a few small experiments in Colab:


I think there is a real, testable core here. In one pinned T4 setup, I was able to extract all of the token-attention tensors from jinaai/jina-embeddings-v2-base-en, map token spans back to chunks, and build chunk-to-chunk matrices from them. So the basic extraction path is workable, at least under one reproducible configuration.

The main open question looks less like whether a graph can be built and more like what the edge is supposed to mean.

In the small probes I ran, an all-layer/all-head average behaved mainly like a document-proximity graph. A few individual heads looked much more interesting on controlled synthetic examples, but those head sets did not transfer cleanly to a small held-out natural-text test based on HotpotQA distractors. On that natural sample, query-conditioned dense retrieval was much stronger at useful candidate budgets.

My current default route would therefore be:

  1. Define and inspect the edge before adding traversal or updates. Keep the full [layer, head, source_chunk, target_chunk] tensor, define token-to-chunk pooling explicitly, and preserve directionality initially.
  2. Establish incremental value over simple controls. At minimum: token distance, independent chunk cosine, late-chunk cosine, order permutation, lexical/entity hard negatives, random expansion, and dense query retrieval.
  3. Evaluate traversal as a budget curve, not one chosen budget. Separate oracle entry points from query-derived entry points, and compare tight budgets with nearly exhaustive retrieval.
  4. Treat embedding mutation as a separate experiment. Preserve the original text and original embedding, and compare no-update, routing-only, edge-reinforcement, and content-vector updates independently.

A compact decision tree might be:

What should an edge mean?
├─ document-local context / discourse proximity
│  └─ raw attention may be useful; compare directly with distance and order controls
├─ broad semantic association
│  └─ compare with independent and late-chunk embedding cosine
├─ provenance / “this node was derived from that source”
│  └─ generation-time attention or explicit relation extraction is easier to interpret
└─ relevance to the current query
   └─ use a query-conditioned score rather than relying only on a persistent edge

Does the edge add value beyond the controls?
├─ no
│  └─ keep dense retrieval, or use the graph for organization / inspection only
└─ yes
   ├─ only at large candidate budgets
   │  └─ calibrate against random and near-exhaustive retrieval
   └─ at tight budgets and on held-out data
      └─ proceed to traversal design, then test mutation as a separate ablation
What I tested in Colab, and the limitations

Pinned execution path

The main runs used:

  • model: jinaai/jina-embeddings-v2-base-en
  • model commit: 322d4d7e2f35e84137961a65af894fda0385eb7a
  • remote-code commit: f3ec4cf7de7e561007f27c9efc7148b0bd713f81
  • Transformers: 4.47.1
  • PyTorch runtime reported by the run: 2.11.0+cu128
  • GPU: Tesla T4
  • FP16 model loading

In that setup, output_attentions=True returned 12 layer tensors with 12 heads. The first small document produced a stacked tensor of shape:

[layer=12, head=12, token=106, token=106]

That matches the usual Transformers model-output contract: attention is returned per layer as a token-to-token tensor, normally shaped (batch, heads, sequence, sequence).

Because the model uses remote custom code, reproducing the result may require pinning both the model and code_revision. An older Jina discussion reports a tuple-index error with output_attentions=True, but the pinned run succeeded, so I would treat that as version/backend-dependent rather than a universal blocker.

Probe 1: small synthetic contract and edge-shape check

I used nine short chunks containing:

  • nearby but unrelated statements;
  • separated but related statements;
  • a lexical/entity distractor;
  • a temporal update;
  • reverse-order, random-order, and chunk-length controls.

The all-layer/all-head mean had semantic-label AUC 0.60, Spearman correlation 0.924 with inverse token distance, and 0.526 with chunk cosine. Its strongest edges were mostly adjacent chunks, including unrelated ones. Reverse order preserved much of the matrix, while random permutation changed it sharply. This is consistent with a strong position/discourse component. Jina V2 uses a symmetric bidirectional ALiBi variant, although order changes discourse as well as position.

A few middle-layer heads looked much less position-dominated and retained the labelled pairs across those small controls. That motivated a second held-out probe rather than treating the uniform mean as the final graph.

Probe 2: held-out templated relations and hard negatives

The second probe used 30 deterministic documents:

  • 18 for head selection;
  • 12 held out;
  • six relation families: coreference, temporal update, causal chain, organizational relation, correction, and process dependency.

Against distance-matched unrelated negatives, the strongest results on the 12 held-out documents were:

Edge Mean held-out document AUC
Train-selected heads, symmetric 0.9375
Heads preregistered from the first probe, symmetric 0.9167
Chunk cosine 0.9167
Uniform attention, symmetric 0.4583
Inverse token distance 0.4375

Four of the six selected heads overlapped the head set preregistered from the first probe, which was encouraging.

However, the result reversed when I compared the direct positive relation with a lexical/entity hard negative such as a different person who shared the same city, company, role pattern, or event vocabulary:

Edge Positive-vs-hard-negative AUC
Chunk cosine 0.708
Uniform attention, symmetric 0.708
Preregistered heads, symmetric 0.208
Train-selected heads, symmetric 0.125

So the selected heads were good at separating a direct relation from a distance-matched unrelated statement, but often scored a topically or entity-related false path above the intended relation.

That changed my interpretation. The signal may be closer to broad association, entity continuity, or a coreference candidate than to a universal typed edge such as “causes,” “supersedes,” or “is the next required process step.”

The retrieval result was also highly budget-sensitive. Starting from an oracle seed and requiring both target nodes:

Candidate budget Selected/preregistered attention Cosine graph
3 nodes 2/12 3/12
4 nodes 9/12 4/12

The attention graph often put the useful relation somewhere near the top, but a hard negative could consume one of the very limited slots. Increasing the budget by one changed the conclusion dramatically. That made the proposal’s budget mechanism look like a central experimental variable rather than a secondary tuning parameter.

Probe 3: natural HotpotQA distractors

For a small natural-text check, I used the HotpotQA distractor setting, which provides multiple Wikipedia paragraphs, two supporting documents, sentence-level supporting facts, and both bridge and comparison questions.

I selected 24 eligible examples deterministically:

  • train: 6 bridge + 6 comparison;
  • held out: 6 bridge + 6 comparison;
  • ten paragraphs per question;
  • two supporting paragraphs and eight natural distractors.

To materialize full attention on a free T4, each paragraph was capped at 64 tokens, and I retained only examples whose annotated supporting sentences remained inside that cap. This produced a filtered subset, so the result should not be read as a HotpotQA benchmark result.

On the 12 held-out examples, gold-support-pair ranking looked like this:

Edge method Mean gold-pair percentile Pooled gold-vs-all-pairs AUC
Independently embedded paragraph cosine 0.669 0.632
Uniform attention after subtracting a train-fitted distance component 0.623 0.617
Natural-text train-selected attention heads 0.475 0.483
Late-chunk contextual cosine 0.473 0.466
Synthetic preregistered attention heads 0.453 0.473
Uniform attention 0.424 0.422
Inverse token distance 0.394 0.385

The natural-text train-selected head set overlapped only 2/6 with the first synthetic preregistration and 0/6 with the second probe’s selected set. The selected natural heads were also close to chance on held-out pair ranking.

Original-vs-shuffled paragraph-order matrix correlations were approximately:

Method Mean Spearman correlation
Independent paragraph cosine 1.000
Late-chunk contextual cosine 0.087
Synthetic preregistered attention 0.009
Natural-selected attention -0.008
Uniform attention -0.014
Distance-residual attention -0.078

Again, shuffling changes discourse coherence as well as position, so I would not interpret this as a pure position-invariance test. It does, however, make a raw contextual-attention matrix look fragile as a query-independent, persistent relation between memories whose order may later change.

The query-retrieval result was clearer. The independently embedded query selected one of the two gold paragraphs as its top seed in all 12/12 held-out examples. The fraction for which both gold paragraphs were present in the candidate set was:

Candidate budget out of 10 paragraphs Dense query retrieval Paragraph-cosine graph Distance-residual graph Natural-selected attention Uniform attention
2 8/12 3/12 2/12 2/12 1/12
3 10/12 5/12 3/12 2/12 2/12
4 11/12 7/12 4/12 2/12 2/12
5 12/12 8/12 6/12 3/12 3/12
6 12/12 8/12 8/12 4/12 4/12
7 12/12 9/12 11/12 7/12 6/12
8 12/12 11/12 12/12 9/12 8/12

Because one gold paragraph was already the seed, an unstructured expansion that admits budget - 1 of the nine remaining paragraphs has an expected probability of (budget - 1) / 9 of including the second gold paragraph. The measured random-graph curve was close to that expectation. Several graph variants became successful only when most of the ten paragraphs were already admitted.

There was one narrow positive result: for the six bridge questions, the paragraph-cosine graph found both supports in 6/6 by budget 4, versus 5/6 for dense query retrieval. This used embedding cosine rather than attention. For comparison questions, dense query retrieval was clearly stronger: 5/6 at budget 2 and 6/6 at budget 4.

That split seems conceptually useful. A bridge question can connect two pages through a shared entity or intermediary, so pairwise graph expansion can help. Two comparison pages do not necessarily need to resemble or attend to one another; they may be jointly relevant only because the current query asks for the comparison.

Limits of these observations

These were deliberately small sanity checks, not a claim about the general usefulness of attention graphs.

  • The first two corpora were synthetic or templated.
  • The natural held-out set contained only 12 filtered examples.
  • Head selection can overfit the relation definitions and negative set.
  • Paragraph shuffling changes both order and discourse coherence.
  • I evaluated edge ranking and candidate retrieval, not final generated-answer quality.
  • I did not test learned aggregation, query-conditioned head weights, explicit entity links, a reranker trained on hard negatives, or a large memory stream.
  • I deliberately did not test embedding mutation yet, so none of these results evaluate the proposed update rule.
The token-attention to chunk-edge contract

One distinction that seems important here is that Late Chunking and attention pooling are two different operations.

The Late Chunking reference implementation first obtains contextual token representations for the whole input, then pools the token representations inside each chunk span to produce chunk embeddings.

By contrast, output_attentions=True produces token-to-token matrices. A chunk graph therefore needs a second, explicit aggregation contract. A simple version is:

token attention:
    A[layer, head, source_token, target_token]

chunk pooling:
    E[layer, head, source_chunk, target_chunk]
      = aggregate A[layer, head, tokens(source_chunk), tokens(target_chunk)]

That leaves several design choices which can materially change the graph:

1. Span mapping

  • How are character chunks mapped to token spans?
  • Are special tokens excluded?
  • What happens when a chunk or supporting sentence is partially truncated?
  • Are titles and separators part of the chunk?

2. Pooling

  • Mean over the source-span × target-span rectangle?
  • Sum with source/target-length normalization?
  • Maximum or top-k mean?
  • Separate treatment for punctuation, stopwords, or entity tokens?

A plain mean is easy to reproduce, but it can dilute a sparse useful relation inside a long chunk. A plain sum creates the opposite length bias.

3. Direction

It may be worth retaining both A → B and B → A before deciding whether to symmetrize. In the synthetic probe, directed and symmetric results were noticeably different.

Possible variants include:

  • directed;
  • arithmetic mean of both directions;
  • maximum of both directions;
  • mutual-only edges where both directions exceed a threshold;
  • two separately typed directions.

4. Layer/head aggregation

The full intermediate object is useful:

[layer, head, source_chunk, target_chunk]

If it is averaged immediately, it becomes impossible to tell whether a small group of useful heads was cancelled by many positional or delimiter-oriented heads.

Reasonable comparators include:

  • all-layer/all-head uniform average;
  • layer-wise averages;
  • fixed preregistered heads;
  • train-only learned softmax weights;
  • relation-conditioned weights;
  • query-conditioned weights.

The SproutRAG pooling code is a concrete implementation example: it converts token attention into a layer/head/chunk/chunk tensor by span pooling. Its attention aggregator includes uniform aggregation as a baseline and learnable weights across layers and heads. SproutRAG then uses the result to build a tree, so it is not an end-to-end validation of this memory-graph design, but the tensor contract is highly relevant.

5. Normalization and graph sparsification

A matrix used for visualization is not automatically a calibrated transition matrix.

Possible choices include:

  • row normalization;
  • fixed top-k outgoing edges;
  • global or row-wise thresholds;
  • matched graph density across baselines;
  • calibration per document or per relation type.

This is also where long chunks, dense hubs, and nearly uniform low-valued edges can create unexpected traversal behavior.

Related systems that seem close to different parts of the idea

I found several systems that seem useful as implementation or vocabulary references. I would not call any of them identical to this proposal; each constrains the meaning of its attention relation differently.

PECAN

PECAN constructs a hierarchical weighted graph with edges derived from LLM attention and uses dynamic progress control to vary how much information is retrieved for each query. Its repository is available here.

It shows that an attention-derived graph can be part of a working retrieval architecture. The difference is edge semantics: PECAN’s attention is tied to creating higher-level Information Points from source information, so the source-dependence interpretation is narrower than treating arbitrary bidirectional encoder self-attention as a general persistent memory relation.

SAKI-RAG

SAKI-RAG uses a SentenceAttnLinker to model inter-sentence attention relationships and a Dual-Axis Retriever that expands and filters candidates using both semantic similarity and contextual relevance.

That dual-axis design seems especially relevant here. It does not require one persistent attention edge to simultaneously represent:

  • structural/contextual association;
  • semantic similarity;
  • and relevance to the current query.

SproutRAG

SproutRAG converts sentence-level attention into a hierarchical tree for long-document retrieval. Its code makes several hidden choices explicit:

  • token-span to sentence-span pooling;
  • a complete layer/head/chunk/chunk tensor;
  • diagonal masking;
  • direction symmetrization;
  • uniform aggregation as an initialization/baseline;
  • optional training of layer/head weights;
  • explicit retrieval and reranking stages.

It builds a tree rather than an evolving general graph, but it is probably the closest reusable code example for the token-attention-to-chunk-relation part.

Late Chunking

The Late Chunking paper and implementation are useful for the chunk-embedding side: the chunk vector can retain whole-document context because pooling happens after contextualization.

That does not automatically make the token-attention matrix a sentence-level relation matrix. The two signals can be compared or combined, but they should be measured separately.

Graph propagation references

If the graph itself proves useful, systems such as HippoRAG provide another useful comparison: query-related seeds are introduced into a graph, then relevance is propagated rather than treating the stored edge as the complete retrieval decision.

Possible meanings of an edge, and the controls for each

A single scalar attention_weight(A, B) may be asked to represent several different things. I suspect it will be easier to evaluate if the intended relation is stated first.

Intended edge meaning Plausible signal Essential control Typical failure mode
Local discourse/context proximity Raw contextual attention Token/chunk distance and order permutations Adjacent but unrelated text dominates
Broad semantic association Independent cosine, late-chunk cosine, selected attention heads Lexical/entity hard negatives Same topic or entity type mistaken for the intended relation
Coreference/entity continuity Selected heads plus explicit entity identity Same-type, same-city, or same-role distractors Two different entities are conflated
Temporal update or supersession Typed relation plus timestamps/validity Old/new fact controls Both versions blend into one representation
Provenance or derivation Generation-time attention or explicit extraction Source attribution Edge has no readable causal/source meaning
Current-query relevance Query-conditioned scorer or transition weight Dense query retrieval Fixed graph misses comparison-style relevance

This suggests a multi-edge or multi-signal design may be more natural than a single universal matrix. For example:

  • persistent context edge;
  • entity/coreference edge;
  • temporal supersedes edge;
  • provenance edge;
  • query-conditioned transition score.

An edge that is useful for candidate expansion need not also be best for final ranking, explanation, or memory update.

A low-cost evaluation sequence would label a small held-out set for one relation, separate ordinary from hard negatives, compare distance/cosine/attention/random edges at matched density, test alternative order, and only then evaluate traversal.

Traversal: budget, queue discipline, and baselines

The decaying-budget idea seems testable, but the search rule matters.

If every edge traversal has exactly the same cost, literal breadth-first search is coherent. If each edge has a different penalty and the objective is to preserve the most remaining budget, a priority queue that expands the best current path is a natural comparator. This is analogous to the usual distinction in NetworkX’s shortest-path guidance: BFS for unweighted hop distance and Dijkstra-like methods for non-negative weighted cost.

The objective may be spreading activation rather than one shortest path, but making the frontier rule explicit would make the comparison easier.

Questions that change the result include:

  • Is path cost additive, multiplicative, or based directly on remaining budget?
  • If a node is reached again through a stronger path, is it reopened?
  • Can a strong cycle repeatedly reinforce the same region?
  • Is there a maximum out-degree or edge threshold?
  • Is budget counted in nodes, tokens, total context characters, or computation?
  • Are nodes ranked by best path, sum of paths, or first visit?

The evaluation should separate seed quality, edge quality, traversal quality under a fixed budget, and final answer quality.

Useful controls are:

  • oracle seed vs query-derived seed;
  • dense query top-k;
  • the same graph with random weights or permuted edges;
  • a random expansion with the same candidate count;
  • a budget curve from tight retrieval to nearly exhaustive retrieval;
  • context tokens consumed, not only node count.

The budget curve is particularly important. In the HotpotQA probe, dense query retrieval found both supporting paragraphs in 8/12 examples at budget 2 and 12/12 by budget 5. Several graph variants only approached full recall at budget 8 of 10 paragraphs. Reporting only the large-budget endpoint would make a weak expansion method look much stronger than it was at useful context sizes.

Why I would separate persistent association from query-conditioned relevance

The bridge/comparison split in the small HotpotQA probe gave a concrete example of this distinction.

For a bridge question, the first supporting paragraph may mention an intermediary entity that connects naturally to the second paragraph. A persistent entity, semantic, or discourse edge can help expand from one support to the other.

For a comparison question, the two supporting paragraphs may have little pairwise similarity. They are connected because the query asks to compare two things. A query-independent edge between the paragraphs is not necessarily expected to be strong.

That leaves several reasonable architectures:

Option A: persistent graph for candidates, query scorer for ranking

  • Dense query retrieval chooses one or more seeds.
  • Persistent graph edges expand structural candidates.
  • Query relevance and hard-negative reranking choose the final context.

Option B: typed persistent edges with query-conditioned transitions

  • Store entity, temporal, provenance, and discourse relations separately.
  • The current query decides which edge types and directions receive weight.

Option C: use graph expansion only for bridge-like uncertainty

  • If dense retrieval already returns several independently relevant supports, keep it.
  • If the query appears to require an intermediary relation, expand through the graph.

Option D: route between dense-only, graph, and hybrid retrieval

  • The routing signal could be query type, score margin, retrieval entropy, or failure to find enough independent evidence.

The probes do not identify the best option, but they suggest that a fixed raw attention graph should not be expected to replace query relevance by itself.

The embedding-update part looks like a separate, higher-risk experiment

The update rule is interesting, but it changes a different contract from graph construction.

Moving an existing content embedding toward a newly retrieved embedding changes both:

  • how the node will be routed to later;
  • and the vector that is supposed to represent the original evidence.

That creates several possible feedback loops:

  • a mistaken retrieval changes the node so it becomes even easier to retrieve incorrectly next time;
  • frequently visited nodes drift into general-purpose hubs;
  • old and new facts become geometrically blended even when the newer fact supersedes the older one;
  • the current embedding may no longer be reproducible from the stored source text.

I did not implement the update rule, so these are reasons to isolate the experiment rather than observed failures.

A safer decomposition could be:

  • immutable raw text / episode;
  • reproducible original content embedding;
  • mutable routing embedding;
  • mutable typed edge weights;
  • timestamps and validity intervals;
  • update lineage;
  • regression tests and rollback.

Graphiti is a useful implementation reference for this separation. It keeps raw episodes as provenance, gives facts temporal validity windows, preserves superseded history, and combines semantic, keyword, and graph retrieval. It is a much heavier architecture than the proposal here, but the provenance and temporal boundaries are relevant even in a small implementation.

LongMemEval is also a useful evaluation map because it separates long-term memory into information extraction, multi-session reasoning, temporal reasoning, knowledge updates, and abstention. A retrieval improvement on the newest query does not by itself show that older memories remain correct.

A clean mutation ablation might be:

  1. no update;
  2. edge reinforcement only;
  3. mutable routing-vector update while preserving the original content vector;
  4. direct content-vector nudge;
  5. gated update, accepted only if both the new query and a regression set of older queries improve;
  6. rollback when they do not.

I would keep the retrieval graph frozen while comparing those variants. Otherwise an edge change, traversal change, and vector mutation can compensate for one another and make the source of an improvement difficult to identify.

Implementation and reproducibility checklist

For this specific idea, I think the following small record would make results much easier to compare across machines and future revisions:

  • exact model ID;
  • model commit SHA;
  • remote-code repository and code_revision SHA;
  • Transformers and PyTorch versions;
  • attention backend actually used by each module;
  • returned attention shapes;
  • input token count and truncation status;
  • chunk character spans and token spans;
  • special-token handling;
  • token-to-chunk pooling formula;
  • directed or symmetric edge rule;
  • layer/head aggregation rule;
  • normalization and graph sparsity rule;
  • dataset IDs and selection filters;
  • train/held-out split used for head selection;
  • ordinary and hard-negative definitions;
  • random seed;
  • seed-selection rule;
  • candidate budgets;
  • random and dense baselines;
  • candidate recall, final reranked recall, answer quality, and context cost as separate metrics.

Saving the config, chunk spans, full layer/head chunk tensor, embeddings, query scores, edge metrics, budget curve, and environment/errors would allow many later aggregation and traversal experiments to run on CPU without another GPU quota.

Possible next routes, depending on the goal

If the immediate goal is a conceptual prototype

The smallest convincing demonstration may be:

  1. choose one intended edge meaning;
  2. show the directed per-head chunk matrix for one readable document;
  3. compare it with token distance and cosine;
  4. include one ordinary negative and one hard negative;
  5. show how the result changes under order permutation.

That is enough to establish what the edge is doing without building the full evolving memory system first.

If attention tensors and pooling are already implemented

The highest-value additions would be:

  • retain and optionally publish the full layer/head matrix rather than only the mean;
  • document the span-pooling and normalization rules;
  • treat uniform averaging as a baseline;
  • add held-out hard negatives;
  • compare directed, symmetric, and learned/query-conditioned aggregation.

If the goal is retrieval performance

I would keep dense query retrieval as the primary baseline and test whether the graph adds candidates which dense retrieval misses at the same context budget.

The most informative measurements would separate bridge-like from comparison-like queries and report budget curves, oracle/query seeds, random expansion, candidate recall, post-reranking recall, answer accuracy, and context-token cost.

If the goal is long-term evolving memory

I would add provenance, timestamps, and supersession before direct embedding mutation. The first update experiment could change only routing state or edge strength while leaving evidence immutable.

If the goal is visualization or interpretability

Directed per-head attention graphs may still be useful even if they are not the best retriever. A graph can be diagnostically valuable without also serving as the final persistent semantic graph.

Overall, I think the proposal is experimentally tractable, and the closest related systems suggest that attention-derived relations can be useful when the edge semantics, aggregation, query conditioning, and traversal objective are explicit.

The small results changed my own default from “average the attention and then tune the graph” to:

retain the full tensor, define one relation at a time, test it against strong controls and hard negatives, measure the whole budget curve, and only then decide which part deserves to become persistent memory state.

Even if the raw attention ultimately turns out to represent mostly local discourse structure rather than a universal semantic relation, that could still be a useful edge type. It just may need to live alongside semantic, temporal, provenance, and query-conditioned signals rather than replacing all of them with one scalar.

During my tests, I also encountered the issue where entries occurring in close temporal succession are more strongly linked to one another. But there are still weak connections that link based on meaning. That’s not a bad thing, or it could even be an advantage. The memory system is designed for an embodied agent capable of retrieving scenes (comprising episodes, generalizations, and transitions) while attention-based edges enable the formation of more nuanced associations. I have now implemented “distance-residual attention” to attenuate the influence of temporal proximity.

Perhaps this approach can solve some of the problems mentioned earlier. We use a SentenceVAE, which functions like an autoencoder: the encoder converts a sentence or chunk into a sentence token represented as a vector, and the decoder can subsequently reconstruct a sentence from that token.

Positioned between them is a Set Transformer—acting as an LLM—that processes multiple sentence tokens simultaneously as both input and output.

The memory system could be structured as follows:
A document is split into multiple chunks or sentences. For every sentence in the document, the encoder generates a corresponding sentence token.
Next comes a Transformer layer that takes these new sentence tokens as input; this is also where relevant memories—which are themselves sentence tokens serving as context for the new entries—are retrieved.
All these sentence tokens then enter the Set Transformer (a block comprising multiple layers). Much like the Jina embedding model using “late chunking,” its task is to modify the embeddings based on the context of all the sentences; it outputs the same number of sentence tokens it received (though this number could vary if needed). At the same time, it is responsible for memory consolidation and semantic understanding. It aims to identify generalizations or accumulations—for instance, if a user has gone jogging every afternoon for the past five days, the system could recognize this as a jogging habit. The sentence tokens can then be stored in the database—not as raw text, but as vectors—allowing the Transformer layer to retrieve them again during a subsequent pass.

This could resolve the issues identified earlier. When a new memory arrives, existing memories with similar meanings are retrieved and can be updated. The activated entries share relationships not only with one another but also with entries outside that immediate set. If an entry consisted solely of text, updating it would risk stripping it of its context; however, storing the text as an embedding within the context of similar entries could make this approach viable. Normally, memories would be stored as word tokens, but they would likely be harder to update because they form a sequence with a fixed order and length; if the Transformer were to update the word tokens, it would be impossible to track or interpret which tokens transformed into which others. However, using sentence tokens or chunk-based tokens would avoid this problem.
Typically, an LLM would be invoked to receive the memories as input and then modify the database via commands—such as SQL commands—to handle memory consolidation, as seen in NapMem:

In contrast, the Transformer (i.e., the LLM within the memory system) already utilizes the appropriate input and output formats, eliminating the need for external commands. Furthermore, memories intended to be preserved exactly as they are could potentially be passed through via residual connections. This approach would make it much more likely that the model performs as intended. Additionally, memories would be processed simultaneously rather than sequentially, as is the case with an RNN.

Nice. It might make things easier later if you pin down just one boundary for now:


I think this is a genuinely interesting second branch.

Moving the editable unit from a variable-length sequence of word tokens to a sentence-level token makes sense as a way to avoid the token-correspondence problem you described. A decoder also gives this approach an inspection path that an ordinary embedding does not have: the system can turn its operational memory back into text and let us examine what survived.

The one boundary I would probably keep fixed while exploring it is:

immutable raw episode / evidence
        ↓
immutable original sentence token
        ↓
mutable operational sentence token
        ↓
retrieval / consolidation / decoding

In other words, I would let the Set Transformer freely operate on sentence tokens, but I would not initially make the latest edited vector the only surviving source of truth.

That does not require the memory processor itself to become text-based, command-based, or SQL-driven. It can remain entirely latent-native. The raw layer would only provide a point of comparison, re-encoding, rollback, and provenance while the latent approach is being developed.

The first milestone could then be deliberately boring:

encode
→ Set Transformer performs a no-op / preserve operation
→ decode
→ re-encode

Before asking the model to generalize or consolidate anything, this path could check whether it preserves:

  • names and entity identity;
  • numbers and dates;
  • negation;
  • subject/object direction;
  • temporal order;
  • distinctions between similar memories;
  • stability over several repeated cycles.

The important part would be checking factual preservation rather than only whether the decoded sentence is fluent.

The SentenceVAE paper trains its decoder to reconstruct sentence tokens produced by its own encoder. Once a separate Set Transformer modifies those vectors, the edited vectors become a new interface contract: they may still decode perfectly well, but that is something the memory system itself would need to establish.

If the no-op path is stable, the operations could then be added one at a time:

preserve
→ update one fact
→ merge compatible memories
→ supersede while retaining lineage
→ create a generalization

This ordering would not limit the final architecture. It would just make failures attributable to a particular memory operation rather than to the codec, the Set Transformer, variable output cardinality, and consolidation policy changing simultaneously.

A few reasons this boundary may be useful

The editable latent has a different contract from the encoder output

SentenceVAE provides an encoder that compresses the token sequence of a sentence into one vector and a decoder that reconstructs text from that vector.

That establishes a useful codec:

sentence
→ encoder-generated sentence token
→ reconstructed sentence

Your proposal adds an important new path:

sentence
→ encoder-generated sentence token
→ Set Transformer modifies it
→ modified sentence token
→ reconstructed sentence

The second path is not necessarily a problem; it may be exactly where the useful memory behavior emerges. But it is no longer only a reconstruction problem. The modified vector must remain inside a region that the decoder can interpret faithfully.

A useful test might therefore measure both directions:

text₀
→ encode
→ update
→ decode as text₁
→ re-encode
→ latent₁

The system could compare:

  1. the intended memory operation;
  2. the factual difference between text₀ and text₁;
  3. the distance between the edited latent and the re-encoded latent;
  4. whether another cycle changes the result again.

For example, an intended update such as:

Alice lives in Kyoto.
→
Alice moved from Kyoto to Sapporo.

should not silently become:

Alice lives in both Kyoto and Sapporo.

Likewise, merging several jogging episodes into a habit should not require deleting the source episodes immediately. The generalization and its evidence can coexist until the system has demonstrated that the abstraction is reliable.

The recent TrustMem paper uses three useful terms for evaluating a memory transition:

  • coverage — did the updated memory include the information it needed?
  • preservation — did it retain relevant existing information?
  • faithfulness — did it avoid introducing unsupported information?

The exact framework does not need to be adopted, but those three checks seem like a useful minimal rubric for latent memory updates as well.

Raw evidence does not prevent latent-native memory

I do not think the choice has to be:

structured text database
versus
learned latent memory

It can instead be:

raw evidence: immutable recovery layer
latent memory: learned operational layer

The latent layer can still be the normal retrieval and reasoning interface. The raw episode would only be consulted for verification, repair, migration, or unusually detailed questions.

This is one boundary that systems using explicit memory structures tend to preserve. For example, NapMem keeps an append-only raw-conversation layer and connects derived memory records, topic tracks, and profiles back to their sources through persistent identifiers and provenance links.

That does not mean your memory processor should work like NapMem. Your proposal is substantially different: the memory transformation itself would be learned and performed directly in sentence-token space. The transferable idea is only that an abstraction remains connected to the evidence from which it was produced.

RecMem provides another relevant example. It consolidates recurring interactions selectively rather than consolidating every observation immediately, and it can revisit the associated raw interactions when an episodic summary has omitted query-critical details.

For the latent approach, the equivalent might be:

operational sentence token
→ usually sufficient

decoded token + provenance
→ inspection

raw source episode
→ recovery when information was lost or the codec changes

I would not discard the vector-only destination as a possible later optimization. I would simply postpone deleting the original evidence until the update and migration contracts are strong enough to make that irreversible step meaningful.

Set processing and temporal memory are slightly different problems

The Set Transformer is specifically designed for sets whose element ordering should not determine the result. Its attention blocks are therefore a natural way to let several retrieved memories contextualize one another.

However, some of the relations in this memory system are not order-free:

  • observation → action → result;
  • old state → correction → current state;
  • repeated episode → emerging habit;
  • event → later consequence;
  • memory → superseding memory.

I would therefore avoid relying on the input arrangement alone to communicate time. Temporal and functional roles could be represented explicitly, for example through:

  • timestamp or relative time;
  • episode/session identifier;
  • observation/action/result role;
  • new/retrieved/protected status;
  • raw episode/generalization status;
  • source identifiers.

Then the Set Transformer can remain permutation-friendly while still receiving the distinctions that matter.

For example, these two sets contain similar words but describe opposite transitions:

door closed
agent opened door
door open
door open
agent closed door
door closed

A timestamp or transition-role channel would let the model distinguish them without depending on the arbitrary order in which database retrieval happened to return the entries.

Same-cardinality updates are the cleanest first target

Updating the same number of sentence tokens that entered the Set Transformer seems like a natural first implementation:

N input memories
→ contextual interaction
→ N updated or preserved memories

Variable output size introduces another separate problem:

merge two memories into one
create a new generalization
split one ambiguous memory
delete or suppress a memory

A standard Set Transformer can model interactions between set elements, but it does not by itself decide how many persistent memory records should survive. The official Set Transformer implementation uses an explicitly chosen number of output seeds for its pooling decoder.

If variable cardinality becomes necessary, it could be represented explicitly through something such as:

  • a keep/update gate per existing entry;
  • operation labels such as preserve, update, merge, create, supersede, or abstain;
  • a small number of candidate output slots with presence scores;
  • a separate cardinality prediction;
  • matching between predicted outputs and target memory records.

I would probably leave that branch until same-cardinality preservation and one-fact updates are working. Otherwise, a missing memory could mean either an intentional merge or an accidental reconstruction failure.

Residual connections help, but they do not define exact preservation

Residual connections should make identity-like behavior easier to learn:

output = input + learned_delta

However, they do not guarantee that learned_delta is exactly zero for a memory that should be preserved.

If exact preservation matters, the contract could include an explicit path such as:

preserve gate
├─ copy the original operational token exactly
└─ apply the learned update

or copy-on-write:

original token remains fixed
updated token is created as a new version

That also makes supersession easier to represent. Instead of overwriting:

Alice lives in Kyoto.

the system can retain the old state and add:

Alice moved to Sapporo in 2026.

with a relation indicating which fact is currently valid.

Persistent vectors eventually need codec versioning

If the sentence vector becomes persistent database state, it is tied to a particular:

  • tokenizer;
  • sentence encoder;
  • sentence decoder;
  • hidden dimension;
  • checkpoint;
  • latent-space training objective.

If the codec is later fine-tuned, vectors produced by the older encoder may not decode or interact in the same way under the new version.

Keeping raw evidence makes migration straightforward:

raw episode
→ new encoder
→ new operational token

Without it, migration requires learning a reliable mapping between the old and new latent spaces.

Even a minimal record could therefore include:

memory_id
source_ids
codec_version
created_at
updated_at
original_sentence_token
current_operational_token

The system does not need to expose all of this to the reasoning model. It only needs enough information to reproduce and repair persistent state.

So I think the SentenceVAE + Set Transformer branch is worth trying.

The main thing I would keep fixed is not the internal representation or the consolidation algorithm. It is only the distinction between:

evidence that happened
and
the system's current learned representation of that evidence

With that boundary in place, the model can still discover useful latent updates, accumulations, generalizations, and new memory operations. If one experiment produces an interesting but incorrect memory, it remains an inspectable model result rather than an irreversible rewrite of the only surviving record.