Korely

Research & architecture

Korely's memory stack is paper-grounded. Every non-trivial mechanism in the product, how facts get extracted, how contradictions get resolved, how context gets ordered before it reaches the model, traces back to a specific published result. This page maps each mechanism to its source, so you can audit our design decisions instead of taking our word for them.

The framing we find most useful is the Forms, Functions, Dynamics taxonomy from Memory in the Age of AI Agents (arXiv 2512.13564). In that vocabulary, Korely's layers map onto this taxonomy as follows:

Korely layerTaxonomy positionWhat lives there
Layer 1, memory store Factual / token-level memory Memories in a managed store (Postgres + pgvector, EU-hosted on Cloud), with vector search
Layer 3, typed facts Factual memory with temporal dynamics a learned vocabulary of predicates, each in one of 10 families, bi-temporal validity, contradiction handling

Layer 2 is session scope, a run_id filter on Layer 1, so it adds no new memory type.

We didn't pick papers and build features around them. We hit problems while running Korely on our own work: stale facts winning over fresh ones, the model trusting its training data over retrieved sources, contradiction spam in the graph. Then we went looking for who had already solved them.

What we implement

Each entry: what the paper proposes, what Korely implements, and the concept page that documents the mechanism in API-level detail.

PaperWhat it proposesIn Korely
Graphiti / Zep (arXiv 2501.13956) A bi-temporal knowledge graph for agent memory: when something became true and when the system learned it are separate axes Every fact carries valid_from and invalid_at, so point-in-time queries stay correct. See temporal facts
ConflictBank, Su et al. 2024 (arXiv 2408.12076, NeurIPS 2024 D&B) A systematic taxonomy of knowledge conflicts, including temporal contradictions between sources Two-stage contradiction detection at write time: cheap candidate filter first, model-judged resolution second. See temporal facts
Mem0, Chhikara et al. 2025 (arXiv 2504.19413) Extracted, structured memories reach accuracy close to replaying the full conversation history, at a fraction of its latency and token cost (full context 72.9% J, Mem0 66.9%, section 4.3) A dedicated facts surface (GET /v1/facts), separate from document search. See memory model
SELF-RAG, Asai et al. 2023 (arXiv 2310.11511) Critique tokens: the model verifies that a claim is supported by a retrieved passage before asserting it The /v1/context block opens with a short reader note: the memories are the verbatim source, so the model grounds its answer in them and replies that it does not know only when the information is absent. See architecture
Lost in the Middle, Liu et al. 2024 (arXiv 2307.03172) Models attend most to the beginning and end of the context window, and lose information buried in the middle Facts are ranked by relevance to the question, weighed by how recently they were confirmed, and capped at the ten best; memories come most relevant first (in a block above 2,000 tokens, those after the first five are spread so near-duplicates do not crowd out the rest), so off-topic rows cannot bury the ones that answer. See architecture
DPR, Karpukhin et al. 2020 (arXiv 2004.04906) Dense retrieval with asymmetric encoders for queries and passages Queries and documents are embedded with different prefixes, because a three-word question and a thousand-word note are not the same kind of object. See architecture
FrugalGPT, Chen, Zaharia, Zou 2023 (arXiv 2305.05176) A model cascade: route easy steps to small models, reserve strong models for the hard step Simple yes/no questions on the write path (is this the same relation? which family?) run with the least thinking the model allows, to save latency and tokens. Reads never invoke a generative model at all. See architecture

Bi-temporal facts, concretely

The Graphiti insight is that "when something became true" and "when we learned about it" are different timestamps, and conflating them corrupts point-in-time reasoning. A real example from our own store: the fact "EU server costs 40" was superseded on 2026-06-07 by "EU server costs 50 euro per month". The old fact wasn't deleted. Its invalid_at was set, so an agent asking "what does hosting cost now?" gets the current answer, while the history stays queryable. The full mechanics are on the temporal facts page.

Why the facts endpoint is deterministic

GET /v1/facts is a filter and a sort, by subject, predicate family and validity window, not a semantic search: same inputs, same outputs. That is also why facts reads are fast: there is no embedding call and no reranker in the hot path, just a database query. Semantic retrieval exists too (POST /v1/memories/search), but it is a separate endpoint with separate semantics, and the agent knows which is which.

In one CLI call:

korely cli korely facts
# deterministic read: same inputs, same lines, every time
› korely facts --entity "EU server" --include-invalidated
  fct_4b9e2a7c1d0f4e8a9c3b5d7e1f2a6c80  EU server · costs · 50 euro per month [from 2026-06-07]
  fct_e2c71f5a9b3d4c6e8f0a1b2c3d4e5f67  EU server · costs · 40 [from 2026-05-21] (superseded 2026-06-07)

The bi-temporal chain (Graphiti) is visible in the output, and the read itself is a pure lookup. No generative model ever composes output on the read path. Your agent's own model does the reasoning, which is why every plan includes at least a hundred times more reads than writes. The facts read is available on every tier, including the free Hobby plan, within your monthly query quota and your plan's rate limits.

One stack. The mechanisms above sit behind every surface: the REST API, the Python and Node SDKs, the CLI and the MCP server. There is one fact engine, one graph model and one temporal model, not a pipeline per surface, and each project keeps its own store, so one customer's memories never mix with another's.

Related work we study

Two papers that don't map to a single mechanism but shape how we think about the stack:

