mirror of
https://github.com/hanzoai/papers.git
synced 2026-10-22 17:20:17 +00:00
mab-fc.tex carries a row — typed search with one repair call — whose test cells are ellipses and which the paper never mentioned. A reader meets an unexplained, mostly empty row and has no way to tell a missing run from a rejected one. It is a rejected one, and the traces say so precisely: across 196 dev questions the repair fired ONCE, that single plan was chosen, and it is the entire difference between 88 and 89 multi-hop. One question, for a 27B model held resident beside the search. The row beneath it — exhaustive enumeration with a lexical tie-break — buys five points with no model in the loop at all. So it was not promoted to test, and the empty cells are the method working rather than a gap in it: a configuration that loses on dev does not get a second chance on held-out data. Reporting the cells empty and saying why is cheaper than dropping the row and leaving no trace that the idea was tried. The paper already reports its losing LoCoMo variants this way. This one had the numbers and not the sentence.
886 lines
46 KiB
TeX
886 lines
46 KiB
TeX
\documentclass[11pt]{article}
|
|
\usepackage{shared/hanzocover}
|
|
\usepackage[utf8]{inputenc}
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage{amsmath,amssymb}
|
|
\usepackage{graphicx}
|
|
\usepackage{booktabs}
|
|
\usepackage{xcolor}
|
|
\usepackage{tikz}
|
|
\usetikzlibrary{arrows.meta,positioning,calc}
|
|
\usepackage[hidelinks]{hyperref}
|
|
\emergencystretch=1.5em
|
|
|
|
\title{Linkage, Not Similarity:\\
|
|
Context-Sensitive Retrieval for Long-Term Agent Memory}
|
|
\author{Zach Kelling\thanks{Corresponding author: [email protected]} \\
|
|
\textit{Hanzo Industries Inc (Techstars '17)} \\
|
|
Los Angeles, California \\
|
|
\texttt{https://hanzo.ai}}
|
|
\date{Revision~1}
|
|
|
|
\begin{document}
|
|
|
|
\hanzocoverpage
|
|
|
|
\twocolumn[
|
|
\begin{@twocolumnfalse}
|
|
\maketitle
|
|
\begin{abstract}
|
|
\noindent
|
|
Vector similarity retrieves what sounds related. Long-term memory has to
|
|
retrieve what is connected: the turn that answers a question is usually
|
|
linked to the turn that matches it by a person, an event or a date, not by
|
|
wording. We measure this on LoCoMo, where a cosine index recovers every
|
|
annotated turn for only \textbf{22.7\%} of multi-hop questions at $k=20$
|
|
while recovering at least one for 80.1\%. A second index of atomic facts,
|
|
each citing the turn it came from, plus two small structural bonuses,
|
|
raises the complete-evidence rate to \textbf{36.2\%} and the any-evidence
|
|
rate to 87.2\% with nothing learned and under a millisecond per query.
|
|
Every term is ablated; the fact index carries most of the gain, and two
|
|
plausible additions---fusion of whole ranked lists and a surface-entity
|
|
hop---make the result worse.
|
|
|
|
We then argue that this recall number is a unit test, not a product
|
|
score. LoCoMo question answering is saturating under vendor protocols
|
|
(Mem0 reports 92.5\%, Zep 94.7\%, on protocols that differ from each
|
|
other), and the LoCoMo-Conv benchmark shows that the same memories phrased
|
|
as a user would phrase them expose retrieval gaps the QA form hides. We
|
|
describe the memory record and the read path Hanzo Context uses to close
|
|
those gaps---immutable raw memory; atomic facts with canonical entities and
|
|
validity intervals; query-conditioned planning; bounded typed expansion
|
|
instead of global fusion; a hop whose query is rebuilt from the state the
|
|
previous hop resolved; and deterministic resolution of superseded
|
|
facts---and the protocol on which we evaluate it: a declared dev/test
|
|
split, a frozen commit, LoCoMo, MemoryAgentBench FactConsolidation and
|
|
LoCoMo-Conv, with retrieval and answering reported separately and
|
|
evidence graded EXACT, SUPPORTED or ANSWERED.
|
|
\end{abstract}
|
|
\vspace{1em}
|
|
\end{@twocolumnfalse}
|
|
]
|
|
|
|
\section{The Claim}
|
|
|
|
A memory system for an agent is asked one thing: given what was said before,
|
|
find what bears on what is being asked now. The dominant implementation
|
|
embeds every turn, embeds the question, and returns the nearest neighbours.
|
|
That works when the answer resembles the question. It fails, quietly, when the
|
|
answer is \emph{connected} to the question by something a sentence embedding
|
|
does not carry---the same person named two sessions apart, the date a plan
|
|
was made and the date it happened, the fact that one turn answers the turn
|
|
before it.
|
|
|
|
This paper makes one technical claim and one methodological one.
|
|
|
|
The technical claim is that linkage is a separate index, not a better
|
|
embedding. Extract short facts from each turn, keep the pointer from every
|
|
fact back to the turn it came from, give each fact its entities and its time,
|
|
and let a question reach a turn through a fact when it cannot reach it
|
|
through the turn's own wording. Section~\ref{sec:locomo} measures this in
|
|
isolation: on LoCoMo multi-hop questions the complete-evidence rate at $k=20$
|
|
moves from 22.7\% to 36.2\%, and the ablation in Table~\ref{tab:ablation}
|
|
attributes most of it to the fact index.
|
|
|
|
The methodological claim is that the number we just quoted is the wrong one
|
|
to optimise. It measures whether every turn an annotator marked was
|
|
retrieved. A system can answer correctly from a different turn that says the
|
|
same thing; the LoCoMo-Conv authors call this \emph{silent grounding} and
|
|
ship extra annotations because strict gold-turn recall misses it
|
|
\cite{locomoconv}. Section~\ref{sec:measure} sets out what we measure instead
|
|
and why, and Section~\ref{sec:protocol} fixes the protocol before any number
|
|
on the test split is read.
|
|
|
|
\section{What Is Being Measured}
|
|
\label{sec:measure}
|
|
|
|
Three quantities are routinely conflated under ``LoCoMo score''.
|
|
|
|
\paragraph{Evidence recall.} For each question LoCoMo lists the dialogue
|
|
turns that support the answer \cite{locomo}. \textbf{ALL@k} is the fraction
|
|
of questions for which every listed turn is in the top $k$; \textbf{ANY@k}
|
|
the fraction for which at least one is. The two disagree by a factor of
|
|
three on multi-hop questions (Table~\ref{tab:locomo}). ALL is the honest
|
|
number for a retriever that must hand a reader complete evidence; ANY is the
|
|
honest number for a retriever whose reader can follow a lead.
|
|
|
|
\paragraph{Answer accuracy.} A reader is given the retrieved turns and
|
|
scored on what it says: token-level F1 and exact match against the gold
|
|
answer in the LoCoMo paper, or an LLM judge in most vendor reports. This is
|
|
what Mem0's 92.5\% \cite{mem0blog} and Zep's 94.7\% \cite{zepresearch} are,
|
|
and they are not the same measurement as each other: Zep's page names
|
|
gpt-5.4 with medium reasoning as reader and a chain-of-thought gpt-5.4 judge,
|
|
median 5,760 context tokens per question, and 1,459 of 1,540 questions
|
|
correct; Mem0's post names an April 2026 algorithm, 6.7--7.0K tokens per
|
|
retrieval, and states that Zep's figure is disputed by a third-party
|
|
re-run at 75.1\%. Neither is comparable to the LoCoMo paper's own F1
|
|
figures, and neither is comparable to evidence recall.
|
|
|
|
\paragraph{Conflict resolution.} MemoryAgentBench's FactConsolidation task
|
|
numbers its facts, later facts supersede earlier ones, and the question asks
|
|
for the current value, one or two hops deep \cite{mab}. Its metric is
|
|
\texttt{substring\_exact\_match}. CAR \cite{car} reports 78.0 / 30.2 on
|
|
single- and multi-hop with gpt-4o-mini and 94.8 / 51.5 with gpt-4o, pooled
|
|
over context lengths from 6K to 262K tokens; at 262K the same pipelines score
|
|
82 / 27 and 93 / 41, against 54 / 5 for HippoRAG-v2 and 60 / 5 for gpt-4o
|
|
reading the whole context. Pith's page claims 68.0 exact match on the
|
|
262K multi-hop lane \cite{pith}. Na\"ive publishes 91 / 57 pooled on a matched
|
|
gpt-4o-mini backbone \cite{naivebrain}. That page names no dataset and gives no
|
|
protocol, but it is identifiable as this benchmark from its own comparison column:
|
|
its baselines are CAR's to the decimal --- 78.0 / 30.2, and 54, 28, 18 and 7
|
|
single-hop for HippoRAG-v2, MemGPT and Cognee, Mem0 and Zep, whose multi-hop
|
|
scores it collapses into a single ``$\le$7\%''. A table is identified by its
|
|
baselines.
|
|
|
|
We report each quantity under its own name, never one as another.
|
|
|
|
\paragraph{Three grades of evidence.} For a question with gold turns $G$ and
|
|
retrieved turns $R$, a system scores \textbf{EXACT} if $R \cap G \neq
|
|
\emptyset$ (and ALL if $G \subseteq R$), \textbf{SUPPORTED} if some turn in
|
|
$R$ shares an atomic fact with a turn in $G$ or contains the gold answer
|
|
string, and \textbf{ANSWERED} if the reader's answer is correct. The three
|
|
are reported side by side. The gap between EXACT and SUPPORTED is the
|
|
annotation's blind spot; the gap between SUPPORTED and ANSWERED is the
|
|
reader's.
|
|
|
|
\section{Related Work}
|
|
|
|
\paragraph{Benchmarks.} LoCoMo \cite{locomo} provides ten very long
|
|
two-person conversations with question--answer pairs and their supporting
|
|
turns, in single-hop, multi-hop, temporal, open-domain and adversarial
|
|
categories. LongMemEval \cite{longmemeval} tests extraction, multi-session
|
|
reasoning, temporal reasoning, knowledge updates and abstention over
|
|
scalable chat histories. MemoryAgentBench \cite{mab} recasts long-context
|
|
tasks as incremental multi-turn interaction and adds FactConsolidation, the
|
|
conflict-resolution task used here. LoCoMo-Conv \cite{locomoconv} rewrites
|
|
LoCoMo's memories into dialog, implicit, counterfactual and composed
|
|
requests---1,986, 1,986, 1,540 and 1,069 items---and standardises the
|
|
memory systems it compares on all-MiniLM-L6-v2 embeddings, $k=10$,
|
|
gemma-4-31B-it at temperature 0 as reader, and GPT-5.4-mini with reasoning
|
|
as judge, validated against Claude Sonnet 4.5 and Qwen3.6-35B-A3B on a
|
|
1,488-item subset. Without rewriting, Recall@10 falls from 0.531--0.659 on
|
|
dialog to 0.308--0.456 on implicit queries across five systems.
|
|
|
|
\paragraph{Systems.} MemGPT \cite{memgpt} manages context as an operating
|
|
system manages memory tiers. A-MEM \cite{amem} organises notes Zettelkasten
|
|
style. HippoRAG \cite{hipporag} runs personalised PageRank over an extracted
|
|
graph. Mem0 \cite{mem0} extracts and consolidates memories, and its 2026
|
|
algorithm adds single-pass add-only extraction and entity linking
|
|
\cite{mem0blog}. Zep \cite{zep} keeps a temporally aware knowledge graph and
|
|
retrieves across facts, entities, episodes, observations and thread
|
|
summaries \cite{zepresearch}. AnchorMem \cite{anchormem} extracts atomic
|
|
facts as retrieval anchors while preserving the raw context immutably, and
|
|
binds related facts into event nodes rather than bridging through generic
|
|
entities. AtomMem \cite{atommem} selects high-value atomic facts and
|
|
organises them into event structures and temporal profiles. Memora
|
|
\cite{memora} indexes a short primary abstraction and several cue anchors
|
|
per memory and keeps the full value unindexed, reporting up to 98\% fewer
|
|
context tokens. APEX-MEM \cite{apexmem} stores temporally grounded events in
|
|
an entity-centric property graph with append-only history and resolves
|
|
conflicts at query time, reporting 88.88\% on LoCoMo QA and 86.2\% on
|
|
LongMemEval under its setup. Our design takes from each what their own
|
|
ablations support: anchors over raw memory, events over entity hops,
|
|
abstractions beside cue anchors, append-only temporal history.
|
|
|
|
\paragraph{Conflict resolution.} CAR \cite{car} separates evidence
|
|
extraction from policy: retrieve, extract numbered facts, pick the latest
|
|
serial with code, then form the next hop. TEPA \cite{tepa} makes validity an
|
|
explicit, revocable state of a memory. MemTxn \cite{memtxn} gives memory a
|
|
transaction boundary with source-supported admission and a temporal
|
|
resolver. All three converge on the same rule: do not ask the reader which of
|
|
two contradicting facts is current.
|
|
|
|
\section{The Memory Record}
|
|
\label{sec:write}
|
|
|
|
Every write produces one immutable raw memory and a set of derived,
|
|
indexed views of it. Nothing derived replaces the raw text; the reader is
|
|
always handed the original.
|
|
|
|
\begin{itemize}
|
|
\item \textbf{raw} --- the turn or document as received, with \textbf{source}
|
|
(conversation, session, turn) and \textbf{observed\_at}.
|
|
\item \textbf{facts[]} --- atomic statements, several per turn, each with a
|
|
canonical \textbf{subject}, a \textbf{relation}, an \textbf{object}
|
|
that is a canonical entity or a literal, an \textbf{event\_time} when
|
|
the text carries one, \textbf{valid\_from} / \textbf{valid\_to} where
|
|
derivable, a \textbf{confidence}, an embedding, and the pointer to
|
|
its source turn.
|
|
\item \textbf{entities[]} --- canonical identifiers resolved by type
|
|
(person, place, organisation, work, date), not by capitalisation. The
|
|
surface heuristic was measured and rejected
|
|
(Section~\ref{sec:negative}).
|
|
\item \textbf{events[]} --- membership of facts in a shared event, the
|
|
associative link AnchorMem found to beat entity bridging.
|
|
\item \textbf{supersedes[] / superseded\_by[]} --- a supersession key so
|
|
that the current value of a relation is a lookup, not a judgement.
|
|
\item \textbf{primary\_abstraction} and \textbf{cue\_anchors[]} --- a short
|
|
phrase saying what the memory is about and several context-aware tags
|
|
that give the same memory alternative entry points.
|
|
\end{itemize}
|
|
|
|
The fact layer is the linkage index. On LoCoMo the dataset's own
|
|
observation annotations cite 79.9\% of multi-hop gold turns; the remaining
|
|
20\% are unreachable through any fact, which bounds what a re-ranker can do
|
|
and is why extraction coverage, measured in Table~\ref{tab:coverage}, comes
|
|
before tuning.
|
|
|
|
\section{The Read Path}
|
|
\label{sec:read}
|
|
|
|
\begin{figure*}[t]
|
|
\centering
|
|
\resizebox{\textwidth}{!}{%
|
|
\begin{tikzpicture}[
|
|
node distance=3.5mm and 5mm,
|
|
box/.style={draw, rounded corners=1pt, minimum height=7mm, inner sep=3pt, font=\small, align=center},
|
|
soft/.style={box, fill=black!4},
|
|
arrow/.style={-{Latex[length=1.8mm]}, semithick}
|
|
]
|
|
\node[box] (q) {query};
|
|
\node[soft, right=of q, text width=26mm] (plan) {understand\\ \footnotesize semantic, entity, temporal, current-state, multi-hop, implicit};
|
|
\node[soft, right=of plan, text width=27mm] (seed) {seed retrieval\\ \footnotesize dense $\cdot$ BM25 $\cdot$ facts $\cdot$ entities $\cdot$ session/time};
|
|
\node[box, right=of seed, text width=20mm] (anch) {candidate\\ anchors};
|
|
\node[soft, right=of anch, text width=26mm] (exp) {bounded expansion\\ \footnotesize events, timeline, typed edges};
|
|
\node[box, right=of exp, text width=18mm] (score) {one calibrated\\ scorer};
|
|
\node[box, right=of score, text width=20mm] (ctx) {minimal\\ source context};
|
|
\draw[arrow] (q) -- (plan);
|
|
\draw[arrow] (plan) -- (seed);
|
|
\draw[arrow] (seed) -- (anch);
|
|
\draw[arrow] (anch) -- (exp);
|
|
\draw[arrow] (exp) -- (score);
|
|
\draw[arrow] (score) -- (ctx);
|
|
\draw[arrow] (score.south) to[out=-90,in=-90,looseness=0.35] node[below, font=\footnotesize, midway] {resolved state $\rightarrow$ next hop's query} (plan.south);
|
|
\end{tikzpicture}}
|
|
\caption{The read path. Every candidate enters through a named generator
|
|
and carries the contribution of each term that scored it, so a ranking is
|
|
explainable after the fact. A hop that resolves an entity or a date rewrites
|
|
the query for the next hop; the original sentence is embedded once and never
|
|
reused for hop two.}
|
|
\label{fig:read}
|
|
\end{figure*}
|
|
|
|
\subsection{Query understanding}
|
|
|
|
The question is classified into retrieval operators---semantic, entity,
|
|
relationship, temporal, current-value, causal, multi-hop, implicit---by
|
|
rules over its surface (a year, a month, a name, ``after'', ``still'',
|
|
``most recent'') with a small model consulted only where the rules are
|
|
silent. The plan is an explicit state: what is resolved (an entity, a date,
|
|
an event), what is unresolved (the relation or object being asked for),
|
|
the evidence gathered so far, and the budget in hops, candidates, latency
|
|
and context tokens. The weights of the generators below are conditioned on
|
|
the plan; a temporal question spends its budget on the timeline, a
|
|
current-value question on the supersession chain.
|
|
|
|
\subsection{Seed retrieval and bounded expansion}
|
|
|
|
Seeds come from dense search over turns, BM25 over turns, dense search over
|
|
facts (each cited fact adds its source turn), exact matches on canonical
|
|
entities, and the session that a dated question names. Each generator
|
|
contributes a small pool---forty dense turns, twenty facts, three
|
|
neighbours in the shipped configuration---rather than a long ranked list.
|
|
Expansion is then bounded and typed: at most eight turns through event
|
|
membership, at most eight through the timeline, only along edges whose
|
|
confidence clears a threshold. A turn enters the pool because its text
|
|
matched, because a fact it contains matched, or because a high-confidence
|
|
typed link from already-resolved evidence points to it. It does not enter
|
|
because some generator ranked it forty-seventh.
|
|
|
|
\subsection{One scorer}
|
|
|
|
Every candidate is scored once. In the configuration that shipped in
|
|
\texttt{hanzoai/memory}, the score is the turn's cosine to the question,
|
|
plus 0.2 times the cosine of the best fact citing it, plus 0.06 if it sits
|
|
beside one of the top three turns in the same session, plus 0.05 if it sits
|
|
in the month or year a dated question names. The trace records each term,
|
|
so a rank is attributable to a mechanism.
|
|
|
|
Facets---three to five rewrites of an implicit or composed
|
|
request---feed the same seed stage with the same small pools. LoCoMo-Conv
|
|
reports that multi-facet rewriting lifts AnchorMem's implicit Recall@10 from
|
|
0.368 to 0.524 while abstractive systems gain little \cite{locomoconv}; our
|
|
own earlier attempt to fuse whole ranked lists with reciprocal-rank fusion
|
|
lost four points (Section~\ref{sec:negative}), so facets are pooled small
|
|
and scored once, never fused.
|
|
|
|
\subsection{Stateful hops}
|
|
|
|
The second hop is not a second embedding of the first sentence. When hop one
|
|
resolves an entity and an event---``Sarah'' to an identifier, ``leaving
|
|
Acme'' to a dated departure---hop two is the structured query
|
|
\emph{subject = that identifier, relation = employed\_by, time after that
|
|
departure}, answered from the fact graph and the timeline. Similarity to the
|
|
original wording no longer matters for the evidence hop two needs.
|
|
|
|
\subsection{Deterministic resolution}
|
|
|
|
For questions that ask for a current or versioned value, and only for
|
|
those, the candidate facts are grouped by supersession key and the latest
|
|
serial or the latest \textbf{valid\_from} is selected in code before the
|
|
reader sees anything. This is CAR's rule \cite{car} applied to an index that
|
|
already carries the version structure CAR had to reconstruct at inference
|
|
time. The reader is given the winning fact and its raw source turn; it is
|
|
never asked to adjudicate between contradictions.
|
|
|
|
\section{Protocol}
|
|
\label{sec:protocol}
|
|
|
|
The protocol is fixed in \texttt{METHOD.md} of the benchmark repository and
|
|
is repeated here so that no number below can be read without it.
|
|
|
|
\textbf{Splits.} LoCoMo: dev is conversations 0--2, test is 3--9. The
|
|
retrieval figures in Section~\ref{sec:locomo} predate the split and were
|
|
measured on all ten conversations; they are labelled ``all'' and are not
|
|
re-quoted as test numbers. MemoryAgentBench FactConsolidation: dev is the
|
|
two 6K haystacks (single- and multi-hop), test is 32K, 64K and 262K.
|
|
LoCoMo-Conv: the paper's protocol; dev is the first two conversations'
|
|
items, test the rest.
|
|
|
|
\textbf{Metrics.} Retrieval: R@5/10/20 ALL and ANY, MRR of the first gold
|
|
turn, NDCG@20, candidates examined, context tokens delivered, p50 and p95
|
|
latency. Answering: token F1 and exact match on LoCoMo, substring exact
|
|
match on MemoryAgentBench, the benchmark's judge on LoCoMo-Conv. Bootstrap
|
|
95\% intervals, 1,000 resamples over questions, on every headline.
|
|
|
|
\textbf{Readers.} Three lanes, never mixed in a table: \emph{house},
|
|
enso-flash; \emph{open}, google/gemma-4-31b-it, the reader LoCoMo-Conv
|
|
standardises on, with qwen3-30b-a3b-instruct as fallback;
|
|
\emph{matched}, the reader a compared paper used where the router serves
|
|
it. Temperature 0, 64 output tokens, one prompt file per benchmark shared by
|
|
every row. Rows in one table share reader, prompt, $k$ and context budget.
|
|
|
|
\textbf{Freeze.} A configuration is chosen on dev, its commit hash written
|
|
beside its table, and the test split run once. A later change is a new run
|
|
identifier beside the old, never over it. No per-question routing, no
|
|
tuning against test labels.
|
|
|
|
\section{LoCoMo: Retrieval in Isolation}
|
|
\label{sec:locomo}
|
|
|
|
Ten conversations, 5,882 turns, 1,540 questions with evidence: 282
|
|
multi-hop, 321 temporal, 96 open-domain, 841 single-hop; the 446 adversarial
|
|
questions are excluded, as Mem0 and Zep exclude them. Turns and questions are
|
|
embedded with zen-embedding-0.6b; the dataset's observation annotations serve
|
|
as the fact layer for this experiment, each observation citing the turns it
|
|
was extracted from. Nothing is learned. Two systems are measured. The first
|
|
cut (Table~\ref{tab:locomo}) is the four-term pool and re-rank that shipped
|
|
in \texttt{/v1/memory/search}: cosine over turns plus the best citing fact,
|
|
adjacency and a time cue. The engine of Section~\ref{sec:read} follows
|
|
(Tables~\ref{tab:ablation}--\ref{tab:minilm}), with its weights and pools
|
|
chosen on conversations 0--2 and frozen at commit \texttt{33d0f8749bd1}
|
|
before conversations 3--9 were run once.
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\footnotesize
|
|
\begin{tabular}{lrrrr}
|
|
\toprule
|
|
& \multicolumn{2}{c}{single-hop} & \multicolumn{2}{c}{multi-hop} \\
|
|
\cmidrule(lr){2-3}\cmidrule(lr){4-5}
|
|
R@20 (all) & ALL & ANY & ALL & ANY \\
|
|
\midrule
|
|
cosine over turns & 78.2 & 80.7 & 22.7 & 80.1 \\
|
|
linked & \textbf{81.8} & \textbf{83.8} & \textbf{36.2} & \textbf{87.2} \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Evidence recall at $k=20$, in percent. The multi-hop
|
|
complete-evidence rate rises by 13.5 points; the any-evidence rate by 7.1.
|
|
Retrieval stays under a millisecond per question.}
|
|
\label{tab:locomo}
|
|
\end{table}
|
|
|
|
\begin{table}[h]
|
|
\centering
|
|
\small
|
|
\begin{tabular}{lrrr}
|
|
\toprule
|
|
multi-hop ALL, first cut (all ten) & $k=5$ & $k=10$ & $k=20$ \\
|
|
\midrule
|
|
& 13.5 & 23.4 & 36.2 \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\vspace{4pt}
|
|
\input{tables/locomo-byk}
|
|
\caption{The same configuration by $k$. A number quoted from this table
|
|
carries its $k$; a reader that is handed ten turns sees 23.4\%, not 36.2\%.}
|
|
\label{tab:byk}
|
|
\end{table}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\resizebox{\textwidth}{!}{\input{tables/locomo-ablation}}
|
|
\caption{The engine on all ten conversations at $k=20$, one generator added
|
|
per row, the frozen weights throughout. ALL is the complete-evidence rate,
|
|
ANY the any-evidence rate; R@20 is $|\text{retrieved} \cap
|
|
\text{gold}|/|\text{gold}|$; \emph{supported} counts a question whose
|
|
top-20 holds a gold turn, a turn sharing an atomic fact with a gold turn, or a
|
|
turn containing the gold answer. The fact index carries most of the gain; the
|
|
second hop moves single-hop and temporal questions; a fusion of whole ranked
|
|
lists loses nDCG for a little ANY.}
|
|
\label{tab:ablation}
|
|
\end{table*}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\resizebox{\textwidth}{!}{\input{tables/locomo-ablation-test}}
|
|
\caption{The same rows on the test split (conversations 3--9), run once
|
|
after the freeze. The failed shapes are below the rule: pseudo-relevance
|
|
feedback drifts the query toward its own top three and examines 634
|
|
candidates to lose; chain search finds the multi-hop turns but scrambles the
|
|
ranking; surface entities and global fusion are the two results that shaped
|
|
the design.}
|
|
\label{tab:ablation-test}
|
|
\end{table*}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\resizebox{\textwidth}{!}{\input{tables/locomo-minilm}}
|
|
\caption{The same engine over all-MiniLM-L6-v2 vectors at $k=10$, the
|
|
embedder and cut LoCoMo-Conv fixes for every system it compares, all ten
|
|
conversations. With a weak embedder linkage matters more, not less: the
|
|
complete-evidence rate on multi-hop questions rises from 9.6 to 24.1 and
|
|
nDCG from 31.1 to 55.8, from the same fact layer and the same weights.}
|
|
\label{tab:minilm}
|
|
\end{table*}
|
|
|
|
\paragraph{Where the misses are.} For the gold turns cosine fails to
|
|
retrieve, we measured which link would have reached them from a turn it did
|
|
retrieve: adjacency 16.9\%, same session 33.0\%, a shared name 20.1\%, a
|
|
citing fact 23.9\%, any of these 52.2\%. Each link is weak alone and real in
|
|
combination, and each only makes sense as a bonus on a candidate that
|
|
already has a reason to be there---which is the design in
|
|
Figure~\ref{fig:read} and the reason list fusion failed.
|
|
|
|
\paragraph{The ceiling.} 79.9\% of multi-hop gold turns are cited by at
|
|
least one observation; for those, the best citing fact sits at median rank
|
|
8 in the fact index where the turn itself sits at median rank 20 in the turn
|
|
index. The fact index is closer to the answer than the turn index is. The
|
|
other 20.1\% cannot be reached by any re-ranking of this fact layer, so the
|
|
next section measures the fact layer itself.
|
|
|
|
\section{Extraction Coverage}
|
|
\label{sec:coverage}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/coverage}
|
|
\caption{Fact coverage of LoCoMo gold turns. A gold turn is covered when at
|
|
least one extracted fact cites it; covered with the right entity when that
|
|
fact's canonical subject or object is the entity the question names;
|
|
covered with a dated fact when the fact carries an event time. Precision is
|
|
read on a hand-checked sample of 100 facts.}
|
|
\label{tab:coverage}
|
|
\end{table*}
|
|
|
|
\section{Parameter Search on the Dev Split}
|
|
\label{sec:sweep}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/sweep}
|
|
\caption{Every parameter searched, the range, the value chosen on dev, and
|
|
the test number read once after the freeze. The full grid is in
|
|
\texttt{ablations/}.}
|
|
\label{tab:sweep}
|
|
\end{table*}
|
|
|
|
\section{LoCoMo: Answers}
|
|
\label{sec:answers}
|
|
|
|
A reader is handed the retrieved turns and scored on what it says
|
|
(Table~\ref{tab:answers}). Every row of a reader shares the prompt
|
|
(\texttt{prompts/reader-locomo.txt}), temperature 0 and a 64-token cap; rows
|
|
differ only in what was retrieved. The open reader is gemma-4-31B-it, run
|
|
locally, the reader LoCoMo-Conv fixes; qwen3.6-35B-A3B follows on all four
|
|
categories. The oracle row hands the reader exactly the annotated turns.
|
|
|
|
With qwen3.6-35B-A3B over all 1,525 questions of the four categories,
|
|
cosine context yields F1 48.8, the first cut 50.3, the engine 53.3 and the
|
|
annotated turns 61.8; exact match 26.2, 26.7, 29.0 and 34.6. Retrieval moved
|
|
the share of contexts holding a gold turn from 79.3\% to 87.0\%, and the
|
|
engine's rows are above cosine's on every category (multi-hop 36.7
|
|
$\rightarrow$ 43.0, single-hop 56.9 $\rightarrow$ 61.9, temporal 47.5
|
|
$\rightarrow$ 49.5). The multi-hop questions with Gemma say where the remaining error is. Cosine
|
|
context yields F1 37.6; the first cut 40.7; the engine 40.5; the annotated
|
|
turns themselves 53.0. Retrieval moved the share of questions whose context
|
|
holds a gold turn from 79.8\% to 87.9\%, and the reader turned that into
|
|
three points of F1 out of a fifteen-point gap to the oracle. The rest of the
|
|
gap is the reader's: a 31B open model at temperature 0, asked for the
|
|
shortest answer, scores 53.0 even when handed nothing but the evidence.
|
|
That is the ceiling any retrieval improvement is measured against on this
|
|
reader, and it is the reason the retrieval tables are reported on their own:
|
|
a reader can hide a retrieval gain, and a stronger reader raises every row.
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\resizebox{\textwidth}{!}{\input{tables/locomo-answers}}
|
|
\caption{Answer accuracy on LoCoMo with the same reader, prompt and $k$
|
|
across rows, all ten conversations. EXACT is the share of questions whose
|
|
context held an annotated turn; ANSWERED is F1 $\geq 0.5$ or an exact match.
|
|
The oracle row hands the reader exactly the annotated turns and bounds what
|
|
retrieval can still buy. Tokens per question are the retrieved context
|
|
delivered to the reader; the reader's own p50 latency is the local Ollama
|
|
service under shared load and is reported, not claimed.}
|
|
\label{tab:answers}
|
|
\end{table*}
|
|
|
|
\section{MemoryAgentBench: FactConsolidation}
|
|
\label{sec:mab}
|
|
|
|
Eight haystacks: single- and multi-hop at 6K, 32K, 64K and 262K tokens, 100
|
|
questions each, facts numbered in order of arrival, later serials
|
|
superseding earlier ones. The deterministic resolver of
|
|
Section~\ref{sec:read} is scoped to exactly this question type.
|
|
|
|
The write side parses every fact line into (serial, subject, relation,
|
|
object) — 45 templates, no line left unparsed at any size, and the gold
|
|
answer is the object of some fact for every question. The read side compiles
|
|
the question into a base entity and a chain of relations, follows the chain
|
|
hop by hop, and at each hop takes the latest serial for (entity, relation)
|
|
deterministically; the reader, where one is used, sees only the resolved
|
|
facts. The \emph{noreader} row emits the resolved object string itself, so
|
|
it is the resolver's accuracy with no model in the loop at all.
|
|
|
|
Three resolvers stand in Table~\ref{tab:mab}, each developed on the 6K
|
|
haystacks and run on the others once. The first run compiled plans with a hand-written lexicon. It scored 98.0 /
|
|
77.5 (SH / MH) on the 6K dev haystacks, held single-hop at 92.9--98.0 on
|
|
test, and fell to 32.0 / 31.3 / 25.5 on multi-hop at 32K / 64K / 262K. The
|
|
traces say why: 126 of the 209 multi-hop misses were complete chains with
|
|
the wrong answer, and 83 asked for a relation the entity never had. Both are
|
|
the plan: the lexicon emitted relations in the question's surface order
|
|
(``capital of the country that X originates from'' became
|
|
\texttt{[capital, country\_origin]} rather than the reverse) and added a hop
|
|
for every relation word it saw, and it had been written against the 6K
|
|
phrasings. Parse coverage, entity lookup and version selection were not the
|
|
problem. The second run keeps the exact single-hop templates as rules, has a
|
|
model compile every other question into the same plan shape, validated
|
|
against the relation set, and uses the lexicon only where the model's plan
|
|
fails validation. On the shared GPU every model call of that pass timed
|
|
out and the lexicon filled every plan, so its plans were the lexicon's; it
|
|
scored 59 / 59 / 33 on multi-hop at 32K / 64K / 262K, the gain over the
|
|
first run being the fixed plan policy for single-hop and a corrected
|
|
lexicon, not a model.
|
|
|
|
The third row treats the plan as a sketch. An oracle search over the
|
|
parsed graph (\texttt{mab/oracle.mjs}) found a path from the plan's base
|
|
entity to the gold for 65 of the 67 multi-hop misses at 262K; the compiler's
|
|
errors were near-synonym relations (\texttt{language} for
|
|
\texttt{official\_lang}, \texttt{origin} for \texttt{country\_origin}),
|
|
chains cut a hop short or padded with one, and the order of two hops. A
|
|
second measurement (\texttt{mab/versions.mjs}) settled, on dev, what
|
|
``current'' means: for single-hop questions the gold is the last version of
|
|
its key 71 times and the first 0; for multi-hop chains 63 are reachable with
|
|
the latest version at every hop and none with the first. So the search keeps
|
|
``latest wins'' and relaxes the plan: at each hop the planned relation is
|
|
preferred, its class-mates allowed at a cost, an older version taken only
|
|
when the latest leads nowhere, one typed bridge through the entity's own
|
|
facts when it has no such relation, a planned relation nothing satisfies
|
|
skipped at a cost, and the answer type the question names --- a city, a
|
|
country, a person, a language --- as the final constraint, deciding between
|
|
stopping a hop early and going one further. The best complete path wins by a
|
|
fixed score; ties go to the more literal plan and the later version. It is
|
|
deterministic, it reads no gold, and it calls no model at execution time.
|
|
|
|
The plans it searches over are several per question: the lexicon's, and
|
|
those of Qwen3.8-27B (4-bit, local) compiled once at temperature 0 and once
|
|
at 0.7, at the relation level and at the level of relation families, each
|
|
also in every order of its relations. Every plan of every set is executed
|
|
and the same score selects among them; \texttt{meta.json} records the
|
|
planner of every run and the frozen archive carries every plan set with its
|
|
sha256. The compiler is the one place a language model takes part, before any
|
|
haystack is read; it never sees a fact. Table~\ref{tab:mab-nbest} separates
|
|
the two: plan recall@N (some plan among the first N sets reaches the gold)
|
|
against execution success@N (the selected one does). Recall climbs with
|
|
every set and selection tracks it within a point or two --- 68 against 67
|
|
at 262K --- so the sets, not the selector, set the number. A third row asks a language model to repair a
|
|
plan the selector finds suspicious, and it is in the table at its dev numbers
|
|
and nowhere else: across 196 dev questions the repair fired \emph{once}, that
|
|
one plan was chosen, and it is the whole of the row's 88 to 89. One question,
|
|
for a 27B model held resident beside the search. It was not promoted to test,
|
|
which is why its test cells are empty --- a configuration that loses on dev does
|
|
not get a second chance on held-out data, and reporting the empty cells is
|
|
cheaper than pretending the row was never run. The fourth row
|
|
adds an exhaustive enumeration of the relaxed plan and a lexical tie-break
|
|
from the compiler's own templates, and buys five points where the repair bought
|
|
one, with no model in the loop at all. On dev it moved multi-hop from 88 to 93
|
|
and single-hop from 98 to 100; on test, run once, multi-hop 89 / 89 / 67 and
|
|
single-hop 98 / 98 / 97. Pooled, 98.3 / 84.5, counting every unanswered
|
|
question as wrong.
|
|
|
|
Against the reference points: CAR's gpt-4o pipeline reports 94.8 / 51.5
|
|
pooled and 93 / 41 at 262K; this search reports 98.3 / 84.5 pooled and
|
|
97 / 67 at 262K with no reader. Na\"ive's 91 / 57 is pooled on the same
|
|
benchmark, identified as above, on a matched gpt-4o-mini backbone; this search
|
|
reports 98.3 / 84.5 with no reader at all, +7.3 single-hop and +27.5 multi-hop.
|
|
The per-lane split is not published there, so the comparison is of pooled figures,
|
|
and what varied under their measurement is unstated. Pith
|
|
reports multi-hop 95 / 83 / 84 / 68 at 6K / 32K / 64K / 262K under its own
|
|
protocol \cite{pith}, a four-lane mean of 82.5 against this search's 84.5:
|
|
above it at 32K and 64K, two below at 6K and one below at 262K, inside the
|
|
bootstrap interval on every lane. Its protocol is undisclosed, so this
|
|
compares reported numbers, not systems, and we claim no best published
|
|
result on the benchmark.
|
|
|
|
\paragraph{What stops 262K at two thirds.} The search's 33 misses at 262K
|
|
are 29 questions whose gold uses an \emph{older} version of a key that a
|
|
later line updates, and 4 where a shortcut path hides the same choice;
|
|
every one of the 100 has a gold path in the parsed store
|
|
(Table~\ref{tab:mab-ceiling}). The later line is an edit no question in the
|
|
haystack asks for: the benchmark is built from MQuAKE-CF counterfactual
|
|
edits, a haystack packs the edits of instances it never asks about, and the
|
|
gold follows the edit on 183 versioned hops and the original on 46. Two
|
|
ceilings follow. A key is contested when two questions need it in different
|
|
versions; a policy choosing one version per key, however it chooses, can
|
|
satisfy one side of each contest, which caps an oracle at 94 at 262K.
|
|
``Latest wins'' caps at 67, and the search is on that line. Six signals a
|
|
store can read were tried against the 46 older-gold hops, with the 183
|
|
latest-gold hops as control: the object's degree (gold higher 21, lower
|
|
20), whether the object has facts of its own (equal), whether it is tied
|
|
back to its subject elsewhere (13 to 0 for the gold --- and 4 to 42 on the
|
|
control, because the tie marks the \emph{original} fact, which is the gold
|
|
one time in five), contest by another question (6 questions), serial
|
|
distance to the chain's other facts (24 to 38), and position in the list by
|
|
decile (one distribution for followed and ignored edits). None separates
|
|
them. A system that reads only the haystack cannot pass 67 at 262K without
|
|
guessing; the published 68 is one question above that line. The residue is
|
|
a property of the benchmark at that size, and the way past it is not a
|
|
reader but the question's own instance --- which the haystack does not
|
|
carry.
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/mab-fc}
|
|
\caption{Substring exact match on FactConsolidation. Rows name their
|
|
reader; \emph{none} is the resolver's own output. The 6K columns are the dev
|
|
split; 32K--262K were run once per configuration. Pooled is the mean of the
|
|
four sizes, as CAR reports its headline.}
|
|
\label{tab:mab}
|
|
\end{table*}
|
|
|
|
\begin{table}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/mab-nbest}
|
|
\caption{Best-of-N against selected-of-N on the multi-hop haystacks: plan
|
|
recall@N / execution success@N out of 100, no reader. Sets enter in the
|
|
lane's order; every set is also executed in every order of its relations.}
|
|
\label{tab:mab-nbest}
|
|
\end{table}
|
|
|
|
\begin{table}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/mab-ceiling}
|
|
\caption{The ceiling of a consistent version policy per multi-hop haystack,
|
|
out of 100. A contested key is one that two questions need in different
|
|
versions; the oracle row picks one version per key to satisfy the most
|
|
questions, the latest-wins row is the policy every row of
|
|
Table~\ref{tab:mab} uses.}
|
|
\label{tab:mab-ceiling}
|
|
\end{table}
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\small
|
|
\begin{tabular}{llrr}
|
|
\toprule
|
|
System, 262K & reader & FC-SH & FC-MH \\
|
|
\midrule
|
|
CAR pipeline \cite{car} & gpt-4o-mini & 82 & 27 \\
|
|
CAR pipeline \cite{car} & gpt-4o & 93 & 41 \\
|
|
gpt-4o, whole context \cite{car} & gpt-4o & 60 & 5 \\
|
|
HippoRAG-v2 \cite{car} & --- & 54 & 5 \\
|
|
BM25 \cite{car} & --- & 48 & 3 \\
|
|
Cognee, MemGPT \cite{car} & --- & 28 & 3 \\
|
|
Mem0 \cite{car} & --- & 18 & 2 \\
|
|
Zep/Graphiti \cite{car} & --- & 7 & 3 \\
|
|
Pith (vendor page) \cite{pith} & undisclosed & --- & 68.0 \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
\caption{Published reference points at 262K, as reported by their sources.
|
|
CAR's pooled figures over all four lengths are 78.0 / 30.2 with gpt-4o-mini
|
|
and 94.8 / 51.5 with gpt-4o. gpt-4o-mini is not served on our router, so the
|
|
matched lane is reported only where a comparable reader could be run.}
|
|
\label{tab:mabref}
|
|
\end{table*}
|
|
|
|
\section{LoCoMo-Conv}
|
|
\label{sec:conv}
|
|
|
|
The benchmark's own protocol: all-MiniLM-L6-v2 embeddings, $k=10$, recall
|
|
$= |\text{retrieved} \cap \text{gold}|/|\text{gold}|$ with a gold turn
|
|
counted when its verbatim text appears in a returned memory, gemma-4-31B-it
|
|
at temperature 0, GPT-5.4-mini as judge. Reference points from the paper
|
|
\cite{locomoconv}: without rewriting, Recall@10 on dialog queries spans
|
|
0.531--0.659 across the five systems, with AnchorMem at 0.659; on implicit
|
|
queries 0.308--0.456, with mem0 at 0.456 and Memora at 0.445; multi-facet
|
|
rewriting lifts AnchorMem's implicit recall from 0.368 to 0.524 and its
|
|
composed recall from 0.279 to 0.432.
|
|
|
|
At the time of writing the data is not released: the paper's one release
|
|
address, \texttt{github.com/MiuLab/LoCoMo-Conv}, answers 404, and no copy
|
|
exists on Hugging Face or in the authors' other repositories. We therefore
|
|
report no LoCoMo-Conv number. Two things could be done without the data,
|
|
and were. First, the harness: \texttt{conv/retrieve.mjs} implements the
|
|
protocol above against any ranking function, with the four styles as a
|
|
loader slot, so the run is one command when the data appears. Second, a
|
|
sanity check of the protocol on the questions the rewrites came from
|
|
(Table~\ref{tab:conv}): the same embedder, the same $k$, the same
|
|
containment rule, on the original LoCoMo questions. Single turns as the
|
|
memory unit reproduce none of the paper's rows; two-turn exchanges land
|
|
within three points of its Naive RAG dialog row. The paper does not state
|
|
its memory unit, and its containment rule pays for larger units, which is
|
|
worth knowing before any system's number on it is compared with another's.
|
|
The same check with zen-embedding-0.6b in place of MiniLM moves single-turn
|
|
recall by 17 points before any linkage, which is why Table~\ref{tab:minilm}
|
|
holds the embedder fixed.
|
|
|
|
\begin{table*}[t]
|
|
\centering
|
|
\footnotesize
|
|
\input{tables/conv}
|
|
\caption{LoCoMo-Conv's retrieval protocol on the original LoCoMo questions,
|
|
the closest public proxy while the rewrites are unreleased. R@10 by memory
|
|
unit, all-MiniLM-L6-v2. The paper's Naive RAG row is given for scale; it is
|
|
not the same question set and is not compared.}
|
|
\label{tab:conv}
|
|
\end{table*}
|
|
|
|
\section{Negative Results}
|
|
\label{sec:negative}
|
|
|
|
Two additions that read as improvements were measured and removed.
|
|
|
|
\paragraph{Global reciprocal-rank fusion.} Fusing the turn ranking, the
|
|
fact-cited ranking and the neighbour ranking as whole lists lost four points
|
|
of multi-hop ALL@20 against the pooled re-rank. Every weak nominator pushed
|
|
sixty candidates in; the one turn the fact index was meant to lift from rank
|
|
67 to rank 12 was drowned by fifty-nine others it lifted for no reason.
|
|
|
|
\paragraph{Surface-entity expansion.} Treating capitalised words shared
|
|
between the nearest facts as entities and hopping through them lost two
|
|
points. ``Sunday'' is not an entity. Entities must be resolved by type, and
|
|
expansion must be bounded and typed, which is the design of
|
|
Section~\ref{sec:read}.
|
|
|
|
\paragraph{Pending.} Pseudo-relevance feedback, generic multi-query
|
|
expansion and chain search are run as rows in the ablations of
|
|
Tables~\ref{tab:mab} and \ref{tab:conv}; they are reported whether or not
|
|
they help.
|
|
|
|
\section{Hanzo ContextBench}
|
|
\label{sec:contextbench}
|
|
|
|
External benchmarks are run unchanged. Beside them we are building a
|
|
benchmark that measures what a company brain is for, with ten dimensions
|
|
scored per item: answer, grounding, evidence completeness, contextuality,
|
|
composition, temporal choice, conflict suppression, tokens retrieved,
|
|
retrieval latency, and provenance---whether every claim in the answer
|
|
traces to a source. Items are real conversational memory needs: explicit,
|
|
implicit, temporal, conflicting, composed, causal, cross-session,
|
|
cross-document, user and organisation scope, and memory combined with the
|
|
current context. Evidence is graded EXACT, SUPPORTED or ANSWERED as in
|
|
Section~\ref{sec:measure}, so a system that answers from an equivalent turn
|
|
is not scored as a miss. The same structure is applied to code in the
|
|
companion paper: symbol, definition, reference, implementation, caller,
|
|
callee, type, file, commit, issue, test, runtime log. We note that
|
|
\cite{contextbench} independently uses the name ContextBench for a
|
|
coding-agent retrieval benchmark; ours is named for the product it
|
|
measures, and the two are distinct.
|
|
|
|
\section{Limitations}
|
|
|
|
The fact layer used for the retrieval result in Section~\ref{sec:locomo} is
|
|
LoCoMo's own annotation, extracted by the dataset authors with a strong
|
|
model; Section~\ref{sec:coverage} replaces it with our extraction and
|
|
reports coverage and precision so that the substitution is visible. The
|
|
retrieval result was measured on all ten conversations before the split
|
|
was declared and is therefore not a test number. Two readers our
|
|
comparisons name, gpt-4o-mini and gpt-5.4, are not served on our router;
|
|
where a matched lane is missing the table says so rather than substituting.
|
|
LoCoMo has ten conversations; intervals are wide and we print them.
|
|
Vendor figures quoted in Section~\ref{sec:measure} are their own claims on
|
|
their own protocols and are labelled as such.
|
|
|
|
\section{Conclusion}
|
|
|
|
Similarity finds resemblance. Context finds relationships. The measured
|
|
part of this paper shows that a second index of atomic facts, each pointing
|
|
at its source turn, lifts the complete-evidence rate on multi-hop questions
|
|
by more than half with no learning and no latency, and that two natural
|
|
extensions make it worse. The rest sets out a memory record and a read path
|
|
built from what the field's own ablations support---preserve everything,
|
|
index several views, link typed facts and events, resolve time in code,
|
|
change the query after every hop, return the least original context that
|
|
proves the answer---and a protocol under which its numbers can be believed.
|
|
|
|
\begin{thebibliography}{99}
|
|
\bibitem{locomo} A. Maharana, D.-H. Lee, S. Tulyakov, M. Bansal, F. Barbieri, Y. Fang.
|
|
Evaluating Very Long-Term Conversational Memory of LLM Agents. arXiv:2402.17753, 2024.
|
|
\bibitem{locomoconv} W.-Y. Chang, Y.-N. Chen. When Users Don't Ask: Benchmarking
|
|
Context-Driven Memory Retrieval in Conversational Agents. arXiv:2609.03467, September 2026.
|
|
Data: \url{github.com/MiuLab/LoCoMo-Conv}.
|
|
\bibitem{mab} Y. Hu, Y. Wang, J. McAuley. Evaluating Memory in LLM Agents via
|
|
Incremental Multi-Turn Interactions. arXiv:2507.05257, 2025; ICLR 2026.
|
|
\bibitem{longmemeval} D. Wu, H. Wang, W. Yu, Y. Zhang, K.-W. Chang, D. Yu. LongMemEval:
|
|
Benchmarking Chat Assistants on Long-Term Interactive Memory. arXiv:2410.10813, 2024.
|
|
\bibitem{car} V. Reddy, S. R. Challaram. Reliable Post-Retrieval Assembly for Agent
|
|
Memory: Separating Evidence Extraction from Policy Execution. arXiv:2606.01435, May 2026
|
|
(v1 titled ``Don't Ask the LLM to Track Freshness'').
|
|
\bibitem{tepa} Y. Zhou, Y. Ouyang, K. Zheng, S. Xiang. TEPA: Revoking Stale Memories for
|
|
Conflict-Robust Language Agents. arXiv:2608.07429, August 2026.
|
|
\bibitem{memtxn} H. Cui, Z. Tang, Z. Yao, F. Meng, Q. Ma, W. Jia. MemTxn: A Transaction
|
|
Boundary for Source-Supported Updates and Complete-State Recovery in Agent Memory.
|
|
arXiv:2607.27834, July 2026.
|
|
\bibitem{mem0} P. Chhikara, D. Khant, S. Aryan, T. Singh, D. Yadav. Mem0: Building
|
|
Production-Ready AI Agents with Scalable Long-Term Memory. arXiv:2504.19413, 2025.
|
|
\bibitem{mem0blog} Mem0. LoCoMo, LongMemEval \& BEAM Leaderboard: Where Every AI Memory
|
|
System Ranks in 2026. \url{mem0.ai/blog/ai-memory-benchmarks-in-2026}, May 11, 2026.
|
|
Vendor claim.
|
|
\bibitem{zep} P. Rasmussen, P. Paliychuk, T. Beauvais, J. Ryan, D. Chalef. Zep: A
|
|
Temporal Knowledge Graph Architecture for Agent Memory. arXiv:2501.13956, 2025.
|
|
\bibitem{zepresearch} Zep. Research. \url{getzep.com/research}, page dated August 27,
|
|
2026. Vendor claim.
|
|
\bibitem{anchormem} Z. Shen, S. Cheng, Z. Guo, W. Wang, Y. Wang, H. Huang. AnchorMem:
|
|
Anchored Facts with Associative Contexts for Building Memory in Large Language Models.
|
|
arXiv:2604.17377, April 2026.
|
|
\bibitem{atommem} Y. Yao, S. Li, Z. Zheng, H. Zheng, Q. Liu, T. Xu, E. Chen. AtomMem:
|
|
Building Simple and Effective Memory System for LLM Agents via Atomic Facts.
|
|
arXiv:2606.19847, June 2026.
|
|
\bibitem{memora} M. Xia, X. Zhang, S. Dixit, P. Harimurugan, R. Wang, V. R\"uhle, R. Sim,
|
|
C. Bansal, et al. Memora: A Harmonic Memory Representation Balancing Abstraction and
|
|
Specificity. arXiv:2602.03315, 2026; ICML 2026. Code: \url{github.com/microsoft/Memora}.
|
|
\bibitem{apexmem} P. Banerjee, M. Moshtaghi, S. Subramanian, A. Misra, A. Chadha. APEX-MEM:
|
|
Agentic Semi-Structured Memory with Temporal Reasoning for Long-Term Conversational AI.
|
|
arXiv:2604.14362, April 2026; ACL 2026.
|
|
\bibitem{hipporag} B. Jim\'enez Guti\'errez, Y. Shu, Y. Gu, M. Yasunaga, Y. Su. HippoRAG:
|
|
Neurobiologically Inspired Long-Term Memory for Large Language Models. arXiv:2405.14831, 2024.
|
|
\bibitem{amem} W. Xu, Z. Liang, K. Mei, H. Gao, J. Tan, Y. Zhang. A-MEM: Agentic Memory
|
|
for LLM Agents. arXiv:2502.12110, 2025.
|
|
\bibitem{memgpt} C. Packer, S. Wooders, K. Lin, V. Fang, S. G. Patil, I. Stoica,
|
|
J. E. Gonzalez. MemGPT: Towards LLMs as Operating Systems. arXiv:2310.08560, 2023.
|
|
\bibitem{naivebrain} Na\"ive. Agent Brain benchmark results.
|
|
\url{usenaive.ai/lab/memory}, dated July 2026, read 15 September 2026. The page
|
|
reports 91 / 57 on ``FictionalCharacters QA on a matched gpt-4o-mini backbone'',
|
|
metric ``\% of held-out questions answered correctly'', with ``Na\"ive measured,
|
|
others published''. No dataset source, question count, protocol or citation is
|
|
given; a preprint, ``Both Engines, One Harness'', is announced as forthcoming.
|
|
|
|
\bibitem{pith} Pith. AI Agent Memory with Cognitive Governance. \url{pith.run}, accessed
|
|
September 2026. Vendor claim: 95.0 EM on the 6K and 68.0 EM on the 262K
|
|
FactConsolidation multi-hop lanes.
|
|
\bibitem{contextbench} H. Li, L. Zhu, B. Zhang, R. Feng, J. Wang, Y. Pan, E. T. Barr,
|
|
F. Sarro, et al. ContextBench: A Benchmark for Context Retrieval in Coding Agents.
|
|
arXiv:2602.05892, 2026.
|
|
\end{thebibliography}
|
|
|
|
\end{document}
|