PaperWhy it matters here
HippoRAG, Gutierrez et al. 2024 (arXiv 2405.14831) Canonicalize entity names at write time instead of fanning out at read time. Korely keeps aliases of one entity (an explicit rename, for example), so facts written under the old name and the new one read as one subject. See the graph
Sleep-time compute, Lin et al. 2025 (arXiv 2504.13171) Consolidation work belongs off the critical path, when no one is waiting on a response. Korely follows the same principle: extraction and contradiction checking run at write time and in background work, never while an agent waits on a read; a read at most embeds the query. See architecture

Forgetting

Korely's temporal decay is scoring decay, never hard deletion. Older facts lose retrieval weight on a half-life schedule, but the rows stay in the graph. Erasure is a separate, explicit call. When you erase an end user with delete_all, their facts are actually gone, but the ranking algorithm never silently destroys data on its own.

For the design spectrum here: MemoryBank (arXiv 2305.10250) introduced Ebbinghaus-inspired forgetting curves for agent memory, and more recent variants (FadeMem, FSFM) explore learned and selective forgetting policies. We sit at the conservative end of that spectrum on purpose: a stale fact that ranks too high is visible and correctable by the user, data that disappears silently is not.

Benchmarks

We evaluate on benchmarks that probe the properties this page describes, rather than generic retrieval leaderboards.

The one we publish results on is LongMemEval (arXiv 2410.10813): 500 questions over timestamped multi-session haystacks. Its temporal-reasoning subset probes event time: Korely stores each memory's event time (the write's timestamp, or the day it was stored when none is given) and prints every memory in the context block under that day.

MemoryAgentBench (arXiv 2507.05257) scores selective forgetting: updating or invalidating a memory when new information contradicts it, the property Korely's two-stage invalidation targets. We have not published a run on it yet.

Our publishing principle: numbers ship with methodology, including the question categories where the system loses, so you can judge the result instead of a headline score.

How the write path works

Fact extraction and contradiction checking run when something is written. The read path never invokes a generative model: a search or context read embeds the query, and a facts read is a database query. Here is the full write pipeline, annotated by the paper it implements:

StageWhat happensPaper grounding
Embed Content is embedded with asymmetric prefix routing: queries and documents carry different prefixes because a three-word question and a thousand-word note are not the same kind of object DPR, Karpukhin et al. 2020
Store The memory is stored and the call returns. The next two steps run afterwards in a background worker, off the read path Sleep-time compute, Lin et al. 2025
Extract facts (subject, predicate, object) triples are typed against a learned vocabulary of predicates in 10 families and stamped with valid_from Graphiti / Zep, arXiv 2501.13956
Contradiction check Candidate conflict filter first; model-judged resolution second. Opposing fact gets invalid_at set, never deleted ConflictBank, Su et al. 2024

Every subsequent read is a pure data retrieval. The intelligence ran once, at write time. For a detailed diagram of the two paths, see Architecture: reads without an LLM.

How we evaluate: connecting claims to results

The paper table maps mechanisms to sources. The benchmark page maps those mechanisms to measurable outcomes on public datasets.

Our evaluation principle: numbers ship with their method, including the axes where the system is weak, so you can judge a result rather than a headline score.

What we claimHow it is testedWhere to read
Current answers after a change LongMemEval knowledge-update axis: returns the new value, not the stale one. Korely score: 90% (QA, n=20, oracle corpus). In this run the answers came from the retrieved memories; typed facts appeared in 1 of the 20 context blocks. Benchmark
Temporal reasoning over when things happened LongMemEval temporal-reasoning axis: recency, before/after, point-in-time. Korely score: 85% (QA, n=20, oracle corpus), answered from dated memories. Benchmark
Single-session recall LongMemEval single-session-user (85%) and single-session-assistant (100%) axes (QA, n=20 per axis, oracle corpus) Benchmark
Preference and cross-session answers LongMemEval single-session-preference (60%) and multi-session (55%) axes (QA, n=20 per axis, oracle corpus), the weakest axes of the run; recall is 100% and 95% Benchmark

Scores are self-reported from our own runs. Every question, an excerpt of the memory it was tested on, the answer and the judge verdicts are published on the benchmark page so you can inspect them.

Going deeper

The concept pages walk through each mechanism with API-level detail:

  • Temporal facts: the bi-temporal model, contradiction resolution, and point-in-time queries
  • Memory model: memories and facts, scoping (user_id / agent_id / run_id, where run_id labels memories and facts with one run or session and memory search and the memory listing can filter on it), and how reads compose
  • The graph: the entities named by the typed facts, their relations, and how an entity read returns every fact where an entity is subject or object
  • Architecture: the read path versus the write path, and why reads are retrieval, not generation

Read a paper we should know about? We mean it. If there is published work on agent memory, temporal knowledge graphs, or forgetting policies that you think beats what's described here, open an issue on GitHub or email info@korely.ai. Several rows in the tables above started as exactly that kind of pointer.


See also

  • Benchmark, LongMemEval per-axis scores, the method, and every question with its answer and verdict
  • Temporal facts, bi-temporal model, valid_from / invalid_at, the as_of parameter, contradiction pipeline in full
  • Architecture, the write pipeline vs the read path, why reads carry no model cost
  • The graph, entities from the typed facts, typed relationships, facts by entity
  • Memory model, memories and facts, scoping, how facts and memories compose in GET /v1/context
  • API reference, every endpoint with request and response shapes